Delen via


Hoofdstuk 8 - Externe communicatie van PowerShell

PowerShell biedt verschillende manieren om opdrachten uit te voeren op externe computers. In het laatste hoofdstuk hebt u verkend hoe u op afstand een query kunt uitvoeren op WMI met behulp van de CIM-cmdlets. PowerShell bevat ook verschillende cmdlets met een ingebouwde computernaamparameter .

Zoals in het volgende voorbeeld wordt weergegeven, kunt u met de parameter Get-Command cmdlets identificeren die een ComputerName-parameter bevatten.

Get-Command -ParameterName ComputerName
CommandType Name              Version Source                         
----------- ----              ------- ------                         
Cmdlet      Add-Computer      3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Clear-EventLog    3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Connect-PSSession 3.0.0.0 Microsoft.PowerShell.Core      
Cmdlet      Enter-PSSession   3.0.0.0 Microsoft.PowerShell.Core      
Cmdlet      Get-EventLog      3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Get-HotFix        3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Get-Process       3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Get-PSSession     3.0.0.0 Microsoft.PowerShell.Core      
Cmdlet      Get-Service       3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Get-WmiObject     3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Invoke-Command    3.0.0.0 Microsoft.PowerShell.Core      
Cmdlet      Invoke-WmiMethod  3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Limit-EventLog    3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      New-EventLog      3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      New-PSSession     3.0.0.0 Microsoft.PowerShell.Core      
Cmdlet      Receive-Job       3.0.0.0 Microsoft.PowerShell.Core      
Cmdlet      Receive-PSSession 3.0.0.0 Microsoft.PowerShell.Core      
Cmdlet      Register-WmiEvent 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Remove-Computer   3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Remove-EventLog   3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Remove-PSSession  3.0.0.0 Microsoft.PowerShell.Core      
Cmdlet      Remove-WmiObject  3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Rename-Computer   3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Restart-Computer  3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Send-MailMessage  3.1.0.0 Microsoft.PowerShell.Utility   
Cmdlet      Set-Service       3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Set-WmiInstance   3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Show-EventLog     3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Stop-Computer     3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Test-Connection   3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Write-EventLog    3.1.0.0 Microsoft.PowerShell.Management

Opdrachten zoals Get-Process en Get-HotFix bevatten een ComputerName-parameter , maar deze benadering is niet de langetermijnrichting die Microsoft aanbeveelt voor het uitvoeren van opdrachten op externe systemen. Zelfs wanneer u een opdracht met een ComputerName-parameter vindt, ontbreekt deze vaak aan een referentieparameter , waardoor het lastig is om alternatieve referenties op te geven. Het uitvoeren van PowerShell vanaf een sessie met verhoogde bevoegdheid garandeert geen succes, omdat een netwerkfirewall de aanvraag tussen uw systeem en de externe computer kan blokkeren.

Om de PowerShell-opdrachten voor externe communicatie die in dit hoofdstuk worden gedemonstreerd te gebruiken, moet PowerShell-remoting zijn ingeschakeld op de externe computer. U kunt deze inschakelen door de Enable-PSRemoting cmdlet uit te voeren.

Enable-PSRemoting
WinRM has been updated to receive requests.
WinRM service type changed successfully.
WinRM service started.

WinRM has been updated for remote management.
WinRM firewall exception enabled.

Een-op-een externe communicatie

Als u een interactieve externe sessie wilt, is een-op-een verbinding op afstand wat u nodig heeft. Dit type remote communicatie wordt geleverd via de Enter-PSSession cmdlet.

Sla uw domeinbeheerdersreferenties op in de $Cred variabele. Met deze methode kunt u uw referenties eenmaal invoeren en opnieuw gebruiken per opdracht zolang uw huidige PowerShell-sessie actief blijft.

$Cred = Get-Credential

Stel een een-op-een externe PowerShell-sessie tot stand met de domeincontroller met de naam dc01.

Enter-PSSession -ComputerName dc01 -Credential $Cred

U ziet dat de PowerShell-prompt wordt voorafgegaan door [dc01]. Dit voorvoegsel geeft aan dat u zich in een interactieve sessie bevindt met de externe computer met de naam dc01. Opdrachten die u nu uitvoert, worden uitgevoerd op dc01, niet op uw lokale computer.

[dc01]: PS C:\Users\Administrator\Documents>

Houd er rekening mee dat u alleen toegang hebt tot de PowerShell-opdrachten en -modules die op de externe computer zijn geïnstalleerd. Als u andere modules lokaal hebt geïnstalleerd, zijn deze niet beschikbaar in de externe sessie.

