Powershell erweitern mit Modulen
In der ersten Version von Powershell konnten zusätzliche Kommandos in Powershell nur durch Snap-Ins nachgerüstet werden. Snap-Ins sind Binärerweiterungen, die installiert werden müssen. Mit Powershell 2 hat Microsoft Module eingeführt, die Snap-Ins fast vollständig ersetzt haben.
Module gibt es in Form von Binärmodulen, die in einer .NET-Sprache geschriebenen Code als DLLs nachladen. Zusätzlich gibt es aber auch sogenannte Skriptmodule. Skriptmodule sind Skripte, die global gestartet werden. Funktionen und Variablen, die im Skript definiert sind, stehen daher nach dem Import eines Skriptmoduls für die Lebensdauer der Powershell global zur Verfügung. Ab Powershell 3 werden Module, die sich in einem der Modulordner befinden, sogar automatisch importiert, so dass alle Funktionen des Moduls immer in Powershell verfügbar sind. Die komplette Skriptausführung findet dabei erst statt, sobald eine der Funktionen des Skripts aufgerufen wird.
Um sich alle in den Modulordnern vorhandenen Module anzeigen zu lassen, nutzt man Get-Module. Get-Module listet standardmäßig nur die Module auf, die bereits verwendet und damit geladen wurden. Mit dem Parameter -Listavailable kann man sich aber alle Module auflisten lassen.
Get-Module
Get-Module -ListAvailableModule
Um ein Modul manuell zu laden, verwendet man den Befehl Import-Module. Der Parameter -Force erzwingt das Laden auch dann, wenn es bereits geladen ist. Das kann sinnvoll sein, wenn man ein bereits geladenes Modul durch eine neue Version aktualisieren will, da Import-Module Module ein Modul nicht neu lädt, wenn es sich bereits im Speicher befindet.
Import-Module -Name PSWindowsUpdate -Force
Alle Module, die sich in einem der Modulpfade befinden, werden beim Starten einer Powershell-Sitzung automatisch gescannt (Autodiscovery) und bei Bedarf geladen. Die Modulpfade sind in der Umgebungsvariablen PSModulePath hinterlegt.
$env:PSModulePath.Split(';')
Hier wurde die String-Methode Split() verwendet, um den String PSModulePath am Trennzeichen ';' aufzutrennen. Alternativ kann man auch den -Split Operator einsetzen.
$env:PSModulePath -split ';'
Standardmäßig kennt Powershell drei Modulordner:
|
Ordner |
|
|
$PSHOME\Modules |
Im Powershell-Binärordner. Soll nur von Windows-Modulen verwendet werden |
|
$env:ProgramFiles\WindowsPowershell\Modu-les |
Im Programme-Ordner. Hier können Module abgelegt werden, die für alle Benutzer ver-fügbar sein sollen. |
|
$home\Documents\WindowsPowershell\Modules |
Im Benutzerprofil. Sind nur für den jeweiligen Benutzer verwendbar |
Achten Sie darauf, dass nur in die Benutzerprofile ohne administrative Rechte geschrieben werden kann.
Um Powershell neue Module hinzuzufügen, brauchen Sie das Modul einfach nur in einem der Modulordner abzulegen. Alternativ können Sie den Ordner, in dem sich Ihr Modul befindet, aber auch dem Modulpfad hinzufügen. Mit Powershell kann das dauerhaft nur über eine statische (.NET-)Methode geschehen, da alle Änderungen über das ENV:-Laufwerk nur Ihre aktuelle Sitzung ändern.
$CustomModulePath = 'C:\Program Files (x86)\code4ward.net\Royal TS V3'
$newModulePath = $env:PSModulePath,$CustomModulePath -join ';' [System.Environment]::SetEnvironmentVariable('PSModulePath',$newModulePath,'User')
Zuerst wird die Variable $newModulePath erzeugt, die den Modulpfad und den neuen Modulordner über den Operator -join mit einem Semikolon getrennt zu einem neuen String verknüpft. Anschließend wird mit der Methode SetEnvironmentVariable() die Umgebungsvariable PSModulePath dauerhaft geändert, wobei SetEnvironmentVariable() drei Parameter erwartet: Den Namen der zu setzende Variable, den neuen Wert und den Gültigkeitsbereich. Die Variable kann dabei für den aktuellen Prozess gesetzt werden, für den Benutzer oder für alle Benutzer (Process, User, Machine). Mehr zu statischen Methoden finden Sie im Abschnitt Arbeiten mit .NET.
$CustomModulePath = 'C:\Program Files (x86)\code4ward.net\Royal TS V3'
$newModulePath = $env:PSModulePath,$CustomModulePath -join ';' [System.Environment]::SetEnvironmentVariable('PSModulePath',$newModulePath,'User')