Távoli futtatás

Még nagyobb hiánya volt az 1.0-ás verziónak, hogy nem volt lehetőség PowerShell cmdletek távoli futtatására. Persze bizonyos WMI metódusok rendelkeztek távoli futtatás lehetőségével, amelyeket PowerShellből meghívva persze olyan érzésünk lehetett, hogy táv-futtatunk, de ez nem volt az igazi. Most már viszont bármit futtathatunk távolról is! Nem teszteltem le az összes cmdletet, de a BITS fájlátvitellel kapcsolatos cmdleteket biztos nem lehet távolról futtatni.

A háttérben ennek és a később előkerülő távoli futtatás infrastruktúráját a WinRM szolgáltatás biztosítja. Ez Vista operációs rendszertől fölfelé érhető el alaphelyzetben, de a Management Framework részeként (amelyben a PowerShell 2.0 is benne van) Windows XP-re és Windows Server 2003-ra is telepíthető. Ez a szolgáltatás telepítés után magától nem fut, legegyszerűbben az Enable-PSRemoting  paranccsal lehet bekapcsolni:

[14] PS C:\> Enable-PSRemoting

 

WinRM Quick Configuration

Running command "Set-WSManQuickConfig" to enable this machine for remote

management through WinRM service.

 This includes:

    1. Starting or restarting (if already started) the WinRM service

    2. Setting the WinRM service type to auto start

    3. Creating a listener to accept requests on any IP address

    4. Enabling firewall exception for WS-Management traffic (for http

only).

 

Do you want to continue?

[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help

(default is "Y"):y

WinRM already is set up to receive requests on this machine.

WinRM already is set up for remote management on this machine.

 

Confirm

Are you sure you want to perform this action?

Performing operation "Set-PSSessionConfiguration" on Target "Name:

microsoft.powershell SDDL:

O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD). This will

allow selected users to remotely run Windows PowerShell commands on this

computer".

