假设我有一组Windows主机名:
$server_hostnames = @("server1","server2")
对于每个服务器,我需要找到特定用户的任何会话,然后理想地捕获新阵列中的所有会话。
$results = @()
$account = "JohnDoe"
foreach ($s in $server_hostnames) {
$r = (qwinsta /server:$($s) 2> $null | out-string -stream | sls $account)
$results += $r
}
在这个例子中,我有2台服务器,但在生产中我会针对2-3000台服务器运行它,因此并行执行非常重要。
我曾多次尝试使用作业,工作流程或Split-Pipeline
重写代码,但收效甚微。
通常情况下,使用sls
(Select-String
)进行过滤不起作用,即使使用findstr
也不行。
Split-Pipeline
示例:
PS C:\SplitPipeline> $server_hostnames | Split-Pipeline {process{ $_; qwinsta /server:$($_) | out-string -stream | sls $account }} Split-Pipeline : Cannot bind argument to parameter 'Pattern' because it is null. At line:1 char:21 + $server_hostnames | Split-Pipeline {process{ $_; qwinsta /server:$($_) | out-str ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidData: (:) [Split-Pipeline], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,SplitPipeline.SplitPipelineCommand
答案 0 :(得分:0)
使用工作可以做到这样的事情:
$servers = 'server1', 'server2'
$account = 'JohnDoe'
$results = @()
$sb = {
Param($server, $name)
& qwinsta /server:$server |
Select-String $name -SimpleMatch |
Select-Object -Expand Line
}
$servers | ForEach-Object {
Start-Job -ScriptBlock $sb -ArgumentList $_, $account | Out-Null
}
$results += while (Get-Job -State Running) {
Get-Job -State Complete | ForEach-Object {
Receive-Job -Job $_
Remove-Job -Job $_
}
}
$results += Get-Job -State Complete | ForEach-Object {
Receive-Job -Job $_
Remove-Job -Job $_
}
但是,由于您要对数千台服务器运行qwinsta
,您可能希望使用job queue而不是同时运行所有作业,否则大量的作业可能会耗尽您当地计算机的资源。