PowerShell 4.0: Kraftfutter für Admins und Entwickler
Kommentare

Mittlerweile gibt es eine Version 4.0 der Windows PowerShell. Im Alltag findet man aber immer noch viele Administratoren und Softwareentwickler, die die Macht der PowerShell nicht kennen. Dabei ist die PowerShell inzwischen sogar in Visual Studio integriert. Grund genug, die PowerShell noch einmal von Grund auf vorzustellen und die neuesten Features hervorzuheben.

Die PowerShell 4.0 ist in Windows 8.1 oder Windows Server 2012 R2 bereits im Standard installiert. In Windows Server 2012 R2 Core ist sie ein optionales Installationsfeature. Die PowerShell 4.0 wird auf Windows 7 und Windows Server 2008 R2 sowie Windows Server 2012 als Teil des Windows Management Framework 4.0 (WMF) installiert. In Windows 8 lässt sich die PowerShell 4.0 nur durch ein Update auf Windows 8.1 nutzen. Ältere Versionen der PowerShell laufen auch auf Windows XP (PowerShell 1.0 und 2.0). Die PowerShell 3.0 läuft ab Windows 7 bzw. Windows Server 2008.

Die PowerShell gibt es auf dem System in zwei Formen: die PowerShell-Konsole (vom Aussehen und Bedienung her dem Windows-Kommandozeilenfenster entsprechend) und das WPF-basierte „Windows PowerShell Integrated Scripting Environment“ (kurz: ISE) mit Skripteditor und interaktivem Eingabebereich.

Commandlets

Ein einzelner Befehl der PowerShell heißt Commandlet (kurz: Cmdlet). Ein Commandlet besteht typischerweise aus drei Teilen: einem Verb und einem Substantiv (getrennt durch einen Bindestrich) sowie einer (optionalen) Parameterliste mit Name-Wert-Paaren, die durch Leerzeichen getrennt sind. Die Parameter müssen nur dann in Anführungszeichen stehen, wenn im Parameterwert selbst Leerzeichen (z. B. in einem Dateisystempfad) vorkommen. Die Groß- und Kleinschreibung ist bei den Namen nicht relevant.

Ein einfaches Beispiel ohne Parameter lautet: Get-Process. Durch einen Parameter kann man z. B. die Prozesse filtern: Get-Process –name i* liefert Prozesse, deren Namen mit i anfangen. Alternativ kann man auch bei einigen Parametern den Namen weglassen, dann muss man aber die Position einhalten. Get-Process i* führt zum gleichen Ergebnis. Das Filtern über die Prozess-ID funktioniert dann aber nur mit Abgabe des Parameternamens –id: Get-Process –id 7844.

Wenn ein Commandlet mehrere Parameter besitzt, ist die Reihenfolge der Parameter entscheidend oder der Nutzer muss die Namen der Parameter mit angeben. Alle folgenden Befehle sind gleichbedeutend, um Dateien mit dem Muster *.doc aus dem c:temp-Verzeichnis aufzulisten:

Get-Childitem C:temp *.doc 
Get-Childitem -Path C:temp -Filter *.doc
Get-Childitem -Filter *.doc -Path C:temp

Die PowerShell-Konsole unterstützt bei der Eingabe durch Tabulatorvervollständigung. Die ISE bietet eine IntelliSense-Eingabeunterstützung wie Visual Studio.

Durch so genannte Aliase kann der Nutzer die Eingabe von Commandlets verkürzen. So ist dir als Alias für Get-Childitem oder help für Get-help vordefiniert. Statt Get-Childitem c: kann er also auch schreiben: dir c:. Ebenso als Alias definiert ist der DOS-Befehl cd, der hier Set-Location repräsentiert. ps und gps sind Aliase für Get-Process. Durch Get-Alias (oder den entsprechenden Alias „aliases„) erhält man eine Liste aller vordefinierten Abkürzungen. Durch Angabe eines Namens bei Get-Alias erhält man die Bedeutung eines Alias, z. B. Get-Alias gps.

Pipelining

Das Commandlet Get-Process lieferte eine Liste der laufenden Prozesse in einer tabellarischen Ausgabe. Diese Ausgabe zeigt aber nicht alle Eigenschaften der Prozesse, sondern nur eine Auswahl, die durch die bei PowerShell mitgelieferte Datei DotNetTypes.Format.ps1xml festgelegt ist. Diese Datei kann man theoretisch ändern. Eine fallweise Ausgabe der gewünschten Eigenschaften erreicht man aber besser durch das „pipen“ der Ausgabe an ein Ausgabe-Commandlet:

