Powershell kaugtöö ja töövood

Sageli on meil vaja teha automaatselt midagi mitmes masinas.  toome näiteks üsna levinud vajaduse korjata masinatest kokku, et kes on lokaalse administraatorite grupi liikmed.

Alustame kõigepealt ühest masinast.  Siin pole vaja eriti midagi leiutada, sest internetis ringi vaadates leiab hulgaliselt variatsioone sellel teemal.  Valime neist minu arust kõige lihtsama ja kiirema lahenduse:

net localgroup Administrators

Seda tulemust tuleb natuke ilusamaks teha ja ära kaotada käsurea käsu asjasse mittepuutuv eelinfo, tabeli päis ja lõputeade, et kõik läks hästi (plus paar tühja rida)

net localgroup Administrators |
  Select-Object -Skip 6 |
  Where-Object {$_ -and $_ -notmatch "completed successfully."}

Nüüd jääb veel üle võimalus/vajadus muuta tulemus lihtsalt stringidest objektideks, mis muuhulgas teevad vahet domeeni ja lokaalsetel kasutajatel.  Ja teeme selle veel kohe funktsiooniks, et oleks mugavam korduvalt kasutada:

function Get-LocalAdmins {
  net localgroup Administrators |
    Select-Object -Skip 6 |
    Where-Object {$_ -and $_ -notmatch "completed successfully."} |
    ForEach-Object {
      $name = $_.split("\")
      $member = New-Object PSObject -Property @{DisplayName=$_
                                                Name=$name[-1]
                                                Domain=""}
      if ($name.length -eq 2) { $member.domain = $name[0] }
      $member
    }
}

Täiesti töötav lahendus.  Aga meil oleks vaja sama asja mitmes erinevas masinas.  Põhimõtteliselt, kui lisada ülaltoodud koodi lõppu funktsiooni väljakutse või jätta funktsioon ära, siis saaks koodi kirjutada faili ja siis kasutada tavalist Powershelli kaugkasutust:

"server1", "server2" | Out-File servers.txt
$session = New-PSSession -ComputerName (Get-Content .\servers.txt) -Credential domain\admin

Invoke-Command -FilePath .\get-localadmins.ps1 -Session $session |
  Select-Object Name, Domain, PSComputerName |
  Group-Object PSComputerName

Paarikümne masinaga polegi rohkem vaja, aga kui masinaid on rohkem, siis saaks teha ka natuke teistmoodi.  Nimelt saaksime me funktsiooni ümber defineerida töövooks, jättes funktsiooni sisu täpselt samaks.:

#Requires -Version 3

workflow Test-LocalAdmins {
  net localgroup Administrators |
    Select-Object -Skip 6 |
    Where-Object -FilterScript {$_ -and $_ -notmatch "completed successfully"} |
    ForEach-Object {
      $name = $_.split("\")
      $member = New-Object psobject -Property @{DisplayName=$_
                                                Name=$name[-1]
                                                Domain=""}
      if ($name.length -eq 2) { $member.domain = $name[0] }
      $member
    }
}

Ja nüüd saab seda töövoogu kasutada kohe võõraste masinate peal:

"server1", "server2" | Out-File servers.txt

Test-LocalAdmins -PSComputerName (Get-Content .\servers.txt) -PSCredential domain\admin |
  Select-Object Name, Domain, PSComputerName |
  Group-Object PSComputerName

Vaikimisi jookseb töövoog paralleelselt 100 masina peal (Invoke-Command jookseb vaikimisi 32 masina peal).  Lisaks võimaldab töövoog veel muid eeliseid, mida ilma töövoota on raskem teha, ent mis praeguses näites ei leia eriti kasutust.  Loomulikult võib ka Invoke-Command käsule ütelda paralleeltöötluse limiidiks suurema numbri kui 32 ja vajadusel saaks lisada ka parameetri –AsJob (et panna kogu krempel taustal tööle), ent töövoog tundub siiski lihtsam.  Kasvõi juba selle poolest, et sama töövoogu saab kasutada ka ainult lokaalse masina peal (kui parameeter –PSComputerName ära jätta).  Samuti aitab kaasa see, et töövoog võib olla osa imporditud moodulist (nagu funktsioon) töövoogu jooksutavas masinas, aga kaugtöö jaoks on enamasti lihtsam kirjutada skript (fail kettal), sest funktsioon tuleks defineerida ja käivitada eemal olevates (paljudes) masinates.

Töövoogude ainsaks puuduseks võiks pidada vajadust Powershell 3.0 järgi, aga kuna juba Server 2008/Vista võimaldavad antud versiooni kasutada, siis tänapäeval ei tohiks see enam problemaatiline olla.  Samas, kui masinate hulgas on ikka veel Windows XP/Server 2003 masinaid, siis tuleb otsustada tavalise kaugtöö kasuks.

Advertisements