Behandelte Themen
0
1
Beispiel 1: Verhindern von Versionskonflikten
2
2.1
2.2
Beispiel 1: Versionskontrolle
3
3.1
3.2
3.3
3.3.1
3.3.1.1
3.3.1.2
Beispiel 1: Anpassen des Powershellfensters mit der Microsoft.PowerShell_profile.ps1
Beispiel 2: Anpassen der Powershell selbst mit der profile.ps1
3.3.2
3.3.2.1
Beispiel 1: get-childitem und sein Alias gci
Beispiel 2: Auflisten der cmdlets, die Aliases ver- und bearbeiten
Beispiel 3: Welches cmdlet steckt hinter dem Alias "dir"
Beispiel 4: welche Aliase besitzt Get-ChildItem
3.3.2.2
Beispiel 1: Auflisten der Kompatibilitäts-Aliase
Beispiel 2: Entfernen der Kompatibilitäts Aliase
Beispiel 3: Auflisten der Canonical-Aliase
Beispiel 4: Beweis, das "readonly" wirklich "readonly" bedeutet
Beispiel 5: Definition eigener Aliase
Beispiel 6: Abfrage selbst definierter Aliase
3.3.2.3
3.3.3
Beispiel 1: Registrierung der QAD-cmdlets ,
Beispiel 2: Anzeige der neu hinzugekommenen QAD-cmdlets
Beispiel 3: Import aller pscx-Module
Beispiel 4: Import von bestimmten pscx-Modulen
Beispiel 5: Anzeige der einzelnen pscx-Module
Beispiel 6: Kontrolle der pscx-cmdlets und weitere Informationen
Beispiel 7: Import eines Modules aus dem Powershellpack
3.3.4
3.3.5
3.4
4
0 Einleitung
Mit der Powershell kann man nicht mehr ganz so einfach mit dem Programmieren loslegen oder fertige Skripte starten, wie man das vielleicht von Früher mit VBScript oder der Batchprogrammierung gewohnt war.
Dies
- ist a) der Sicherheit geschuldet, die default das Ausführen von PS-Skripten auf Rechnern erstmal radikal unterbindet.
- kann b) durch Powershell-Profildateien verursacht sein, denen Alias- oder Funktionsdefinitionen fehlen oder die auf dem Rechner auf nicht existente Pfade veweisen und einiges mehr.
- ist c) eventuell auf notwendige, aber nicht vorhandene Spracherweiterungen zurückzuführen. Im weiteren Verlauf dieses Kapitels werden wir Module und SnapIns kennenlernen, die das Skriptingleben einerseits sehr vereinfachen, aber andererseits bei Nichtvorhandensein erstmal Fehler werfen.
Wie man sieht, ist das richtige Customizing einer Umgebung sehr wichtig, um Powershellskripte entwickeln und ausführen zu können. Dies ist damit das Thema der folgenden Kapitel.
1 Historie: Powershell V1.0 / Powershell V2.0
Die ersten veröffentlichten Versionen dieser Skriptsprache liefen unter dem Codenamen "Monad". Im Jahr 2006 wurde dann Powershell V1.0 von Microsoft released und mit Windows7 und Server2008 kam die aktuell gültige Powershell V2.0 heraus.
Laut einem der Powershellguys -Ed Wilson- ist eine 100%-ige Abwärtskompatibilität gegeben. Jedes unter Powershell V1.0 geschriebene und lauffähige Skript läuft auch unter Powershell V2.0. Von daher gibt es keinen Grund heute nicht mit der Powershell V2.0 zu arbeiten.
Die neuen Features der Powershell V2.0 kann man nachlesen unter
Grundlegende Sprachelemente wie beispielsweise Schleifen, Variablen, .Net-Programmierung, reguläre Ausdrücke um nur ein paar wenige zu nennen, haben sich von V1.0 auf V2.0 nicht verändert. Wenn man in einem Buchladen günstig ein Werk zu Powershell V1.0 bekommt, sollte man wirklich zuschlagen. Gerade die Grundlagen sind in den V1.0 Büchern oft viel ausführlicher dargestellt, da in den V2.0 Büchern den Autoren durch die neu hinzugekommenen Features wie Remoting einfach der Platz ausgeht.
Beispiel 1: Verhindern von Versionskonflikten
Das folgende #Requires Statement verhindert, dass ein PS-Skript in einer zu niedrigen Powershellumgebung abläuft und durch fehlende Elemente Fehlermeldungen produziert.
#Requires -version 2.0
Näheres unter
get-help about_Requires
2 Installation der Powershell V2.0
2.1 Installationsourcen
Powershell v2.0 ist ab Windows XP mit SP3 / Server 2003 aufwärts für jedes MS Betriebssystem zum Nachinstallieren verfügbar. Ab Windows Version 7 /Server 2008R2 ist die Powershell V2.0 standardmässig installiert.
Für die genannten früheren Windows Versionen steht die Powershell v2.0 entweder unter
Zu Beachten sind für die älteren Windowsversionen noch diese beiden Punkte
- Die Powershell 2.0 benötigt das DotNetPaket 2.0 . Ohne dieses Paket lässt sich die Installation zwar durchführen, beim Arbeiten erscheinen allerdings Fehlermeldungen wie “objekt nicht gefunden” etc.
- Um die ISE (integrierte Entwicklungsumgebung) zu nutzen, wird zusätzlich das DotNetPaket 3.0 benötigt
2.2 Versionskontrolle
Verwirrenderweise wird auch die v2.0-Version im v1.0 Pfad "%Systemroot%\system32\WindowsPowerShell\v1.0" installiert. Das kann eventuell zu Verwirrung führen.
Beispiel 1: Versionskontrolle
Nach erfolgreicher Installation oder zur Überprüfung der installierten PS-Version kann man über die PS-Variable $PSVersionTable eine Abfrage durchführen, die erst ab der Version 2 enthalten ist. In der Powershellversion 1.0 würde eine Fehlermeldung ausgegeben
(Start -> Ausführen -> Powershell)
$psversiontable
#Ausgabe
Name Value
---- -----
CLRVersion 2.0.50727.5444
BuildVersion 6.1.7601.17514
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
3 Aufbau der Entwickungsumgebung
Unter diesem Punkt beschreibe ich, wie meine persönliche Entwicklungsumgebung aussieht.
Ich habe das Glück, dass ich einen HyperV-Server mit 60 GB RAM zur Verfügung habe, auf dem sich trefflich Testumgebungen aufbauen lassen. Aber auch mit weniger Ausstattung, selbst auf einem einigermassen modernen Notebook ab 4 GB Ram, lässt sich eine komplette virtualisierte Testumgebung mit vmware oder Microsoft VirtualPC gut erstellen.
3.1 Windows Maschinen
Meine Entwicklungsumgebung besteht aus drei virtuellen Maschinen
- 1 Domaincontroller Server2008R2 Enterprise (SP1) - Domänenname: Dom1.intern / Servername: Dom1DC01
- 1 Server 2008R2 Enterprise (SP1) - Servername: Dom1Srv01
- 1 Client Windows7 Ultimate (SP1) - Clientname: Dom1Cli01
Auf dem Win7-Client installiere ich Powershellerweiterungen und Programme. Dort entwickle ich hauptsächlich meine Skripte.
Auf den Server kommen diverse Rollen und Backoffice-Produkte wie Zertifikatsdienste, SQL-Server.
Den Domaincontroller brauche ich natürlich für die Powershellpolicies und nutze ihn außerdem fürs Powershellremoting.
3.2 Anpassen der DomainPolicy
Default können auf Windowsrechnern ohne Anpassungen erstmal keine Powershellskripte ausgeführt werden. Dies liegt an der sogenannten ExecutionPolicy, die das unterbindet. Die ExecutionPolicy kann entweder lokal für jeden Host einzeln, oder generell per Grouppolicy in der Domäne konfiguriert werden.
Ich würde es, wie im nachfolgenden Bild dargestellt, per Policy einstellen. Da wir uns hier in einer Entwicklungsumgebung bewegen, setze ich den Status auf "unrestricted" oder "allow all scripts".

Weitere Information über die ExecutionPolicy habe ich unter
In produktiven Umgebungen sollten nur signierte Skripte erlaubt sein. Das Signieren von Skripten ist unter
3.3. Anpassen des Windows7 Clients
Den Windows7 EntwicklerClient werden wir am Stärksten an unsere Bedürfnisse anpassen. Natürlich können diese Schritte bei Bedarf auch auf einem Server durchgeführt werden, wenn man dort programmiert.
Unter 3.3.1 passen wir über Profile das Verhalten und das Erscheinungsbild der Powershell an.
Unter 3.3.2 betrachten wir Aliase. Mit Aliasen gibt man Befehlen neue -meist kürzere oder einprägsamere- Namen und erleichtert sich dadurch das Leben
Unter 3.3.3 erweitern wir durch Module und SnapIns den Befehlssatz der Powershell
Unter 3.3.4 installieren wir einige nützliche Tools und Programme.
Sollte die Powershell ExecutionPolicy nicht über eine Policy angepasst sein, wie im Kapitel 3.2 oben beschrieben, so muss die ExecutionPolicy über den lokalen Befehl
set-executionpolicy unrestricted
gesetzt werden. Genauere Informationen über dieses cmdlet finden sich in unter
3.3.1 Profile
In einer Profil-Datei werden beispielsweise
- Aliase für häufig benutzte cmdlets hinzugefügt (etwa gh für get-help)
- Aliase für häufig benutzte Anwendungen hinzugefügt (etwa np für notepad)
- generell gültige Funktionen definiert
- Erscheinungsbild der Console definiert (etwa. Farben, Grösse, Titel, Buffer)
- Fenstergrössen definiert
- zusätzliche SnapIns registriert (wenn die Registrierung bei einem Neustart nicht erhalten bleibt)
- Pfade gesetzt
- PreferenceVariablen modifiziert (siehe Technet:
about_preference_variables )
Möchte man bestimmte Einstellungen auf mehrere Rechner verteilen, so macht man dies ab der Powershell V2.0 besser mit Modulen, siehe Technet:
3.3.1.1 Profilpfade
ProfilDateien werden –sofern vorhanden– bei jedem Start der Powershell.exe oder der Powershell_ISE.exe automatisch ausgeführt. Die Profile sind gewöhnliche Powershellscripte (*.ps1), die mit jedem Texteditor erstellt und editiert werden können.
Mit diesen Profilskripten lässt sich Powershell userspezifisch (ein bestimmter oder alle User) und shellspezifisch (Powershell.exe und /oder Powershell_ISE.exe) beim Start der Powershell anpassen.
Im Folgenden sind die Möglichkeiten tabellarisch dargestellt
Priorität | Pfad (Erklärung unten) | Geltungsbereich |
1 | <Eigene Dateien>\Microsoft.PowerShell_profile.ps1 | -für den angemeldeten User |
1 | <Eigene Dateien>\Microsoft.PowerShellISE_profile.ps1 | -für den angemeldeten User |
2 | <Eigene Dateien>\PowerShell\profile.ps1 | -für den angemeldeten User |
3 | <Installationsverzeichnis>\ Microsoft.PowerShell_profile.ps1 | -für alle User |
3 | <Installationsverzeichnis>\ Microsoft.PowerShellISE_profile.ps1 | -für alle User |
4 | <Installationsverzeichnis>\profile.ps1 | -für alle User |
Abkürzung | Prozessor | OS | Pfad |
<Eigene Dateien> |
| XP/ W2k3 | %UserProfile%\My Documents\WindowsPowerShell |
<Eigene Dateien> |
| Vista/ W2K8 | %UserProfile%\Documents\WindowsPowerShell |
<Installationsverzeichnis> | 32-bit |
| %windir%\system32\WindowsPowerShell\v1.0\ |
<Installationsverzeichnis> | 64-bit |
| %windir%\syswow64\WindowsPowerShell\v1.0\ %windir%\system32\WindowsPowerShell\v1.0\ |
Je spezifischer ein Profil ist, umso höher seine Priorität
Beispiel 1: Auslesen der Profilpfade
Die Variable $profile enthält nicht nur den Profilpfad des aktuellen Benutzers sondern -vielleicht etwas versteckt in Noteproperties- auch die anderen Pfade
$profile | gm -membertype noteproperty
[Environment]::NewLine
"AllUsersAllHosts: {0}" -f $profile.AllUsersAllHosts
"AllUsersCurrentHost: {0}" -f $profile.AllUsersCurrentHost
"CurrentUserAllHosts: {0}" -f $profile.CurrentUserAllHosts
"CurrentUserCurrentHost: {0}" -f $profile.CurrentUserCurrentHost
"CurrentUserCurrentHost: {0}" -f $profile
#Ausgabe, wenn das Skript in der Powershell_ise aufgerufen wird
TypeName: System.String
Name MemberType Definition
---- ---------- ----------
AllUsersAllHosts NoteProperty System.String AllUsersAllHosts=C:\WINDOWS\system32\WindowsPowerShell\v1.0\profile.ps1
AllUsersCurrentHost NoteProperty System.String AllUsersCurrentHost=C:\WINDOWS\system32\WindowsPowerShell\v1.0\Microsoft.PowerShellISE_profile.ps1
CurrentUserAllHosts NoteProperty System.String CurrentUserAllHosts=C:\Dokumente und Einstellungen\j184710\Eigene Dateien\WindowsPowerShell\profile.ps1
CurrentUserCurrentHost NoteProperty System.String CurrentUserCurrentHost=C:\Dokumente und Einstellungen\j184710\Eigene Dateien\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1
AllUsersAllHosts: C:\WINDOWS\system32\WindowsPowerShell\v1.0\profile.ps1
AllUsersCurrentHost: C:\WINDOWS\system32\WindowsPowerShell\v1.0\Microsoft.PowerShellISE_profile.ps1
CurrentUserAllHosts: C:\Dokumente und Einstellungen\j184710\Eigene Dateien\WindowsPowerShell\profile.ps1
CurrentUserCurrentHost: C:\Dokumente und Einstellungen\j184710\Eigene Dateien\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1
Profile C:\Dokumente und Einstellungen\j184710\Eigene Dateien\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1
3.3.1.2 Beispiele für Profile
Die in den beiden folgenden Beispielen gezeigten Profile benütze ich so. Mit der Microsoft.PowerShell_profile.ps1 definiere ich das Aussehen des Powershell.exe Prompts und mit der profile.ps1 definiere ich einige Aliase und Funktionen.
Beispiel 1: Anpassen des Powershellfensters mit der Microsoft.PowerShell_profile.ps1
In der Microsoft.PowerShell_profile.ps1 können die passenden Fenstereinstellungen der Powershell vorgegeben werden. Ich habe dieses ProfileSkript unter C:\Windows\System32\WindowsPowerShell\v1.0 gespeichert, so daß es für alle Benutzerkonten gültig ist. (siehe Tabelle in 3.3.1.1 oben)
#Skript
#Powershell Console Definieren
#Console definieren
$h=get-host
#Console Farben
$win = (Get-Host).UI.RawUI
$win.BackgroundColor = "gray"
$win.ForegroundColor = "DarkBlue"
#Console Fenstergrösse
$win_size=$win.windowsize
$win_size.height=45
$win_size.width=120
$h.ui.rawui.set_windowsize($win_size)
#Console Buffergrösse
$win_buffersize=$win.buffersize
$win_buffersize.height=5499
$win_buffersize.width=120
$h.ui.rawui.set_buffersize($win_buffersize)
#Bereinigen des Bildschirms
clear-host
#Prüfen ob Fehler gemeldet wurden (entspricht dem %errorlevel% aus MSDOS)
$LastExitCode
Anmerkung 1:
In der unteren Hälfte des Artikels
Anmerkung 2:
Auch das Fenster der Powershell_ise.exe lässt sich noch customizen. Da ich am Default-Erscheinungsbild der GUI nichts groß auszusetzen habe, verweise ich nur auf den folgenden Link
Technet Scripting Guys:
Beispiel 2: Anpassen der Powershell selbst mit der profile.ps1
In der profile.ps1 können Aliase und Pfade definiert und zusätzliche SnapIns registriert werden, die für alle Shells wie die ISE und die Commandshell der Powershell gelten sollen. Ich habe auch dieses ProfileSkript unter C:\Windows\System32\WindowsPowerShell\v1.0 gespeichert, so daß es für alle Benutzerkonten gültig ist.
#Skript
#Setzen von Aliasen
set-alias -name gh -value get-help –description "own: get-help"
set-alias –name np –value notepad.exe –description "own: notepad"
#sa soll alle aliasse anzeigen
Function sa{ gh * |?{$_.category -eq "Alias"}|sort name |format-table -auto }
#cd\ soll auch ohne Leerzeichen funktionieren
Function cd\ {cd \}
#PromptPfad setzen
set-location D:\Powershell\MyScripts\
#PathVariable erweitern
$env:path += ";$env:windir\System32\WindowsPowerShell\v1.0\Tools"
# PreferenceVariable setzen
$OFS="+"
#Bereinigen des Bildschirms
Clear-host
#Prüfen ob Fehler gemeldet werden (entspricht dem %errorlevel% aus MSDOS)
$LastExitCode
Anmerkung 1:
Für selbst erstellte Aliase oder Funktionen im Profile ist in grösseren Umgebungen möglicherweise ein Namenskonzept sinnvoll. Zum Beispiel beginnen diese alle mit “o” für own .
Die obige Skriptdatei sähe dann so aus:
set-alias -name ogh -value get-help
set-alias –name onp –value notepad.exe
Function osa{get-help about_ |select name,synopsis | format-table -auto}
Anmerkung 2:
Seit der Einführung der ISE-Shell neben der Powershell-Shell ist es meiner Meinung nach sinnvoll, ein Profilskript für Befehle zu haben, die auf beide Shells wirken (z.B. Aliase, Registrierung von SnapIns) sowie jeweils eine ProfilDatei für die ISE-Shell und die Powershell-Shell z.B. (Aussehen der Shell, Buffergrössen)
3.3.2 Aliase
3.3.2.1 Überblick
Ein Alias ist ein alternativer Name für ein cmdlet oder eine Funktion. Der Aufruf eines Alias ist damit gleichbedeutend wie der Aufruf des dahinterliegenden cmdlets oder einer Funktion
Beispiel 1: get-childitem und sein Alias gci
$a=get-childitem c:\windows\system32
#ist gleichbedeutend mit
$a=gci c:\windows\system32
Beispiel 2: Auflisten der cmdlets, die Aliase ver- und bearbeiten
get-help *alias*
#Ausgabe
Name Category Synopsis
---- -------- --------
Export-Alias Cmdlet Exports information about currently defined aliases to a file.
Get-Alias Cmdlet Gets the aliases for the current session.
Import-Alias Cmdlet Imports an alias list from a file.
New-Alias Cmdlet Creates a new alias.
Set-Alias Cmdlet Creates or changes an alias (alternate name) for a cmdlet or other comma...
Alias Provider Provides access to the Windows PowerShell aliases and the values that th...
about_aliases HelpFile Describes how to use alternate names for cmdlets and commands in Windows
Beispiel 3: Welches cmdlet steckt hinter dem Alias "dir" ?
get-alias dir
#oder ausführlich
get-alias dir | select-object *
#Ausgabe
HelpUri : go.microsoft.com/fwlink/
ResolvedCommandName : Get-ChildItem
ReferencedCommand : Get-ChildItem
ResolvedCommand : Get-ChildItem
Definition : Get-ChildItem
Options : AllScope
Description :
OutputType : {System.IO.FileInfo, System.IO.DirectoryInfo, System.String}
Name : dir
CommandType : Alias
Visibility : Public
ModuleName :
Module :
Parameters : {[Path, System.Management.Automation.ParameterMetadata], [LiteralPath, System.Management.Automation.ParameterMetadata], [Filter, System.Management.Automation.ParameterMetadata], [Include, System.Management.Automation.ParameterMetadata]...}
ParameterSets :
Anmerkung:
Man erkennt, dass "dir" ein Alias des cmdlets Get-ChildItem ist und ein Kompatibilitäts-Alias, da die Eigenschaft "Options" nicht auf "readonly" steht. ("Kompatibilitäts-Aliase" werden im nächsten Kapitel erklärt)
Beispiel 4: welche Aliase besitzt Get-ChildItem
Möchte man umgekehrt zu Beispiel 3 sehen, welche Aliase das cmdlet Get-ChildItem besitzt, so erfährt man das über
get-childitem alias: | where{$_.definition -eq "Get-ChildItem"}
#oder kürzer per Parameter
get-alias -definition Get-ChildItem #siehe Beispiele in der Onlinehilfe zu get-alias
#Ausgabe
CommandType Name Definition
----------- ---- ----------
Alias dir Get-ChildItem
Alias gci Get-ChildItem
Alias ls Get-ChildItem
3.3.2.2 Die drei Aliastypen
A) Kompatibilitäts-Aliase
diese Aliase dienen dazu altbekannte Commandlinebefehle vergangener DOS-Tage auch in der Powershell zu Verfügung zu stellen.
Beispiel 1: Auflisten der Kompatibilitäts-Aliase
Diese Aliase sind in der Powershell automatisch dabei. Ein Merkmal dieser Aliase ist, dass sie (temporär) entfernt werden können (-notmatch "Readonly")
get-childitem alias: | where{$_.options -notmatch "Readonly"}
#gekürzte Ausgabe
CommandType Name Definition
----------- ---- ----------
Alias cat Get-Content
Alias cd Set-Location
Alias chdir Set-Location
Alias clear Clear-Host
Alias cls Clear-Host
Alias copy Copy-Item
…
Alias set Set-Variable
Alias spjb Stop-Job
Alias type Get-Content
Alias wjb Wait-Job
Die Eigenschaft "options" kann man über "get-alias <alias> | select options" herausfinden
Beispiel 2: Entfernen aller Kompatibilitäts Aliase
get-childitem alias: | where{$_.options -notmatch "Readonly"} | remove-item
Anmerkung: Es muss ja nicht alles immer einen tieferen Sinn haben :-)
B) Canonical-Aliase
Im Gegensatz zu den Kompatibilitäts-Aliasen dienen die Canonical-Aliase dazu, Abkürzungen für häufiger benutzte PS-Cmdlets und Funktionen bereitzustellen. Diese Aliase sind ebenfall native in Powershell dabei, haben allerdings die Eigenschaft "Options" auf Readonly und können damit nicht entfernt werden. Allerdings kann ein User einem Alias eine neue Bedeutung zuweisen, was mir aber auch nicht besonders sinnvoll erscheint.
Beispiel 3: Auflisten der Canonical-Aliase
get-childitem alias: | where{$_.options -match "Readonly"}
#gekürzte Ausgabe
CommandType Name Definition
----------- ---- ----------
Alias % ForEach-Object
Alias ? Where-Object
Alias ac Add-Content
Alias asnp Add-PSSnapIn
Alias clc Clear-Content
…
Alias tee Tee-Object
Alias where Where-Object
Alias write Write-Output
Beispiel 4: Beweis, das "readonly" wirklich "readonly" bedeutet
get-childitem alias: | where{$_.options -match "Readonly"} | remove-item
#liefert Fehlermeldungen
Remove-Item : Alias was not removed because alias where is constant or read-only
...
Canonical Aliase können auch aus Sonderzeichen bestehen, wie z.B "%" und "?" für das Foreach- und WhereObject
C) Userdefinierte Aliase
Unter dem Kontext des Customizings der eigenen Umgebung, ist dieser Typ Alias der Wichtigste:
Anwender können sich in ihren Profilen oder in der Powershellsession nach Belieben eigene Aliase definieren und verwenden. Sollen Aliase dauerhaft bestehen bleiben, so muss die Definition in einer Profildatei
Beispiel 5: Definition eigener Aliase
set-alias -name gh -value get-help –description "own: get-help"
set-alias –name np –value notepad.exe –description "own: notepad"
Durch die angefügte Beschreibung ist es auch leicht, sich diese Gruppe von Aliasen anzeigen zu lassen.
Beispiel 6: Abfrage selbst definierter Aliase
get-alias | where {$_.description -like "own*"}
# oder get-alias | where {$_.description -notlike ""}
#Ausgabe
CommandType Name Definition
----------- ---- ----------
Alias gh get-help
Alias np notepad.exe
3.3.2.3 Verwendung von Aliase
Beim Entwickeln von Skripten ersparen Aliases häufiger cmdlets wie "gh" für "get-help" oder "gm" für "für get-member" eine Menge Tipparbeit
Man sollte beim Einsatz von Aliases innerhalb von Skripten bedenken, daß diese die Lesbarkeit des Skriptes eher verschlechtern.
Den Einsatz von Kompatibilitätaliases und userdefinierten Aliases in Skripten vermeide ich wegen möglicher Kompatibilitätsproblemen auf anderen Rechnern oder späteren Powershellversionen gänzlich.
Das ist aber die persönliche Entscheidung jedes Skripters für sich.
3.3.3 Module und SnapIns
An diesem Kapitel geht es um die Erweiterung der Powershell mit neuen Funktionen. Dies kann seit der Powershell V1.0 über SnapIns und seit Powershell V2.0 auch über Module geschehen.
Ganz kurz ein paar Unterschiede der beiden Techniken:
SnapIns
- sind in einer Microsoft .Net Sprache geschrieben. Dadurch ist mit der Powershell alles möglich, was mit diesen Programmiersprachen möglich ist
- können nur cmdlets und Provider enthalten
- müssen installiert oder als DLLs registriert werden
- bilden die Powershell (siehe die Technet OnlineHilfe about_PSSnapins unter "integrierte Snapins")
Module
- sind in Powershell geschrieben (*.psm1).
- können alle Powershellbestandteile wie cmdlets, Funktionen, Aliase, Variablen und Provider enthalten
- werden im Skript einfach eingebunden (Import-Module)
- sind einfacher zu erstellen und haben etliche Möglichkeiten mehr als SnapIns (siehe die Technet OnlineHilfe about_Modules)
Für den Endanwender macht es aber keinen Unterschied -abgesehen von der Installation-, ob seine zusätzlichen cmdlets von einem Module oder einem SnapIn bereitgestellt werden.
Im Folgenden beschreibe ich die Installation einiger recht verbreiteter und nützlicher SnapIns und Module.
A) SnapIn: Quest ActiveRoles Management Shell for Active Directory
Download:
Dieses SnapIn ist eine Ergänzung zum Questprodukt "Active Roles". Es enthält eine ganze Reihe nützlicher cmdlets für Active Directory und das X.509 Zertifikatsmanagement, die unabhängig vom Einsatz der Questsoftware benutzt werden können.
Auf der genannten Downloadseite wird mehrfach das Wörtchen "Freeware" erwähnt, daher gehe ich als Laie mal davon aus, dass die cmdlets tatsächlich ohne Einschränkungen benutzt werden können.
Da es sich um ein SnapIn handelt, ist eine Installation des *msi Files notwendig. Diese läuft recht unspektakuär ab: Doppelklick, Lizenzbedingungen bestätigen und die zusätzlichen cmdlets sind auf dem Rechner.
Im Startmenü unter "Alle Programme" -> "Quest Software" -> "ActiveRoles Management Shell for Active Directory x64" kann nun eine Powershellsession mit integrierten QAD-cmdlets gestartet werden.
Möchte man die QAD-cmdlets in jeder Powershellsession zur Verfügung haben, so muss das SnapIn zu Beginn jeder PS-Session folgendermaßen registriert werden:
Beispiel 1: Registrierung der QAD-cmdlets
Add-PSSnapin quest.activeroles.admanagement
Anmerkung:
Damit man die Registrierung nicht bei jedem PowershellStart manuell durchführen muss, kann man diesen Befehl im Startprofile profile.ps1 ablegen (siehe das
Beispiel 2: Anzeige der neu hinzugekommenen QAD-cmdlets
get-command *qad*
Anmerkung:
Die Quest-cmdlets beinhalten alle den String "qad"
B) Module: Community-Extensions (PSCX) Version 2.0
Diese Extensions bringen zusätzliche cmdlets mit, die viele Aufgaben vereinfachen
Download:
Die Installation der PSCX-Module ist auf dieser Seite ebenfalls beschrieben, daher hier nur eine kurze Zusammenfassung:
1.) Download der zip-Datei
2.) lokales Unblocken der zip-Datei (rechte Maustaste -> Eigenschaften -> Sciherheit: Zulassen
(ohne dieses Unblocken erhält man bem späteren Importieren der Module laufend Sicherheitsabfragen)
3. ) Kopieren des Ordners ./pscx entweder ins Userprofile unter "My Documents\WindowsPowerShell\Modules" oder nach $PSHome\Modules, je nachdem ob die Extensions für einen oder alle User verfügbar sein sollen. $PSHome bedeutet im Normalfall "C:\windows\system32\WindowsPowershell\v1.0\ . Der Ordner "pscx" wird also unter den vorhanden Ordner "Modules" kopiert.
4.) Import einer oder mehrerer Module entweder jedesmal im Script oder allgemein in profile.ps1
Beispiel 3: Import aller pscx Module
Import-module pscx
Beispiel 4: Import von bestimmten pscx Modulen
Import-Module Pscx -arg ~\Pscx.UserPreferences.ps1
In der Datei $PSHome\Modules\Pscx\Pscx.UserPreferences.ps1 ist in einer Hashtabelle festgelegt, welche Untermodule von pscx geladen werden sollen. Selbst wenn man alle Module lädt, spürt man kein Zeitverzögerung. Die einzelnen Untermodule sieht man im nächsten Beispiel
Beispiel 5: Anzeige der einzelnen pscx-Untermodule
C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Pscx\Modules> get-childitem | select name
#Ausgabe
Name
----
CD
DirectoryServices
FileSystem
GetChildItem
GetHelp
Net
Prompt
TabExpansion
TranscribeSession
Utility
Vhd
Wmi
Beispiel 6: Kontrolle der pscx-cmdlets und weitere Informationen
get-help about_pscx
get-command -module pscx -verb *
Unglücklich finde ich, dass einige, genauer gesagt drei, Community-cmdlets aus dem Namespace PSCX den gleichen Namen tragen, wie die orginal Powershell-cmdlets aus dem Namespace Microsoft.PowerShell.Management
Teilweise werden die orginal cmdlets mit nützlichen Funktionen ergänzt, wie das Starten von Prozessen auf einem Remoterechner mit PSCX\Start-Process. Leider erhalten aber auch Parameter neue Bedeutungen wie beispielsweise der -Wait Parameter von Start-Process. In der nativen Powershell -Microsoft.PowerShell.Management\Start-Process- wartet das Skript bei
"Start-Process notepad -wait"
auf eine Tastendruck, bevor es mit der Verarbeitung weiterfährt.
Bei dem Start-Process aus PSCX wird hinter -wait ein Wert erwartet, der die Anzahl der Sekunden angibt, wielange das Skript warten soll.
get-help about_pscx liefert diese drei überschriebenen cmdlets
* Get-Random
* Start-Process
* Select-Xml
Benutzt man nicht auf allen Rechnern die CommunityExtensions, so sind seltsame Verhalten eines Skriptes auf unterschiedlichen Rechner im wahrsten Sinne "vorprogrammiert". Informationen, wie man dieses Kompatibiltätsproblem umgehen kann, gibt es gleich zu Beginn der Online Hilfe "get-help about_pscx" im Abschnitt "Powershell Compatibility"
C) Module: Powershellpack
Download und erste Schritte:
Das Powershellpack bringt nach der Installation des PowerShellPack.msi 10 neue Module mit:
| ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Diese Modul legt die Installationsroutine ins Modulverzeichnis des Userprofiles " .\Documents\WindowsPowerShell\Modules". Möchte man die Module für alle Anwender auf dem Rechner verfügbar haben, muss man diese ins Powershellinstallationsverzeichnis unter C:\Windows\System32\WindowsPowerShell\v1.0\Modules kopieren.
Danach können die Module wie gewohnt importiert und benutzt werden
Beispiel 7: Import eines Modules aus dem Powershellpack
import-module Taskscheduler
get-scheduledtask
#Ausgabe
Name Status LastRunTime NextRunTime
---- ------ ----------- -----------
SidebarExecute Ready 26.04.2011 08:53:46 30.12.1899 00:00:00
{EF2D7E73-E8C1-4F84-BA95-6... Ready 24.04.2011 22:26:52 30.12.1899 00:00:00
Ich muss zugeben, dass ich selbst noch nicht viel mit diesen Modulen gearbeitet habe.
D) neben den bereits genannten SnapIns und Modulen gibt es noch viele andere Erweiterungen
Besonders die freie Entwicklerseite
* www.codeplex.com/PSHyperv A project to provide a PowerShell management library for Hyper-V.
* www.codeplex.com/PSSharePoint A full PowerShell provider for exposing WSS/SPS 2003 (support for 2007 coming) as a filesystem
* www.codeplex.com/PSEventing
* poshbing.codeplex.com A PowerShell script library for accessing Bing.com's API services
* einge mehr (auf www.codeplex.com nach "Powershell Provider" suchen)
3.3.4 Include File (Dot Sourcing)
Technet:
In ein Powershellskript A kann ein anderes Powershellskript B eingebunden werden, so dass danach alle Variablen oder Funktionen aus Skript B verfügbar sind.
Beispiel 1: Einbinden eines anderen Skriptes (Include File)
. c:\powershell\Funktionen\zufall.ps1
# "c:\powershell\Funktionen\zufall.ps1"
get-alphanumericRandom -digits 8 -flag 1100
#Ausgabe
4507 928
Das Skript zufall.ps1 enthält eine Funktion zur Erzeugung zufälliger alphanumerischer Werte, die ich häufiger benutze. (Kapitel
Die Einbindung erfolgt durch einen Punkt ("."), gefolgt von einem Leerzeichen und dem Pfad. Genauso funktioniert es ohne den Punkt ("."), wenn man den Pfad in Anführungszeichen setzt.
Natürlich können auch mehrere Funktionen in einer solchen Datei abgelegt werden, die man dann als zentrale Funktionsbibilothek betrachten kann.
3.3.5 nützliche Tools
- Installation VisualStudio + Productdocumentation
Um Zugriff auf den Objectbrowser zu bekommen, installiert man am besten eine Version des VisualStudioPaketes z..B. Visual Basic 2008Edition with SP1.
Mit dem ObjektBrowser kann man direkt auf das Dotnet-Framework durchgreifen und dort Klassen, Methoden und Eigenschaften erforschen
Stehen die kostenpflichtigen Vollversionen von Visualstudio 2008 nicht zur Verfügung, so genügt die konstenlose Expressversion vollkommen, Microsoft Download Center: Microsoft Visual Studio 2008 Express Editions with SP1
- WMIExplorer
Um die WMI-Welt zu erforschen, bietet sich der selbst in Poweshell geschriebene WMIExplorer an. Ausserdem lassen sich automatisiert WMI-Skripte erstellen
Download der Version für Powershell V2.0 (bei Attachment(s): WmiExplorer.ps1) http://thepowershellguy.com/blogs/posh/archive/2008/03/05/powershell-wmi-explorer-update-for-powershell-v2-ctp.aspx
Die WmiExplorer-v2.ps1 speichere ich unter C:\Windows\System32\WindowsPowerShell\v1.0\Tools ab. Den Pfad füge ich der $Path Variable in der Profildate profile.ps1 hinzu. Siehe unter "Profile" im nächsten Kapitel. Der Aufruf kann dann jederzeit mit
WMIe + Tabulator erfolgen - PowerGUI bzw. PowerGui Scripteditor
Die beiden Tools stammen ebenfalls von Quest. Die PowerGui ist eine grafische Oberfläche, um administrative Tätigkeiten in einer Windowsdomäne auszuführen. http://www.powergui.org/downloads.jspa
Der PowerGUI Script Editor ist der Oberfläche von Visual Studio nachgebildet. Man kann dort Haltepunkte setzen, Einzelschritte ausführen etc.
3.4 .Net Framework Versionen in Powershell
Ohne besondere Modifikationen an der Powershellkonfiguration oder am Betriebssystem kann Powershell die angebotenen Klassen, Methoden und Eigenschaften des .Net Frameworks 2 ausnutzen. Das ist auf jeden Fall schon mal eine ganze Menge.
Trotzdem kann es passieren, dass man interessante Funktionen beispielsweise in Codebeispielen zu C# oder VB in der MSDN findet, die man gerne in ein Powershellskript übersetzen möchte.
Beispielsweise enthält die Beschreibung der Klasse GZipStream ein schönes Beispiel, um Verzeichnisse zu Komprimieren. MSDN:
Versucht man dieses Beispiel in Powershell nachzuprogrammieren, wird man feststellen, dass die Methode "CopyTo" in der Powershell default nicht angeboten wird. Das Thema Packen behandle ich im Kapitel
Beispiel 1: Methoden der Klasse GZipStream im Framework 2 und im Framework 4
$ms = New-Object System.IO.MemoryStream
$GzipStream = new-Object System.IO.Compression.GzipStream $ms , ([IO.Compression.CompressionMode]::Compress), $true
$GzipStream | get-member
#Ausgabe unter dem Framework 2 (gekürzt)
TypeName: System.IO.Compression.GZipStream
NameMemberType Definition
-------------- ----------
BeginRead Method System.IAsyncResult BeginRead(byte[] ...
BeginWrite Method System.IAsyncResult BeginWrite(byte[] array, ...
Close Method System.Void Close()
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef ...
#Ausgabe unter dem Framework 4 (gekürzt)
TypeName: System.IO.Compression.GZipStream
NameMemberType Definition
-------------- ----------
BeginRead Method System.IAsyncResult BeginRead(byte[] , ...
BeginWrite Method System.IAsyncResult BeginWrite(byte[] array, int offset ..
Close Method System.Void Close()
CopyTo Method System.Void CopyTo(System.IO.Stream destination), ...
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type ...
Wie man erkennt, steht unter dem Framework 2 die Methode "CopyTo" nciht zur Verfügung.
Es gibt nun zwei Möglichkeiten der Powershell den Zugriff auf das Framework 4 zu ermöglichen.
a) Mit den folgenden beiden Registryschlüsseln wird systemweit der Zugriff auf das Framework 4 geregelt
reg add hklm\software\microsoft\.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1
reg add hklm\software\wow6432node\microsoft\.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1
das zweite obige Beispiel habe ich erstellt, nachdem die Keys auf meinem Windows7 gesetzt waren.
b) durch Hinzufügen der beiden Config-Dateien " PowerShellISE.Exe.Config " und " PowerShellISE.Exe " mit dem in den Powershellordner mit folgenden Inhalt
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
wird nur Powershell beeinflusst, das Framework 4 zu nutzen.
tfl09.blogspot.com/2010/08/using-newer-versions-of-net-with.html
Diese Methode hat auf meinen Maschinen, auf denen allerdings Visual Studio installiert ist, nicht funktioniert.
Powershellskripte, die Funktionen aus dem Framework 4 sind nicht mehr so einfach auf andere Rechner portierbar! Das sollte man berücksichtigen.
4 Troubleshooting Installation/ Customizing
- Auf einem deutschen XP-System (Powershell CTP3) lässt sich keine "Conceptual help topics" aufrufen, die man normalerweise mit "get-help about_" erreicht.
Dies funktioniert, wenn man im Powershell Installationsverzeichnis z.B. C:\WINDOchtWS\system32\WindowsPowerShell\v1.0 das Unterverzeichnis "en-US" kopiert und die Kopie in "de-DE" umbenennt. - Auf einem XP-System kamen beim Start der Powershell dutzende Fehlermeldungen. Das Deaktivieren und Umbenennen, sowie das Entfernen der Registrykeys aus
http://blogs.msdn.com/powershell/archive/2007/01/09/behind-powershell-installer-for-windows-xp-windows-server-2003.aspx brachte keine Besserung.
Erst das Entfernen des Powershell-Installationsverzeichnisse (default: %windir%\system32\WindowsPowershell\ und anschließender Neuinstallation ließ die Powershell fehlerfrei starten.