Get-Process | Format-Table name,id,workingset.

Die PowerShell arbeitet aber nicht zeichen- oder zeilenorientiert, sondern objektorientiert. Dies bedeutet, dass die Commandlets typisierte .NET-Objekte in die Pipeline werfen und die folgenden Commandlets in der Pipeline diese Objekte anhand ihrer Attribute auswerten können, z. B. Filtern durch Where-Object. $_ steht dabei für das jeweils aktuelle Objekt in der Pipeline. –eq ist der Vergleichsoperator. Deutlicher wird der objektorientierte Ansatz, wenn man als Attribut keine Zeichenkette heranzieht, sondern eine Zahl. WorkingSet ist ein Zahlenwert, der den aktuellen Speicherverbrauch eines Prozesses repräsentiert. Alle Prozesse, die aktuell mehr als 20 Megabyte verbrauchen, liefert der folgende Befehl:

Get-Process | Where-Object {$_.WorkingSet -gt 20*1024*1024 } | Sort-Object WorkingSet -desc | Format-Table name,id,workingset 

Anstelle von 20*1024*1024 hätte man auch das Kürzel 20MB einsetzen können. Workingset kann man durch ws abkürzen. Außerdem kann man Where-Object mit einem Fragezeichen und Sort-Object mit sort und Format-Table mit ft abkürzen. Zudem kann man seit PowerShell 3.0 bei Bedingungen ohne logische Verknüpfung auch die geschweiften Klammern und das $_ weglassen. Die ganz prägnante Variante des Befehls wäre dann also (Das Ergebnis zeigt Abbildung 1):

ps | ? ws -gt 20MB | sort ws -desc | ft name,id,ws 

Abb. 1: Einfaches Pipeline-Beispiel mit Filter, Sortierung und benutzerdefinierter Ausgabe

Es stellt sich die Frage, welches .NET-Objekt da in der Pipeline liegt und welche Eigenschaften damit zur Verfügung stehen. Die Metadaten der Pipeline-Objekte erhält man mit Get-Member, z. B. Get-Process | Get-Member. Die Klasse ist hier System.Diagnostics.Process aus der .NET-Framework-Klassenbibliothek. In anderen Fällen sind diese aber spezielle Klassen der PowerShell oder WMI-Klassen, z. B. bei Get-Hotfix ist dies:

System.Management.ManagementObject#rootcimv2Win32_QuickFixEngineering. 

.NET-Softwareentwickler werden sich wundern, dass in den Metadaten (Abb. 2) neben Property, Method und Event auch andere Eintragsarten wie Alias Property, Note Property, Script Property, Code Property und Property Set erscheinen. Dies sind von der PowerShell im Rahmen einer Extended Reflection dem Objekt hinzugefügte Eigenschaften, die zum Beispiel den Abruf von mehreren Eigenschaften unter einem Namen (Property Set), den Abruf von Eigenschaften unter einem Kurznamen (Alias Property) oder den Abruf von Informationen aus abhängigen Objekten (Script und Code Property) ermöglichen. Als Beispiel sei das Script Property Company bei Get-Process genannt, dass die Firma aus der Startdatei des Prozesses ausliest.

Abb. 2: „Get-Member“ zeigt, was sich in der Pipeline befindet und welche Möglichkeiten man hat

Gesteuert wird das Pipelining von dem PowerShell-Pipeline-Prozessor, der die Objekte von einem Commandlet entgegennimmt und an das folgende Commandlet weiterleitet. Wie Abbildung 3 zeigt, erfolgt im Standard eine Streamingverarbeitung, d. h. das folgende Commandlet beginnt schon mit der Arbeit, auch wenn das vorherige Commandlet noch nicht alle Objekte geliefert hat. Es gibt allerdings Commandlets wie Sort-Object und Group-Object, die naturgemäß kein Streaming erlauben.

Abb. 3: Pipelining in der PowerShell

Die Objekt-Pipeline ermöglicht aber nicht nur den Abruf von Attributen, sondern auch den Aufruf von Methoden. Die Klasse System.Diagnostics.Process besitzt eine Methode Kill() zum Beenden von Prozessen. Der Aufruf dieser Methode ist in der PowerShell in der Methode Stop-Process gekapselt.

