以下是我的WMI查询:
$Query = "SELECT * from MSVM_ComputerSystem where ElementName='$Gen2'"
$VMs = gwmi -Query $Query -Namespace "root\virtualization\v2"
但我希望有一个变量而不是虚拟机名Gen2。像
这样的东西$Query = "SELECT * from MSVM_ComputerSystem where ElementName='$VMName'"
$VMs = gwmi -Query $Query -Namespace "root\virtualization\v2"
命令Get-Help about_Quoting_Rules
没有帮助,或者我无法正确解释规则。我尝试了几十种不成功的变种,试图把它弄好。
答案 0 :(得分:1)
如果在定义查询时已经定义了嵌套变量,那么带变量的查询应该可以正常工作。像这样:
$VMName = 'Gen2'
$Query = "SELECT * FROM MSVM_ComputerSystem WHERE ElementName='$VMName'"
$VMs = gwmi -Query $Query -Namespace 'root\virtualization\v2'
如果您先定义$Query
,之后定义$VMName
$Query = "SELECT * FROM MSVM_ComputerSystem WHERE ElementName='$VMName'"
$VMName = 'Gen2'
因为嵌套变量会自动扩展为空字符串,因为它尚未定义,因此$Query
的值变为SELECT * FROM MSVM_ComputerSystem WHERE ElementName=''
。
如果由于某种原因你必须首先定义查询(例如作为排序的模板),并在稍后的时间点(来自用户输入或其他)定义变量,你必须这样做:
$Query = "SELECT * FROM MSVM_ComputerSystem WHERE ElementName='{0}'"
$VMName = 'Gen2'
$VMs = gwmi -Query ($Query -f $VMName) -Namespace 'root\virtualization\v2'
或者像这样:
$Query = "SELECT * FROM MSVM_ComputerSystem WHERE ElementName='`$VMName'"
$VMName = 'Gen2'
$VMs = gwmi -Query ($ExecutionContext.InvokeCommand.ExpandString($Query)) `
-Namespace 'root\virtualization\v2'
第一个示例将$Query
定义为带占位符({0}
)的格式字符串,并使用格式运算符(-f
)填充实际值,而第二个示例展开转义变量(`$VMName
)。
你也可以通过“切换”引号来做第二个例子的变体,这样你就不需要转义$
:
$Query = 'SELECT * FROM MSVM_ComputerSystem WHERE ElementName="$VMName"'
$VMName = 'Gen2'
$VMs = gwmi -Query ($ExecutionContext.InvokeCommand.ExpandString($Query)) `
-Namespace 'root\virtualization\v2'
答案 1 :(得分:0)
试试这样:
"ElementName=`"$Gen2`""
答案 2 :(得分:0)
似乎我自己找到了答案,感谢命令Get-Help about_Quoting_Rules。诀窍是使用所谓的Here String。我将它发布在这里供将来参考。
我不得不稍微重新设计代码。这是有效的代码。只需确保正确对齐Here String $ filter并在Here字符串的所有行的末尾使用CRLF。也许还有很多其他解决方案。
$filter=@"
ElementName='$VMName'
"@
$VMs = gwmi -class "MSVM_ComputerSystem" `
-namespace "root\virtualization\v2" `
-computername "." `
-filter $filter
完整代码在这里:
Function WaitForVMShutDown($VMName){
$filter=@"
ElementName='$VMName'
"@
$job = Start-Job {
$state=""
while ($state -ne "Stopped")
{
Start-Sleep -Seconds 1
$VMs = gwmi -class "MSVM_ComputerSystem" `
-namespace "root\virtualization\v2" `
-computername "." `
-filter $filter
foreach ($VM IN $VMs)
{
switch ($VM.EnabledState)
{
2{$state="Running"}
3{$state="Stopped"}
32768{$state="Paused"}
32769{$state="Suspended"}
32770 {$state="Starting"}
32771{$state="Taking Snapshot"}
32773{$state="Saving"}
32774{$state="Stopping"}
}
}
}
}
Wait-Job $job
}
WaitForVMShutDown("LondonDC")