我有一台工作计算机(A)和另一台运行虚拟机的Hyper-V服务器(B)。
如果我使用RDP连接到Hyper-V服务器B并运行Get-VM Where-Object {$_.State -eq 'Running'}
,我将得到一个有效的答案:
Name State CPUUsage(%) MemoryAssigned(M) Uptime Status
---- ----- ----------- ----------------- ------ ------
vm1 Running 2 2048 20:07:05 Operating normally
vm2 Running 0 1024 3.00:49:30 Operating normally
接下来,我编写了一个PS脚本以在我的工作机A上运行:
$sess = New-PSSession $SETTING_SESSION_HOST
$commandStr = "Get-VM | Where-Object { `$_.State -eq 'Running' }"
#or a simple version: $commandStr = "Get-VM"
[console]::writeline("Executing: [{0}]", $commandStr)
$commandBlock = [scriptblock]::Create($commandStr)
$job = Invoke-Command -Session $sess -ScriptBlock $commandBlock -AsJob
Wait-Job $job
$vml = Receive-Job $job
foreach($m in $vml)
{
[console]::writeline("Executing: [{0}]", $m.Name)
}
$g = Format-List -InputObject $vml
[console]::writeline("format list: [{0}]", $g)
在这里,我希望看到2行分别包含“ vm1”和“ vm2”。但是我得到了一个空的答复:
Executing: [Get-VM | Where-Object { $_.State -eq 'Running' }]
format list: []
关于如何从远程作业中获得远程响应的任何想法? 此外,脚本的执行时间约为6秒(全部花费在Wait-Job中),而在服务器上则可以立即运行。
编辑:添加了-AsJob参数 编辑:固定变量
答案 0 :(得分:0)
我可以提出以下建议:
$sess = New-PSSession $SETTING_SESSION_HOST
$wml = Invoke-Command -Session $sess -ScriptBlock {Get-VM | where State -eq 'Running'}
$wml.Name
PS:在撰写本文时,我注意到您将$wml
设置为Receive-Job $job
,但随后您又遍历了$vml
,因此它可能只是{{1}的错字v
}
答案 1 :(得分:0)
进行一些调试之后,我找到了答案:只有一台机器正在运行时,返回结果是类型为Microsoft.HyperV.PowerShell.VirtualMachine
的对象,因此此代码可以很好地工作:
$vml = Invoke-Command -Session $sess -ScriptBlock {Get-VM | where State -eq 'Running'}
$vml.Name
但是,如果有1台以上的计算机正在运行,则结果为Object[]
,我发现工作的代码如下:
$vml = Invoke-Command -Session $sess -ScriptBlock {Get-VM | where State -eq 'Running'}
$len = $vml.length
if ($len)
{
[console]::writeline("Machine count: [{0}]", $len)
for ($i=0; $i -lt $len; $i++)
{
$m = $vml[$i]
[console]::writeline("machine: [{0}]", $m.Name)
}
}
else
{
[console]::writeline("Machine: [{0}]", $vml.Name)
}
请注意,由于某种原因,似乎foreach($m in $vml)
似乎不起作用。
我认为问题在于方法要么返回对象,要么返回数组。