PowerShell 7
PowerShell 5.1 ist die letzte Version, die auf dem NET-Framework basiert. Die "Powershell 6 Core" (Siehe PowerShell Core) hingegen nutzte das NET Core-Framework und konnte so auch auf diversen Linux-Derivaten und MacOS installiert werden. War aber in der Funktion noch eingeschränkt, z.B. gab es keine Windows Performance Counter etc. Mit der PowerShell 7 (Release 4. März) wird vieles besser und ich nutze bis auf wenige Aufgaben nur noch PWSH.
Installation
Sie können die PowerShell problemlos "neben" der früheren PowerShell installieren. So gar die Parallelinstallation der verschiedenen Release-Kandidaten ist möglich, denn jede PowerShell bringt ihre eigene NET-Laufzeitumgebung mit. Daher ist die Powershell 7 auf meinem PC auch etwas umfangreicher.
C:\Program Files\PowerShell\7\pwsh.exe
Unter Linux sind es ca. 150MByte. Die Installation könne Sie auf unterschiedliche Wege durchführen.
Downloadquelle GitHub
https://GitHub.com/PowerShell/PowerShell/releases
- Download und Installation des ZIP-Files
Sie können einfach das passende ZIP-Archiv für ihre Umgebung herunterladen und irgendwo auspacken. Darin befindet sich dann die PWSH.EXE - Download und Starten des MSI
Natürlich gibt es in den Quellen auch einen MSI-Installer, der letztlich aber auch nur den Code ins Programmverzeichnis kopiert. Zusätzlich gibt es dann aber einen Eintrag im Startmenü, im Suchpfad und der Liste der installierten Programme - "DotNet"-Installation
Das ist dann die dritte und vermutlich am wenigsten bekannte Installationsweise. Sobald Sie nämlich das .NET Core-Framework installiert haben, gibt es das "dotnet"-Tool, mit dem Sie auch entsprechende Programme nachladen können.
Hier mal das Beispiel mit DOTNET, die ich einfach als "Benutzer" in einer CMD-Shell ausgeführt habe.
C:\>dotnet tool install --global powershell Willkommen bei .NET Core 3.1! --------------------- SDK-Version: 3.1.101 Telemetrie --------- Die .NET-Tools erfassen Nutzungsdaten, damit wir die Plattform stetig verbessern können. Die Daten sind anonym. Sie werden von Microsoft erfasst und mit der Community geteilt. Sie können das Erfassen von Telemetriedaten deaktivieren, indem Sie die Umgebungsvariable DOTNET_CLI_TELEMETRY_OPTOUT in Ihrer bevorzugten Shell auf "1" oder "true" festlegen. Hier können Sie mehr zu Telemetriedaten in .NET Core-CLI-Tools erfahren: https://aka.ms/dotnet-cli-telemetry ---------------- Erkunden Sie die Dokumentation: https://aka.ms/dotnet-docs Melden Sie Probleme, und finden Sie Quellen in GitHub: https://GitHub.com/dotnet/core Informieren Sie sich über Neuheiten: https://aka.ms/dotnet-whats-new Erfahren Sie mehr über das installierte HTTPS-Entwicklerzertifikat: https://aka.ms/aspnet-core-https Verwenden Sie "dotnet --help", um die verfügbaren Befehle anzuzeigen, oder besuchen Sie diese Website: https://aka.ms/dotnet-cli-docs Schreiben Sie Ihre erste Anwendung: https://aka.ms/first-net-core-app -------------------------------------------------------------------------------------- Da Sie gerade das .NET Core SDK installiert haben, müssen Sie das Eingabeaufforderungsfenster neu öffnen, bevor Sie das installierte Tool ausführen. Sie können das Tool über den folgenden Befehl aufrufen: pwsh Das Tool "powershell" (Version 7.0.0) wurde erfolgreich installiert.
Der Aufruf erfolgt, zumindest wenn das Programm auch im Suchpfad ist wie bei PowerShell 6 durch den Start von "PWSH.EXE". Beachten Sie auch die Links zu Einführungsvideos
- .NET Tutorial - Hello World in 10
minutes
https://aka.ms/first-net-core-app
https://dotnet.microsoft.com/learn/dotnet/hello-world-tutorial/intro
Sie haben nicht direkt etwas mit PowerShell zu tun, sondern eher mit dem genutzten NET-Core.
PS7 Neuerungen
Ich kann und will gar nicht auf alle Neuerungen eingehen. Dazu ändert sich die neue PowerShell sehr schnell und selbst von Version 6 auf 7 gibt es viele weitere Verbesserungen. Das interpretiere ich aber auch so, dass hier die Musik spielt.
ForEach mit Parallel
Parallele Programmierung war mit PowerShell 1-5 nicht immer einfach. Start-Process war sehr ressourcenhungrig und selbst Start-ThreadJob erfordert immer noch eine Job-Verarbeitung. Wenn Sie For-Schleifen nutzen, dann sollten Sie den Parameter "-parallel" kennen und den Scope von Variablen kennen.
1..10 | foreach-object -parallel { write-host "Loop $($_) Test $($test)" start-sleep -milliseconds 500 } Loop 4 Loop 3 Loop 1 Loop 2 Loop 5 Loop 6 Loop 7 Loop 8 Loop 9 Loop 10
So werden die Befehle in der Schleife parallel ausgeführt. Per Default laufen aber nur 5 Threads parallel, so dass diese Schleife dann ca. 1 Sekunde statt 5 Sekunden läuft. An der Ausgaben sehen Sie aber auch, dass die Reihenfolge veränderlich sein kann. Auch kann ein Thread einfach pausiert sein was bei einfachen Operationen wie "$a++" zu Problemen führen kann. Daher sind per Default Variablen in der Schleife immer nur "Lokal. Globale Variablen kann man über "$using" dann in der Schleife referenzieren aber sollte natürlich sicherstellen, dass der Zugriff "Thread-Safe" ist, z.B. mit
$wert = 10; # variable belegen $refWert=[ref]$wert 1..10 | foreach-object -parallel { write-host "Loop $($_) Test $([System.Threading.Interlocked]::Read($using:refWert))" [System.Threading.Interlocked]::Read($using:refWert) write-host "Loop $($_) Test $([System.Threading.Interlocked]::Increment($using:refWert))" start-sleep -milliseconds 500 } Loop 1 Test 10 10 Loop 2 Test 10 10 Loop 1 Test 11 Loop 2 Test 12 Loop 3 Test 10 12 Loop 3 Test 13 Loop 4 Test 10
Damit wir das Skript aber etwas länger laufen, da die Abstimmung der Thread aufeinander die parallele Ausführung etwas hindert. Die Abarbeitung ist etwas "serieller" aber immer noch schneller als ohne "-parallel"
Performance Counter
Das Commandlet "Get-Counter" war in der alten PowerShell schon lange da und in der PowerShell 6 hat es gefehlt. Erst seit der Powershell 7 ist der Befehl wieder im Standard enthalten.
CIM statt WMI
WMI ist COM und daher "Old Style". PS6+ kann aber keine COM-Objekte mehr nutzen und damit auch nicht mehr auf WMI-Klassen zugreifen. Hier kommen dann die CIM-Commandlets zum Einsatz.
PS C:\> Get-Command *-*cim* CommandType Name Version Source ----------- ---- ------- ------ Cmdlet Get-CimAssociatedInstance 6.1.0.0 CimCmdlets Cmdlet Get-CimClass 6.1.0.0 CimCmdlets Cmdlet Get-CimInstance 6.1.0.0 CimCmdlets Cmdlet Get-CimSession 6.1.0.0 CimCmdlets Cmdlet Invoke-CimMethod 6.1.0.0 CimCmdlets Cmdlet New-CimInstance 6.1.0.0 CimCmdlets Cmdlet New-CimSession 6.1.0.0 CimCmdlets Cmdlet New-CimSessionOption 6.1.0.0 CimCmdlets Cmdlet Register-CimIndicationEvent 6.1.0.0 CimCmdlets Cmdlet Remove-CimInstance 6.1.0.0 CimCmdlets Cmdlet Remove-CimSession 6.1.0.0 CimCmdlets Cmdlet Set-CimInstance 6.1.0.0 CimCmdlets
Operatoren
Interessant sind auch Neuerungen bei Operatoren, die den Code kürzer und übersichtlicher werden lassen, wenn Sie denn die Befehle auch kennen. Hier ein paar Beispiele:
Alt | Neu | Beschreibung |
---|---|---|
if ($a -eq "test") { write-host "Gleich" } else { write-host "Ungleich" } |
($a -eq "test") ? (write-host "Gleich") : (Write-Host "Ungleich") |
Verkürzt den Code für einfache IF-Anweisungen, die in eine Zeile passen. |
get-item "user2 -ev err if (!$err) { remove-item $user" } |
get-item "user" && remove-item "user" |
Verkettung von zwei Befehlen, bei dem der zweite nur ausgeführt wird, wenn der erste Befehl fehlerfrei durchlief |
get-item "user2 -ev err if ($err) { new-item $user" } |
get-item "user" || new-item "user" |
Verkettung von zwei Befehlen, bei dem der zweite nur ausgeführt wird, wenn der erste Befehl NICHT fehlerfrei durchlief |
if ($null eq $var2) { $var1 = ?? "Ungenutzt" } |
$var1 = $var2 ?? "Ungenutzt" |
Wenn $var2 nicht "$null" ist, dann wird sie $var1 zugewiesen. Ansonsten wird der Wert hinter dem "??" zugewiesen. |
if ($null -eq $var1) { $var1 = "startwert" } |
$var1 ??= "startwert" |
$var1 wird nur dann mit "startwert" belegt, wenn sie vorher $null ist. |
Diese kleinen Verbesserungen sind wohl in anderen Programmiersprachen in der ein oder anderen Form schon vorhanden. Sie können den Code kürzer und übersichtlicher gestalten, wenn Sie denn die neuen Schreibweisen auch kennen.
Dauerlast
Interessant ist eine Dauerlast. Ich habe dazu ein paar Skripte aus meiner Ende zu Ende Monitoring-Kollektion über viele Wochen während der Corona laufen lassen.
Interessant war, dass die Prozesse kein Speicher gefressen haben und auch sonst sehr sparsam unterwegs sind.
Weitere Links
- PowerShell Core
- PowerShell 7.0: Technische Basis und
Installation
https://www.heise.de/developer/artikel/PowerShell-7-0-Technische-Basis-und-Installation-4686676.html - PowerShell 7.0 freigegeben: Eine Shell
für (fast) alle und (fast) alles
https://www.heise.de/developer/meldung/PowerShell-7-0-freigegeben-Eine-Shell-fuer-fast-alle-und-fast-alles-4656825.html