Der folgende PowerShell-Pipeline-Befehl beendet alle Instanzen des Internet Explorers auf dem lokalen System, indem das Commandlet Stop-Process die Instanzen des betreffenden Prozesses von Get-Process empfängt:

Get-Process iexplore | Stop-Process

Wer sich mit dem .NET Framework gut auskennt, könnte die Methode auch direkt aufrufen. Dann ist aber eine explizite ForEach-Schleife notwendig. Die Commandlets iterieren automatisch über alle Objekte der Pipeline, die Methodenaufrufe aber nicht:

Get-Process iexplore | Foreach-Object { $_.Kill() }

Auch diese Schreibweise ist erlaubt:

(Get-Process iexplore).Kill()

Dies funktioniert aber nur dann gut, wenn es auch Instanzen des Internet Explorers gibt. Sind alle beendet, meldet Get-Process einen Fehler. Dies kann das gewünschte Verhalten sein. Mit einer etwas anderen Pipeline kann man diesen Fehler jedoch unterbinden:

Get-Process | Where-Object { $_.Name -eq "iexplore" } | Stop-Process

Der Inhalt der Pipeline kann in einer Variablen zwischengespeichert werden. Der Name einer Variablen beginnt immer mit dem Dollarzeichen:

$DiensteMitW = Get-Service | ? name -like "w*"
$DiensteMitW | group status 

Variablen können auch auf jeden beliebigen .NET-Typ typisiert werden, z. B. [int] Anzahl = 10;.

[ header = Seite 2: Remoting ]

Remoting

Einige Commandlets wie Get-Process, Get-Hotfix und Get-Service besitzen einen Parameter –ComputerName, mit dem man auch ein entferntes System abfragen kann. Diese Commandlets sprechen das Fernsystem entweder direkt über Microsoft RPC oder über DCOM an. Aber längst nicht alle Commandlets haben diese Fernfunktion. Für alle Commandlets, die keine direkte Fernaufruffunktion bieten, muss man das WS-Management-Protokoll einsetzen. Dazu muss auf dem Zielsystem der Dienst Windows Remote Management (WinRM) laufen und konfiguriert sein. Am einfachsten macht man dies mit Enable-PSRemoting in der PowerShell.

Danach kann man mit Invoke-Command jeden beliebigen PowerShell-Befehl auf einem Fernsystem ausführen, zum Beispiel das Dateisystem eines entfernten Systems abfragen:

Invoke-Command -ComputerName Server123 -scriptblock { dir "c:program files" -Directory | Sort lastwritetime } 

Spannend ist, dass man bei Computername auch eine durch Komma getrennte Liste von mehreren Computernamen (oder IP-Adressen) angeben kann und so mehrere Systeme parallel abfragen kann. Gut ist, dass die PowerShell an jedes gelieferte Objekt ein Note-Property PSComputername anhängt, damit man die asynchron eingehenden Antwortobjekte auch den Systemen zuordnen kann.

Alternativ kann man mit WS-Management auch eine interaktive Sitzung auf einem entfernten System im Stil des Telnet-Protokolls eröffnen:

Enter-PSSession –Computername Server123

Nach erfolgreicher Ausführung des Befehls wird der Computername vor der PowerShell-Eingabeaufforderung angezeigt.

Skripte

Obwohl das PowerShell-Pipelining sehr komplexe Befehlsfolgen ermöglicht und es Wettkämpfe gibt, mit dem Ziel, möglichst viel in einer PowerShell-Codezeile zu erreichen, ist es für Übersichtlichkeit und Wartbarkeit von Scripting-Lösungen erstrebenswert, die Befehle aufzuteilen.

PowerShell-Skripte sind reine Textdateien und haben die Dateierweiterung .ps1. Die Zahl 1 steht dabei für die Version 1.0 der PowerShell. Microsoft hat in Hinblick auf die Langlebigkeit vieler Skripte vorgesehen, dass verschiedene Versionen der PowerShell auf einem System koexistieren können, die Nummer in den Folgeversionen dann aber noch nicht erhöht.

Abbildung 4 zeigt ein Softwareinventarisierungsskript in der PowerShell ISE, das mithilfe des Commandlets Get-WMIObject die WMI-Klasse Win32_Product auf mehreren Computern abfragt. Die Namen der Computer stammen aus einer Textdatei. Das Ergebnis wird in eine CSV-Datei geschrieben.

