প্যারামিটার এবং শংসাপত্রগুলির সাথে পাওয়ারশেল থেকে .ps1 স্ক্রিপ্ট শুরু করা এবং ভেরিয়েবল ব্যবহার করে আউটপুট পাওয়া


10

হ্যালো স্ট্যাক সম্প্রদায় :)

আমার একটা সহজ লক্ষ্য আছে। আমি অন্য পাওয়ারশেল স্ক্রিপ্ট থেকে কিছু পাওয়ারশেল স্ক্রিপ্ট শুরু করতে চাই, তবে এখানে 3 টি শর্ত রয়েছে:

  1. আমাকে শংসাপত্রগুলি পাস করতে হবে (এক্সিকিউশনটি একটি নির্দিষ্ট ডাটাবেসের সাথে সংযুক্ত থাকে যা নির্দিষ্ট ব্যবহারকারী থাকে)
  2. এটি কিছু পরামিতি নিতে হবে
  3. আমি আউটপুটটি একটি ভেরিয়েবলের মধ্যে পাস করতে চাই

অনুরূপ প্রশ্ন লিঙ্ক আছে । তবে উত্তরটি হ'ল 2 পিএস স্ক্রিপ্টগুলির মধ্যে যোগাযোগের উপায় হিসাবে ফাইলগুলি ব্যবহার করা। আমি কেবল অ্যাক্সেস দ্বন্দ্ব এড়াতে চাই। @ আপডেট: মূল স্ক্রিপ্ট আরও কয়েকটি স্ক্রিপ্ট শুরু করতে চলেছে। সুতরাং ফাইলগুলির সাথে সমাধানটি জটিল হতে পারে, যদি একই সময়ে একাধিক ব্যবহারকারীর কাছ থেকে মৃত্যুদন্ড কার্যকর করা হয়।

স্ক্রিপ্ট 1.ps1 হ'ল স্ক্রিপ্ট যা আউটপুট হিসাবে স্ট্রিং থাকা উচিত। (কেবল স্পষ্ট করে বলতে গেলে, এটি একটি কল্পিত স্ক্রিপ্ট, আসলটির 150 টি সারি রয়েছে, সুতরাং আমি কেবল একটি উদাহরণ বানাতে চেয়েছিলাম)

param(  
[String]$DeviceName
)
#Some code that needs special credentials
$a = "Device is: " + $DeviceName
$a

এক্সিকিউটস স্ক্রিপ্টস.পিএস 1 এর উপরে উল্লিখিত 3 টি শর্তের সাথে একটিটি আহ্বান করা উচিত

আমি একাধিক সমাধান চেষ্টা করেছি। নমুনা জন্য এটি:

$arguments = "C:\..\script1.ps1" + " -ClientName" + $DeviceName
$output = Start-Process powershell -ArgumentList $arguments -Credential $credentials
$output 

আমি এটি থেকে কোনও আউটপুট পাই না এবং আমি কেবল স্ক্রিপ্ট দিয়ে কল করতে পারি না

&C:\..\script1.ps1 -ClientName PCPC

কারণ আমি -Credentialএটিতে প্যারামিটারটি পাস করতে পারি না ..

তুমাকে অগ্রিম ধন্যবাদ!


যদি এটি অ্যাক্সেস দ্বন্দ্বগুলি সম্পর্কে হয়: প্রতিটি অনুরোধের জন্য অনন্য ফাইলের নাম তৈরি করা আপনার সমস্যার সমাধান করবে, তাই না?
mklement0

1
@ এমকিলেটমেন্ট 0 যদি এটি একমাত্র উপায় হয় তবে আমি সেই সমাধানটি সন্ধান করব। কেবল এলোমেলো ফাইলের নাম উত্পাদন করা, এ জাতীয় ফাইল উপস্থিত রয়েছে কিনা তা যাচাই করা হচ্ছে ... আমি আমার জাভা কোড থেকে 6 থেকে 10 স্ক্রিপ্টগুলি সম্পাদন করব এবং প্রতিবার আমি ব্যবহার করছি বা অন্য কেউ আমার অ্যাপ্লিকেশন ব্যবহার করছে তখন 6 থেকে 10 ফাইলের প্রয়োজন হবে files সুতরাং এর পারফরম্যান্স সম্পর্কেও
Dmytro

