如何将变量值传递给Invoke-Command

时间:2018-04-04 06:07:08

标签: function powershell variables 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

我没有任何价值。

当我用$ProgramName替换RUNNING时,我得到了预期的输出。

2 个答案:

答案 0 :(得分:1)

有几件事情跳出来:

如果单引号内有变量,PowerShell将无法自动解析它,因此在本节中,您实际上是将VM的状态与字符串 $ ProgramName 进行比较而不是它的价值:

$_.VMState -eq '$ProgramName'

尝试更改为双引号,或者根本不加引号。

另外,检查包围 - 你错过了 Where-Object 的结束。

答案 1 :(得分:1)

供参考,请参阅例如这篇关于如何Pass arguments to a scriptblock in powershell

的文章

脚本中的问题是你如何调用脚本块,这在上面的链接中有更详细的解释,但你需要传递任何“外部”输入,就像你调用它一样一个功能。

您正在部分正确地执行此操作,您正在使用-ArgumentList参数将$ProgramName发送到scriptslock,但您尚未在脚本块中指定如何访问它。

例如,请查看

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和scriptblock在同一个cmdlet上。