Abb. 4: Softwareinventarisierung per PowerShell-Skript

Das einzige Windows-Betriebssystem, auf dem das zumindest im lokalen Dateisystem liegende PowerShell-Skript im Standard ausgeführt werden darf, ist Windows Server 2012 R2. Bei allen anderen Windows-Versionen muss man die Skriptausführung erst mit Set-Executionpolicy erlauben. Dabei kann man eine digitale Skriptsignatur für alle Skripte (AllSigned) oder nicht vom lokalen System stammende Skripte (RemoteSigned) verlangen.

Aber auch dann hat Microsoft nicht vorgesehen, ein PowerShell-Skript per Doppelklick in Windows auszuführen. Bewusst muss man dazu im Kontextmenü „Run with PowerShell“ wählen. Alternativ startet man ein PowerShell-Skript in der PowerShell-Konsole durch Eingabe des Skriptnamens (mit und ohne .ps1 am Ende). Wenn der Skriptpfad ein Leerzeichen enthält, muss man folgende Syntax wählen:

&"c:SkripteSkriptname mit Leerzeichen.ps1" 

Durch Voranstellen eines Punkts und eines Leerzeichens vor dem Skriptpfad (in PowerShell „Dot Sourcing“ genannt) erreicht man, dass alle in dem Skript definierten globalen Variablen und Funktionen auch nach Beendigung des Skripts noch zur Verfügung stehen:

"c:Skripte Skriptname mit Leerzeichen.ps1". 

PowerShell-Skripte kann man seit Windows 7 und Windows Server 2008 auch als Gruppenrichtlinienskripte (z. B. bei Systemstart und Benutzeranmeldung) ausführen. PowerShell unterstützt im Rahmen von Skripten übliche Konstrukte wie if, switch, while, do, for, foreach, break, continue, function, return und try … catch … finally.

Navigationsprovider

Eine weitere interessante Eigenschaft der PowerShell besteht darin, dass man in ganz unterschiedlichen Containern genauso navigieren und agieren kann wie im Dateisystem. Dies bedeutet, dass die Navigations-Commandlets (Set-Location, Get-ChildItem, New-Item, Get-ItemProperty etc.) in diversen Speichern zur Verfügung stehen:

  • Die Unterschlüssel eines Registry-Schlüssels listet man auf mit: Get-Childitem hklm:software (Alias: dir hklm:software).
  • Man kann auch mit CD den aktuellen Pfad in die Registry verlegen: Set-Location hklm:software (Alias: cd hklm:software) und dann einfach mit Get-Childitem (Alias: dir) auflisten.
  • Zugriff auf einen einzelnen Schlüssel der Registrierungsdatenbank erhält man mit: Get-Item hklm:softwarewww.it-visions.de.
  • Durch das Definieren eines neuen PowerShell-Laufwerks kann man eine Abkürzung zum schnellen Zugang zu Schlüsseln definieren: New-PSDrive -Name ITV -PSProvider Registry -Root hklm:softwarewww.it-visions.de.
  • Danach kann man anstelle von: Get-Item hklm:softwarewww.it-visions.de auch schreiben: Get-Item itv:.

Die Registry ist nicht der einzige Datenspeicher, den die PowerShell betrachten kann wie ein Dateisystem. Möglich ist zum Beispiel auch die Navigation

  • in Windows-Umgebungsvariablen (env:)
  • im Windows-Zertifikatsspeicher (cert:)
  • in Funktionen der PowerShell (function:)
  • in Variablen der PowerShell (variable:)
  • in Aliase der PowerShell (alias:)
  • im Active Directory (ad:) – wenn das Active-Directory-PowerShell-Modul aktiv ist
  • im IIS-Webserver (iis:) – wenn das Modul „WebAdministration“ aktiv ist
  • im Microsoft SQL Server (sqlserver:) – wenn das Modul „SQLPS“ aktiv ist

[ header = Seite 3: Module ]

Module

