【问题标题】:RunSpacePool hash table lookupRunSpacePool 哈希表查找
【发布时间】:2016-03-13 19:41:47
【问题描述】:

我正在编写一个 powershell 脚本,该脚本将使用 RunSpacePools 输出一个 CSV 文件,其中包含 1)ServerName、2)SCCM 维护窗口、3)PingCheck、4)LastRebootTimestamp。

我使用this amazing answer 有一些工作,但我的 CSV 文件有空行,我一直坚持将 SCCM 维护窗口放入 CSV。

我不确定如何完成 SCCM 维护窗口查找,然后将其添加到 $Job.Result 的输出中,或者我可以将其添加到 $ScriptBlock 并让 RunSpacePool 快速完成查找。

空白的 CSV 行是 ,,,有些行没有多余的空白行。

-编辑,我现在的想法是执行 SCCM 窗口查找,然后简单地将其作为另一个参数/参数传递到 runspacepool。

    IF(Get-Command Get-SCOMAlert -ErrorAction SilentlyContinue){}ELSE{Import-Module OperationsManager}

    "Get Pend reboot servers from prod"
New-SCOMManagementGroupConnection -ComputerName ProdSCOMServer

$AlertData = get-SCOMAlert -Criteria "Severity = 1 AND ResolutionState < 254 AND Name = 'Pending Reboot detected on the ConfigMgr 2012 Client'" | Select NetbiosComputerName

    "Get Pend reboot servers from test"
#For test information
New-SCOMManagementGroupConnection -ComputerName TestSCOMServer

$AlertData += Get-SCOMAlert -Criteria "Severity = 1 AND ResolutionState < 254 AND Name = 'Pending Reboot detected on the ConfigMgr 2012 Client'" | Select NetbiosComputerName

    "Remove duplicates"
$AlertDataNoDupe = $AlertData | Sort NetbiosComputerName -Unique

$Global:table = @{}
    "Populate hash table"

$MaintenanceWindow = Import-Csv D:\Scripts\MaintenanceWindow2.csv

$MaintenanceWindow | ForEach-Object {$Global:table[$_.Computername] = $_.CollectionName}

$scriptblock = {
 Param([string]$server)

#Try getting SCCM Maintenance Window
$SCCMWindow = IF($Global:table.ContainsKey($server)){
                $SCCMWindow = $table[$server]
                } Else { $SCCMWindow = "Not Found!"}

 $PingCheck = Test-Connection -Count 1 $server -Quiet -ErrorAction SilentlyContinue
        IF($PingCheck){$PingResults = "Alive"}
        ELSE{$PingResults = "Dead"}

 Try{$operatingSystem = Get-WmiObject Win32_OperatingSystem -ComputerName $server -ErrorAction Stop
        $LastReboot = [Management.ManagementDateTimeConverter]::ToDateTime($operatingSystem.LastBootUpTime)
        $LastReboot.DateTime}
        Catch{$LastReboot = "Access Denied!"}

 [PSCustomObject]@{

 Server=$server
 Ping=$PingResults
 LastReboot=$LastReboot
 }#end custom object
}#script block end

$RunspacePool = [RunspaceFactory]::CreateRunspacePool(100,100)
$RunspacePool.Open()
$Jobs = 
 foreach ( $item in $AlertDataNoDupe )
 {
 $Job = [powershell]::Create().
        AddScript($ScriptBlock).
        AddArgument($item.NetbiosComputerName)
 $Job.RunspacePool = $RunspacePool

 [PSCustomObject]@{
  Pipe = $Job
  Result = $Job.BeginInvoke()
 }
}

Write-Host 'Working..' -NoNewline

 Do {
  Write-Host '.' -NoNewline
  Start-Sleep -Seconds 1
} While ( $Jobs.Result.IsCompleted -contains $false)

Write-Host ' Done! Writing output file.'
Write-host "Output file is d:\scripts\runspacetest5.csv"

$(ForEach ($Job in $Jobs)
{ $Job.Pipe.EndInvoke($Job.Result) }) |
 Export-Csv d:\scripts\runspacetest5.csv -NoTypeInformation

$RunspacePool.Close()
$RunspacePool.Dispose()

【问题讨论】:

  • 使用 RunspacePool 最好使用同步哈希表 $Global:table = [hashtable]::Synchronized(@{}) 这将防止同时执行多个作业时发生访问冲突。
  • 我正在努力让它发挥作用,但事情并不如我所愿。
  • 最终通过采用the answer here 并使用 IF 语句来使用这种方法,但现在一些结果是System.Object[],我认为这是两次出现在列表/CSV 中的结果。

标签: csv powershell runspace


【解决方案1】:

不确定这是否是最好的方法,但我最终使用了以下方法,如果 MaintenanceWindow2.csv 中有两个条目,则会出现问题,因为它返回 System.Object[]

$scriptblock = {
 Param([string]$server)

 $csv = Import-Csv D:\Scripts\MaintenanceWindow2.csv
 $window = $csv | where {$_.Computername -eq "$server"} | % CollectionName
 $SCCMWindow = IF ($window){$window}ELSE{"NoDeadline"}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-03
    • 2023-03-12
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 2012-07-02
    • 1970-01-01
    相关资源
    最近更新 更多