我创建了一个对象列表$ 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的服务列表?
答案 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参数在并行作业中运行。