Die PowerShell selbst enthält nur ein paar Hundert Commandlets. Viele weitere Commandlets stecken in Zusatzmodulen, die das jeweilige Windows-Betriebssystem enthält oder die man durch Zusatzpakete von Microsoft, anderen Anbietern oder im Open-Source-Bereich erhält. Module gibt es in kompilierter Form als .NET DLL oder in Form von PowerShell-Skriptdateien im Quellcode. Die Module werden in Modulverzeichnissen global (WindowsSystem32WindowsPowerShellv1.0Modules) oder auf Benutzerebene ($homeDocumentsWindowsPowerShellModules) installiert.

Bis zur PowerShell 3.0 musste man die Module immer explizit mit Get-Module laden, bevor man ein Commandlet daraus verwenden konnte. Dieser Befehl ist jetzt nur noch notwendig, wenn das Modul auch einen Navigationsprovider anbietet.

Seit Windows 7 und Windows Server 2008 R2 liefert Microsoft mit dem Betriebssystem zahlreiche Module mit Commandlets, mit denen man viele Bereiche von Windows verwalten kann. Exemplarisch seien folgende Gebiete erwähnt: Dateisystem, Dokumente, XML, Relationale Datenbanken, ODBC-Datenquellen, Registry, Computerverwaltung, Hardwareverwaltung, Softwareverwaltung, Prozessverwaltung, Systemdienste, Netzwerk, Windows Firewall, Sicherheitseinstellungen, Ereignisprotokolle, Leistungsdaten, Active Directory, Gruppenrichtlinien, Hyper-V und IIS.

.NET und COM nutzen

Die PowerShell basiert auf .NET und neben der Nutzung über Commandlets kann man alle .NET-Klassen auch direkt verwenden, was sehr viele Möglichkeiten eröffnet. Mit dem Commandlet New-Object kann man eine .NET-Klasse auch unter Angabe von Konstruktorparametern (Listing 1) instanziieren. Die Attribute und Methoden des .NET-Objekts können dann über die übliche Punktnotation verwendet werden.

$user = New-Object System.Directoryservices.DirectoryEntry("WinNT://Server123/HolgerS") 
$user.Fullname + ": " + $user.Descriptiona
$user.Fullname = "Dr. Holger Schwichtenberg";
$user.Description = "Softwarearchitekt & Trainer";
$user.SetInfo() 

Für den Fall der statischen Mitglieder gibt es in der PowerShell ein anderes Konstrukt, bei dem man den .NET-Klassennamen in eckige Klammern setzt und dann den Namen des Mitglieds mit zwei Doppelpunkten abtrennt:

[System.Environment]::MachineName

Wenn die Assembly, welche die .NET-Klasse enthält, noch nicht geladen ist, kann der PowerShell-Nutzer dies mit Add-Type erledigen:

Add-type -assembly "System.windows.forms"
[System.Windows.Forms.MessageBox]::Show("Text","Ueberschrift", [System.Windows.Forms.MessageBoxButtons]::OK) 

Wenn die Assembly nicht im Global Assembly Cache (GAC) liegt, muss man den Pfad im Parameter –Path angeben. Auch COM-Klassen kann man nutzen, indem man den Parameter –com bei new-object angibt:

$ie = new-object -com "InternetExplorer.Application"
$ie.Navigate("http://www.powershell-doktor.de")
$ie.visible = $true

Desired State Configuration (DSC)

Desired State Configuration (DSC) ist ein mit PowerShell-Version 4.0 neu eingeführtes, deklaratives Verfahren zur Systemkonfiguration. Bei klassischer skriptbasierter Konfiguration legt der Administrator die einzelnen Schritte zur Zielkonfiguration fest. Er muss in der Regel vor Beginn eines Konfigurationsschritts prüfen, ob die Konfiguration schon vorhanden ist, bevor er sie ausführt. Auch das Rückgängigmachen einer Konfiguration muss er durch einzelne Schritte realisieren. Bei DSC beschreibt der Administrator deklarativ nur das Ziel einer Konfiguration. DSC ist selbst in der Lage, den aktuellen Zustand zu prüfen, einen nicht notwendigen Schritt zu überspringen, eine aus (vielen) Teilen bestehende Konfiguration durchzusetzen und auch diese Schritte wieder rückgängig zu machen. Aus der Sicht von DSC ist es kein Fehler, wenn eine Konfiguration schon vorhanden ist (idempotente Ausführung).