উত্তর:


2

বিঃদ্রঃ:

  • নিম্নলিখিত সমাধানটি যে কোনও বাহ্যিক প্রোগ্রামের সাথে কাজ করে এবং আউটপুটটিকে টেক্সট হিসাবে অবিচ্ছিন্নভাবে ক্যাপচার করে

  • আর একটি পাওয়ারশেল উদাহরণ হিসাবে প্রার্থনা করতে এবং এর আউটপুটটি সমৃদ্ধ বস্তু (সীমাবদ্ধতা সহ) হিসাবে ক্যাপচার করতে নীচের অংশে বৈকল্পিক সমাধানটি দেখুন বা ম্যাথিয়াস আর জেসেনের সহায়ক উত্তরটি বিবেচনা করুন , যা পাওয়ারশেল এসডিকে ব্যবহার করে ।

মেমরিতে প্রসেস আউটপুট ক্যাপচার করার জন্য এবং নেট নেটওয়ার্কের সরাসরি ব্যবহারেরSystem.Diagnostics.ProcessSystem.Diagnostics.ProcessStartInfo উপর ভিত্তি করে একটি প্রমাণ-ধারণাটি রয়েছে (আপনার প্রশ্নে যেমন বলা হয়েছে, Start-Processকোনও বিকল্প নয়, কারণ এটি কেবল ফাইলগুলিতে আউটপুট ক্যাপচারকে সমর্থন করে , যেমন এই উত্তরে দেখানো হয়েছে ) :

বিঃদ্রঃ:

  • ভিন্ন ব্যবহারকারী হিসাবে চলার কারণে, এটি কেবল উইন্ডোজে সমর্থিত (। নেট কোর 3.1 হিসাবে) তবে সেখানে পাওয়ারশেল উভয় সংস্করণেই।

  • ভিন্ন ব্যবহারকারী হিসাবে চালানোর প্রয়োজন হওয়ার কারণে এবং আউটপুট ক্যাপচার .WindowStyleকরার কারণে, লুকানো কমান্ডটি চালানোর জন্য ব্যবহার করা যাবে না (কারণ এটি হওয়া .WindowStyleদরকার যা এই প্রয়োজনীয়তার সাথে সামঞ্জস্যপূর্ণ নয়); যাইহোক, যেহেতু সমস্ত আউটপুট ক্যাপচার করা হচ্ছে , কার্যকরভাবে গোপন বাস্তবায়নের ফলাফল নির্ধারণ করে ।.UseShellExecute$true.CreateNoNewWindow$true

# Get the target user's name and password.
$cred = Get-Credential

# Create a ProcessStartInfo instance
# with the relevant properties.
$psi = [System.Diagnostics.ProcessStartInfo] @{
  # For demo purposes, use a simple `cmd.exe` command that echoes the username. 
  # See the bottom section for a call to `powershell.exe`.
  FileName = 'cmd.exe'
  Arguments = '/c echo %USERNAME%'
  # Set this to a directory that the target user
  # is permitted to access.
  WorkingDirectory = 'C:\'                                                                   #'
  # Ask that output be captured in the
  # .StandardOutput / .StandardError properties of
  # the Process object created later.
  UseShellExecute = $false # must be $false
  RedirectStandardOutput = $true
  RedirectStandardError = $true
  # Uncomment this line if you want the process to run effectively hidden.
  #   CreateNoNewWindow = $true
  # Specify the user identity.
  # Note: If you specify a UPN in .UserName
  # (user@doamin.com), set .Domain to $null
  Domain = $env:USERDOMAIN
  UserName = $cred.UserName
  Password = $cred.Password
}

# Create (launch) the process...
$ps = [System.Diagnostics.Process]::Start($psi)

# Read the captured standard output.
# By reading to the *end*, this implicitly waits for (near) termination
# of the process.
# Do NOT use $ps.WaitForExit() first, as that can result in a deadlock.
$stdout = $ps.StandardOutput.ReadToEnd()

# Uncomment the following lines to report the process' exit code.
#   $ps.WaitForExit()
#   "Process exit code: $($ps.ExitCode)"

"Running ``cmd /c echo %USERNAME%`` as user $($cred.UserName) yielded:"
$stdout