[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help

(default is "Y"):y

 

Confirm

Are you sure you want to perform this action?

Performing operation "Set-PSSessionConfiguration" on Target "Name:

Microsoft.PowerShell32 SDDL: O:NSG:BAD:P(A;;GA;;;BA)S:P. This will allow

selected users to remotely run Windows PowerShell commands on this

computer".

[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help

(default is "Y"):y

 

Confirm

Are you sure you want to perform this action?

Performing operation "Set-PSSessionConfiguration" on Target "Name:

microsoft.ServerManager SDDL:

O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD). This will

allow selected users to remotely run Windows PowerShell commands on this

computer".

[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help

(default is "Y"):y

Ez egy összetett folyamatot indít el. Egyrészt a winrm quickconfig parancs PowerShelles megfelelőjét, a Set-WSMandQuickCOnfig -ot futtatja, másrészt a távoli csatlakozás pontjait állítja be. Ez egy 64 bites gépen tartalmazza az alaphelyzet szerinti Microsoft.Powershell csatlakozási pontot (PSSessionConfiguration-t) és a Microsoft.Powershell32 csatlakozási pontokat. Ezekről majd részletesebben a gyakorlati részben, a 2.23 Távoli futtatási környezet testre szabása fejezetben lesz szó.

A WinRM szolgáltatás http protokollba ágyazott kommunikációt folytat, így akár tűzfalon keresztül is képes két gép ezzel egymással kommunikálni. A kommunikáció eleve titkosított, így nem feltétlenül szükséges SSL titkosítás használata, de arra is van lehetőség. Ha sikeresen beindítottuk a WinRM szolgáltatást, akkor létrehozhatjuk a távoli futtatáshoz szükséges munkameneteket.

Visszatérve a távoli futtatás engedélyezésére, látható volt, hogy sok jóváhagyás után tudtunk csak eljutni a funkció bekapcsolásáig. Ha ezeket a jóváhagyásokat ki akarjuk hagyni, akkor használjuk a ‑force kapcsolót:

[15] PS C:\> Enable-PSRemoting -force

A távoli futtatással kapcsolatos cmdletek főneve a PSSession:

PS C:\> Get-Command -noun pssession

 

CommandType     Name                          Definition

-----------     ----                          ----------

Cmdlet          Enter-PSSession               Enter-PSSession [-Computer...

Cmdlet          Exit-PSSession                Exit-PSSession [-Verbose] ...

Cmdlet          Export-PSSession              Export-PSSession [-Session...

Cmdlet          Get-PSSession                 Get-PSSession [[-ComputerN...

Cmdlet          Import-PSSession              Import-PSSession [-Session...

Cmdlet          New-PSSession                 New-PSSession [[-ComputerN...

Cmdlet          Remove-PSSession              Remove-PSSession [-Session...

Nyissunk is gyorsan egy ilyen PSSession-t a New-PSSession  cmdlet segítségével, rögtön két gépre:

[16] PS C:\> New-PSSession -ComputerName dc, member

 

 Id Name            ComputerName    State    ConfigurationName    Availab

                                                                    ility

 -- ----            ------------    -----    -----------------    -------

  1 Session1        member          Opened   Microsoft.PowerShell ...able

  2 Session2        dc              Opened   Microsoft.PowerShell ...able

Ha egy picit részletesebb listanézetre váltunk, akkor még több információt kapunk:

[17] PS C:\> Get-PSSession 1 | fl

 

 

ComputerName           : member

ConfigurationName      : Microsoft.PowerShell

InstanceId             : 3c8eafa1-1efe-4f7f-ae2d-f1bab9f749f9

Id                     : 1

Name                   : Session1

Availability           : Available

ApplicationPrivateData : {PSVersionTable}

Runspace               : System.Management.Automation.RemoteRunspace

State                  : Opened

Megjegyzés

Egy géphez egy időben akár több PSSession-t is nyithatunk. Vigyázzunk, ezt csak akkor alkalmazzuk, ha tényleg erre van szükség. Például sok gépnek akarjuk újraindítani ugyanazt a szolgáltatást, akkor nem sok értelme van ezt kétszer megcsinálni egy adott gépen.

Bírjuk munkára ezt a fajta munkamenetet is, kíváncsi vagyok az összes bevont gépen futó, „g” betűvel kezdődő szolgáltatásra:

[23] PS C:\> Invoke-Command -Session (Get-PSSession) -ScriptBlock {get-ser

vice g*}

 

Status   Name               DisplayName                            PSComp

                                                                   uterNa

                                                                   me

------   ----               -----------                            ------

Running  gpsvc              Group Policy Client                    member

Running  gpsvc              Group Policy Client                    dc

Itt nem kell külön lekérni a futtatás eredményét, hiszen itt most nem „job”-ként hajtattam végre a scriptet, azaz az eredményt rögtön megkaptam. A kimenet elvileg akár lehetne „vegyes” is, azaz a különböző gépekről érkező információk keveredhetnének is, ilyenkor szükség lehet a kimenet PSComputerName szerinti rendezésére is.

Ha mégis háttérben szeretném futtatni ezeket, akkor van lehetőség erre is, a korábban már említett –AsJob kapcsoló használatával:

[33] PS C:\> Invoke-Command -Session (Get-PSSession) -ScriptBlock {get-ser

vice g*} -AsJob

 

WARNING: column "Command" does not fit into the display and was removed.

 

Id              Name            State      HasMoreData     Location

--              ----            -----      -----------     --------

23              Job23           Running    True            member,dc

 

 

[34] PS C:\> Receive-Job 23

 

Status   Name               DisplayName                            PSComp

                                                                   uterNa

                                                                   me

------   ----               -----------                            ------

Running  gpsvc              Group Policy Client                    member

Running  gpsvc              Group Policy Client                    dc

Az első lépésben tehát most nem magát a szolgáltatások listáját kaptam meg, hanem az elindított munkamenet-objektumot. Itt láthatjuk, hogy a Location tulajdonság tartalmazza a számítógépneveket, ahol a munkamenet fut. A Receive-Job-bal kérdezhetjük le a futtatott szkript kimenetét.

Még érdekesebb, hogy interakcióba is léphetünk ilyen PSSession objektumokkal az Enter-PSSession  cmdlet segítségével, azaz úgy dolgozhatunk, mintha tényleg azon a gépen nyitottunk volna meg egy PowerShell ablakot:

[35] PS C:\> Get-PSSession

 

 Id Name            ComputerName    State    ConfigurationName    Availab

                                                                    ility

 -- ----            ------------    -----    -----------------    -------

  1 Session1        member          Opened   Microsoft.PowerShell ...able

  2 Session2        dc              Opened   Microsoft.PowerShell ...able

 

 

[36] PS C:\> Enter-PSSession 1

[member]: PS C:\Users\TEMP\Documents> cd c:\

[member]: PS C:\> $env:computername

MEMBER

A fenti példában az 1-es PSSession-höz csatlakoztam, minek következtében a prompt is megváltozott jelezvén, hogy amit ezután látok és gépelek az nem a saját gépemen, hanem a távoli gépen érvényes. Kilépni ebből az Exit-PSSession  cmdlettel lehet:

[member]: PS C:\> Exit-PSSession

[37] PS C:\>

A létrehozott PSSession objektumokat a Remove-PSSession  cmdlettel tudjuk megszüntetni, például az összes megszüntetése a következő kifejezéssel lehetséges:

[38] PS C:\> Get-PSSession | Remove-PSSession

Ha a PSSession objektumokra nincs szükségünk tartósan, mert csak egy szkript futtatásának erejéig akarjuk használni, akkor az invoke-command dinamikusan is képes ilyeneket létrehozni, futtatni bennük a szkriptet és megszüntetni. Ilyenkor a ComputerName paramétert kell megadni:

[39] PS C:\> Invoke-Command -ComputerName dc, member -ScriptBlock {$env:co

mputername}

MEMBER

DC

A futtatás után nem is marad semmilyen PSSession objektum, amit meg kellene szüntetni.

A paraméterátadás ugyanolyan módon történik, mint ahogy a háttérfolyamatok során láttuk, itt is az ‑inputobject paraméteren keresztül lehet átadni a változókat:

[40] PS C:\> $a = " gép"; Invoke-Command -Session (get-pssession) -ScriptB

lock {$env:computername + $input} -InputObject $a

MEMBER gép

DC gép

Megjegyzés

Vigyázat! A PSSession-nek átadott objektumok némi csonkításon mennek keresztül. Az alábbi példában egy mappaobjektumot adok át a PSSesson-nek, és a munkamenetből nézve kérek egy get-member-t erre az objektumra:

[44] PS C:\> $a = get-item C:\munka

[45] PS C:\> Invoke-Command -Session (Get-PSSession) -ScriptBlock {$input

| gm} -inputobject $a

 

 

   TypeName: Deserialized.System.IO.DirectoryInfo

 

WARNING: column "PSComputerName" does not fit into the display and was re

moved.

 

Name              MemberType   Definition

----              ----------   ----------

ToString          Method       string ToString(), string ToString(stri...

BaseName          NoteProperty System.String BaseName=munka

Mode              NoteProperty System.String Mode=d----

PSChildName       NoteProperty System.String PSChildName=munka

PSDrive           NoteProperty Deserialized.System.Management.Automati...

PSIsContainer     NoteProperty System.Boolean PSIsContainer=True

PSParentPath      NoteProperty System.String PSParentPath=Microsoft.Po...

Látható, hogy a System.IO.DirectoryInfo objektumomból „Deserialized” változat lett, azaz elvesztette az objektum az összes metódusát és csak a tulajdonságai élnek tovább. A háttérben pont az játszódik le, mint amit korábban láttunk az objektumok XML adatblokkokká történő konvertálása során, hiszen a hálózaton keresztül itt is pont XML adatok formájában utazgatnak az objektumok.



Word To HTML Converter