DSC kennt „Ressourcen“. Für eine Ressource (z. B. Benutzer, Gruppen, Dienste, Umgebungsvariablen, Prozesse, Registry) definiert der Administrator den Zielzustand. Zu jeder konfigurierbaren Ressource gibt es in der PowerShell einen DSC-Ressourcentyp. Eine sehr universelle Ressource ist die „Script“-Ressource. Mit dieser kann man beliebige PowerShell-Skripte in einer DSC-Datei verwenden und so auch Aktionen ermöglichen, die nicht durch eine der bestehenden Ressourcen abgedeckt sind. Die Ressourcentypen sind erweiterbar. Zusätzliche Ressourcentypen gibt es z. B. hier und hier. Man kann auch selbst eigene Ressourcentypen entwickeln. Ressourcentypen haben Eigenschaften, die die Arbeit der Ressource steuern. Die Eigenschaften werden gemäß der Syntax Name=“Wert“ zugewiesen. Alle Ressourcentypen haben folgende gemeinsame Eigenschaften:

  • Ensure=“Present“ oder „Absent“: Diese Eigenschaft sorgt dafür, dass eine Konfiguration durchgesetzt (wenn sie nicht vorhanden ist) oder rückgängig gemacht wird (wenn sie vorhanden ist).
  • DependsOn=“[Ressourcentypename]RessourceName“ ist ein Verweis auf einen Ressourcenblock in derselben DSC-Datei. Die dortige Bedingung muss erfüllt sein, bevor dieser Ressourcenblock ausgeführt werden kann.

Listing 2 zeigt ein Beispiel für eine DSC-Datei, die Folgendes erledigt:

  • Kopieren von Set-up-Dateien von einem Netzlaufwerk ins c:Temp-Verzeichnis.
  • Installieren einer Anwendung per MSI-Paket.
  • Löschen der Set-up-Dateien im c:Temp-Verzeichnis.
  • Erstellen eines Ereignisprotokolleintrags.

In Listing 2 ist ganz bewusst der DestinationPath beim Ressourcenblock File SetupKopieren mit umgekehrtem Schrägstrich und bei File SetupLoeschen ohne diesen angegeben. Ohne dies würde sich DSC beschweren: „The key properties combination „C:tempHelloWorld“ is duplicated for keys DestinationPath of resource File in node localhost. Please make sure key properties are unique for each resource in a node.“

"Lade DSC..."
configuration HelloWorldInstallieren
{
  
File SetupKopieren
  {
    Ensure = "Present"
    SourcePath = "\Server123InstallSetup_for_Hello World VBNET NET 4.5"
    DestinationPath = "C:tempHelloWorld"
    Recurse = $true
    Type = "Directory"
  }       

  Package HelloWorldInstallieren
  {
    Ensure = "Present"  
    Path  = "C:tempHelloWorldHello World VB.NET.msi"
    Name = "HelloWorld"
    ProductId = "111B8A9D-0B16-46A6-8F3A-C83E80D199CD"
    DependsOn="[File]SetupKopieren"
  }

  File SetupLoeschen
  {
    Ensure = "Absent"
    DestinationPath = "C:tempHelloWorld"
    Recurse = $true
    Force=$true
    Type = "Directory"
    DependsOn="[Package]HelloWorldInstallieren"
  }       
  
  
  Log Protokolleintrag
  {
    Message = "Hello World installiert!"
    DependsOn="[File]SetupLoeschen"
  } 
}

"DSC ist geladen!"
HelloWorldInstallieren
"DSC ist kompiliert"
Start-DscConfiguration HelloWorldInstallieren -verbose -wait -force 

Um die DSC-Datei anzuwenden, sind vier Schritte notwendig:

1. Die DSC-Datei muss ausgeführt werden wie eine normale PowerShell-Skriptdatei (in der ISE oder an der Kommandozeile). Normalerweise erhält man dabei keine Ausgabe. In dem Fall des obigen ersten Beispiels erhält man eine Ausgabe, weil vor und nach dem Configuration-Block noch Ausgabebefehle stehen.

2. Nun kompiliert man die Konfiguration, indem man den Namen der Konfiguration an der Konsole wie den Namen einer PowerShell-Funktion ausführt. Das Ergebnis ist eine WMI-MOF-Datei. Die PowerShell antwortet mit dem Namen der erzeugten MOF-Datei. Dies ist im obigen Fall, wo es keinen dedizierten DSC-Knoten gibt, der Name „localhost.mof„. Die Datei landet in einem Unterverzeichnis, das so heißt wie die Konfiguration. Man sollte dabei aufpassen, wo man mit dem aktuellen Verzeichnis steht, denn die Datei wird relativ zum aktuellen Standort abgelegt.

