7

有没有办法使用 Powershell Start-Process cmdlet 来启动一个新的 Powershell 会话并传递一个带有局部变量的脚本块(其中一个将是一个数组)?

例子:

$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 会话传递到另一个。您可以做的最好的事情是一些解决方法,例如在您传入-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

您可以将脚本块的内容包装在一个函数中,然后从 ArgumentList 调用该函数并将变量作为参数传递给该函数,就像我在这篇文章中所做的那样。

$ScriptBlock = {
    function Test([string]$someParameter)
    {
        # Use $someParameter to do something...
    }
}

# Run the script block and pass in parameters.
$myString = "Hello"
Start-Process -FilePath PowerShell -ArgumentList "-Command & {$ScriptBlock Test('$myString')}"
于 2014-03-19T22:54:29.343 回答
2

我能够通过使用“/”连接数组来创建一个字符串并将脚本块输入另一个具有适当参数的.ps1脚本并将连接的字符串拆分回第二个脚本中的数组并使用

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”未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。检查名称的拼写,或者如果包含路径,请验证路径是否正确并重试。

我添加$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

如果你想传递可序列化但不是字符串的对象,我写了一个解决方案:有没有办法通过启动进程将可序列化对象传递给 PowerShell 脚本?

于 2015-12-07T01:05:18.640 回答