Powershell启动进程以启动Powershell会话并传递局部变量

Powershell启动进程以启动Powershell会话并传递局部变量,powershell,start-process,scriptblock,Powershell,Start Process,Scriptblock,是否有方法使用Powershell Start Process cmdlet启动新的Powershell会话并传递带有本地变量的scriptblock(其中一个变量将是数组) 例如: $Array = @(1,2,3,4) $String = "This is string number" $Scriptblock = {$Array | ForEach-Object {Write-Host $String $_}} Start-Process Powershell -ArgumentLi

是否有方法使用Powershell Start Process cmdlet启动新的Powershell会话并传递带有本地变量的scriptblock(其中一个变量将是数组)

例如:

$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)
$command=''
启动进程powershell-ArgumentList(“`$Array=echo$Array;`$String='$String';“+$command”)

我可以通过将数组与“/”合并来创建一个字符串,并将scriptblock输入另一个带有适当参数的.ps1脚本,然后将合并的字符串拆分回第二个脚本中的数组,并使用

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

难看,但这是我唯一能让它工作的方法。感谢您的回复。

您可以将脚本块的内容包装在函数中,然后从ArgumentList调用函数,并将变量作为参数传递给函数


如果您想传递可序列化但不是字符串的对象,我编写了一个解决方案:

假设您应该能够通过添加-args在使用脚本块时传递参数:

PowerShell.exe -Command { - | <script-block> [-args <arg-array>] | <string> [<CommandParameters>] }
将其包装在脚本块中,并使用
$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"

请退后一步,描述您试图解决的实际问题,而不是您认为的解决方案。为什么您认为需要这个?您可以使用
&
操作符调用表达式。如您的示例中的
&$Scriptblock
。我想启动一个新的powershell会话并在该会话中运行Scriptblock。scriptblock需要包含初始会话中的局部变量。@atownson为什么需要新会话?您是否试图防止不必要的输出?或者您想将输出发送到其他地方吗?我在下面提出了一个可行的建议,但这有点困难,所以除非您真的决定通过Start Process将变量传递到新会话,在这里接受建议并重新审视一下你想用它来完成什么,以及是否有更优雅的方法来完成它,这不是一个坏主意。
$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
$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"