Хеш-таблицы и RunSpaces в powershell - PullRequest
0 голосов
/ 05 марта 2019

У меня возникли проблемы с обновлением данных в списке по результатам хэш-таблицы.Я на 99% уверен, что это связано с отсутствием понимания того, что я делаю.

Я генерирую $ список серверов из CSV.CSV содержит имя сервера, домен, описание, а также некоторые дополнительные пустые столбцы для использования позже.

Что я пытаюсь сделать в двух словах: мне нужно вывести процессы из списка удаленных серверов.чтобы сделать это, я выбрасываю каждый сервер из списка и функцию в свое собственное пространство выполнения, Hashtable обновляется, как и ожидалосьНо я не могу обновить исходный список $, который у меня есть.

Вот мой код:

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.

или есть лучший способ сделать это?Является ли Hashtable единственным способом синхронизации данных из пространств выполнения с текущим процессом?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...