首页 > 解决方案 > powershell 中的哈希表和运行空间

问题描述

我在从哈希表的结果更新列表中的数据时遇到了一些问题。我有 99% 的把握,这是由于对我在做什么缺乏了解。

我正在从 CSV 生成一个 $list 的服务器。CSV 包含服务器名称、域、描述以及一些额外的空白列以供以后使用。

简而言之,我想做的是:我需要从远程服务器列表中拉下进程。为此,我将列表中的每个服务器和函数放入其自己的运行空间中,Hashtable 正在按预期进行更新。但我无法更新我拥有的原始 $list。

这是我的代码:

Function OpenFile ($FilePath) {

$OFDiag = new-object system.windows.forms.openfiledialog
$OFDiag.filter = 'CSV (*.csv) | *.csv'
$OFDiag.ShowDialog() | out-null
$OFDiag.filename

} 

# Create Primary Variables

$FilePath = OpenFile 
$list = (get-content $FilePath) -replace '\(',' -' #ALL Servers and Groups need to remove parenthesis
$list = $list -replace '\)' #finish up removing the parenthesis
$list = $list -replace ' Or WorkGroup'
$list = convertFrom-CSV $list | select 'Name', 'Computer_Description', 'Domain' #Need to convert the list into a CSV formatted table.
$list = $list | sort Name 
$list | Add-Member -NotePropertyName 'LastReboot' -NotePropertyValue $null
$list | Add-Member -NotePropertyName 'LastDeployment' -NotePropertyValue $null 
$list | Add-Member -NotePropertyName 'RebootStatus' -NotePropertyValue $null
$list | Add-Member -NotePropertyName 'DownProcess' -NotePropertyValue $null
$list | Add-Member -NotePropertyName 'EnabledStatus' -NotePropertyValue $null
$list | Add-Member -NotePropertyName 'RDP' -NotePropertyValue $null
$list | Add-Member -NotePropertyName 'SchedTask' -NotePropertyValue $null
$servers = $list | %{$_.Name} | sort #ALL SERVERS - ONLY Servernames



$ServProSel = {
    #
    #  Checks for Running Services and Processes.
    # This Makes a determination as to what service/process groups should be checked. 
    # The Information as to what processes to look for are sent to the ProSer_Check function
    # information from there is sent to the ServerStatus Tab
    #
    #Write-Host 'starting ServerProSel'


   Param ($computer,$cred,$grpName,$hash)

    #$cred = $(get-Variable "$Domain" -valueOnly)
    $ck =@{} #$(Get-Variable -name "SCP_$serName" -ValueOnly)


    Function ProSer_Check {

            # This is the actual function that is run on the remote system to check
            # for processes and services.

            param ( [array] $Prcs,
                    [string] $Computer )
            $script:chkres =@()
            foreach ($p in $Prcs){
                $script:res = Get-Process -name $p -ErrorAction SilentlyContinue
                if (!$res) {
                    $chk = "$p -DOWN`r`n"
                    $chkres += $chk
                        }
                }
            if ($chkres.count -eq 0){
                $chkres = "All Processes Up"}

            Return $chkres

            }


    switch -Regex ($grpName){

        'Demonstration' {
            $Prcs = @('Process.Service'); break}
        'Historian' {
            $Prcs =@('Process.Service'); break}
        'Models' {
            $Prcs =@('UpdaterServer'); break}
        'Inflictor' {
            $Prcs =@('Automation.EngineService','Automation.Manager.Service','Automation.SmfLauncher','postgres','Redundancy.Server','WatchDog.Service'); break}
        'Simulator' {
            $Prcs =@('proc','moni','server','serve','clerk','web'); break}
        'WebServer' {
            $Prcs =@('w3wp','VShell'); break}
        default {
            $Prcs =@('svchost'); break}
        }

    $R = invoke-command -credential $cred -computername $Computer -scriptblock ${function:ProSer_Check} -ArgumentList  $Prcs,$Computer



    $hash[$Computer]=([string]$R)

}



$Script:runspaces = New-Object System.Collections.ArrayList   
$Global:hash = [hashtable]::Synchronized(@{}) 

$global:sessionstate = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
$global:runspacepool = [runspacefactory]::CreateRunspacePool(1, 10, $sessionstate, $Host)
$global:runspacepool.Open() 

Function SendToRunSpace {

    $function = $args[0]
    #$function
    $powershell = [powershell]::Create().AddScript($function).AddArgument($computer.name).AddArgument($cred).AddArgument($grpName).AddArgument($hash)

    $powershell.RunspacePool = $global:runspacepool
    #$hash = @{Name=$computer.name;DownProcess = "Waiting.."}

    $temp = "" | Select-Object PowerShell,Runspace,Computer
    $Temp.Computer = $Computer
    $temp.PowerShell = $powershell

    $temp.Runspace = $powershell.BeginInvoke()
    Write-Verbose ("Adding {0} collection" -f $temp.Computer)
    $runspaces.Add($temp) | Out-Null   

}


ForEach ($Computer in $list) {
    $domain = $computer.Domain
    $grpName = $computer.'Computer_Description'
    $cred = $(get-Variable "$Domain" -valueOnly)
    #Create the powershell instance and supply the scriptblock with the other parameters 
    if(!$(Get-Variable "TEST_$domain" -ValueOnly)){
                CredCheck $computer.name $cred
                    }

    #SendToRunSpace $scriptBlock $computer $domain $global:hash
    SendToRunSpace $ServProSel $computer $cred $grpName $global:hash

}

我在 PowerShell ISE 中运行它,所以我可以动态编辑和测试东西。当我运行此代码时,我会生成$list$hash项目。最终我想从服务器中获取值$hash并更新对象中相应的服务器信息$list

还是有更好的方法来做到这一点?哈希表是将数据从运行空间同步到当前进程的唯一方法吗?

标签: powershellhashtable

解决方案


推荐阅读