3. Im letzten Schritt wird nun die kompilierte MOF-Datei ausgeführt und damit die Konfiguration angewendet. Dies erfolgt mit dem Commandlet Start-DscConfiguration erneut unter Angabe des Konfigurationsnamens Start-DscConfiguration DSCBeispiel-Wait –Verbose.

4. Normalerweise wird die Konfiguration in einem Hintergrundjob ausgeführt, sodass der Benutzer nichts davon sieht, sondern nur den Jobstatus abfragen kann. Mit –Wait wird bestimmt, dass die Konfiguration interaktiv gestartet wird. –Verbose sorgt wie immer für eine detaillierte Ausgabe.

Weitere Möglichkeiten

Dieser Beitrag kann längst nicht alle der vielfältigen Möglichkeiten der PowerShell vorstellen. Neben vielen syntaktischen Details gilt es bei der PowerShell zu lernen:

  • Berechnungen ausführen
  • Objekte vergleichen
  • Objekte zur Laufzeit um Eigenschaften erweitern
  • C#- und Visual-Basic-Code in Skripte einbinden
  • Interaktion mit dem Skriptbenutzer
  • Benutzeroberflächen mit Windows Forms und WPF erstellen
  • WMI-Objekte ändern
  • XML-Dokumente lesen und ändern
  • Transaktionen definieren
  • Hintergrundaufträge und zeitgesteuerte Aufträge (Jobs) starten
  • Windows Workflow Foundation nutzen
  • Auf Ereignisse in .NET- und WMI-Objekten reagieren
  • Daten in Datenbereiche und Datendateien auslagern
  • Eigene Commandlets in PowerShell-Skriptsprache oder einer .NET-Sprache schreiben
  • Den Editor ISE erweitern
  • Mittlerweise kann man PowerShell sogar im Rahmen von Node.js-Webanwendungen verwenden

Fazit

Die PowerShell ist ein Werkzeug, bei dem .NET-Entwickler sehr viel Know-how wiederverwenden können. Durch die mächtigen Commandlets kann man viele Aufgaben sehr viel prägnanter als in anderen .NET-Sprachen erledigen. Anwendungsgebiete der PowerShell sind nicht nur die klassische Systemadministration sowie Anmeldeskripte, sondern auch Build- und Deployment-Skripte lassen sich mit PowerShell einfach erstellen. Das neue DSC-Feature steckt aber noch in den Kinderschuhen, wie man auch an den Downloadzahlen hier sieht, die teilweise noch unter 100 liegen.

 

PowerShell in Visual Studio Der NuGet Package Manager ist ein Teil von Visual Studio seit Version 2012 (bzw. eine kostenfreie Erweiterung für Visual Studio 2010) zum Verwalten von Erweiterungspaketen. Der NuGet Package Manager basiert auf der PowerShell und unterstützt alle PowerShell-Befehle, nicht nur diejenigen für die Paketverwaltung. Die PowerShell Tools for Visual Studio sind eine Erweiterung für Visual Studio ab Version 2012. Mit dieser Erweiterung kann man PowerShell-Skriptdateien in Visual Studio komfortabel bearbeiten (mit Farbhervorhebung, IntelliSense-Eingabeunterstützung und einklappbaren Regionen) und ausführen. Mehrere Skriptdateien können zu einem PowerShell-Projekt zusammengefasst werden (Projektvorlage „PowerShell Script Project“). Die Skriptausgaben landen im Output-Fenster von Visual Studio. Das Debugging wird unterstützt.

Hilfe zur PowerShell Die PowerShell hat einige eingebaute Hilfefunktionen. Get-Command liefert eine Liste aller verfügbaren Commandlets in der PowerShell. Dabei sind auch Muster erlaubt: Get-Command get-* liefert alle Befehle, die mit get anfangen. Get-Command [gs]et-* liefert alle Befehle, die mit get oder set anfangen. Hilfe zu einem Commandlet bekommt man über „Get-Help commandletname“, z. B. Get-Help Get-Process. Dabei kann man durch die Parameter –detailed und –full mehr Hilfe erhalten. Get-Help get listet alle Commandlets auf, die das Verb get verwenden.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -