Powershell调用命令传递一个对象

时间:2014-11-15 22:29:50

标签: powershell powershell-remoting invoke-command

我创建了一个对象列表$ 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)
}

但后来我放弃了invoke-command CmdLet的并行性优势。

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

3 个答案:

答案 0 :(得分:0)

如果是$ LIST [“COMPUTER”]。服务的COMPUTER返回列表服务,你可以在你的scriptblock中为每个传递的对象进行测试..可能这个但未测试:(伪代码)

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

答案 1 :(得分:0)

我认为有一种简单的方法可以通过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     

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

答案 2 :(得分:0)

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

下面脚本中的一个关键部分是Invoke-Command参数列表的生成数组,其中包含关联计算机的services数组。剩下的就是你的代码。最后我使用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参数在并行作业中运行。