উপরেরটি নীচের মতো কিছু দেয়, প্রসেসটি সফলভাবে প্রদত্ত ব্যবহারকারীর পরিচয় দিয়ে চলেছে:

Running `cmd /c echo %USERNAME%` as user jdoe yielded:
jdoe

যেহেতু আপনি অন্য আহ্বান করছি PowerShell উদাহরণস্বরূপ , আপনি চাইতে পারেন সদ্ব্যবহার PowerShell CLI এর CLIXML বিন্যাস, যা আউটপুট deserializing দেয় আউটপুট প্রতিনিধিত্ব করার ক্ষমতা সমৃদ্ধ বস্তু , সীমিত টাইপ বিশ্বস্ততা যদ্যপি , যেমন ব্যাখ্যা এই সংশ্লিষ্ট উত্তর

# Get the target user's name and password.
$cred = Get-Credential

# Create a ProcessStartInfo instance
# with the relevant properties.
$psi = [System.Diagnostics.ProcessStartInfo] @{
  # Invoke the PowerShell CLI with a simple sample command
  # that calls `Get-Date` to output the current date as a [datetime] instance.
  FileName = 'powershell.exe'
  # `-of xml` asks that the output be returned as CLIXML,
  # a serialization format that allows deserialization into
  # rich objects.
  Arguments = '-of xml -noprofile -c Get-Date'
  # Set this to a directory that the target user
  # is permitted to access.
  WorkingDirectory = 'C:\'                                                                   #'
  # Ask that output be captured in the
  # .StandardOutput / .StandardError properties of
  # the Process object created later.
  UseShellExecute = $false # must be $false
  RedirectStandardOutput = $true
  RedirectStandardError = $true
  # Uncomment this line if you want the process to run effectively hidden.
  #   CreateNoNewWindow = $true
  # Specify the user identity.
  # Note: If you specify a UPN in .UserName
  # (user@doamin.com), set .Domain to $null
  Domain = $env:USERDOMAIN
  UserName = $cred.UserName
  Password = $cred.Password
}

# Create (launch) the process...
$ps = [System.Diagnostics.Process]::Start($psi)

# Read the captured standard output, in CLIXML format,
# stripping the `#` comment line at the top (`#< CLIXML`)
# which the deserializer doesn't know how to handle.
$stdoutCliXml = $ps.StandardOutput.ReadToEnd() -replace '^#.*\r?\n'

# Uncomment the following lines to report the process' exit code.
#   $ps.WaitForExit()
#   "Process exit code: $($ps.ExitCode)"

# Use PowerShell's deserialization API to 
# "rehydrate" the objects.
$stdoutObjects = [Management.Automation.PSSerializer]::Deserialize($stdoutCliXml)

"Running ``Get-Date`` as user $($cred.UserName) yielded:"
$stdoutObjects
"`nas data type:"
$stdoutObjects.GetType().FullName

উপরের ফলাফলগুলি নীচের মতো কিছু করে, যা দেখায় যে [datetime]উদাহরণ ( System.DateTime) আউটপুট দ্বারা এর Get-Datedeserialized ছিল:

Running `Get-Date` as user jdoe yielded:

Friday, March 27, 2020 6:26:49 PM

as data type:
System.DateTime

5

Start-Processপাওয়ারশেল থেকে পাওয়ারশেলটি আহ্বানের জন্য আমার শেষ অবলম্বন পছন্দ হবে - বিশেষত কারণ সমস্ত I / O স্ট্রিং হয়ে যায় (ডিসরিয়ালাইজড) বস্তু নয়।

দুটি বিকল্প:

1. ব্যবহারকারী যদি স্থানীয় প্রশাসক হন এবং পিএসরেমোটিং কনফিগার করা থাকে

যদি স্থানীয় মেশিনের বিরুদ্ধে দূরবর্তী সেশনটি (দুর্ভাগ্যক্রমে স্থানীয় প্রশাসকদের মধ্যে সীমাবদ্ধ) থাকে তবে আমি অবশ্যই এটি নিয়ে যাব Invoke-Command:

$strings = Invoke-Command -FilePath C:\...\script1.ps1 -ComputerName localhost -Credential $credential

$strings ফলাফল থাকবে।


