如何将变量值传递给 Invoke-Command
How to pass variable value to Invoke-Command
我正在尝试获取处于特定状态(已保存、运行、已停止)的机器列表。我将机器的状态作为参数传递给函数。
Function global:Resource-Summary
{
Param(
[parameter(mandatory=$true)] $ProgramName,
[parameter(mandatory=$true)] $ServerName
)
PROCESS
{
Foreach ($Server in $ServerName)
{
Invoke-Command -ComputerName $Server -ScriptBlock {
$VMs = Get-VM
$colVMs = @()
foreach ($VM in $VMs)
{
$objVM = New-Object System.Object
$objVM | Add-Member -MemberType NoteProperty -Name VMName -Value $VM.VMName
$objVM | Add-Member -MemberType NoteProperty -Name VMNotes -Value $VM.Notes
$objVM | Add-Member -MemberType NoteProperty -Name VMState -Value $VM.State
$colVMs += $objVM
}
$a = @{Expression={$_.VMName};Label='VM Name'}, `
@{Expression={$_.VMNotes};Label='VM Description'}, `
@{Expression={$_.VMState};Label='State'}
"Program Name : $ProgramName"
$colVMs |Where-Object {($_.VMState -eq '$ProgramName')} | Format-Table $a -AutoSize
} -ArgumentList $ProgramName
}
}
}
当我运行Resource-Summary -ProgramName Running -ServerName Demo
我没有得到任何价值。
当我用 RUNNING
替换 $ProgramName
时,我得到了预期的输出。
有几件事跳出来了:
如果您在单引号内有一个变量,它不会被 PowerShell 自动解析,因此在本节中,您实际上是将 VM 的状态与字符串 $ProgramName 而不是它的值:
$_.VMState -eq '$ProgramName'
尝试更改为双引号,或者根本 none。
此外,请检查括号 - 您缺少 Where-Object.
的结尾括号
供参考,例如参见post 关于如何 将参数传递给 powershell 中的脚本块
.
你的脚本中的问题是你如何调用脚本块,这在上面的 link 中有更详细的解释,但是你需要以相同的方式将任何 "external" 输入传递给它就好像你会像函数一样调用它。
您部分正确地执行了此操作,您正在使用 -ArgumentList
参数将 $ProgramName
发送到脚本锁,但您尚未在脚本块中指定如何访问它。
例如,查看
Invoke-Command -ArgumentList "Application" -ScriptBlock {
param($log)
Get-EventLog $log
}
此处 -ArgumentList
包含输入,在脚本块内,$log
被赋值。
更新脚本以考虑到这一点:
Function global:Resource-Summary
{
Param(
[parameter(mandatory=$true)] $ProgramName,
[parameter(mandatory=$true)] $ServerName
)
PROCESS
{
Foreach ($Server in $ServerName)
{
Invoke-Command -ComputerName $Server -ScriptBlock {
param($name)
$VMs = Get-VM
$colVMs = @()
foreach ($VM in $VMs)
{
$objVM = New-Object System.Object
$objVM | Add-Member -MemberType NoteProperty -Name VMName -Value $VM.VMName
$objVM | Add-Member -MemberType NoteProperty -Name VMNotes -Value $VM.Notes
$objVM | Add-Member -MemberType NoteProperty -Name VMState -Value $VM.State
$colVMs += $objVM
}
$a = @{Expression={$_.VMName};Label='VM Name'}, `
@{Expression={$_.VMNotes};Label='VM Description'}, `
@{Expression={$_.VMState};Label='State'}
"Program Name : $ProgramName"
$colVMs |Where-Object {($_.VMState -eq "$name") | Format-Table $a -AutoSize
}
} -ArgumentList $ProgramName
}
}
}
另外,在我看来,-ArgumentList
在错误的行上,它需要在下面的右括号之后,一行完成。这样它就与 Invoke-Command
和脚本块在同一个 cmdlet 上。
我正在尝试获取处于特定状态(已保存、运行、已停止)的机器列表。我将机器的状态作为参数传递给函数。
Function global:Resource-Summary
{
Param(
[parameter(mandatory=$true)] $ProgramName,
[parameter(mandatory=$true)] $ServerName
)
PROCESS
{
Foreach ($Server in $ServerName)
{
Invoke-Command -ComputerName $Server -ScriptBlock {
$VMs = Get-VM
$colVMs = @()
foreach ($VM in $VMs)
{
$objVM = New-Object System.Object
$objVM | Add-Member -MemberType NoteProperty -Name VMName -Value $VM.VMName
$objVM | Add-Member -MemberType NoteProperty -Name VMNotes -Value $VM.Notes
$objVM | Add-Member -MemberType NoteProperty -Name VMState -Value $VM.State
$colVMs += $objVM
}
$a = @{Expression={$_.VMName};Label='VM Name'}, `
@{Expression={$_.VMNotes};Label='VM Description'}, `
@{Expression={$_.VMState};Label='State'}
"Program Name : $ProgramName"
$colVMs |Where-Object {($_.VMState -eq '$ProgramName')} | Format-Table $a -AutoSize
} -ArgumentList $ProgramName
}
}
}
当我运行Resource-Summary -ProgramName Running -ServerName Demo
我没有得到任何价值。
当我用 RUNNING
替换 $ProgramName
时,我得到了预期的输出。
有几件事跳出来了:
如果您在单引号内有一个变量,它不会被 PowerShell 自动解析,因此在本节中,您实际上是将 VM 的状态与字符串 $ProgramName 而不是它的值:
$_.VMState -eq '$ProgramName'
尝试更改为双引号,或者根本 none。
此外,请检查括号 - 您缺少 Where-Object.
的结尾括号供参考,例如参见post 关于如何 将参数传递给 powershell 中的脚本块 .
你的脚本中的问题是你如何调用脚本块,这在上面的 link 中有更详细的解释,但是你需要以相同的方式将任何 "external" 输入传递给它就好像你会像函数一样调用它。
您部分正确地执行了此操作,您正在使用 -ArgumentList
参数将 $ProgramName
发送到脚本锁,但您尚未在脚本块中指定如何访问它。
例如,查看
Invoke-Command -ArgumentList "Application" -ScriptBlock {
param($log)
Get-EventLog $log
}
此处 -ArgumentList
包含输入,在脚本块内,$log
被赋值。
更新脚本以考虑到这一点:
Function global:Resource-Summary
{
Param(
[parameter(mandatory=$true)] $ProgramName,
[parameter(mandatory=$true)] $ServerName
)
PROCESS
{
Foreach ($Server in $ServerName)
{
Invoke-Command -ComputerName $Server -ScriptBlock {
param($name)
$VMs = Get-VM
$colVMs = @()
foreach ($VM in $VMs)
{
$objVM = New-Object System.Object
$objVM | Add-Member -MemberType NoteProperty -Name VMName -Value $VM.VMName
$objVM | Add-Member -MemberType NoteProperty -Name VMNotes -Value $VM.Notes
$objVM | Add-Member -MemberType NoteProperty -Name VMState -Value $VM.State
$colVMs += $objVM
}
$a = @{Expression={$_.VMName};Label='VM Name'}, `
@{Expression={$_.VMNotes};Label='VM Description'}, `
@{Expression={$_.VMState};Label='State'}
"Program Name : $ProgramName"
$colVMs |Where-Object {($_.VMState -eq "$name") | Format-Table $a -AutoSize
}
} -ArgumentList $ProgramName
}
}
}
另外,在我看来,-ArgumentList
在错误的行上,它需要在下面的右括号之后,一行完成。这样它就与 Invoke-Command
和脚本块在同一个 cmdlet 上。