Seite 1, Druckdatum: 08.04.2017, 05:39 Uhr Powershell für .NET Entwickler Teil 2 – Praxisbeispiele aus dem Entwickleralltag Listing 1: PowerShell Remoting #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 0.27 8900 7804 64 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)… Ende Listing 2: Sprachausgabe mit COM und Excel Interop #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) Seite 2, Druckdatum: 08.04.2017, 05:39 Uhr $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"); Ende Listing 3: PowerShell Provider #Anzeigen aller verfügbaren Provider PS C:\> Get-PSProvider Name Capabilities Drives ---- ------------ ------ Registry ShouldProcess, Transactions {HKLM, HKCU} Alias ShouldProcess {Alias} Environment ShouldProcess FileSystem {Env} 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. Seite 3, Druckdatum: 08.04.2017, 05:39 Uhr 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 … Ende Listing 4: PowerShell Provider für Sql Server und IIS #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 ---- -- ----- ------------- -------- Seite 4, Druckdatum: 08.04.2017, 05:39 Uhr 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 Seite 5, Druckdatum: 08.04.2017, 05:39 Uhr ResourceGovernor Roles #Pfad zu einer Tabelle SQLSERVER:\sql\ltmme02\default\databases\mydb1\tables\dbo.mytable Ende Listing 5: SOAP und REST WebServices aufrufen #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 Seite 6, Druckdatum: 08.04.2017, 05:39 Uhr Ende Listing 6: Gemischte Snippets #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' Seite 7, Druckdatum: 08.04.2017, 05:39 Uhr 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 Ende Blog-Link zu den Listings http://manuelmeyer.net/2016/03/powershell/