PowerShell Scripting Language (.PS1 und PSM1)
Die PowerShell Scripting Language ist eine dynamisch typisierte Skriptsprache, um Skripte für die PowerShell Engine zu entwickeln. Mit einem PowerShell Script können eigene Cmdlets erstellt werden. Die Skriptsprache unter stützt objektorientierte Programmierung (OOP) und somit das Implementieren von Klassen. Scripte haben die Dateiendung .PS1
oder für Scripte die beim Laden eines PowerShell Moduls ausgeführt werden die Erweiterung .PSM1
. Beide Dateien gehören zu den ausführbaren Dateien und unterliegen den Ausführungsrichtlinien (Execution Policy).
Die Skriptsprache (PowerShell Scripting Language) unterstützt Variablen, Funktionen, Verzweigungen, Schleifen, strukturierte Fehler- / Ausnahmebehandlung, Lambda-Ausdrücke und die Integration von .NET. Variablen in PowerShell-Skripten wird $
vorangestellt. Variablen kann ein beliebiger Wert oder Objekt zugewiesen werden. Zeichenfolgen können entweder in einfache Anführungszeichen oder in doppelte Anführungszeichen eingeschlossen werden. Bei Verwendung doppelter Anführungszeichen werden Variablen im String aufgelöst.
Unter Verwendung des function
Schlüsselworts ermöglicht PowerShell die Erstellung von Funktionen in der folgenden EINFACHEN Form:
function name ([string]$para1, [string]$para2)
{
$result = "Wert1: $para1 und Wert2: $para2"
return $result
}
Weitere Einblicke in PowerShell Scripting Language finden Sie in den öffentlich zugänglichen Büchern PowerShell in Depth, Chapter 19. PowerShell’s scripting language und Learn PowerShell Toolmaking in a Month of Lunches, Chapter 3. PowerShell’s scripting language.
Es wurde Wert darauf gelegt die Syntax der PowerShell-Skriptsprache einfach zu halten. Aber behalten Sie trotzdem immer das Thema Sicherheit in und an skripten im Auge:
Wissen vom Trainer mit vielen praxisbezogenen Übungen, Wissenstests und Frage und Antwort-Runden. Jetzt in meinen PowerShell-Seminaren und -Workshops.
Welche Elemente gehören in einer PowerShell Script-Datei, was ist sinnvoll und welche Reihenfolge soll eingehalten werden? Die Antwort auf diese Fragen erhalten Sie hier in 8 kompakten Schritten.
1. Module und Namensräume importieren
Diese Modul-Liste ist für Dritte eine Übersicht der benötigten und damit zu installierenden Module. Im Grunde ist using Module
identisch mit Import-Module -Name ..
.
using Module Microsoft.PowerShell.Management
using Module Microsoft.PowerShell.Utility
Als nächstes werden benötigte Namespace bekannt gemacht, um den Zugriff auf Typen zu erleichtern und die Lesbarkeit zu erhöhen. Anstelle [System.Management.Automation.ActionPreference]::Stop
kann nun [ActionPreference]::Stop
geschrieben werden.
using namespace System.Management.Automation
using namespace System.Windows.Forms
2. Laufzeitverhalten festlegen
Die Skript-Verarbeitung (.PS1 & .PSM1) sollte beim ersten auftretenden Fehler (Exception) abbrechen [ActionPreference]::Stop
und nicht fehlerhaft weiterlaufen (Standard ist Continue
), um so einen Schaden auf minimum zu beschränken. Sollte das Skript (.PS1 & .PSM1) im aktuellen Kontext laufen, sichern wir vorher die aktuelle Einstellung, um sie zum Schluss wiederherstellen zu können.
$backupErrorActionPreference = $ErrorActionPreference
$ErrorActionPreference = [ActionPreference]::Stop
Vor der ersten Verwendung der Variable $sume -eq 99
muss $summe
nicht explizit deklariert werden, das Ergeb-nis wäre $false
. Ärgerlich ist, das nicht erkennen von Schreibfehler wie $sume
anstelle $summe
. Diese Anweisung sorgt dafür, das Variablen vor der ersten Verwendung einen Wert zugewiesen bekommen. Ist dies nicht der Fall wird eine Ausnahme ausgelöst.
Set-StrictMode -Version 'Latest'
3. .NET-Assemblies laden
Um Ressourcen zu schonen, sind nur die gebräuchlisten Assemblies sind geladen. Darüber hinaus (z.B. WinForms und WPF) muss manuell nachgeladen werden.
Add-Type -AssemblyName 'System.Windows.Forms'
Welches Assemblies bereits geladen wurden erfahren Sie über:
[AppDomain]::CurrentDomain.GetAssemblies() | Sort-Object -Property FullName | Select-Object -Property FullName
4. PowerShell Script-Übergabe-Parameter definieren
Diese Script-Datei (.PS1) könnte wie folgt mit Parametern aufgerufen werden.
MyScript.ps1 -Path x:\wtf -BenutzerId 47110815
OPTIONAL - Sind Parameter nicht nötigt, so entfällt dieser Punkt.
Um dies zu realisieren muss der folgende Block hinzugefügt werden.
param (
[string]$Path,
[int]$BenutzerId
)
5. Funktions-Definitionen implementieren
Vor dem ersten Aufruf einer Funktion muss derer function
-Definition stehen.
OPTIONAL - Werden keine eigenen Funktionen benötigt entfällt dieser Block.
function Invoke-Irgendwas {
param ([string]$Stadtname)
$Stadtname
}
6. Business-Logik implementieren
Ab jetzt kommt der eigentliche Code, der Ihrem Skript den Sinn gibt.
$prozesse = Get-Process
foreach($p in $prozesse) {
$prozessname = $p.Name
if($prozessname -eq "notepad") {
$p.Kill()
}
}
$fenster = New-Object -TypeName Form
$fenster.ShowDialog()
Invoke-Irgendwas -Stadtname Köln
7. Aufräumen
Zum Schluss wird so aufgeräumt das Spuren, außer unser Skript-Ziel bleiben.
Remove-Variable -Name prozesse, prozessname, p, fenster -Force
Remove-Item -Path function:\Invoke-Irgendwas -Force
Set-StrictMode -Off
$ErrorActionPreference = $backupErrorActionPreference
Remove-Module -Name Module Microsoft.PowerShell.Utility -Force
Remove-Module -Name Microsoft.PowerShell.Management -Force
8. Digitale Signatur
Mit dem letzten Schritt können wir unser Skript (.PS1 & .PSM1) mit einer digitalen Signatur vor Veränderung schützen.
OPTIONAL - Eine digitale Signatur ist nur nötigt, wenn die Ausführungsrichtlinien
ExecutionPolicy
aufAllSigned
stehen.
# SIG # Begin signature block
# MIIkBwYJKoZIhvcNAQcCoIIj+DCCI/QCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# ...
# Dg4zxvPhyyMhIuS/Rz2KOG8Ly6rTmGC1C5VxdjpP96xuhz6IefLKVxRZqZQNRJ25
# oCid85NU8LI2+rA=
# SIG # End signature block
Epilog
Zum Schluss überprüfen Sie das PowerShell Script noch mittels der folgenden Punkte.
- Im PowerShell Script dürfen keine Aliase verwendet werden - Diese könnten sich ändern oder in einer späteren Version wegfallen.
- Wenden Sie
Invoke-ScriptAnalyzer -Path .\MeinSkript.ps1
auf Ihr PowerShell Script an, um schwachstellen zu finden und Code smell zu vermeiden. - Sie können PowerShell Scripte und Code-Blöcke per
Invoke-Formatter -Settings CodeFormattingAllman -ScriptDefinition (Get-Clipboard -Raw)
formatieren - So schauen alle immer gleich aus.
Für Ihre PowerShell Script-Vorlagen können Sie sich, ohne Erklärungen den folgenden Block kopieren.
## 1. Module und Namensräume importieren
using Module Microsoft.PowerShell.Management
using Module Microsoft.PowerShell.Utility
using namespace System.Management.Automation
using namespace System.Windows.Forms
## 2. Laufzeitverhalten festlegen
$backupErrorActionPreference = $ErrorActionPreference
$ErrorActionPreference = [ActionPreference]::Stop
Set-StrictMode -Version 'Latest'
## 3. .NET-Assemblies laden
Add-Type -AssemblyName 'System.Windows.Forms'
## 4. PowerShell Script-Übergabe-Parameter definieren
param (
[string]$Path,
[int]$BenutzerId
)
## 5. Funktions-Definitionen implementieren
function Invoke-Irgendwas {
param ([string]$Stadtname)
$Stadtname
}
## 6. Business-Logik implementieren
$prozesse = Get-Process
foreach($p in $prozesse) {
$prozessname = $p.Name
if($prozessname -eq "notepad") {
$p.Kill()
}
}
$fenster = New-Object -TypeName Form
$fenster.ShowDialog()
Invoke-Irgendwas -Stadtname Köln
## 7. Aufräumen
Remove-Variable -Name prozesse, prozessname, p, fenster -Force
Remove-Item -Path function:\Invoke-Irgendwas -Force
Set-StrictMode -Off
$ErrorActionPreference = $backupErrorActionPreference
Remove-Module -Name Module Microsoft.PowerShell.Utility -Force
Remove-Module -Name Microsoft.PowerShell.Management -Force
## 8. Digitale Signatur
# SIG # Begin signature block
# MIIkBwYJKoZIhvcNAQcCoIIj+DCCI/QCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# ...
# Dg4zxvPhyyMhIuS/Rz2KOG8Ly6rTmGC1C5VxdjpP96xuhz6IefLKVxRZqZQNRJ25
# oCid85NU8LI2+rA=
# SIG # End signature block
Bitte bewerten Sie diesen Artikel
[site_reviews_form category="121" assign_to="170" id="kc7stc4o" hide="title,content,name,email,terms"]