Powershell启动进程以启动Powershell会话并传递本地变量



是否有方法使用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"

谢谢。

我确信没有直接的方法可以将变量从一个PowerShell会话传递到另一个。你能做的最好的事情是一些变通方法,比如在-ArgumentList中传递的代码中声明变量,在调用会话中插值。如何将变量插入-ArgumentList中的声明取决于变量的类型。对于一个数组和一个字符串,你可以这样做:

$command = '<contents of your scriptblock without the curly braces>'
Start-Process powershell -ArgumentList ("`$Array = echo $Array; `$String = '$String';" + $command)

我通过用"/"连接数组来创建一个字符串,并将脚本块输入到另一个带有适当参数的.ps1脚本中,然后在第二个脚本中将连接的字符串拆分回一个数组,并使用

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

很难看,但这是我唯一能让它发挥作用的方法。谢谢你的回复。

您可以将脚本块的内容封装在一个函数中,然后从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')}"

PowerShell.exe的命令行选项表示,在使用脚本块时,您应该能够通过添加-args:来传递参数

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

然而,当我尝试这样做时,我会得到以下错误:

-args:术语"-args"未被识别为cmdlet、函数、脚本文件或可操作程序的名称。检查的拼写名称,或者如果包含路径,请验证该路径是否正确,并且再试一次。

我将$MyInvocation | fl添加到脚本块中,以查看发生了什么,看起来-args只是附加到脚本块的反序列化命令上(因此出现了错误,因为-args不是有效的命令)。我还尝试过使用GetNewClosure()和$using:VariableName,但它们似乎只有在调用脚本块时才起作用(而不是我们使用它来序列化/反序列化命令)。

我把它包装在一个类似于deadlydog答案的函数中,就可以让它发挥作用。

$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]$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"

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

相关内容

  • 没有找到相关文章

最新更新