Powershell PSSession变量上下文

时间:2014-01-23 18:13:27

标签: powershell

我正在使用New-PSSession通过Invoke-Command在远程计算机上运行命令。举个例子,假设我运行命令FROM的机器叫做FROM-MACHINE,而我运行命令TO的机器叫做TO-MACHINE。

$session = New-PSSession -ComputerName TO-MACHINE
$script = ScriptBlock::Create("Write-Host Machine name is $env:COMPUTERNAME")
Invoke-Command -session $session -scriptBlock $script

我希望这能输出:

Machine name is TO-MACHINE

然而,它实际上是输出

Machine name is FROM-MACHINE

这也发生在文件路径的情况下 - 如果我想在“C:\ myprogram.exe”运行程序,powershell将尝试在“\\ FROM-MACHINE \ c $ \ myprogram”中找到myprogram.exe。 EXE”。

我的问题是:有没有办法(除了使用psexec)真正运行远程命令,变量和所有?我在这里错过了一些简单的东西吗?

2 个答案:

答案 0 :(得分:2)

您可以通过将ScriptBlock直接在代码中声明为ScriptBlock而不是String对象来避免这种情况。您只需将花括号中的代码包围起来即可。您可以将ScriptBlock对象存储在变量中,然后使用Invoke-Command参数将其传递到-ScriptBlock,就像之前一样。

$ScriptBlock = {
    $Program = 'c:\MyProgram.exe';
    Start-Process -Wait -FilePath $Program -ArgumentList 'args go here';

    Write-Host -Object "Write-Host Machine name is $env:COMPUTERNAME";
    }

Invoke-Command -ComputerName to-machine -ScriptBlock $ScriptBlock;

注意:您不必手动创建PowerShell远程处理会话。 Invoke-Command将为您照顾,除非您特别想让它们在后台打开。

答案 1 :(得分:1)

这种情况正在发生,因为您使用双引号字符串来创建脚本块。 $ env:在创建脚本块之前,COMPUTERNAME正在扩展为本地计算机名。如果使用单引号字符串,$ env:COMPUTERNAME将作为文本文本在脚本块中传递,并且在远程计算机上执行扩展之前不会进行扩展。因此,当您从字符串创建脚本块以便在远程计算机上执行时,如果要在脚本块中使用局部变量,则使用可扩展(双引号)字符串;如果要使用,则使用不可扩展(单引号)字符串来自远程机器的变量。

$session = New-PSSession -ComputerName TO-MACHINE
$script = [ScriptBlock]::Create('$env:COMPUTERNAME')
Invoke-Command -session $session -scriptBlock $script

如果要在同一个脚本块中混合和匹配,请使用可扩展字符串,然后使用反引号转义所有远程变量引用上的$:

$session = New-PSSession -ComputerName TO-MACHINE 
$script = [ScriptBlock]::Create(" Write-output $env:Computername; Write-Output `$env:COMPUTERNAME ")
Invoke-Command -session $session -scriptBlock $script
相关问题