【问题标题】:PowerShell multithreaded script output formattingPowerShell 多线程脚本输出格式
【发布时间】:2013-11-11 20:32:22
【问题描述】:

我在 powershell 中有一个脚本来访问列表中的每个服务器并检查它是否在线。由于这很耗时,我编写了一个线程逻辑来调用该脚本,我的脚本工作正常。但是我想将我的好/坏服务器分成两个不同的文本文件,我不能在我的脚本中对其进行硬编码,因为显然资源可能被另一个线程使用。如果我在线程逻辑中编写它,我的输出(好的和坏的)将在同一个文件中。我怎样才能很好地格式化只需要的输出?

### Start-MultiThread.ps1 ###
$Servers =Get-Content -Path "C:\Scripts\Servers.txt"

#Start all jobs
ForEach($Server in $Servers){
    Start-Job -FilePath "C:\Scripts\ChkOnline.PS1" -ArgumentList $Server
}

#Wait for all jobs
Get-Job | Wait-Job

#Get all job results
Get-Job | Receive-Job |Out-File -FilePath "C:\Scripts\Output.txt"


##ChkOnline.PS1###

Param($Server = "ServerNameHolder")
$PingStatus= Test-Connection $Server -Quiet

              If ($PingStatus -eq 1)
                        {
                          Return $Server " is online!!"
                        }
            Else
                        {
                          Return $Server " is offline!"
                        }

【问题讨论】:

  • 你能发布你的脚本吗?
  • 感谢您的关注...我已经发布了
  • 您使用作业/多线程执行此操作的原因是什么?
  • 您可以通过使用带有“-Count 1”参数和值的“Test-Connection”来大大加快速度。

标签: powershell


【解决方案1】:

您可以在不启动多个作业的情况下执行此操作。启动多个作业会产生内存和处理时间开销,对于这样的任务,开销大于其价值。

$Servers = Get-Content -Path "C:\Scripts\Servers.txt"
$results = Test-Connection -ComputerName $servers -Count 1 -ErrorAction silentlycontinue;
$AvailableServers = $results|select -expandproperty address
$OfflineServers = Compare-Object -ReferenceObject $Servers -DifferenceObject $AvailableServers -PassThru;
$AvailableServers | out-file c:\scripts\onlineservers.txt;
$OfflineServers | out-file c:\scripts\offlineservers.txt;

【讨论】:

  • 我仍然会使用我发布的技术来过滤掉离线服务器。然后,如果需要,为每个服务器生成一个作业以获取您的其他健康数据。该作业可能会返回一个自定义的PSObject,它包含您所有的健康检查数据(可能还有代表它的其他对象的集合)。但是“服务器健康检查”已经是一个已解决的问题 - 很多 PowerShell 专业人士/博主/MVP 已经发布了此类内容,您应该首先查看这些内容。您可能会发现他们还没有发现需要使用作业,并且可能已经编写了一个脚本,您只需进行少量更改即可使用。
  • 但是在你开始编写一个产生 100 个额外作业的脚本之前,请仔细考虑你是否首先需要它是多线程的。放在后兜里是个不错的选择,但除非你真的需要它,否则不要使用它。
  • 感谢您的输入。我选择多线程的原因是我希望将来能在我的脚本中添加更多的健康检查,比如服务健康和数据库健康检查。在这种情况下,要么我必须将所有数据转储到一个文件中,要么我应该设计我的脚本来只给我失败的服务器/服务/数据库状态?
  • 我真的希望你没有删除我正在回复的 cmets/问题,因为我是直接回复他们的。现在你重新提出了问题,但稍微改变了它们,改变了上下文。
【解决方案2】:

使用 -asjob 参数(多进程)使其非常快。那些启动的将有一个非空的 ResponseTime 属性。不幸的是,默认情况下,测试连接将 ResponseTime 属性显示为“时间(毫秒)”。目标名称可以是一个数组。

$servers = 'microsoft.com','yahoo.com'
$a = test-connection $servers -AsJob | Receive-job -Wait -AutoRemoveJob

$a | where responsetime # up

Source        Destination     IPV4Address      IPV6Address  Bytes    Time(ms)
------        -----------     -----------      -----------  -----    --------
DESKTOP-JQ... yahoo.com       98.138.219.231                32       65


$a | where { ! $_.responsetime } # down

Source        Destination     IPV4Address      IPV6Address  Bytes    Time(ms)
------        -----------     -----------      -----------  -----    --------
DESKTOP-JQ... microsoft.com   40.112.72.205                 32

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    • 2022-07-20
    相关资源
    最近更新 更多