Dieser Artikel erklärt, wie PowerShell Remoting und die Integration mit COM und WMI/CIM funktioniert. Weiter werden das Providermodell und die Arbeit mit SOAP und REST Web Services vorgestellt. Abgerundet wird der Artikel mit einer Sammlung von PowerShell-Snippets für den Alltag.
Die PowerShell ist ein Kommandozeileninterpreter für Windows. Sie wird mit dem Windows-Betriebssystem ausgeliefert und ist in vielen Produkten, wie SharePoint, TFS oder Exchange Server integriert. Weil die PowerShell auf dem .NET Framework aufgebaut ist und Schnittstellen zur Windows Management Instrumentation (WMI), dem Component Object Model (COM), der Registry und vielen anderen Komponenten anbietet, können komplexe Aufgaben mithilfe der PowerShell oft mit einem einzigen Befehl erledigt werden. Diese Befehle lassen sich sowohl lokal als auch remote ausführen.
Teil 1: PowerShell-Grundlagen: Hilfe, wie geht’s los?
Teil 2: PowerShell-Grundlagen: Bearbeitung und Weiterverarbeitung von Cmdlet-Ergebnissen
Teil 3: PowerShell-Praxisbeispiele aus dem DevOps-Alltag
PowerShell-Befehle – auch Commandlet (Cmdlet) genannt – können über den Pipe-Operator „|“ miteinander verbunden werden. Die PowerShell kommt mit einer Fülle von Cmdlets, die beispielsweise zur Formatierung der Ausgabe verwendet werden können.
Folgendes Beispiel zeigt einen Befehl, der vom lokalen Rechner die ersten zehn Windows Services ermittelt und deren Namen und Status als HTML-Datei ausgibt. Das Resultat ist in Abbildung 1 zu sehen.
PS C:\> Get-Service | Select-Object Name, Status -First 10 |Sort-Object Status -Descending | ConvertTo-Html | Out-File "D:\ServiceReport.html"
PowerShell Remoting
Ein großer Anteil der Power in der Shell kommt daher, dass Cmdlets mit wenig Aufwand auch auf Remote-Maschinen ausgeführt werden können. Der Zielrechner muss dabei für PowerShell Remoting vorbereitet sein, indem unter anderem der Windows-Remote-Management-Service eingeschaltet wird. Mit dem Cmdlet Test-WSMan –ComputerName
kann überprüft werden, ob der Zielrechner PowerShell-Anfragen entgegennehmen kann.
Ist dies nicht der Fall, kann Remoting mit Enable-PSRemoting –force
eingeschaltet werden. Dabei wird der benötigte Windows-Service gestartet, ein Listener registriert und Firewallports geöffnet.
Die PowerShell bietet mehrere Möglichkeiten, um auf andere Rechner zuzugreifen.
Mit dem Enter-PSSession Cmdlet
wird eine PowerShell-Session auf dem Zielrechner geöffnet, vorausgesetzt, die Berechtigung ist vorhanden. Mit der Option -Credentials kann ein Benutzername angegeben werden, und die PowerShell erfragt das dazugehörende Passwort. Sobald die Verbindung steht, können Cmdlets normal ausgeführt werden.
Gewisse Cmdlets unterstützen von sich aus die Ausführung auf einem anderen Rechner. Das Öffnen einer Remote-Session ist dann nicht mehr nötig. Listing 1 zeigt ein Beispiel mit dem Get-Process
Cmdlet. Dabei wird mit dem Argument -Computername der Name des Zielrechners übergeben.
Noch spannender wird PowerShell Remoting wenn ein Befehl gleichzeitig auf mehreren Rechnern ausgeführt wird. Dem Cmdlet Invoke-Command
kann ein Skriptblock übergeben werden, der einen weiteren Befehl enthält. Mit der Option –ComputerName können ein oder mehrere Zielrechner angegeben werden.
#Variante 1: Enter-PSSession #Öffnen einer Remoting Session auf Zielrechner LTMME05 PS C:\> Enter-PSSession –ComputerName LTMME05 #Der Rechnername wird in der Eingabeaufforderung angezeigt und Befehle können auf dem Remote-Rechner ausgeführt werden. [LTMME05] PS C:\> hostname LTMME05 #Variante 2: Cmdlet mit Option –Computername PS C:\> Get-Process -ComputerName LTMME05 | Select-Object -First 1 Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id SI ProcessName ------- ------ ----- ----- ----- ------ -- -- ----------- 113 9 6156 7804 64 0.27 8900 1 ACEngSvr #Variante 3: Invoke-Command #Das Beispiel holt einen EventLog Eintrag von 3 Rechnern PS C:\> Invoke-Command -ComputerName LTMME05, LTMME06, LTMME07 -ScriptBlock {Get-EventLog Security -Newest 1} #Alternativ können die Rechnernamen auch aus einer Textdatei gelesen werden PS C:\> Invoke-Command –ComputerName (Get-Content Rechnerliste.txt)...
COM Interop
Auf das Component Object Model (COM) kann aus der PowerShell mit New-Object
in Kombination mit der Option -ComObject zugegriffen werden. Listing 2 zeigt zwei Beispiele. Im ersten Beispiel wird die SAPI.SPVoice
-COM-Komponente verwendet, um eine Sprachausgabe zu erzeugen.
Das zweite Beispiel greift mit Excel-Interop
auf Microsoft Excel zu und erstellt ein Excel-Dokument, das eine Liste aller Windows-Services enthält. Die Services werden dabei nach ihrem Status eingefärbt (Abb. 2).
#Sprachausgabe mit COM Interop PS C:\> $voice = New-Object –ComObject SAPI.SPVoice PS C:\> $voice.Speak("Hello Windows Developer"); #Vorlesen einer Datei PS C:\> New-Object –ComObject SAPI.SPVoice PS C:\> $text = Get-Content C:\Datei.txt PS C:\> $voice.Speak($text) #Erstellen eines Excel Sheets mit COM Interop [Threading.Thread]::CurrentThread.CurrentCulture = "EN-us" $ex = New-Object -ComObject Excel.Application $ex.visible = $true $exWb = $ex.Workbooks.Add() $exWs = $exWb.Worksheets.Item(1) $exWs.Cells.Item(2, 1).EntireColumn.ColumnWidth = 40 $exWs.Cells.Item(2,1) = "Services Name" $exWs.Cells.Item(2,2) = "Service Status" $row = 3 $services = Get-Service | Select-Object -First 20 foreach($Service in $services) { $exWs.Cells.Item($row,1) = $Service.DisplayName $exWs.Cells.Item($row, 2) = $Service.Status.ToString() if($Service.Status -eq "Running") { $exWs.Cells.Item($row,1).Font.ColorIndex = 10 $exWs.Cells.Item($row,2).Font.ColorIndex = 10 } elseif($Service.Status -eq "Stopped") { $exWs.Cells.Item($row,1).Font.ColorIndex = 3 $exWs.Cells.Item($row,2).Font.ColorIndex = 3 } $row++ Write-Host "row++" } $exWs.SaveAs("C:\ServiceStatusReport.xlsx");
WMI
Die Windows Management Instrumentation (WMI) ist eine Schnittstelle zum Windows-Betriebssystem. Über die WMI kann auf eine riesige Menge von Informationen des lokalen Rechners oder eines Remote-Rechners zugegriffen werden. Beispiele dafür sind Informationen über das BIOS, sämtliche Peripheriegeräte, Prozesse oder die installierte Software.
Mit dem Befehl Get-WmiObject -Class * -List
können sämtliche verfügbaren WMI-Klassen abgefragt werden. Alternativ kann mit Get-CimClass *usb*
nach einer Klasse gesucht werden, die usb im Namen enthält. CIM steht für Common Information Model und ist ein offener Standard zur Beschreibung von Prozessen, Komponenten und Software. Die Cim-Cmdlets kapseln den Zugriff auf die WMI gemäß der CIM-Spezifikation.
Sobald eine Klasse gefunden wurde, lassen sich mit Get-WmiObject –Class Win32_BIOS
oder Get-CimInstance –ClassName Win32_BIOS
ihre Informationen abrufen.
Script Execution Policy
Grundsätzlich ist die Ausführung von PowerShell-Skripten abgeschaltet. Mit dem Cmdlet Set-ExecutionPolicy
kann die Skriptausführung erlaubt werden. Folgende Werte können gesetzt werden:
- Restricted: Keine Scripts können ausgeführt werden
- AllSigned: Nur Skripte, die von einem Trusted Publisher signiert wurden, dürfen ausgeführt werden
- RemoteSigned: Heruntergeladene Skripte müssen von einem Trusted Publisher signiert sein
- Unrestricted: Alle Skripte können ausgeführt werden
Damit sich die „ExecutionPolicy“ ändern lässt, muss die PowerShell mit administrativer Berechtigung ausgeführt werden.
PowerShell-Provider
Die PowerShell implementiert ein erweiterbares Providermodell. Das Providermodell erlaubt die Navigation durch hierarchische Strukturen, wie zum Beispiel ein Dateisystem. Im Dateisystem wird mit den Befehlen dir, cd, „..“ usw. durch die vorhandenen Ordner navigiert, wie es in der Windows Eingabeaufforderung üblich ist. Dass dies in der PowerShell auch funktioniert, ist dem FileSystem-Provider zu verdanken.
Die Liste aller verfügbaren Provider kann mit Get-PSProvider
abgerufen werden. Die Provider können über so genannte Drives angesprochen werden, genau wie man es vom alten DOS-Prompt gewohnt sein dürfte. Im Listing werden für den Filesystemprovider die Drives C, A, D, Z aufgeführt, die logischen Laufwerken entsprechen. Viel interessanter sind aber die anderen Provider. Über den Drive Env kann zum Beispiel auf die Umgebungsvariablen oder über das Drive HKLM auf die Registry zugegriffen werden. Listing 3 zeigt, wie über das Providermodell durch die Registry navigiert wird.
#Anzeigen aller verfügbaren Provider PS C:\> Get-PSProvider Name Capabilities Drives ---- ------------ ------ Registry ShouldProcess, Transactions {HKLM, HKCU} Alias ShouldProcess {Alias} Environment ShouldProcess {Env} FileSystem Filter, ShouldProcess, Credentials {C, D, G, H} … #Wechsel zum Registry Provider über das „HKLM“ Drive #Hinweis: HKLM steht hier für den Registry-Ast HKEY_LOCAL_MACHINE PS C:\> cd hklm: #Navigation durch die Registry zum PowerShellEngine Eintrag #Hinweis: Mit der Tabulatortaste können die Einträge vervollständigt werden. PS HKLM:\> dir Name ---- BCD00000000 DRIVERS HARDWARE SAM SOFTWARE SYSTEM PS HKLM:\> cd .\SOFTWARE\Microsoft\PowerShell\1\ PS HKLM:\SOFTWARE\Microsoft\PowerShell\1\> dir Name Property ---- -------- PowerShellEngine ApplicationBase : C:\Windows\System32… ConsoleHostAssemblyName : Microsoft.PowerShel… Culture=neutral, PublicKeyToken=31bf… PowerShellVersion : 2.0 RuntimeVersion : v2.0.50727 …
Mit dem Import-Module
Cmdlet können weitere Provider importiert werden. Eine Liste von Produkten, die einen PowerShell-Provider bereitstellen, ist in der Wikipedia ersichtlich.
Listing 4 zeigt die Benutzung der Provider für SQL Server und die Internet Information Services (IIS). Das Modul für den SQL Server wird mit dem SQL Server zusammen installiert oder kann manuell nachinstalliert werden. Das WebAdministration
-Modul für den IIS wird auf Windows Server zusammen mit der Web Server Role installiert.
#Importieren der Provider für Sql Server und IIS PS C:\> Import-Module SQLPS PS C:\> Import-Module WebAdministration PS C:\> Get-PSProvider Name Capabilities Drives ---- ------------ ------ SqlServer Credentials {SQLSERVER} WebAdministration ShouldProcess {IIS} … #Anzeigen aller Sites im IIS PS C:\> cd IIS: PS IIS:\> dir Name ---- AppPools Sites SslBindings PS IIS:\> dir sites Name ID State Physical Path Bindings ---- -- ----- ------------- -------- Default Web Site 1 Stopped D:\PROJECTS… net.tcp 808:* net.pipe * net.msmq MySite1 3 Started D:\TFS\... http *:41019: #Anzeige aller Application Pools und deren Applications PS IIS:\> dir apppools Name State Applications ---- ----- ------------ .NET v4.5 Started .NET v4.5 Classic Started DefaultAppPool Started Default Web Site /App1 /App2 /App3 MySite1 Started MySite1 /AppA /AppB #Hinweis: Die AppPools können auch von einem anderen Drive aus aufgerufen werden ohne explizit in den Provider zu wechseln: PS C:\> dir iis:\apppools #Erstellen eines neuen Application Pools PS IIS:\> New-Item AppPools\NewAppPool #Setzen eines Application Pools PS IIS:\> Set-ItemProperty 'sites\MySite1\AppB' –Name applicationPool –Value NewAppPool #Wechsel auf den SqlServer Provider PS C:\> cd sqlserver: PS SQLSERVER:\> dir Audits AvailabilityGroups BackupDevices Credentials CryptographicProviders Databases Endpoints JobServer Languages LinkedServers Logins Mail ResourceGovernor Roles #Pfad zu einer Tabelle SQLSERVER:\sql\ltmme02\default\databases\mydb1\tables\dbo.mytable
Arbeiten mit SQL Server und IIS
Neben den Providern für SQL Server und IIS gibt es eine weitere Möglichkeit, um mit Produkten von Microsoft oder Drittherstellern via PowerShell zu kommunizieren. Viele dieser Produkte bringen bei der Installation ihre eigenen PowerShell-Module mit. Ein Modul ist dabei nichts anderes als ein Behälter für PowerShell Cmdlets. Mit Get-Module –ListAvailable
können die auf dem Rechner vorhandenen Module abgefragt werden. Der Befehl Import-Module –Name modulname
importiert das entsprechende Modul in die aktive Session. Über die Umgebungsvariable PSModulePath werden Module der PowerShell bekannt gemacht, damit sie nicht in jede Session importiert werden müssen, sondern automatisch zur Verfügung stehen.
Die Module für SQL Server und IIS enthalten Cmdlets für alle gängigen Operationen. Die folgende Liste zeigt einen Auszug:
- Invoke-Sqlcmd
- Backup-SqlDatabase
- Restore-SqlDatabase
- New-WebSite
- New-WebApplication
- Backup-WebConfiguration
Efficient Transformers
Christoph Henkelmann, DIVISIO
Enhancing Page Visits by Topic Prediction
Dieter Jordens, Continuum Consulting NV
Machine Learning on Edge using TensorFlow
Håkan Silfvernagel, Miles AS
Web Services
Das Aufrufen eines SOAP Web Service geht mit der PowerShell sehr komfortabel. Dem Cmdlet New-WebServiceProxy
wird der URI zur WSDL-Datei (Web Services Description Language) übergeben, der Rückgabewert wird in einer Variablen gespeichert, und schon hat man einen typisierten Web-Services-Client. Durch die Typisierung können die Namen der Operationen des Web Service mit der Tabulatortaste vervollständigt oder durchgeklickt werden. Im Integrated Scripting Environment (ISE) werden die Operationsnamen in einem IntelliSense-ähnlichen Dialog angezeigt.
Das Aufrufen eines REST Web Service, was einem einfachen HTTP-Call entspricht, ist mit dem Invoke-Query
Cmdlet möglich. Listing 5 zeigt, wie das Google-Maps-API aus der PowerShell aufgerufen werden kann.
#Aufruf eines SOAP WebServices mit einem typisierten Client PS C:\> $uri = 'http://www.webservicex.net/airport.asmx?WSDL' PS C:\> $airportProxy = New-WebServiceProxy -Uri $uri -Namespace ws PS C:\> $airportProxy.getAirportInformationByAirportCode('ZRH') <NewDataSet> <Table> <AirportCode>FRA</AirportCode> <CityOrAirportName>FRANKFURT INTL</CityOrAirportName> <Country>Germany</Country> … #Durch Zuweisung an eine Variable vom Typ XML wird die Antwort in ein XML Objekt gespeichert werden, mit welchem weitergearbeitet werden kann PS C:\> [XML]$xml = $airportProxy.getAirportInformationByAirportCode('FRA'); PS C:\> $xml.NewDataSet.Table[0].CityOrAirportName FRANKFURT INTL #Aufruf eines REST WebServices #Es soll über die Google Maps API die Distanz zwischen der Basta Spring (Darmstadt) und der Basta (Mainz) ermittelt werden. PS C:\> $uri = 'https://maps.googleapis.com/maps/api/directions/json' PS C:\> $query = '?mode=driving&origin=Rheinstrasse 105, 64283 Darmstadt&destination=Rheinstrasse 66, 55116 Mainz' PS C:\> $response = Invoke-RestMethod $uri$query #Die Variable $response enthält ein JSON Objekt PS C:\> $response.routes[0].legs[0].distance text value ---- ----- 35.1 km 35141 PS C:\> $response.routes[0].legs[0].duration text value ---- ----- 27 mins 1615
Gemischte Snippets
Listing 6 enthält eine Sammlung von nützlichen PowerShell-Snippets für die folgenden Aufgaben:
- Testen von .NET-Format-Strings
- Testen von Regular Expressions (Regex)
- Finden des voll qualifizierten Namens einer Assembly
- Finden des ASCII- oder Unicode-Codes für ein Zeichen
- Abfragen von Performance-Counters
- Messen der Zeit, die für einen REST-Aufruf benötigt wird
- Einträge aus dem EventLog in eine HTML-Datei exportieren
#Testen von Format Strings PS C:\> [string]::Format("{0:r}", [DateTime]::Now); Wed, 16 Mar 2016 23:57:49 GMT #Hinweis: Dasselbe geht auch mit dem Powershell Operator „-f“ PS C:\> „{0:r}“ –f [DateTime]::Now #Testen von Regex #Finde alle zweistelligen Zahlen PS C:\> $regex = [regex]"\b\d\d\b" PS C:\> $regex.Matches("123 45 1 95 1412 99 343 0202 23") | % { $_.value } 45 95 99 23 #Ausgabe des voll qualifizierten Assemblynamen eines Typs PS C:\> [System.IO.FileStream].AssemblyQualifiedName System.IO.FileStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 #Finden des ASCII/Unicode für ein Zeichen PS C:\> [int][char]'£' 163 #Installieren der IIS Rolle auf mehreren Windows Servern PS C:\> 'Server1', 'Server2', 'Server3' |Foreach-Object { Install-WindowsFeature Web-Server –IncludeAllSubFeature –IncludeManagementTools –ComputerName $_} #Anzeigen einer Windows Forms MessageBox PS C:\>[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") PS C:\>[System.Windows.Forms.MessageBox]::Show("Hallo Windows Developer!") #Den Performance Counter „Total CPU Percentage“ jede Sekunde abfragen PS C:\> Get-Counter '\Processor(_total)\% Processor Time' -Continuous -SampleInterval 1 -ComputerName LTMME05 3/17/2016 8:26:13 PM \\ltmme05\processor(_total)\% processor time : 25.7970432422004 … #Messen der Zeit, die für ein REST Aufruf benötigt wird PS C:\> $uri = 'https://maps.googleapis.com/maps/api/directions/json' PS C:\> $query = '?mode=driving&origin=Rheinstrasse 105, 64283 Darmstadt&destination=Rheinstrasse 66, 55116 Mainz' PS C:\> (Measure-Command {Invoke-RestMethod $uri$query}).TotalMilliseconds 356.4796 #Die ersten 100 Einträge im application EventLog als HTML-Datei exportieren PS C:\> get-eventlog -log "application" | select -first 100 | ConvertTo-Html > c:\evt.html
Weitere interessante Ressourcen
Neben den Tipps und Tricks in diesem Artikel gibt es noch eine Vielzahl weiterer Themen, die den begeisterten PowerShell-Benutzer interessieren könnten. So ist es zum Beispiel möglich, mit PowerShell Workflow (PSW) so genannte long-running Workflows zu erstellen. PSW basiert auf der Windows Workflow Foundation (WF) und ermöglicht PowerShell-Aktivitäten zu erstellen, die gestoppt, gestartet und sogar parallelisiert werden können.
Da die PowerShell auf dem .NET Framework basiert, ist es mit wenig Aufwand möglich, PowerShell-Anwendungen mit grafischen Benutzeroberflächen zu erstellen. Dabei kann gewählt werden, ob mit WinForms oder Windows Presentation Foundation (WPF) gearbeitet werden soll.
Natürlich gibt es noch eine Vielzahl an spannenden PowerShell-Modulen, zum Beispiel für die Arbeit mit dem Team Foundation Server oder posh-git für die Arbeit mit Git.
Als letzter Punkt sei die Integration in Microsoft Azure erwähnt. Das Azure SDK enthält eine Vielzahl an PowerShell-Skripten für die Verwaltung sämtlicher Azure-Ressourcen, wie virtuelle Maschinen, Storage-Container oder Cloud-Services. Ein besonders spannendes Feature von Azure ist die PowerShell im Browser. Für jede Azure-Website besteht unter der Adresse https://meinewebsite.scm.azurewebsites.net/ eine Kudu-Seite. Kudu ist die Engine, die für das Git Deployment in die Azure-Website verantwortlich ist. Auf der Kudu-Startseite (Abb. 3) kann über das Menü Debug Console | Powershell die PowerShell-Konsole im Browser (!) geöffnet werden (Abb. 4).
Für weiterführende Informationen zur PowerShell lohnt sich ein Blick in das frei verfügbare E-Book von Keith Hill und in die offizielle PowerShell-Startseite.
Die PowerShell hat sich im Windows-Umfeld etabliert und kann den Entwickleralltag spannender und effektiver gestalten. Diese Artikel haben Ihnen dieses mächtige Werkzeug nähergebracht, damit Sie mit der PowerShell loslegen können, um die Power bei der täglichen Arbeit zu nutzen!
[…] hatte allerdings auch einen schwerwiegenden Fehler für eine der Hauptfunktionen des OS im Gepäck: PowerShell. Konkret betrifft der Bug die Desired State Configuration (DSC); dabei handelt es sich um eine […]