২. ব্যবহারকারী যদি লক্ষ্য সিস্টেমে প্রশাসক না হন

Invoke-Commandপ্রক্রিয়া বহির্ভূত রানস্পেস স্পিনিং করে আপনি নিজের "স্থানীয় কেবল " লিখতে পারেন :

  1. PowerShellProcessInstanceএকটি ভিন্ন লগইনের অধীনে একটি তৈরি করা হচ্ছে
  2. উক্ত প্রক্রিয়াটিতে একটি রানস্পেস তৈরি করা
  3. প্রক্রিয়া বহির্ভূত রানস্পেসে আপনার কোডটি কার্যকর করুন

আমি নীচে এই জাতীয় ফাংশন একসাথে রেখেছি, ওয়াক-থ্রোয়ের জন্য ইনলাইন মন্তব্যগুলি দেখুন:

function Invoke-RunAs
{
    [CmdletBinding()]
    param(
        [Alias('PSPath')]
        [ValidateScript({Test-Path $_ -PathType Leaf})]
        [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [string]
        ${FilePath},

        [Parameter(Mandatory = $true)]
        [pscredential]
        [System.Management.Automation.CredentialAttribute()]
        ${Credential},

        [Alias('Args')]
        [Parameter(ValueFromRemainingArguments = $true)]
        [System.Object[]]
        ${ArgumentList},

        [Parameter(Position = 1)]
        [System.Collections.IDictionary]
        $NamedArguments
    )

    begin
    {
        # First we set up a separate managed powershell process
        Write-Verbose "Creating PowerShellProcessInstance and runspace"
        $ProcessInstance = [System.Management.Automation.Runspaces.PowerShellProcessInstance]::new($PSVersionTable.PSVersion, $Credential, $null, $false)

        # And then we create a new runspace in said process
        $Runspace = [runspacefactory]::CreateOutOfProcessRunspace($null, $ProcessInstance)
        $Runspace.Open()
        Write-Verbose "Runspace state is $($Runspace.RunspaceStateInfo)"
    }

    process
    {
        foreach($path in $FilePath){
            Write-Verbose "In process block, Path:'$path'"
            try{
                # Add script file to the code we'll be running
                $powershell = [powershell]::Create([initialsessionstate]::CreateDefault2()).AddCommand((Resolve-Path $path).ProviderPath, $true)

                # Add named param args, if any
                if($PSBoundParameters.ContainsKey('NamedArguments')){
                    Write-Verbose "Adding named arguments to script"
                    $powershell = $powershell.AddParameters($NamedArguments)
                }

                # Add argument list values if present
                if($PSBoundParameters.ContainsKey('ArgumentList')){
                    Write-Verbose "Adding unnamed arguments to script"
                    foreach($arg in $ArgumentList){
                        $powershell = $powershell.AddArgument($arg)
                    }
                }

                # Attach to out-of-process runspace
                $powershell.Runspace = $Runspace

                # Invoke, let output bubble up to caller
                $powershell.Invoke()

                if($powershell.HadErrors){
                    foreach($e in $powershell.Streams.Error){
                        Write-Error $e
                    }
                }
            }
            finally{
                # clean up
                if($powershell -is [IDisposable]){
                    $powershell.Dispose()
                }
            }
        }
    }

    end
    {
        foreach($target in $ProcessInstance,$Runspace){
            # clean up
            if($target -is [IDisposable]){
                $target.Dispose()
            }
        }
    }
}

তারপরে যেমন ব্যবহার করুন:

$output = Invoke-RunAs -FilePath C:\path\to\script1.ps1 -Credential $targetUser -NamedArguments @{ClientDevice = "ClientName"}

0

rcv.ps1

param(
    $username,
    $password
)

"The user is:  $username"
"My super secret password is:  $password"

অন্য লিপি থেকে কার্যকর:

.\rcv.ps1 'user' 'supersecretpassword'

আউটপুট:

The user is:  user
My super secret password is:  supersecretpassword

1
আমি এই exectuion করার credentails পাস করতে হবে ...
Dmytro

প্রাসঙ্গিক অংশ আপডেট।
thepip3r

স্পষ্ট করার জন্য: উদ্দেশ্যটি কেবল শংসাপত্রগুলি পাস করার জন্য নয়, শংসাপত্রগুলির দ্বারা চিহ্নিত ব্যবহারকারী হিসাবে চালানো
mklement0

1
@ এমকিলেটমেন্ট ০, স্পষ্টির জন্য ধন্যবাদ কারণ প্রশ্নটি জিজ্ঞাসিত হওয়ার বিভিন্ন পুনরাবৃত্তি দ্বারা এটি আমার কাছে মোটেই পরিষ্কার ছিল না।
thepip3r

0

আপনি একটি পিএস 1 স্ক্রিপ্টে প্যারামিটারটি পাস করার জন্য নিম্নলিখিতটি কী করতে পারেন।

প্রথম লিপিটি একটি উত্স.ps1 হতে পারে যেখানে আমরা লিখি:

& C:\scripts\dest.ps1 Pa$$w0rd parameter_a parameter_n

ভেরিয়েবলগুলি ক্যাপচারের জন্য নিম্নলিখিত গন্তব্য স্ক্রিপ্ট dest.ps1 এ নিম্নলিখিত কোড থাকতে পারে

$var0 = $args[0]
$var1 = $args[1]
$var2 = $args[2]
Write-Host "my args",$var0,",",$var1,",",$var2

এবং ফলাফল হবে

my args Pa$$w0rd, parameter_a, parameter_n

1
মূল লক্ষ্যটি হ'ল সমস্ত শর্তকে 1 টি প্রয়োগের সাথে সংযুক্ত করা। আমাকে প্যারামিটারগুলি পাস করতে হবে এবং শংসাপত্রগুলি পাস করতে হবে!
Dmytro

"সমস্ত শর্তকে 1 কার্যকরকরণের সাথে একত্রিত করুন" এর সাথে আপনার অর্থ কী? আমি মনে করি না যে আপনি নিজের মতো করে "-" চিহ্ন দিয়ে একটি প্যারামিটার যুক্ত করতে পারবেন .. আমি মনে করি আপনাকে গন্তব্য স্ক্রিপ্টে স্ট্রিংগুলি পুনরায় ফর্ম্যাট করতে হবে
অ্যান্ডি ম্যাক্রে

আমার অবশ্যই কিছু PS1 ফাইল প্যারামিটার সহ -Credential $credentialsকার্যকর করতে হবে এবং এই এক্সিকিউশনে প্যারামিটারটি পাস করতে হবে এবং এর থেকে আউটপুটটি ভেরিয়েবলের মধ্যে পেতে পারি। পিএস 1। স্ক্রিপ্ট ইম এক্সিকিউট করা শেষে একটি শৃঙ্খলা শব্দের স্ট্রিং নিক্ষেপ করছে। আমি এটি দিয়ে কীভাবে করেছি তা দেখুন Start-processতবে এই ফাংশনটি আউটপুট উৎপন্ন করে না
Dmytro

আমি মনে করি পাওয়ারশেল আপনাকে এই $ আর্গুমেন্টগুলি = "সি: \ .. \ স্ক্রিপ্ট 1.ps1" + "-প্রেমী নাম" + $ ডিভাইসনামের মতো প্যারামিটারটি পাস করার অনুমতি দেয় না। আপনার সম্ভবত সম্ভবত "-" মুছে ফেলার কথা ভাবা উচিত
অ্যান্ডি ম্যাক্রে

1
যে মৌমাছি বলেছে। প্রারম্ভিক প্রক্রিয়া প্যারামিটার এবং শংসাপত্রগুলির সাথে স্ক্রিপ্টটি কার্যকর করে, বিট এটি এই আউটপুটটিকে ভেরিয়েবলের মধ্যে সংরক্ষণ করে না। আমি যদি $outputভেরিয়েবল অ্যাক্সেস করার চেষ্টা করি তবে এটি শূন্য। @ এমকিলেমেন্ট ০ থেকে আসা অন্যান্য আইডিয়াটি কোনও ফাইলে আউটপুট সংরক্ষণ করা। তবে আমার ক্ষেত্রে এটি এক জায়গায় প্রচুর পরিমাণে ফাইলের কারণ হবে। সমস্ত বিভিন্ন স্ক্রিপ্ট সহ বিভিন্ন ব্যবহারকারী থেকে তৈরি
Dmytro
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.