Sie sind auf Seite 1von 7

Windows Powershell: Einfhrung und Beispiele

Microsofts Powershell (frher Codename Monad) erlaubt es, das gesamte System von einer Zentrale aus zu
steuern. Aktueller Stand (Oktober 2011) ist Version 3.0 Community Technology Preview (CTP) sowie die Powershell
als Standardkomponente in der Windows 8 Developer Preview. Der Download ist kostenlos.
Dass Microsoft berhaupt in eine Kommandozeilen-Shell investiert, muss berraschen. Gut, bei Tftlern, Script-Fans
und Admins ist die Befehlszeile nicht totzukriegen aber Microsoft hat eigentlich genug schlechte Erfahrungen
gesammelt, um dieses Feld einfach anderen zu berlassen. Die berchtigte und wenig genutzte
Eingabeaufforderung hat wenig Ruhm geerntet: Die Variante Command.COM unter Windows 98/ME war grauenhaft,
die Cmd.EXE von Windows 2000/XP gerade mal alltagstauglich. Normale Windows-Anwender sehen heute kaum
noch Anlass, krude Befehle auf einer solchen Kommandozeile einzugeben sie halten sich an bequeme
Mausaktionen.
Ein vllig neues Kapitel: Die Powershell wirft alle Altlasten ber Bord und verwirklicht eine ehrgeizige Synthese.
Monad verbindet die Fhigkeiten einer Unix-Shell mit dem objektorientierten .NET Framework. Wir erlutern, was das
konkret heit, wer das tatschlich braucht und wo die Vorteile gegenber den bekannten Instrumenten liegen (Cmd,
Wmic, Windows Scripting Host). Die Powershell ist eindeutig ein Scripting-Instrument fr Profis, bietet aber auch
Einsatzmglichkeiten fr den normalen Anwender.
1. Was eine Shell (und warum Powershell eine) ist
Unter einer Shell versteht man eine System-Zentrale, die einen mglichst umfassenden Zugang zu smtlichen
Komponenten erffnet. Eine Shell sollte also Informationen zur gesamten Hard- und Software liefern, alle externen
Programme und Scripts starten, ferner Benutzerdateien selbst bearbeiten oder an Anwendungsprogramme
weitergeben. Die grafische Windows-Shell, der Explorer, bietet jedoch keinen umfassenden Zugang an die Registry,
die Prozesse oder die Systemdienste etwa kommen Sie nur ber eigene Programme heran in diesen Fllen
Regedit, Task-Manager und MMC (Management-Konsole). Viele weitere Windows-Komponenten sind zwar irgendwo
integriert. Wo sie jeweils zu finden sind, lsst sich aber nicht intuitiv erschlieen. Eine gute Shell zeichnet sich vor
allem dadurch aus, dass sie alle Programme, Inhalte und Methoden an einem Punkt integriert. Die Powershell startet
praktisch alles, womit man sie fttert: EXE, BAT, MSC, VBS Benutzerdateien wie DOC, JPG, XLS, PDF ldt die
Shell direkt in die passende Anwendung. brigens: Steht der Dateiname in Anfhrungszeichen, muss ein &
vorangestellt werden, um den Befehlszeilenmodus zu erzwingen. Meister aller Klassen: Die Powershell holt via WMI
(Windows Management Instrumentation) Informationen aus allen verfgbaren Windows-Klassen und steuert COMAnwendungen wie den Internet Explorer oder Office-Programme. Ein Beispiel:
$dlg = new-object -ComObject "shell.application"
$tmp = $dlg.BrowseForFolder(0,"",1,17)
Die beiden Zeilen starten den Windows-Dialog Ordner suchen. Der gewhlte Ordner landet dann in der Variablen
$tmp. Das ist nur ein kleines Beispiel fr die Mglichkeiten. Dreh- und Angelpunkt sind die derzeit 153 vordefinierten
Befehle, welche die Powershell nach get-command auflistet, Ein erstes Cmdlet (Commandlet so der Name
dieser Kommandos) deutet an, dass die Shell Objekte integriert, die bislang nicht unter einen Hut zu bringen waren:
get-psdrive
listet nicht nur die Laufwerke auf, sondern auch die Registry (hklm: und hkcu:), Variablen und Funktionen. Da diese
Objekte als Laufwerke gemountet sind, lassen sie sich auch genauso ansprechen:

cd hklm:\software\classes\exefile
dir
cd und dir sind DOS-freundliche Aliases fr die eigentlichen Cmdlets set-location und get-childitem. Das Beispiel
zeigt, dass die Shell in der Registry, in Funktionen und Variablen ebenso wie in Datei-Ordnern spazierengeht. ndern,
Lschen, Eintragen ist natrlich mit den passenden Cmdlets ebenso mglich. Nur noch zwei Beispiele:
get-itemproperty "hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
stop-process -processname notepad*
Der erste Befehl zeigt die Windows-Standardordner des aktuellen Benutzers, der zweite beeendet Notepad oder
Notepad2.
2. Der Prompt und die Datei Profile.PS1
Von der Bedienung gibt es starke hnlichkeiten mit der gewohnten Kommandozeile Cmd.EXE: Das Editieren der
Zeilen geschieht auf dem Prompt auf vergleichbare Weise. Das gilt fr die automatische Pfad- und DateiNamenserweiterung mit der-Taste, ebenso wie fr die History-Funktion, bei der Sie mitoderdie letzten Befehle
zurckholen. Zahlreiche Aliases fr die umstndlichen Cmdlets orientieren sich an alten Cmd-Kommandos (dir, del,
cls, ren, md, type ). Eine eigenes Alias ist mit
new-alias n notepad.exe
schnell angelegt (um mit n den Editor zu starten). Der Wert der Aliases ist aber begrenzt, da sie nur als
Kommandoabkrzung taugen und keinerlei Argumente zulassen. Weit leistungsfhiger sind Functions:
function n {notepad.exe $args}
Jetzt kann auf dem Prompt der Dateiname gleich mitgegeben werden (n). $Args ist eine Standardvariable, die
smtliche oder einzelne ($Args[]) Argumente weitergibt. Da der Powershell-Prompt eine Eingabe wie 3.14 * 6.34
oder 0x2A1 (Hexzahl) direkt als Rechenaufgabe interpretiert und lst, knnen Sie mit etwas Code auch komplexere
Aufgaben umsetzen:
function Tage {((get-date("$args"))-(get-date)).days}
Die Eingabe tage 22.10.2009 gibt dann die Anzahl der Tage bis zum eingegebenen Datum zurck. Die Powershell
geizt mit vorgefertigten Funktionen, aber es ist nur eine Frage der Zeit, bis Anwender selbstgestrickte im Web
anbieten werden. Der in einer Funktion abgelegte Code gilt so lange, bis die Shell geschlossen wird. Aber es ist
natrlich nicht zumutbar, komplexere Funktionen oder Befehle jedes Mal neu per Hand einzugeben. Hier kommt das
Script Profile.ps1 ins Spiel, das die Shell beim Start automatisch einliest. Es kann alle mglichen Variablen,
selbstgestrickte Funktionen und Aliases enthalten. Der Standardpfad der aktuellen Version 3.0 ist
%windir%\System32\WindowsPowerShell\v1.0
Eine hier abgelegte Profile.ps1 liest die Shell beim Start in jedem Fall neu ein. PS1-Scripts werden aber erst
ausgefhrt, wenn die Policy entsprechend eingestellt ist:
Set-ExecutionPolicy unrestricted
3. Der Kern der Powershell: Objekte in der Pipeline

Bis hierher habe ich die Powershell wie eine Unix-hnliche Shell beschrieben. Damit sind wir aber noch nicht beim
Kern der Sache. Der heit nmlich: Objektorientierung im Verbund mit Pipelines. Pipes wie Sort oder Find unter
Cmd filtern einfach Text, Pipes in der Powershell hingegen das gesamte Objekt inklusive aller Eigenschaften und
Methoden. Dazu ein Beispiel:
$a=get-process
Das Kommando schreibt die aktuelle Prozessliste in die Variable $a (alle Variablen, gleich welchen Typs, beginnen mit
$). Einfaches
$a
zeigt dann die Prozessliste mit acht Eigenschaften an. Diese Reprsentation ist aber nur freundliche Formathilfe der
Shell. Die Variable enthlt in Wahrheit wesentlich mehr:
$a | where {$_.name -like "*explorer*"}|format-list *
Hoppla: Jetzt liefert Variable zu dem einen Prozess Explorer gut die doppelte Menge an Daten, die sie vorher ber
smtliche Prozesse zurckgab eine Unzahl weiterer Eigenschaften, welche die Shell ohne explizite Formatangabe
automatisch wegfiltert. Erst format-list * (Kurzform: fl *) liefert das Ganze. Um herauszufinden, welche
Eigenschaften und Methoden fr ein Datenobjekt insgesamt vorliegen, gibt es einen systematischeren Weg:
"Hallo" | get-member
Hallo ist ein String-Objekt, daher erhalten wir eine Liste der .NET-Methoden zur Stringverarbeitung, so etwa
ToUpper und folgerichtig gibt dann
"Hallo".toupper()
HALLO zurck. ber get-member ermittelte Pipes helfen dann, Objekt-Variablen genau auf das inhaltlich
Gewnschte einzugrenzen:
$aktuell=dir c:,d:,e: -recurse -include *.doc,*.xls | where {$_.lastaccesstime -gt "1.10.2008"} | select
name,lastaccesstime
Schon der Dir-Befehl grenzt ein, der Where-Filter lsst auch davon nur die jngst genutzten Dateien brig, und
Select reduziert dann die Objekteigenschaften auf zwei. Das Objekt enthlt jetzt nur noch diese zwei Eigenschaften
der zuletzt genutzten DOC- und XLS-Dateien auf den Laufwerken C:, D: und E:. Beachten Sie, dass nun fr diese
Objektvariable scheinbar selbstverstndliche Datei-Eigenschaften tatschlich fehlen: Eine Sortierung nach der
Extension (sort extension) wre etwa nicht mehr mglich. Aus dem gleichen Grund kann
dir -recurse|select name,length|where {$_.CreationTime -gt "1.10.2008"}
nie ein Ergebnis befrdern, weil die Eigenschaft des Erstellungsdatums (CreationTime) durch den Select-Befehl
ausgefiltert wurde und nicht mehr existiert. Die zwei Pipes sind also syntaktisch umzustellen. Ein letztes praktisches
Beispiel fr kombinierte Pipes:
$doppel=dir c: -recurse *.mp3 | group length|where {$_.count -gt 1}|select -expand group| ft name,length

Diese eine Zeile beantwortet eine komplexe Frage: Wenn es auf Laufwerk C: MP3-Dateien gleicher Bytezahl gibt,
werden diese untereinander angezeigt. Lautet dann auch noch der Name hnlich, handelt es sich offenbar um
berflssige Doppel.
4. Powershell mit umfassenden Script-Fhigkeiten
Die Beispielzeilen in diesem Beitrag sind der Lesbarkeit halber bewusst knapp gehalten. Komplexe Objekt-Pipes
per Hand einzugeben ist weder vergnglich noch notwendig. Der Platz fr globale Funktionen und Variablen ist die
schon angesprochene Profile.PS1 , weiterer Code kann in beliebigen Textdateien mit Endung PS1 abgelegt und in der
Shell durch Eingabe der Code-Datei abgerufen werden. Die umfangreichen Script-Mglichkeiten, um Objektvariablen
weiter zu bearbeiten, knnen wir hier kaum andeuten. Sie entsprechen in vielen Belangen der Syntax von Unix-Shells,
sind aber auch fr jeden WSH-oder Batch-Erfahrenen durchaus zugnglich an If, For, Foreach, While oder
Switch in der einen oder anderen Form kommt keine Sprache vorbei. Die Fehlermeldungen des Interpreters sind
informativ und zielfhrend, das Hilfesystem verdient hingegen bislang seinen Namen nicht. Den simpelsten Zugang
zum Scripten bieten sicherlich Filter, die den Datenstrom der Pipeline entweder weiterflieen lassen oder nicht. Die
einzelne Instanz wird in jedem Filter (auch in Where oder Foreach) mit der globalen Variable $_ bezeichnet. Darf
das Ding oder eine Eigenschaft desselben also durch, schreibt man einfach $_ oder $_.. Ganz einfaches Beispiel:
Filter Dirs {if ($_.parent) {$_}}
dir -recurse|Dirs|select name
5. Super-Shell? Nicht jetzt und nicht fr jeden
Objektorientierung und Scriptsprache der Shell sind konzeptionell beeindruckend. Selbst die sperrigen Cmdlets
verlieren zusehends ihren Schrecken, wenn man sich eingearbeitet hat und ihre konsistente Grammatik kennt: getcontent (gc) funktioniert einfach immer, wenn ein Content vorliegt, also bei der Datei Boot.INI ebenso wie bei der
Funktion Prompt. Fr Fehlerbehandlung (Trap), Testlufe (-Whatif bei Methoden), automatische Erkennung von
Variablentypen und saubere Gltigkeitsbereiche der Variablen (Scopes) ist ebenso gesorgt wie fr die
Erweiterbarkeit: Das .NET-Framework mit dem C#-Compiler enthlt alles, um neue DLLs und darin enthaltene
Cmdlets zu erstellen. Die Shell kann wesentlich mehr als Cmd und der Scripting Host zusammen und macht nebenbei
eine ganze Reihe von Windows-Applets arbeitslos. Den Geschmack der Admins und Tftler drfte die Shell treffen.
Den normalen Anwender wird sie kaum auf die Kommandozeile locken: Das Editieren der Zeilen ist so spartanisch
wie bei Cmd, vor allem aber mangelt es noch an interessanten, fertigen Funktionen, die sofort Produktivitt
versprechen. Die derzeit verfgbare Beta kommt buchstblich nackt zum Anwender: Er muss sie erst selbst Funktion
um Funktion zu einem tauglichen Werkzeug machen. Es ist wohl nur eine Frage der Zeit aber im Moment sind im
Web berzeugende Scripts und Funktionen noch Mangelware. Nicht ganz nebenschlich ist ferner der
Ressourcenverbrauch: Schon die nackte Shell ist mit ihren .NET-Bibliotheken kein Leichtgewicht. Einige grere
Objektvariablen mit Dateiobjekten eingelesen, und Powershell wird im Handumdrehen zum RAM- und CPUKonsumenten Nummer 1.
6. Einige Kommandozeilen-Beispiele
Zur Ausgabe auf dem Prompt bietet die Shell verschiedene vordefinierte Farbcodes.

write-host "Starte Vorgang..."


write-warning "Achtung..."
write-error "Fehler..."
So definieren Sie das Erscheinungsbild (hier blaue Schrift auf weiem Hintergrund) und Titel.
$host.UI.RawUI.ForegroundColor = "DarkBlue"
$host.UI.RawUI.BackgroundColor = "White"
$host.ui.rawui.WindowTitle = "Powershell on ${env:userdomain}${env:username}" + " " + (get-date -uformat "%A, %d.
%m.%Y [%T]")
Folgende Pipe gibt die 10 grten Dateien auf Laufwerk D: zurck.
Get-ChildItem -recurse d: | Select name,length | Sort-Object length -descending | Select-Object -first 10
Die nchste Pipe gibt die 10 grten Dateien auf Laufwerk D: zurck und zeigt an, wie lange die Aktion dauert.
measure-command {Get-ChildItem -recurse d: | Select name,length | Sort-Object length -descending | Select-Object
-first 10 }
So lesen Sie die Shellfolder aus der Registry in eine Variable und nutzen diese zur Navigation:
$UserFolder=get-itemproperty "HKCU:SoftwareMicrosoftWindowsCurrentVersionExplorerShell Folders"
push-location $UserFolder.Desktop
Folgender Befehl erzwingt eine Pause von 5 Sekunden:
start-sleep -s 5
Die folgenden Befehle erstellen ein COM-Objekt und nutzen es dann zur Fensterdarstellung:
$dlg = new-object -ComObject "shell.application"
$dlg.CascadeWindows()
$dlg.MinimizeAll()
$dlg.UndoMinimizeAll()
Das nachfolgende Kommando (eine Zeile!) listet die Windows-Dienste mit ihren beschreibenden Namen auf und
kennzeichnet alle laufenden Dienste rot, die beendeten grn:
get-service | foreach {if ($_.status -eq "stopped") {write-host -f green $_.displayname} else {write-host -f red
$_.displayname}}
Das nchste Kommando beendet den Explorer:
stop-process -processname explorer
Die kleine Funktion n verkrzt den Aufruf von Notepad auf die Eingabe n. Die Standardvariable $Args sorgt dafr,
dass eine bergebene Datei in Notepad geffnet wird:
Function n{Notepad.EXE $args}
n c:\boot.ini

Folgende Funktion liefert eine Tabelle aller verfgbaren Laufwerke mit Typ, Gre und freiem Speicher:
Function Disks {
$Disks = Get-WMIObject Win32_LogicalDisk -computer "."
""
write-host " Kennung Typ GB GB frei" -BackGroundColor DarkRED -ForeGroundColor White
""
ForEach ($d in $Disks) {
$typ=$d.drivetype
Switch ($typ) {
2 {$typ="FDD"}
3 {$typ="HDD"}
4 {$typ="Net"}
5 {$typ="CD "}
}
" {0} {1} {2,7:n} {3,10:n}" -f $D.DeviceID, $typ, $($d.Size/1024/1024/1024), $($d.freespace/1024/1024/1024)
}
""
}

Kleine Funktion in Powershell...


Das nchste Beispiel (eine Zeile!) liefert eine Statistik zu den Dateierweiterungen im aktuellen Ordner (inkl.
Unterordner):
dir -recurse|group-object -property extension|sort count|Format-table
@{expression="name";width=8},@{expression="group";width=65},@{expression="count";width=5}
Zwei simple Kalkulationsbeispiele, eines mit Einsatz der .NET-Klasse [math]:

12*45
[math]::pi * 4
Folgender Ablauf knnte in einem PS1-Script erfolgen: Aufruf eines Tasks Warten auf dessen Abschluss
Fortsetzen des Scripts:
notepad.exe
$a=get-process notepad
$a.WaitForExit()
write-host "Weiter..."
Die nachfolgenden Zeilen greifen eine Webseite ab und legen den Inhalt in einer Textdatei ab:
$wc = new-object System.Net.WebClient
$wc.DownloadString('http://www.beispiel.de/index.html') | out-file s.txt
get-content s.txt
Eine seit Version 2.0 eingefhrte attraktive Out-Variante ist Gridview. Die Objektdaten werden grafisch dargestellt
und lassen sich filtern und sortieren:
get-service | select status, name, displayname, servicesdependedon | out-gridview

Powershell mit grafischem Ausgabefenster (Gridview)