【问题标题】:Powershell invoke-command passing an object传递对象的 Powershell 调用命令
【发布时间】:2014-11-15 22:29:49
【问题描述】:

我创建了一个对象列表 $LIST。列表中的每个对象都有几个属性,包括 FQDN 和服务。 FQDN 是完全限定的服务器名称,服务是我要在远程服务器上检查的服务列表。

我将开始:

$LIST = <CALL to Module function to populate the server information>

接下来是调用invoke-command

Invoke-Command -ComputerName $LIST.FQDN -ScriptBlock { 
Write-Host "Working on $($env:ComputerName)" 
    Get-Service
}

但我需要做的是传递与 -ComputerName 对应的服务列表。我知道我可以使用 -ArgumentList 并且我已经尝试过:

Invoke-Command -ComputerName $LIST.FQDN -ScriptBlock { 
    Param ([string[]] $ServiceList)
    Write-Host "Working on $($env:ComputerName)"
    ($ServiceList -split(",")).trim() | %{ 
        $svc =Get-Service $_ 
        $Svc
    }
} -ArgumentList $LIST.Services

但这会传递每台服务器的所有服务列表。我可以这样做:

$LIST | %{
    $Server = $_

    Invoke-Command -ComputerName $Server.FQDN -ScriptBlock { 
        Param ([string[]] $ServiceList)
        Write-Host "Working on $($env:ComputerName)"
        ($ServiceList -split(",")).trim() | %{ 
            $svc =Get-Service $_ 
            $Svc
        }
    } -ArgumentList $($Server.SERVICES)
}

但随后我失去了调用命令 CmdLet 的并行性优势。

如何传递正在处理的特定 ComputerName 的服务列表?

【问题讨论】:

  • 你看过Invoke-Command的-AsJob参数了吗?

标签: powershell powershell-remoting invoke-command


【解决方案1】:

如果 $LIST["COMPUTER"].SERVICES 返回 COMPUTER 的列表服务,您可以在脚本块中测试通过的每个对象..也许这但未测试:(在伪代码中)

Icm -comp $LIST.FQDN -Script {
   Param($obj)
        $c=$env:computername
        $obj["$c"].services
} -arg $LIST

【讨论】:

    【解决方案2】:

    我认为没有一种简单的方法可以通过Invoke-Command 传递您的列表,因此您可能需要考虑让每台目标计算机运行相同命令的替代方法。

    如果服务列表特定于每台远程计算机,并且每次运行命令时都相同,那么您可以简单地将每台目标计算机上的参数存储在注册表或文件中。理想情况下,您可以使用 DSC、Puppet 或 Chef 等配置管理器进行设置。

    您可以将参数转储到本地计算机上的文件中,并让每台目标计算机连接回网络共享并获取与其名称对应的文件。如果网络共享连接不可行,那么简单的 Web 服务或数据库连接将是您可以让每台计算机获取服务列表的其他方式。

    是否存在将收到相同列表的目标组?假设您有 10 个不同的服务列表,每个服务列表要发送到一组 100 台计算机。在这种情况下,也许您可​​以从每个组中选择一台任意计算机,并向这些计算机发送包含所有数据的相同命令。然后,您定位的每台计算机都会确定它所在的组,并将相同的命令分发给它的所有兄弟姐妹。这也有增加并行度的好处。

    或者只是创建一组服务,它是所有服务列表的联合,将其发送到每台机器,并根据您想要的结果过滤结果。这可能是最简单的解决方案:

    PS C:\WINDOWS\system32> $allServices = 'WerSvc','WinRM','ZeroConfigService','AnotherService'
    
    PS C:\WINDOWS\system32> Invoke-Command -ComputerName . -ScriptBlock {
      Get-Service -Name $args -ErrorAction Ignore
     } -ArgumentList $allServices
    
    Status   Name               DisplayName                            PSComputerName                                                                                                      
    ------   ----               -----------                            --------------                                                                                                      
    Stopped  WerSvc             Windows Error Reporting Service        localhost                                                                                                           
    Running  WinRM              Windows Remote Management (WS-Manag... localhost                                                                                                           
    Running  ZeroConfigService  Intel(R) PROSet/Wireless Zero Confi... localhost     
    

    将简单地忽略您要求的任何未安装在该特定计算机上的服务。

    【讨论】:

      【解决方案3】:

      为了测试,我创建了两个对象,其中包含指向 localhost 的指针,以及要验证的特定服务列表。目标是调用将远程并行运行的后台作业,并验证提供的服务列表。

      以下脚本中的关键部分之一是为 Invoke-Command 参数列表生成的数组,其中包含关联计算机的服务数组。剩下的就是你的代码了。最后我使用 Get-Job | Receive-Job 从 Invoke-Command 作业中检索输出。

      $LIST = @()
      
      $Computer1 = New-Object PSObject -Property @{
              FQDN = "localhost";
              SERVICES = @()
          }
      $Computer1.SERVICES += "W32Time"
      $Computer1.SERVICES += "vmms"
      $LIST += $Computer1
      
      $Computer2 = New-Object PSObject -Property @{
              FQDN = "localhost";
              SERVICES = @()
          }
      $Computer2.SERVICES += "ShellHWDetection"
      $Computer2.SERVICES += "SharedAccess"
      $LIST += $Computer2
      
      $LIST | %{
          $Server = $_
          $arguments = @(,($Server.SERVICES))
          Invoke-Command -ComputerName $Server.FQDN -AsJob -ScriptBlock { 
              Param ([string[]]$ServiceList)
              Write-Host "Working on $($env:ComputerName)"
                      ($ServiceList -split(",")).trim() | %{ 
                  $svc =Get-Service $_ 
                  $Svc
              }
          } -ArgumentList $arguments
      }
      Get-Job | Receive-Job
      

      输出是这样的:

      Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
      --     ----            -------------   -----         -----------     --------             -------                  
      28     Job28           RemoteJob       Running       True            localhost             ...                     
      30     Job30           RemoteJob       Running       True            localhost             ...                     
      Working on CORSAIR-PC
      
      Status   Name               DisplayName                            PSComputerName                                                                                                                         
      ------   ----               -----------                            --------------                                                                                                                         
      Stopped  W32Time            Windows Time                           localhost                                                                                                                              
      Running  vmms               Hyper-V Virtual Machine Management     localhost                                                                                                                              
      Working on CORSAIR-PC
      Running  ShellHWDetection   Shell Hardware Detection               localhost                                                                                                                              
      Stopped  SharedAccess       Internet Connection Sharing (ICS)      localhost  
      

      因此,每台计算机的不同服务被传递给 Invoke-Command,该命令使用 -AsJob 参数在并行作业中运行。

      【讨论】:

        猜你喜欢
        • 2012-11-30
        • 2018-12-07
        • 1970-01-01
        • 2023-04-03
        • 1970-01-01
        • 2021-09-11
        • 1970-01-01
        • 2010-11-12
        • 1970-01-01
        相关资源
        最近更新 更多