7

Powershell Start-Process コマンドレットを使用して新しい Powershell セッションを開始し、ローカル変数 (そのうちの 1 つは配列になります) を含むスクリプト ブロックを渡す方法はありますか?

例:

$Array = @(1,2,3,4)

$String = "This is string number"

$Scriptblock = {$Array | ForEach-Object {Write-Host $String $_}}

Start-Process Powershell -ArgumentList "$Scriptblock"

ありがとう。

4

5 に答える 5

3

ある PowerShell セッションから別の PowerShell セッションに変数を直接渡す方法はないと確信しています。あなたができる最善の方法は、-ArgumentListで渡すコードで変数を宣言し、呼び出しセッションで値を補間するなど、いくつかの回避策です。-ArgumentListの宣言に変数を補間する方法は、変数のタイプによって異なります。配列と文字列の場合、次のようなことができます。

$command = '<contents of your scriptblock without the curly braces>'

Start-Process powershell -ArgumentList ("`$Array = echo $Array; `$String = '$String';" + $command)
于 2013-07-21T21:38:46.163 に答える
2

配列を「/」で結合して文字列を作成し、適切なパラメーターを使用してスクリプトブロックを別の.ps1スクリプトに入力し、結合された文字列を2番目のスクリプト内の配列に分割して使用することで、これを機能させることができました

Start-Process Powershell -ArgumentList "&C:\script.ps1 $JoinedArray $String"

醜いですが、それが私がそれを機能させる唯一の方法です。すべての返信に感謝します。

于 2013-07-22T02:25:16.290 に答える
2

PowerShell.exeのコマンド ライン オプションには、スクリプト ブロックを使用するときに -args を追加することで引数を渡すことができるはずであることが示されています。

PowerShell.exe -Command { - | <script-block> [-args <arg-array>] | <string> [<CommandParameters>] }

ただし、それを実行しようとすると、次のエラーが発生します。

-args : 「-args」という用語は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。名前のスペルを確認するか、パスが含まれている場合は、パスが正しいことを確認してから再試行してください。

何が起こっているかを確認するためにスクリプト ブロックに追加$MyInvocation | flしましたが、スクリプト ブロック内の逆シリアル化されたコマンドに -args が追加されているように見えます (したがって、-args は有効なコマンドではないため、エラーが発生します)。GetNewClosure() と $Using:VariableNameも使用してみましたが、これらはスクリプト ブロックが呼び出されたときにのみ機能するように見えます (これとは対照的に、コマンドをシリアル化/逆シリアル化するために使用しています)。

Deadlydog's answer のような関数でラップすることで、機能させることができました。

$var = "this is a test"

$scriptblock = {
    $MyInvocation | fl #Show deserialized commands
    function AdminTasks($message){
        write-host "hello world: $message"
    }
}

Start-Process powershell -ArgumentList '-noexit','-nologo','-noprofile','-NonInteractive','-Command',$scriptblock,"AdminTasks('$var')" -Verb runAs #-WindowStyle Hidden

#Output:
MyCommand             :
                         $MyInvocation | fl #Show deserialized commands
                         function AdminTasks($message){
                         write-host hello world: $message
                         }
                         AdminTasks('this is a test')
BoundParameters       : {}
UnboundArguments      : {}
ScriptLineNumber      : 0
OffsetInLine          : 0
HistoryId             : 1
ScriptName            :
Line                  :
PositionMessage       :
PSScriptRoot          :
PSCommandPath         :
InvocationName        :
PipelineLength        : 2
PipelinePosition      : 1
ExpectingInput        : False
CommandOrigin         : Runspace
DisplayScriptPosition :


hello world: this is a test

スクリプト ブロックでラップして$args[0]orを使用$args[1]することもできますが、デシリアライズ時に問題が発生した場合は $var0 または $var1 を引用符で囲み、`$ を使用して $sb が置き換えられないようにする必要があることに注意してください。 "" その変数は呼び出し元のスコープに存在しないため:

$var0 = "hello"
$var1 = "world"

$scriptblock = {
    $MyInvocation | fl #Show deserialized commands
    $sb = {
        write-host $args[0] $args[1]
    }
}

Start-Process powershell -ArgumentList '-noexit','-nologo','-noprofile','-NonInteractive','-Command',$scriptblock,"& `$sb $var0 $var1"
于 2016-01-07T19:07:44.103 に答える
0

シリアル化可能で文字列ではないオブジェクトを渡したい場合、私は解決策を書きました

于 2015-12-07T01:05:18.640 に答える