简体   繁体   English

从多个PowerShell线程收集和转换输出的最佳方法是什么?

[英]What is the best way to collect and transform output from multiple PowerShell threads?

I am new to PowerShell scripting and would like to do the following: 我是PowerShell脚本的新手,并希望执行以下操作:

  1. Given a list of config names and servers, return the values for the configs from each server. 给定配置名称和服务器的列表,请从每个服务器返回配置的值。

  2. Transform them in such a way to group them by config name, and not server. 转换它们的方式是按配置名称而不是服务器将其分组。

Currently, I have a script that spawns one job per server and calls a script remotely on the server to return the list of configs for that server. 当前,我有一个脚本,该脚本在每个服务器上产生一个作业,并在服务器上远程调用脚本以返回该服务器的配置列表。

However, I do not know how to aggregate and transform the output from these jobs so that instead of getting config names by server, I would like to sort them by config name first, then server. 但是,我不知道如何聚合和转换这些作业的输出,因此我不想先按服务器获取配置名称,而是先按配置名称对它们进行排序,然后对服务器进行排序。

Current output: 电流输出:

Server1: 
Config1 = 'abc'
Config2 = 'def'

Server2: 
Config1 = 'xyz'
Config2 = '123'

Desired output: 所需的输出:

Config1: 
Server1 : 'abc'
Server2 : 'xyz'

Config2:
Server1 : 'def'
Server2 : '123'

I don't want to iterate over the config names because that would waste time in connecting to the server for every call. 我不想遍历配置名称,因为那样会浪费时间为每个调用连接到服务器。 Therefore I'd like to iterate over the servers and do some kind of transformation. 因此,我想遍历服务器并进行某种转换。

I'm wondering if this is a matter of having each job return some kind of dictionary, then iterate over them after all the threads finish to transform? 我想知道是否要让每个作业返回某种字典,然后在所有线程完成转换之后在它们上进行迭代?

Here is the code that calls the jobs: 这是调用作业的代码:

$all_servers = @('server1', 'server2')
$config_names = @('config1', 'config2')

foreach($servername in $all_servers) {
    Start-Job -FilePath C:\scripts\get_config_from_servers.ps1 
              -ArgumentList $servername,$config_names
}

Get-Job | Wait-Job
Get-Job | Receive-Job | Out-GridView

Here is the job script: 这是作业脚本:

Param($servername,$config_names)

$session = Get-Session -computername $servername 
                       -username $$$$
                       -pwd ####
try {
        $sb = {
                param($servername,$config_names)

                $output = @{}
                    foreach ($cfg in $config_names) {
                        $config_value = Get-Config -configname $cfg
                        $output.Add("$servername : $cfg", "($config_value)")
                    }
                write-host $output | Out-String
                return $output | Out-String
        }
        $out = Invoke-Command -session $session 
                              -ScriptBlock $sb 
                              -ArgumentList $servername,$config_names
        write-host $out
        return $out
}
finally {
    Remove-PSSession $session
}

Instead of making a hash table and converting to a string you could create some custom object in you job script just like this SO Question 而不是使一个哈希表,并转换成字符串的,你可以在你的工作脚本创建一些自定义对象就是这样的SO问题

Instead of this: 代替这个:

$output = @{}
    foreach ($cfg in $config_names) {
        $config_value = Get-Config -configname $cfg
        $output.Add("$servername : $cfg", "($config_value)")
    }
write-host $output | Out-String
return $output | Out-String

You could try something like this: 您可以尝试这样的事情:

$output = New-Object System.Object
Add-Member -MemberType NoteProperty -Name Server -Value $servername -InputObject  $output
foreach ($cfg in $config_names) {
   $config_value = Get-Config -configname $cfg
   Add-Member -MemberType NoteProperty -Name "Config$cfg" -Value $config_value -InputObject  $output
}
write-host $output 
return $output

I can't test this accurately as i'm not sure what Get-Config is but hopefully it should be enough to get you thinking. 由于我不确定Get-Config是什么,因此我无法进行准确的测试,但希望它足以让您思考。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM