【问题标题】:How to pass variable value to Invoke-Command如何将变量值传递给 Invoke-Command
【发布时间】:2018-04-04 06:07:07
【问题描述】:

我正在尝试获取处于特定状态(已保存、正在运行、已停止)的机器列表。我将机器的状态作为参数传递给函数。

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 时,我得到了预期的输出。

【问题讨论】:

  • 请检查你的问题:你真的打电话给Resource-Summary -Program name ...还是Resource-Summary -ProgramName ...
  • 抱歉,问题中有错字。我使用 Resource-Summary -ProgramName Running -ServerName Demo ..

标签: function powershell variables invoke-command


【解决方案1】:

作为参考,请参见例如这篇关于Pass arguments to a scriptblock in powershell 的帖子。

脚本中的问题是如何调用脚本块,上面的链接中对此进行了更详细的说明,但是您需要将任何“外部”输入传递给它,就像您调用它一样一个函数。

您部分正确地执行了此操作,您正在使用-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 上。

【讨论】:

【解决方案2】:

有几件事跳出来:

如果你有一个单引号内的变量,它不会被 PowerShell 自动解析,所以在本节中,你实际上是将 VM 的状态与字符串 $ProgramName 进行比较,而不是它的价值:

$_.VMState -eq '$ProgramName'

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-31
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多