Wanneer u bent verbonden via een een-op-een interactieve externe communicatiesessie, is het alsof u rechtstreeks op de externe computer zit.

[dc01]: Get-Process | Get-Member
   TypeName: System.Diagnostics.Process

Name                       MemberType     Definition
----                       ----------     ----------
Handles                    AliasProperty  Handles = Handlecount
Name                       AliasProperty  Name = ProcessName
NPM                        AliasProperty  NPM = NonpagedSystemMemorySize64
PM                         AliasProperty  PM = PagedMemorySize64
SI                         AliasProperty  SI = SessionId
VM                         AliasProperty  VM = VirtualMemorySize64
WS                         AliasProperty  WS = WorkingSet64
Disposed                   Event          System.EventHandler Disposed(Sy...
ErrorDataReceived          Event          System.Diagnostics.DataReceived...
Exited                     Event          System.EventHandler Exited(Syst...
OutputDataReceived         Event          System.Diagnostics.DataReceived...
BeginErrorReadLine         Method         void BeginErrorReadLine()
BeginOutputReadLine        Method         void BeginOutputReadLine()
CancelErrorRead            Method         void CancelErrorRead()
CancelOutputRead           Method         void CancelOutputRead()
Close                      Method         void Close()
CloseMainWindow            Method         bool CloseMainWindow()
CreateObjRef               Method         System.Runtime.Remoting.ObjRef ...
Dispose                    Method         void Dispose(), void IDisposabl...
Equals                     Method         bool Equals(System.Object obj)
GetHashCode                Method         int GetHashCode()
GetLifetimeService         Method         System.Object GetLifetimeService()
GetType                    Method         type GetType()
InitializeLifetimeService  Method         System.Object InitializeLifetim...
Kill                       Method         void Kill()
Refresh                    Method         void Refresh()
Start                      Method         bool Start()
ToString                   Method         string ToString()
WaitForExit                Method         bool WaitForExit(int millisecon...
WaitForInputIdle           Method         bool WaitForInputIdle(int milli...
__NounName                 NoteProperty   string __NounName=Process
BasePriority               Property       int BasePriority {get;}
Container                  Property       System.ComponentModel.IContaine...
EnableRaisingEvents        Property       bool EnableRaisingEvents {get;s...
ExitCode                   Property       int ExitCode {get;}
ExitTime                   Property       datetime ExitTime {get;}
Handle                     Property       System.IntPtr Handle {get;}
HandleCount                Property       int HandleCount {get;}
HasExited                  Property       bool HasExited {get;}
Id                         Property       int Id {get;}
MachineName                Property       string MachineName {get;}
MainModule                 Property       System.Diagnostics.ProcessModul...
MainWindowHandle           Property       System.IntPtr MainWindowHandle ...
MainWindowTitle            Property       string MainWindowTitle {get;}
MaxWorkingSet              Property       System.IntPtr MaxWorkingSet {ge...
MinWorkingSet              Property       System.IntPtr MinWorkingSet {ge...
Modules                    Property       System.Diagnostics.ProcessModul...
NonpagedSystemMemorySize   Property       int NonpagedSystemMemorySize {g...
NonpagedSystemMemorySize64 Property       long NonpagedSystemMemorySize64...
PagedMemorySize            Property       int PagedMemorySize {get;}
PagedMemorySize64          Property       long PagedMemorySize64 {get;}
PagedSystemMemorySize      Property       int PagedSystemMemorySize {get;}
PagedSystemMemorySize64    Property       long PagedSystemMemorySize64 {g...
PeakPagedMemorySize        Property       int PeakPagedMemorySize {get;}
PeakPagedMemorySize64      Property       long PeakPagedMemorySize64 {get;}
PeakVirtualMemorySize      Property       int PeakVirtualMemorySize {get;}
PeakVirtualMemorySize64    Property       long PeakVirtualMemorySize64 {g...
PeakWorkingSet             Property       int PeakWorkingSet {get;}
PeakWorkingSet64           Property       long PeakWorkingSet64 {get;}
PriorityBoostEnabled       Property       bool PriorityBoostEnabled {get;...
PriorityClass              Property       System.Diagnostics.ProcessPrior...
PrivateMemorySize          Property       int PrivateMemorySize {get;}
PrivateMemorySize64        Property       long PrivateMemorySize64 {get;}
PrivilegedProcessorTime    Property       timespan PrivilegedProcessorTim...
ProcessName                Property       string ProcessName {get;}
ProcessorAffinity          Property       System.IntPtr ProcessorAffinity...
Responding                 Property       bool Responding {get;}
SafeHandle                 Property       Microsoft.Win32.SafeHandles.Saf...
SessionId                  Property       int SessionId {get;}
Site                       Property       System.ComponentModel.ISite Sit...
StandardError              Property       System.IO.StreamReader Standard...
StandardInput              Property       System.IO.StreamWriter Standard...
StandardOutput             Property       System.IO.StreamReader Standard...
StartInfo                  Property       System.Diagnostics.ProcessStart...
StartTime                  Property       datetime StartTime {get;}
SynchronizingObject        Property       System.ComponentModel.ISynchron...
Threads                    Property       System.Diagnostics.ProcessThrea...
TotalProcessorTime         Property       timespan TotalProcessorTime {get;}
UserProcessorTime          Property       timespan UserProcessorTime {get;}
VirtualMemorySize          Property       int VirtualMemorySize {get;}
VirtualMemorySize64        Property       long VirtualMemorySize64 {get;}
WorkingSet                 Property       int WorkingSet {get;}
WorkingSet64               Property       long WorkingSet64 {get;}
PSConfiguration            PropertySet    PSConfiguration {Name, Id, Prio...
PSResources                PropertySet    PSResources {Name, Id, Handleco...
Company                    ScriptProperty System.Object Company {get=$thi...
CPU                        ScriptProperty System.Object CPU {get=$this.To...
Description                ScriptProperty System.Object Description {get=...
FileVersion                ScriptProperty System.Object FileVersion {get=...
Path                       ScriptProperty System.Object Path {get=$this.M...
Product                    ScriptProperty System.Object Product {get=$thi...
ProductVersion             ScriptProperty System.Object ProductVersion {g...

Wanneer u klaar bent met het werken met de externe computer, voert u de Exit-PSSession cmdlet uit om de externe sessie te beëindigen.

[dc01]:  Exit-PSSession

Een-op-veel externe communicatie

Hoewel u soms taken interactief moet uitvoeren op een externe computer, wordt externe communicatie van PowerShell krachtiger wanneer u opdrachten tegelijk uitvoert op meerdere externe systemen. Gebruik de Invoke-Command cmdlet om opdrachten uit te voeren op een of meer externe computers tegelijk.

In het volgende voorbeeld voert u een query uit op drie servers voor de status van de Windows Time-service. De Get-Service cmdlet wordt in het scriptblok van Invoke-Command geplaatst, wat betekent dat deze op elke externe computer wordt uitgevoerd.

Invoke-Command -ComputerName dc01, sql02, web01 {
    Get-Service -Name W32time
} -Credential $Cred

De resultaten worden geretourneerd naar uw lokale sessie als gedeserialiseerde objecten.

Status   Name        DisplayName       PSComputerName
------   ----        -----------       --------------
Running  W32time     Windows Time      web01
Start... W32time     Windows Time      dc01
Running  W32time     Windows Time      sql02

Als u wilt controleren of de geretourneerde objecten gedeserialiseerd zijn, sluist u de uitvoer door naar Get-Member.

Invoke-Command -ComputerName dc01, sql02, web01 {
    Get-Service -Name W32time
} -Credential $Cred | Get-Member
   TypeName: Deserialized.System.ServiceProcess.ServiceController

Name                MemberType   Definition
----                ----------   ----------
GetType             Method       type GetType()
ToString            Method       string ToString(), string ToString(strin...
Name                NoteProperty string Name=W32time
PSComputerName      NoteProperty string PSComputerName=dc01
PSShowComputerName  NoteProperty bool PSShowComputerName=True
RequiredServices    NoteProperty Deserialized.System.ServiceProcess.Servi...
RunspaceId          NoteProperty guid RunspaceId=5ed06925-8037-43ef-9072-...
CanPauseAndContinue Property     System.Boolean {get;set;}
CanShutdown         Property     System.Boolean {get;set;}
CanStop             Property     System.Boolean {get;set;}
Container           Property      {get;set;}
DependentServices   Property     Deserialized.System.ServiceProcess.Servi...
DisplayName         Property     System.String {get;set;}
MachineName         Property     System.String {get;set;}
ServiceHandle       Property     System.String {get;set;}
ServiceName         Property     System.String {get;set;}
ServicesDependedOn  Property     Deserialized.System.ServiceProcess.Servi...
ServiceType         Property     System.String {get;set;}
Site                Property      {get;set;}
StartType           Property     System.String {get;set;}
Status              Property     System.String {get;set;}

U ziet dat de meeste methoden ontbreken in gedeserialiseerde objecten. De methoden ontbreken omdat deze objecten niet actief zijn. Ze zijn inerte momentopnamen van de status van het object wanneer u de opdracht uitvoert op de externe computer. U kunt bijvoorbeeld een service niet starten of stoppen met een gedeserialiseerd object omdat deze geen toegang meer heeft tot de vereiste methoden.

Dit betekent echter niet dat u methoden zoals Stop() met Invoke-Command kunt gebruiken. De sleutel is dat u de methode binnen de externe sessie moet aanroepen.

Als u dit wilt demonstreren, stopt u de Windows Time-service op alle drie de externe servers door de Stop() methode op afstand aan te roepen.

Invoke-Command -ComputerName dc01, sql02, web01 {
    (Get-Service -Name W32time).Stop()
} -Credential $Cred

Invoke-Command -ComputerName dc01, sql02, web01 {
    Get-Service -Name W32time
} -Credential $Cred
Status   Name        DisplayName       PSComputerName
------   ----        -----------       --------------
Stopped  W32time     Windows Time      web01
Stopped  W32time     Windows Time      dc01
Stopped  W32time     Windows Time      sql02

Zoals vermeld in een eerder hoofdstuk, als er een cmdlet beschikbaar is om een taak uit te voeren, is het beter om deze te gebruiken in plaats van een methode rechtstreeks aan te roepen. Gebruik bijvoorbeeld de Stop-Service cmdlet in plaats van de Stop() methode om een service te stoppen.

In het vorige voorbeeld wordt de Stop() methode gebruikt om een punt te maken. Sommige mensen denken ten onrechte dat je geen methoden kunt gebruiken met PowerShell-remoting. Hoewel het waar is dat u geen methoden kunt aanroepen voor gedeserialiseerde objecten die zijn geretourneerd naar uw lokale sessie, kunt u ze echter wel aanroepen binnen de externe sessie.

PowerShell-sessies

In het laatste voorbeeld uit de vorige sectie hebt u twee opdrachten uitgevoerd met behulp van de Invoke-Command cmdlet. In dit scenario zijn twee afzonderlijke sessies tot stand gebracht en afgebroken. Eén voor elke opdracht.

Net als bij CIM-sessies kunt u met een permanente PowerShell-sessie meerdere opdrachten uitvoeren op een externe computer zonder dat u voor elke opdracht een nieuwe sessie hoeft te maken.

Maak een PowerShell-sessie voor elk van de drie computers waarmee u werkt in dit hoofdstuk, DC01, SQL02 en WEB01.

$Session = New-PSSession -ComputerName dc01, sql02, web01 -Credential $Cred

Gebruik nu de $Session variabele om de Windows Time-service te starten door de methode aan te roepen en vervolgens de servicestatus te controleren.

Invoke-Command -Session $Session {(Get-Service -Name W32time).Start()}
Invoke-Command -Session $Session {Get-Service -Name W32time}
Status   Name        DisplayName       PSComputerName
------   ----        -----------       --------------
Running  W32time     Windows Time      web01
Start... W32time     Windows Time      dc01
Running  W32time     Windows Time      sql02

Zodra u de sessie met alternatieve referenties hebt gemaakt, hoeft u deze referenties niet opnieuw op te geven voor elke opdracht.

Verwijder de sessies wanneer u klaar bent met het gebruik ervan.

Get-PSSession | Remove-PSSession

Samenvatting

In dit hoofdstuk hebt u de basisprincipes van externe communicatie van PowerShell geleerd, waaronder het interactief uitvoeren van opdrachten op één externe computer en het uitvoeren van opdrachten op meerdere systemen met behulp van een-op-veel externe communicatie. U hebt ook de voordelen van het gebruik van permanente PowerShell-sessies verkend bij het uitvoeren van meerdere opdrachten op dezelfde externe computer.

Recensie

  1. Hoe schakelt u PowerShell-remote-vermogen in?
  2. Welke PowerShell-opdracht gebruikt u om een interactieve sessie met een externe computer te starten?
  3. Wat is een voordeel van het gebruik van een externe PowerShell-sessie in plaats van de computernaam op te geven met elke opdracht?
  4. Kunt u een PowerShell-sessie gebruiken in een een-op-een interactief remoting-scenario?
  5. Wat is het verschil tussen de objecten die worden geretourneerd door cmdlets die lokaal worden uitgevoerd en de objecten die worden geretourneerd wanneer dezelfde cmdlets op externe computers worden uitgevoerd met behulp van Invoke-Command?

Verwijzingen

Volgende stappen

In hoofdstuk 9 leert u hoe u herbruikbare PowerShell-functies schrijft. U verkent functieontwerp, parameters, pijplijninvoer, foutafhandeling en aanbevolen procedures voor het omzetten van één regel en scripts in betrouwbare hulpprogramma's.