PowerShell Seminar

(Wer sofort mit den PowerShell Seminarunterlagen loslegen will: Einführung)

Die PowerShell - alter Code- und Entwickler-Name Monad (Monad Manifest Jeffrey P. Snover - Aug 8, 2002) - ist Microsofts Antwort auf die Bedürfnisse moderner Administrationen für Windows und auch heterogene Netze und Cloud-Techniken.

Durch die Entwicklung der PowerShell Core Versionen ist die Microsoft Skripttechnik für die Konsole sogar auf anderen Plattformen (Linux, MacOS oder auch für ARM-Hardware) eingezogen.

Die Quelloffene Struktur zieht viele Entwickler aus vielen IT-Bereichen an und diese erweitern das PowerShell Universe täglich.

PowerShell Hero Wallpaper (Microsoft)

PowerShell Hero Wallpaper (Microsoft)

Ich zitiere an dieser Stelle einmal aus einem Exchange-Fachbuch von T. Stensitzki:

Wenn Sie an dieser Stelle des Buches angekommen sind und zum ersten Mal etwas über PowerShell lesen, so kann ich Ihnen nur einen Rat geben: Lernen Sie PowerShell!

Die aktuellen Versionen von Exchange Server und alle wie auch immer gearteten Clouddienste von Microsoft erfordern die Administration per PowerShell. Es gibt keine Alternative!

Und diesem Rat will ich mich gerne aus vollem PowerShell-Herzen anschließen ;-)

Hier also für den Anfang meine Struktur zur PowerShell - mein Roter Faden:

Themenabschnitte

Hier eine Übersicht über die behandelten Themenabschnitte rund um die PowerShell und Co:

  1. Basics - Einführung in die PowerShell und mein „Roter Faden“

  2. Hosts - Die Ausführumgebungen der PowerShell: ConsoleHost, ISE

  3. Cmdlets - Die Cmdlets und alle Techniken für die effiziente Nutzung von PowerShell-Aufrufen

  4. Scripting - Die PowerShell Profile und die Erstellung eigener PowerShell Logik

  5. Module - Module kapseln unsere PowerShell Techniken

  6. Remoting - Die PowerShell im Netzwerk nutzen

  7. Specials - Spezialthemen, Bücher, Links, …

Und los geht es mit unseren Themen rund um die PowerShell

Für einen schnelleren Überblick - in den HTML-Dokumenenten - folgt hier das Stichwortverzeichns und die Dokumentstruktur:


Stichwortverzeichnis


Einführung

Automatisierung von Administrationsaufgaben mit der Microsoft PowerShell

„Roter Faden“

Dieses Seminar ist für Alle, die die Befehlszeile und Skriptumgebung Windows PowerShell kennenlernen möchten. Mit der PowerShell lassen sich Administrationen, Konfigurationen und Diagnosen der Windows Betriebssysteme schneller und effektiver durchführen und automatisieren.

Erlernen Sie anhand praktischer Beispiele die neuen PowerShell-Cmdlets und -Techniken dieser mächtigen Windows-Administrations-Technik. Alle aktuellen Windows Betriebssysteme lassen sich komplett über die PowerShell administrieren!

Übersicht PowerShell Technik

Übersicht PowerShell Techniken

Die Inhalte werden nicht zwangsläufig in der Reihenfolge dieser Ausarbeitung erarbeitet. Die speziellen Themenwünsche der Teilnehmer werden zu Beginn des Seminars evaluiert.

PowerShell Techniken im Seminar

Technische Basis: Windows basierte PowerShell Versionen

  • 5.0 (WMF 5.0 für Windows 7/8.1)

  • 5.1 (WMF 5.1 ab Windows 10: Codename Redstone 1, Version 1607, 10.0.14393)

Aktuellere Versionen: Codename Redstone 4, „April Update“, Version 1803, 10.0.17134;

dann: 1809, 1903, 1909 (bzw. 19H2), 2004, 20H2, …

Anm.: kleinere Macken in Version 5.1 von Windows 1809 (z.B. Strg + L hat nicht sauber funktioniert).

PowerShell Core:

  • 6.0 (PowerShell Core 6.0) - plattformübergreifende (Windows, MacOS, Linux) Open-Source-Edition der PowerShell für heterogene Umgebungen und die Cloud

  • 7.0 Preview 1 am 30.05.2019 - selbstverständlich wieder PowerShell Core 7!

  • 7.1 am 11.11.2020 (!)

  • 7.2 am 08.11.2021

Anmerkung zu Seiten-/Quellangaben:

Falls Literatur oder Quelle nicht ausdrücklich genannt ist, so ist häufig das PowerShell Praxisbuch von Holger Schwichtenberg gemeint (siehe abschließende Literaturübersicht).

Trainer J. Brandes pflegt ein korrespondierendes Text-Dokument (PowerShell-Seminar- scriptlines.ps1) welches nur Kommentare und ausführbaren PowerShell Code (Snippets, Funktionen) enthält.

Mit diesen PowerShell-Snippets wird im Seminar die „Abtipparbeit“ für die Trainees über entsprechend freigegebene Clouddateien, Git-Repos oder lokale Netzwerk-Freigaben erleichtert.

Hinweis

Datei: PowerShell Seminar Skripte aktuell als Gitlab-Repo.

Ich wünsche viel Spaß und Erfolg bei der „Arbeit“ mit der PowerShell.

Ihr Trainer J. Brandes

Braunschweig, November 2022


Hier weitere Abschnitte zum Thema:

Allgemeines

Tipps:

  • keine Groß-/Kleinschreibung (non case-sensitive)

  • Tab-Taste für Vervollständigungen nutzen

  • Strg + Leertaste für Codevervollständigungen (siehe PS 5 Standard-Modul PSReadline)

Architektur:

  • DOS-Shell (Befehle, Oberfläche)

  • Unix-Shells (Pipelinig, Syntax, Befehlsnamen)

  • Andere Skriptsprachen z.B. Perl oder auch Hochsprachen C# (Syntax)

  • Dot.NET Framework (Objektorientierung, Zugriff auf über 12.000 Klassen!)

  • Windows Scripting Host (WSH, Sicherheit)

  • Einsatz WSH bis ca. 2020! - PowerShell bis min. 2030

  • WMI (Klassen, Tool wmic.exe) Anm.: besser CIM?! Mehr dazu später…

Reihenfolge für Aufrufsabarbeitungen in PowerShell:

  1. Aliase

  2. Funktionen

  3. Cmdlets

  4. Externe Befehle (netstat, ipconfig, notepad, …)

Wichtig: ungeschickte Aliase können also die weiteren Befehle (Funktionen, Cmdlets, Tools) „deaktivieren“/überschreiben!

PowerShell Versionen

Infos zur PowerShell-Version mit $PSVersionTable anzeigen lassen:

PS E:\_temp> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.0.10586.117
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.10586.117
CLRVersion                     4.0.30319.36366
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

PS E:\_temp> $host.Version

Major  Minor  Build  Revision
-----  -----  -----  --------
5      0      10586  117

oder „etwas neuer“: (Windows 10 – Version 1607)

PS E:\_temp> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.14393.206
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14393.206
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

PS E:\_temp> $host.Version

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      14393  206

Und selbstverständlich gibt es noch neuere Windows 10 Versionen (also: 1703, 1709, 1803, 1809, 1903, …).

Hier das Home-Verzeichnis für die PowerShell mit Variable $PSHOME:

PS E:\_temp> $PSHOME
C:\Windows\System32\WindowsPowerShell\v1.0

Ja es handelt sich als Verzeichnis immer noch um die Version 1.0 und das ist natürlich die 64-Bit-Variante auf 64-Bit-OS. Die 32-Bit-Variante befindet sich im SysWoW64-Ordner (!):

C:\Windows\SysWOW64\WindowsPowerShell\v1.0

Warum ist das wichtig?

Beispiel: beim Zugriff auf 32-Bit Access DB oder Module mit 32-Bit-Programmierungen.

PowerShell Core

Die PowerShell Core eingeführt mit Version 6 stellt eine komplette Neuentwicklung dar. Sie basiert auf .NET Core - einer plattformunabhängigen Entwicklungsumgebung (Wichtig: nicht mit .NET Framwork für Windows verwechseln!).

Bitte auch nicht mit den PowerShell Core 5.1 Versionen für den Windows Nano Server verwechseln.

Die PowerShell Core ist für viele unterschiedliche Betriebssysteme (Windows, Linux, MacOS) verfügbar. Auf Windows Systemen lässt sich die Core auch als nicht installierte (also entpackte Zip-Variante) neben der vollwertigen PowerShell betreiben.

PowerShell Core 6 (Preview)

Konsole PowerShell Core 6.2

Natürlich ist die Core-Version gegenüber der vollständig für Windows optimierten Shell 5.1 (noch) stark abgespeckt! Und bei der Nutzung auf Nicht-Windows-Systemen muss man sich an die dortigen Practises halten.

Anm.: seit Mai 2019 gab es erste Preview-Versionen der PowerShell Core 7 mit den entsprechenden Releases über das Github-Portal: https://github.com/PowerShell/powershell/releases

Cmdlets 101

Interne Cmdlets ab PS 1.0: 129; Später in PowerShell 4.0: 328

Inklusive aller OS-spez. Cmdlets (siehe auch Server-OS) und in aktuellen Windows 8.1/10 dann über 1000!

Hier mal ein Zahl zur Version mit Windows 10 2004 Build 19041 - aber wer zählt schon ;-) : 1600 Kommandos

Hinweis

Bitte niicht von der schieren Zahl beeindrucken lassen. Auch diese Shell folgt der klassischen Vorgabe: ein Tool für eine Aufgabe. Die Shell hilft uns (interaktiv) die richtigen Tools zu finden und zu kombinieren!

Grundsätzlicher Aufbau von Cmdlets:

Verb    -   Substantiv  [-Parameterliste]
Get     -   Command     -CommandType Cmdlet

Meine drei Master-Cmdlets (They rule them all):

  • Get-Command

  • Get-Help

  • Get-Member

Mit diesen drei PowerShell Commands kann man die gesamte PowerShell nutzen und verstehen.

Grundaufbau der Cmdlets mit Verben:

Get, Set, Add, New, Remove, Clear, Push, Pop, Write, Export, Select, Sort, Update, Start, Stop, Invoke usw.

Ausgabekommandos wie Out und Format

Extra-Cmdlets sind zahlreich verfügbar:

Hier ein erstes Beispiel PSCX - PowerShell Community Extensions (früher: http://pscx.codeplex.com/ ; heute: https://www.powershellgallery.com/ )

z.B.: Get-DomainController, Ping-Host (obsolet, heute: Test-Connection), Out-Speech, Packer-Cmdlets, …

Anm.: Die PSCX sind seit geraumer Zeit über das Repository PSGallery online verfügbar, also bitte nicht mehr manuell installieren! Die Installation / Übung zum Modul PSCX folgt später!

Kommandos 101

Die Konsolenumgebung der PowerShell

  • Größe/Aussehen/Fonts für PowerShell-Fenster über Eigenschaften

  • STRG + C kann Befehlsausführung unterbrechen

  • Nutzen der Zwischenablage mit Shortcuts Strg + C/V und Co

Anm.: PowerShell 5.0 kopiert leicht anders als Version 5.1 - in Clipboard/Zwischenablage übertragen mit einfachem Enter

  • Letzte Befehle mit Cursortasten

  • nur in „alten“ PowerShells: letzter Befehl mit F3 oder mit F7 Befehlschronikfenster)

  • Konsolen im Kommandomodus („1-zeilig“) vs. Interpretermodus („mehrzeilig mit Eingaben“)

  • Beispiel für Interpretermodus: Get-EventLog

  • ESC löscht Zeile

  • Strg + L löscht Konsole (PSReadline: Linux Bash lässt grüßen)

  • PSReadline: (wichtiges Standard-Modul in aktuellen PowerShells)

Viele der modernen Eigenschaften werden also durch das Standard-Modul PSReadline bereitgestellt!

  • Copy/Paste, Strg + L (Konsole leeren)

  • besserer Mehrzeilenmodus

  • Strg + Leertaste für Vorschläge

  • Prompt mit rotem > bei fehlerhaften oder unvollständigen Eingaben

  • belegbare Tastenkombination

    (siehe cmdlet Get-PSReadlineKeyHandler bzw. das Pendant Set-PSReadlineKeyHandler)

  • Strg + r / Strg + s für Zurück/Vorwärts- Suche in History

Erste Aufrufe

Wchtig: Rechte beachten (Admin vs. Standardbenutzer):

whoami /all     („Wer bin ich?“ mit ausführlichen Infos)

Interaktive Aufrufe: (siehe „Interpretermodus“):

Get-Process
Get-EventLog

Get-EventLog hat dann Nachfrage zu Parameter: z.B. Application, System, …

Parameter - und einfache Parameter-Switches nutzen. Alle Aufrufe gleich – aber: im ersten Beispiel die Reihenfolge (Position) entscheidend!

Bitte ausführliche Hilfe analysieren mittels Get-Help Get-Childitem –Full (Position?):

Get-ChildItem C:\temp *.txt
Get-ChildItem -Path C:\temp -Filter *.txt
Get-ChildItem -Filter *.txt -Path C:\temp

Aufrufe mit Wildcards:

Get-Process i*
Get-Process i*ore
Get-Process [st]*
Get-Process [st][vf]*

Switch (Schalter):

Get-ChildItem C:\temp -recurse
Get-ChildItem C:\temp -recurse:$false
# Anm.: Schalter deaktivieren mit $false

Allgemeine Parameter: -Force, -Whatif, -Confirm, …

Anm.: Leider manchmal unterschiedliche Nutzung:

Parameter -confirm:$false vs. Parameter -force (bei Skripten mit Remove-ADUser vs. Remove-SmbShare)

Aufrufe zusammensetzen (später sinnvoll mit Variablen in Skripten):

Get-ChildItem ("c:\" + "Windows") *.dll –Recurse

Mehrere Befehle pro Zeile (; kann auch jede Zeile abschließen):

Get-Process ; Get-Service

PowerShell-Aufruf über mehrere interaktive PowerShell-Zeilen:

  • einfach nach dem Pipe-Symbol | Return drücken, (Anm.: PSReadline Unterstützung)

  • oder manuell mit Gravis (Alt 96 – Backtick – Umschalten Hochkomma links neben Backspace) in die nächste Zeile wechseln.

Pipes 101

Erste Beispiele:

Get-EventLog system | Where-Object { $_.source -eq "Kernel" } | Select-Object -first 10

geht nicht wegen Kernel als Source – Vorschlag: Eventvwr.msc genauer ansehen (XML - Details)

Get-EventLog system | Where-Object { $_.source -eq "Microsoft-Windows-Kernel-General"
    –and $_.EventID –eq 12 } | Select-Object -first 10

Frage: was macht der Befehl? Anm.: Get-EventLog hat keinen eigenen Filter!

Policy 101

PowerShell Skripte sind einfache Textdateien. Die Skriptausführung funktioniert nur in geeigneter Umgebung! Die richtigen und gewünschten Sicherheitlevel sind zu beachten (Restricted, RemoteSigned, Unrestricted, …)

Cmdlets:

Get-ExecutionPolicy
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser   # für Standard-User
Set-ExecutionPolicy RemoteSigned                     # so nur für Admin Ebene LocalMachine

Empfehlung: hier schon auf Remotesigned setzen, da sonst das Autoloading von Modulen und Co nicht funktioniert! Das Ändern (Set-ExecutionPolicy ohne Angabe eines Scope/Bereichs) muss mit administrativer PowerShell geschehen!

Tipp: Übersicht über alle ExecutionPolicy Level mit

PS E:\_temp> Get-ExecutionPolicy -List

    Scope ExecutionPolicy
    ----- ---------------
    MachinePolicy       Undefined
    UserPolicy          Undefined
    Process             Undefined
    CurrentUser         Undefined
    LocalMachine        RemoteSigned

Mit der Möglichkeit -Scope CurrentUser (s.o.) können sich User eine andere ExecutionPolicy konfigurieren.

Die Reihenfolge der Abarbeitung geht von unten nach oben: die höchste Wertigkeit hat also die ExecutionPolicy für die Maschine MachinePolicy und kann – wie der Name auch nahelegt – nur per Gruppenrichtlinie (Policy per GPO) festgelegt werden.

GPO Bearbeitungspfade für Maschine oder Benutzer:

Richtlinien\Administrative Vorlagen\Windows Komponenten\Windows PowerShell Policy: Skriptausführung aktivieren

Anm.: GPO - Group Policy Object

History / PSReadline

Get-History oder auch Invoke-History; Tipp:

Get-Command *history*

Anm.: diese History ist die PowerShell.Core History und funktioniert nur für die aktuelle Sitzung! Das würde auf Dauer sehr aufwendig für die Nachvollziehbarkeit der PowerShell Konsolennutzungen sein.

Besser wir nutzen…

PSReadline History

In der Konsole (hier der klassische Host) – durch die Hilfe mit aktuellem Standarmodul PSReadline - stehen mehr Infos/Aufrufe aus der Vergangenheit der Konsole(n) zur Verfügung!

Cmdlet: Get-PSReadlineOption mit Property/Eigenschaft HistorySavePath

Aufruf zum Ermitteln des HistorySavePath also:

PS E:\_temp> (Get-PSReadlineOption).HistorySavePath
C:\Users\joebr_000\AppData\Roaming\PSReadline\ConsoleHost_history.txt
PS E:\_temp> (Get-PSReadlineOption).MaximumHistoryCount
4096
PS E:\_temp> (Get-PSReadlineOption).HistorySaveStyle
SaveIncrementally

oder um den Inhalt der PSReadline-History-Datei gleich mit Editor zu betrachten:

PS E:\_temp> $a = (Get-PSReadlineOption).HistorySavePath
PS E:\_temp> notepad.exe $a                   # oder auch gerne mit dem ISE
PS E:\_temp> ise $a

Die Befehle lassen sich also problemlos über eine längere Nutzung nachvollziehen und effizient anwenden und wiedervorholen.

Transcript

Ich habe lange mit mir gerungen - aber da ich die Technik auch in den Seminaren zeige, will ich sie an dieser Stelle kurz darstellen.

Warum das Zögern - es geht um Datenschutz und Privatsphäre und bitte jeder die eigenen Schlüsse für das eigene Technikumfeld ziehen.

Im Grund handelt es sich um eine Aufzeichnungsfunktion für die PowerShell. Das Transcript ist eine Textdatei mit allen eingegebenen Befehlen und Ausgaben!

Manuelles Starten/Stoppen der Transcript Funktionalität: Cmdlets Start-Transcript und Stop-Transcript

Beispiel:

Start-Transcript -Path aufzeichnung.txt -NoClobber

Anm.: -NoClobber schützt vor Überschreiben

Wer also seine eigenen Aufrufe in der PowerShell mitschneiden möchte, kann dieses manuell aktivieren und nutzen.

GPO

Mit Hilfe einer GPO lässt sich dieses Verhalten auch zentral per Gruppenrichtlinie steuern.

Aktivieren von Transcripts per Gruppenrichtlinie

Kurzanleitung:

  • starten/öffnen des Gruppenrichtlinien-Editors gpedit.msc

  • gehe zu Computerkonfiguration - Administrative Vorlagen - Windows-Komponenten - Windows PowerShell

    konfiguriere: PowerShell-Aufzeichnung aktivieren

Solche Konfigurationen lassen sich natürlich auch Domänenweit über das Richtlinienkonzept des Active Directory von Microsoft verteilen.

Hilfen

Es gibt sehr viele Möglichkeiten in der PowerShell unterstützen zu lassen.

PowerShell Hero will help!

PowerShell Hero will help!


Hier folgen weitere Abschnitte zum Thema - die Praxis erfolgt ausführlich und stets begleitend in unseren Seminaren.

Tabulator

Mit dem Tabulator (TAB) gibt es die Codevervollständigung in der Konsole. inkl. Wildcards:

Get-?e*  (TAB)

Get-Command

Ein paar Beispiele… Alle Befehle, die mit „get“ anfangen:

Get-Command Get-*

Alle Befehle, die mit „get“ oder „set“ anfangen:

Get-Command [gs]et-*

Alle Befehle, die das Substantiv „Service“ besitzen:

Get-Command *-Service

Ebenfalls alle Befehle, die das Substantiv „Service“ besitzen:

Get-Command –Noun Service

Alle Befehle, die die Buchstabenfolge „wmi“ enthalten (und mutmaßlich mit der „Windows Management Instrumentation“ zu tun haben):

Get-Command *wmi*

Beispiel mit mehr Tiefe als Vorbereitung auf Pipelining und Filterungen: Alle Befehle, die die Buchstabenfolge „wmi“ oder „cim“ enthalten!

Get-Command | Where-Object { $_.name -like "*cim*" -or $_.name -like "*wmi*" }

Erläuterungen zu Aufrufen: bitte wieder Reihenfolge beachten

  1. Alias

  2. Function

  3. Cmdled

  4. Application

Hier das Ganze in der Konsole:

PS E:\_temp> Get-Command ps

CommandType     Name                                  Version    Source
-----------     ----                                  -------    ------
Alias           ps -> Get-Process

PS E:\_temp> Get-Command "C:"

CommandType     Name                                  Version    Source
-----------     ----                                  -------    ------
Function        C:

PS E:\_temp> Get-Command Get-Command

CommandType     Name                                  Version    Source
-----------     ----                                  -------    ------
Cmdlet          Get-Command                           3.0.0.0    Microsoft.PowerShell.Core

PS E:\_temp> Get-Command notepad.exe

CommandType     Name                                  Version    Source
-----------     ----                                  -------    ------
Application     notepad.exe                           6.3.960... C:\WINDOWS\system32\notepad.exe

Hinweis

In der zweiten Konsole kann es natürlich auch einfach C: (ohne Quotes) heißen, aber dann geht mir das Syntaxhighlighting kaputt und die PowerShell Konsole wird nicht sauber nach text, latexpdf oder epub exportiert!

Einfache Hilfe zu Kommandos

Get-Command -?

Anzahl von Cmdlets und Funktionen (so seit PS 2.0)

Get-Command | Group-Object CommandType

Und hier wieder ein paar Aufrufe in der Konsole:

PS E:\_temp> (Get-Command).count
1332
PS E:\_temp> Get-Command | Group-Object CommandType

Count Name               Group
----- ----               -----
10 Alias                 {Add-ProvisionedAppxPackage, Apply-WindowsUnattend, Flush-Vol...}
770 Function             {A:, Add-BitLockerKeyProtector, Add-DirectoryLength, Add-DnsC...}
552 Cmdlet               {Add-AppxPackage, Add-AppxProvisionedPackage, Add-BitsFile, A...}

Cmdlets und Funktionen exportieren:

Get-Command | Format-Table name -HideTableHeaders | Out-File E:\_temp\pscommands.txt

Bitte Alles praktisch in der Konsole ausprobieren.

Get-Help

Hilfe aktualisieren mit Update-Help Commandlet

Update-Help –UICulture En-US -force

Anm.: Autor Weltner empfiehlt En-US Schalter! Ich lasse aktuelle einfach Update-Help –force durchlaufen.

Beachten: Admin-PowerShell nötig! Anm.: Nur das Konto domainAdministrator bekommt automatisch eine „Administrator:“ Konsole/Host-Umgebung. Alle anderen Konten bitte UAC – also Rechte Maus „Als Administrator ausführen“ – nutzen.

Tipp: auch mit der ISE lässt sich über Menü „Hilfe“ die PowerShell aktualisieren!

Die eingebaute Hilfe-Technik in der Konsole nutzen:

Get-Help Get-Command

mit Parametern auch

Get-Help Get-Command -Detailed       (-Full, -Examples, -Online, -ShowWindow)

Anm.: unbedingt die „neuen“ -Online, -ShowWindow Optionen durchspielen!

Option -Online ist oft nur für Kern-Cmdlets der PowerShell verfügbar.

Hilfe zu den Parametern der Cmdlets

Get-Help Get-Process -parameter "*"

Hilfe zu PowerShell-Techniken (beachten: in PowerShell 5.1 teilweise keine Help-Files zu about_*)

Get-Help about_for
Get-Help about_foreach

Status Anfang 2017: in vielen Testumgebungen keine Probleme mehr mit about_* Topics. Anscheinend wurden die Hilfen zur PowerShell aktualisiert. Ansonsten bitte den folgenden Online Quellen zuwenden.

Get-Help about (alle verfügbaren Hilfen)

https://technet.microsoft.com/en-us/library/hh847856.aspx (help - about Topics)

https://technet.microsoft.com/de-de/library/hh847856.aspx (help DE - about Topics)

Show-Command

Grafische Oberfläche mit Show-Command seit PS 3.0

Show-Command Get-Process

Ausgabeformate

Die Ausarbeitungen zu den Ausgaben mit der PowerShell finden sich hier im Basics-Abschnitt meiner Ausarbeitung.

Hinweis

In den Seminaren folgen die Übungen rund um diese Techniken an späterer Stelle. Ich orientiere mich hier an meinen Erfahrungen mit den PowerShell Seminaren und den zur Verfügung gestellten Zeitrahmen.

Standardausgabe gemäß der PowerShell-Konfiguration (DotNetTypes.Format.ps1xml)

Out-Default

Siehe auch Get-Help Update-FormatData und Get-Help about_Format.ps1xml

Cmdlets für Ausgaben:

  • Out-Host
    (kurz: oh) wie Out-Default mit zusätzlicher Option zur seitenweisen Ausgabe
  • Out-Null
    Die Objekte der Pipeline werden nicht weitergegeben.
  • Out-GridView
    (kurz: ogv): Ausgabe in grafischer Tabelle mit Such- und Filterfunktionen
    (vorhanden seit PowerShell 2.0)
  • Format-Wide
    (kurz: fw): zweispaltige Liste
  • Format-List
    (kurz: fl): detaillierte Liste
  • Format-Table
    (kurz: ft): Tabellenausgabe

Hier weitere Abschnitte zum Thema:

Ausgaben 101

Gezieltes Ausgeben der Tabellen

Get-Service | Select-Object -first 5 | Format-Table
Get-Service | Select-Object -first 5 | Format-Table *
Get-Service | Select-Object -first 5 | Format-Table -property Name, CanStop

Get-Service | Select-Object * | Out-GridView

Standardausgabe gemäß DotNetTypes.Format.ps1xml (eigentlich also Dot.NET Formate!)

Get-ViewDefinition System.Diagnostics.Process    # Viewdefinition Get-Process ab Zeile 431
Get-Process | Format-Table –view priority

Ausgaben einschränken

Get-Process | Format-Table -Property id,processname,workingset

als auch

Get-Process | Select-Object id, processname, workingset | Format-Table

Seitenweise Ausgabe

Get-Service | Out-Host -Paging

das alte more.exe ginge natürlich auch (aber hier asynchrone Abarbeitung - Nerv!)

Get-ChildItem c:\ -Recurse | more

Ausgabe-Cmdlets Konsole:

  • Write-Host,

  • Write-Warning und

  • Write-Error

Mit Write-Host manuelle Konfiguration der Ausgaben möglich

Write-Host "Hallo Joe" -foregroundcolor red -backgroundcolor white

Diverse Ausgaben:

1$a = "Joe Brandes"
2$b = "info@pcsystembetreuer.de"
3$c = Get-Date
4# und wieder: in Zeichenketten (doppelte) sind Variablen nutzbar; ansonsten immer +
5$a + " ist erreichbar unter " + $b + ". Diese Information hat den Stand: " + $c + "."
6# oder
7"$a ist erreichbar unter $b. Diese Information hat den Stand: $c."

Neu: mit Platzhaltern und Formatbezeichnern: Ausgabeoperator –f

Beispiele: (s.a. Tabelle ab S. 164ff. Schwichtenberg (PS 4.0) bzw. Tabelle S. 182 ff. (PS 5.0))

"{0} ist erreichbar unter {1}. Diese Information hat den Stand: {2:D}." -f $a, $b, $c

Weitere Beispiele:

Get-Process | ForEach-Object { "{0,-40} | {1}" -f $_.Name, ($_.ws/1MB)}
Get-Process | ForEach-Object { "{0,-40} | {1:n}" -f $_.Name, ($_.ws/1MB)}
Get-Process | ForEach-Object { "{0,-40} | {1:0.000}" -f $_.Name, ($_.ws/1MB)}

Benutzerdefinierte Ausgaben

Vorgabe von Eigenschaften und Konfigurationen:

  • Label: Spaltenüberschrift

  • Expression: beliebiger PowerShell-Ausdruck, der die Werte liefert; auch Berechnungen

  • Width: Spaltenbreite

  • Format: Formatierungsbefehl

Beispiel mit drei Spalten:

  • 5 Zeichen für die Prozessnummer in der ersten Spalte

  • 20 Zeichen für den Prozessnamen

  • 11 Zeichen für die Speichernutzung,

wobei die Angabe in Megabyte erfolgt und mit maximal einer Nachkommastelle

PS E:\_temp> Get-Process | sort workingset64 -desc |
>>> Format-Table @{Label="Nr"; Expression={$_.ID}; Width=5},
>>> @{Label="Name"; Expression={$_.Processname}; Width=20 },
>>> @{Label="Speicher MB"; Expression={$_.WorkingSet64 / 1MB}; Width=11; Format="{0:0.0}" }

   Nr Name                 Speicher MB
      -- ----                 -----------
       7280 firefox                    527,7
       2084 explorer                   322,4
        484 dwm                        316,9
       3456 powershell_ise             246,0
       2236 MsMpEng                    226,9
       1724 AcroRd32                   203,6
       1268 svchost                    119,8
       1252 powershell                 116,9
       8108 powershell                 100,6
        904 WINWORD                    100,6
       6484 iexplore                    76,7
       7640 iexplore                    75,0
   ...

Unterobjekt mit eigenen Methoden und Eigenschaften richtig ausgeben:

Get-Process | Format-Table ProcessName, { $_.TotalProcessorTime.Hours }

Get-Process
| Sort-Object CPU
| Format-Table ProcessName, { $_.TotalProcessorTime.MilliSeconds }

Ausgaben unterdrücken

Verschiedene Techniken zur Unterdrückung von Ausgaben:

Out-Null verwenden:

Commandlet | Commandlet | Out-Null

Variable zugewiesen:

$a = Commandlet | Commandlet

Typ [void] nutzen:

[void] (Commandlet | Commandlet)

$null zuweisen:

$null = Commandlet | Commandlet

Ausgaben an Drucker

Standarddrucker:

Get-Process | Out-Printer

bestimmter Drucker (print queue)- kurz Version - nicht in PS 1.0/2.0

Get-Process | Out-Printer "Samsung ML-2580 Series"

eigentlich komplette Zeile

Get-Service | Where-Object status -eq stopped
| Out-Printer -Name "Samsung ML-2580 Series"

Ausgaben in Datei

Ausgaben in Dateien umleiten

Get-Process | Out-File "c:\temp\prozessliste.txt"

Ausgaben anhängen mit -Append

Get-Process | Out-File "c:\temp\prozessliste.txt" -Append

Umleitungsoperator ist > (Ersetzen) bzw. >> (Anhängen):

  • > Umleitung der Pipeline-Ausgabe

  • 2> Umleiten der Ausgabe von Fehlern

  • 3> Umleiten der Ausgabe von Warnungen (seit PowerShell-Version 3.0!)

  • 4> Umleiten der Ausgabe von Verbose-Texten (seit PowerShell-Version 3.0!)

  • 5> Umleiten der Ausgabe von Debug-Texten (seit PowerShell-Version 3.0!)

  • *> Umleiten aller Ausgaben (seit PowerShell-Version 3.0!)

Beispiel

dir u:\Daten 2>> C:\temp\fehler.txt | Format-Table >C:\temp\prozessliste.txt

Ausgabeströme umleiten

dir u:\Daten 2>&1 | Format-Table >C:\temp\prozessliste.txt

Zu beachten: das &1 ist hier nötig, da sonst einfach in die „Datei mit Namen 1“ umgeleitet würde und nicht gewünscht in den Kanal 1!

WMI vs. CIM

Die Ausarbeitungen zu den WMI und CIM Fähigkeiten der PowerShell finden sich hier im Basics-Abschnitt meiner Ausarbeitung.

Hinweis

In den Seminaren folgen die Übungen rund um diese Techniken an späterer Stelle. Ich orientiere mich hier an meinen Erfahrungen mit den PowerShell Seminaren und den zur Verfügung gestellten Zeitrahmen.

Cmdlets:

  • Get-WmiObject und

  • Get-CimInstance

die klassische WMI (Windows Management Interface) und die „neuere“ Variante CIM (Common Information Model) bieten Zugriff auf Hunderte von Klassen mit Zugriff auf Systeminformationen und -Techniken

Get-WmiObject -Class Win32_Bios -Computername DC01

(also gleich mit eingebautem „Fernzugriff“; Übung: die anderen Cmdlets mit -ComputerName ?)

Auflistung aller WMI-Klassen mit

Get-WmiObject -List

Bei CIM nutzt man

Get-CimClass

Übungen zu den „Super-Cmdlets“ der PowerShell zur Systemanalyse:

Aufrufe und Tests zu diversen Klassen für WMI und CIM

Hinweis: bei Get-CimInstance existiert ein Parameter -Query mit SQL-Abfragen wie „SELECT * from Win32_Process WHERE name Like ‚p%‘“

Vergleich WMI vs. CIM: Blog Technet - Scripting Guy

Introduction to CIM-Cmdlets: Blog Technet: Intro to CIM

WMI und CIM Beispiele / Übungen

Suche nach WMI / CIM class name

Get-WmiObject -Class *Share* -List
Get-CimClass -ClassName *Share*

Tiefere Suche - WMI / CIM class name

Get-WmiObject -Class Win32_Share
(Get-CimClass -ClassName Win32_Share).CimClassMethods

auch mit Select-String

Get-WmiObject -List | Select-String Print

sinnvolle Class suchen: rund um Disk mit mehr als 5 Properties und nichts mit Perf

$Keyword = ‘disk’
Get-WmiObject -Class “Win32_*$Keyword*” -List |
Where-Object { $_.Properties.Count -gt 5 -and $_.Name -notlike ‘*_Perf*’ }

tatsächliche Ergebnisse dann mit

Get-WmiObject -Class Win32_DiskPartition

besonders nützliche Classes mit Hilfe Developer-Infos finden:

Select-Xml $env:windir\System32\WindowsPowerShell\v1.0\types.ps1xml -XPath /Types/Type/Name |
ForEach-Object { $_.Node.InnerXML } | Where-Object { $_ -like ‘*#root*’ } |
ForEach-Object { $_.Split(‘[\/]’)[-1] } | Sort-Object -Unique

einfach eine Klasse herauspicken

Get-WmiObject -Class Win32_BIOS

WMI Hilfen mit eigener Funktion finden lassen:

function Get-WmiHelpLocation
 1function Get-WmiHelpLocation
 2{
 3param ($WmiClassName="Win32_BIOS")
 4$Connected = [Activator]::CreateInstance([Type]::GetTypeFromCLSID([Guid]'{DCB00C01-570F-4A9B-8D69-199FDBA5723B}')).IsConnectedToInternet
 5if ($Connected)
 6{
 7$uri = "http://www.bing.com/search?q={0}+site:msdn.microsoft.com" -f $WmiClassName
 8# in  altem Skriptbeispiel stand bei Where-Object href -like noch http - dann $uri leer!
 9$url = (Invoke-WebRequest -Uri $uri -UseBasicParsing).Links | Where-Object href -like "https://msdn.microsoft.com*" | 
10    Select-Object -ExpandProperty href -First 1
11Start-Process $url
12$url
13}
14else
15{
16    Write-Warning "No Internet Connection Available."
17}
18}

Lizenz Status:

Get-WmiObject SoftwareLicensingService

Alle Namespaces auflisten:

Get-WmiObject -Query “Select * from __Namespace” -Namespace Root | Select-Object -ExpandProperty Name

Infos zu bestimmten Namespace:

Get-WmiObject -Namespace root\SecurityCenter2 -List
Get-WmiObject -Namespace root\SecurityCenter2 -Class AntivirusProduct

Aktuellen Energiemodus evaluieren:

$PowerPlan = (Get-WmiObject -Namespace root\cimv2\power -Class Win32_PowerPlan -Filter ‘isActive=True’).ElementName
“Current power plan: $PowerPlan”

Service Start Modi - Anmerkung: Get-Service kann keinen StartMode!

Get-WmiObject Win32_Service | Select-Object Name, StartMode

Ein spezieller Service-Startmodus:

([wmi]'Win32_Service.Name="Spooler"').StartMode

Eingeloggte User:

$ComputerName = ‘localhost’
Get-WmiObject Win32_ComputerSystem -ComputerName $ComputerName | Select-Object -ExpandProperty UserName

Netzwerkanalyse:

function Get-NetworkConfig
 1function Get-NetworkConfig {
 2Get-WmiObject Win32_NetworkAdapter -Filter "NetConnectionStatus=2" |
 3ForEach-Object {
 4   $result = 1 | Select-Object Name, IP, MAC
 5   $result.Name = $_.Name
 6   $result.MAC = $_.MacAddress
 7   $config = $_.GetRelated("Win32_NetworkAdapterConfiguration")
 8   $result.IP = $config | Select-Object -ExpandProperty IPAddress
 9   $result
10   }
11}
12# Aufruf:
13Get-NetworkConfig

Lokale Gruppen:

Get-WmiObject Win32_Group -Filter "domain='$env:computername'" | Select-Object Name,SID

Uptime OS:

$os = Get-WmiObject -Class Win32_OperatingSystem
$boottime = [System.Management.ManagementDateTimeConverter]::ToDateTime($os.LastBootupTime)
$timedifference = New-TimeSpan -Start $boottime
$days = $timedifference.TotalDays
'Das System läuft seit {0:0.000} Tagen.' -f $days

Freier Speicher auf Disks

Get-WmiObject Win32_LogicalDisk |
    ForEach-Object { ‘Disk {0} hat {1,20:0.00} MB Platz frei’ -f $_.Caption, ($_.FreeSpace / 1MB)
    }

Mehr Beispielcode über Unterlagen (PDFs) verfügbar.

Aliase

Aliase können Ihnen das Leben in der Konsole und den Umstieg von anderen Shells erleichtern.

Beispielhafte Voreinstellung:

ps ersetzt standardmäßig Get-process (Unix-Shell lässt grüßen)

Get-Alias
Get-Alias ps

Anzahl: 4096 Aliase möglich (mit Variable $MaximumAliasCount setzen)

Neue Aliase mit Set-Alias (neu oder überschreiben) oder New-Alias

Set-Alias procs Get-Process
New-Alias procs Get-Process

Hinweis

Wichtig: keine Parameter festlegbar - da brauchen wir später Funktionen!

Die Aliase gelten nur in der aktuellen PS-Sitzung (Host-Instanz).

Bei späterer Nutzung dann in Profile integrieren oder hier erst einmal manuell exportieren / importieren:

Export-Alias c:\meinealias.csv                   # in CSV exportieren
Export-Alias c:\meinealias.ps1 -as script        # in ps1 Skript exportieren

Laden von Aliasen:

Import-Alias c:\meinealias.csv                   # CSV importieren
. c:\meinealias.ps1                              # ps1 Skript importieren

Anm.: Punktoperator - „Dot sourcing“)

Es werden immer alle Aliase berücksichtigt - auch die Standardaliase (Systemaliase). Das führt beim Importieren zu „Meldungen“.

Es gibt auch Aliase für Parameter (siehe Datei types.ps1xml im Installordner PowerShell)

Get-Process | Format-Table ProcessName, WorkingSet -AutoSize

wird zu

Get-Process | Format-Table name, ws –AutoSize

Tipp

Aliase sollten niemals in Skripten genutzt werden, aber natürlich kann man in der eigenen Umgebung Aliase als Aufruf für fertige Skript nutzen!

Es folgen Übungen zu Aliasen - siehe auch später Nutzung in den Profilen.

ISE

Auch hier wieder die 32- und 64-Bit-Variante beachten!

Integrated Scripting Environment (ISE) ist der Name des PSHosts/Skripteditors, der mit PS 3.0 nochmals verbessert wurde.

  • Intellisense Eingabeunterstützung - vervollständigen mit Tab und Vorschläge für Komplettierungen mit Strg + Leertaste

  • Eigene Remote-Konsole

  • Copy & Paste: Hier funktionieren die Zwischenablage-Tastenkombinationen Strg + C / V

  • Hilfe zu Befehlen mit F1

  • Show-Command mit Strg + F1

ISE-Addons: (Link)

Beachten: teilweise kommerzielle Produkte; (z.B. ISESteroids - Team Schwichtenberg, Weltner)

Ausführen / Debugging:

  • Skripte ausführen mit „Debuggen Ausführen/Fortsetzen“ oder F5

  • Skriptauswahl ausführen mit F8

  • Debugging: (bei gespeicherten Skripten verfügbar)

  • Haltepunkte mit F9

mehr Informationen im Menü Debugging des ISE; Verhaltensweisen ISE:

  • keine interaktiven Tools/Programme möglich: ftp, nslookup, …

  • kein Blättern (Paging) mit more

Konfiguration

Eigene Farbgebungen in ISE mittels:

$psISE.Options.ConsolePaneBackgroundColor = "red"

oder für die Eingabe-/Ausgabe-Hintergrundfarbe:

$host.ui.RawUI.BackgroundColor = "red"

siehe auch:

$psISE.options

und

$Host.PrivateData

ISE-Einstellungen mittels Tools - Optionen bearbeiten – dort kann man auch die Standardeinstellungen wiederherstellen!

ISE Startprofilskript: Microsoft.PowerShellISE_profile.ps1

Anm.: für den aktuellen User und den ISE-Host: (Profile später eigenes Thema)

C:\Users\username\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1

Tipp (für später): Einfaches (leeres) Profil mittels PS-Befehl erstellen:

New-Item $profile -ItemType file –Force

und dann natürlich direkt mit ISE bearbeiten.

Drives und Provider

Die PowerShell ist technisch nicht nur auf das Dateisystem (FileSystem) ausgelegt, sondern kann mit allen technisch ermöglichten (engl. provided) Objekten des Systems zusammenarbeiten.

Alle aktuellen Provider des Systems anzeigen:

Get-PSProvider

Vereinheitlichte Bewegung/Navigation in unterschiedlichen Daten mittels

Get-PSDrive

Hier beispielhafte Aufrufe/Ergebnisse:

PS E:\_temp> Get-PSProvider

Name                 Capabilities                                                  Drives
----                 ------------                                                  ------
Registry             ShouldProcess, Transactions                                   {HKLM, HKCU}
Alias                ShouldProcess                                                 {Alias}
Environment          ShouldProcess                                                 {Env}
FileSystem           Filter, ShouldProcess, Credentials                            {C, E, D, R}
Function             ShouldProcess                                                 {Function}
Variable             ShouldProcess                                                 {Variable}

PS E:\_temp> Get-PSDrive

Name           Used (GB)     Free (GB) Provider      Root
----           ---------     --------- --------      ----
Alias                                  Alias
C                  93,99         23,90 FileSystem    C:\
Cert                                   Certificate   \
D                                      FileSystem    D:\
E                 808,00        104,26 FileSystem    E:\
Env                                    Environment
Function                               Function
HKCU                                   Registry      HKEY_CURRENT_USER
HKLM                                   Registry      HKEY_LOCAL_MACHINE
R                                      FileSystem    R:\
Variable                               Variable
WSMan                                  WSMan

Speziellen Provider anzeigen

Get-PSDrive -PSProvider FileSystem

Beispiel: Provider cert für Zertifikate

Set-Location cert:\CurrentUser\Root
Get-ChildItem

Bei der Registry kann man den Provider auch direkt ansprechen:

Get-ChildItem "REGISTRY::HKEY_CLASSES_ROOT\" -ErrorAction SilentlyContinue

So kommt man also auch an die Registry-Zweige jenseits von HKCU und HKLM und selbstverständlich lässt sich so auch ein eigenes PSDrive bauen.


Hier weitere Abschnitte zum Thema:

Befehle für Drives

Cmdlets zum Behandeln von Elementen in ihren Umgebungen (Laufwerken):

(Alias: pwd) Abrufen des aktuellen Standorts

Get-Location
  1. Festlegung des aktuellen Standorts

Set-Location

(gi) Holt ein Element

Get-Item

(dir, ls, gpi) Auflisten der Unterelemente

Get-ChildItem

(type, cat, gc) Abruf eines Elementinhalts

Get-Content

(sc) Elementinhalt festlegen

Set-Content

(ac) Elementinhalt ergänzen

Add-Content

(ni, mkdir, md) Erstellen eines Elements (Ast oder Blatt)

New-Item

Tipp

über –ItemType File oder –ItemType Directory den entsprechenden „Typ“ setzen und über –Force komplette Pfade erzeugen lassen!

(gp) Attribut abrufen

Get-ItemProperty

(sp) Attribut eines Elements festlegen bzw. anlegen, wenn nicht vorhanden

Set-ItemProperty

(del, ri, rmdir, rm, erase) Element löschen

Remove-Item

(move, mv) Element verschieben

Move-Item

(copy, cp, cpi) Element kopieren

Copy-Item

(rni, ren) Element umbenennen

Rename-Item

Extras:

Test-Path
Resolve-Path
Convert-Path

Tipp: Befehle suchen und auflisten lassen mit:

Get-Command –Noun *childitem, item*, path, content

Beispielhafte Aufrufe

New-Item -Path c:\temp -Name Testing -ItemType directory

Einfacher natürlich mit md (alias) und mkdir (function)

mkdir Testing

Übung:

Was ist „mkdir“? Tipp für Analyse zu mkdir: Inhalt (Content) holen (Get)…

Beispiel / Quellen für Registry:

nach Schwichtenberg (S. 183 – Beispieldatei: Einsatzgebiete/Registry/Registry_Commandlets.ps1)

Beispiele für Drives

Neues Drive erstellen:

New-PSDrive -Name Skripte -PSProvider FileSystem -Root "E:\ps-skripte"

gerne auch für Registry:

New-PSDrive -Name SoftwareUninstall -PSProvider Registry -Root HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

oder für fehlende Registry-Keys (hier HKCR):

New-PSDrive -Name HKCR -PSProvider Registry -Root "REGISTRY::HKEY_CLASSES_ROOT\"

so erhält man:

PS E:\_temp> Get-PSProvider -PSProvider Registry

Name                 Capabilities                                           Drives
----                 ------------                                           ------
Registry             ShouldProcess, Transactions                            {HKLM, HKCU, HKCR}


PS E:\_temp> Get-PSDrive -PSProvider Registry

Name           Used (GB)     Free (GB) Provider      Root
----           ---------     --------- --------      ----
HKCR                                   Registry      HKEY_CLASSES_ROOT\
HKCU                                   Registry      HKEY_CURRENT_USER
HKLM                                   Registry      HKEY_LOCAL_MACHINE

Entfernen mit

Remove-PSDrive -Name Skripte

Tipp

zur Übung für den Skriptordner ein Laufwerk erstellen!

in Laufwerk Function: arbeiten

mkdir Testing     # function!
Get-Content Function:\mkdir

Resolving Paths - Datei sollte existieren, sonst Fehler

Resolve-Path .\file.txt

Fehler unterdrücken

Resolve-Path .\file.txt -ErrorAction SilentlyContinue
Resolve-Path .\file.txt –ea 0            # Kurzform – Tipp:vermeiden

Pfad erzeugen, ob existent oder auch nicht!

$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(‘.\file.txt’)

Nur Dateien oder Ordner anzeigen lassen:

Get-ChildItem $env:windir | Where-Object { $_.PSIsContainer -eq $true }     # Directory
Get-ChildItem $env:windir | Where-Object { $_.PSIsContainer -eq $false }    # File

ab PowerShell 3.0

Get-ChildItem $env:windir -Directory
Get-ChildItem $env:windir -File

Desktop Ordner „finden“

[Environment]::GetFolderPath('Desktop')

Folder anzeigen für GetFolderPath:

[System.Enum]::GetNames([System.Environment+SpecialFolder])

das führt zu:

[Environment]::GetFolderPath('Cookies')

Übungen Drives

Diverse kleinere PowerShell-Codes zur weiteren Einstimmung.

temp Ordner aufräumen - altes Zeug (hier: 30 Tage+) entfernen:

 1$cutoff = (Get-Date) - (New-TimeSpan -Days 30)
 2$before = (Get-ChildItem $env:temp | Measure-Object Length -Sum).Sum
 3Get-ChildItem $env:temp | Where-Object { $_.Length -ne $null } |
 4    Where-Object { $_.LastWriteTime -lt $cutoff } |
 5    Remove-Item -Force -ErrorAction SilentlyContinue -Recurse -WhatIf
 6# simulation only, no files and folders will be deleted
 7# replace -WhatIf with -Confirm to confirm each delete
 8# remove -WhatIf altogether to delete without confirmation (at your own risk)
 9$after = (Get-ChildItem $env:temp | Measure-Object Length -Sum).Sum
10$freed = $before - $after
11"Cleanup freed {0:0.0} MB." -f ($freed/1MB)

Größe eines Ordners ermitteln: (hier Download)

1$folder = "$env:userprofile\Downloads"
2Get-ChildItem -Path $folder -Recurse -Force -ea 0 | Measure-Object -Property Length -Sum | ForEach-Object {
3    $sum = $_.Sum / 1MB
4        "Der Download-Ordner enthaelt derzeit {0:#,##0.0} MB storage." -f $sum
5        }

Größen Min vs. Max

1Get-ChildItem $env:windir |
2    Measure-Object -Property Length -Minimum -Maximum |
3    Select-Object -Property Minimum,Maximum

Speicherzeit alt vs. neu

1Get-ChildItem $env:windir |
2    Measure-Object -Property LastWriteTime -Minimum -Maximum |
3    Select-Object -Property Minimum,Maximum

Dateien umbenennen - Anm.: die Win8/10 Screenshots (Shortcut: Win+Druck) haben Leerzeichen!

1$global:i = 1
2$path = "$env:userprofile\Pictures\Screenshots"
3Get-ChildItem -Path $path -Filter *.png |
4    Rename-Item -NewName { "screnshot_$i.png"; $global:i++}

1GB Datei in Sekundenbruchteil

1$path = "$env:temp\testfile.txt"
2$file = [io.file]::Create($path)
3$file.SetLength(1gb)
4$file.Close()
5Get-Item $path

Alle Code-Snippets - wie immer ;-) - ohne Gewähr!

Pipelining - Objekte

Die PowerShell arbeitet objektorientiert! Der Pipeline Operator ( | Pipe) stellt mehr dar, als einfach nur die „Weitergabe“ von Objekten an das Folge-Cmdlet. Vielmehr werden durch den Pipeline-Prozessor die Daten verarbeitet und aufbereitet.

Get-Process | Format-List

komplexere Pipeline:

Get-ChildItem e:\_temp –r -filter *.txt |
    Where-Object { $_.Length -gt 40000 } |
    Select-Object Name, Length |
    Sort-Object Length |
    Format-List

Der besondere Bezeichner $_ greift auf das aktuelle Objekt zu.

Neu: $PSItem als gleichwertiger Ersatz zu $_ (seit PowerShell 3.0)

Get-Process | Where-Object {$_.name -eq "iexplore"} |
Format-Table ProcessName, WorkingSet64

Alle Prozesse, die mehr als 20 MB verbrauchen:

Get-Process | Where-Object {$_.WorkingSet64 -gt 20*1024*1024 }

kurze Variante (kann man so nur für die Befehlszeile nutzen! Stichwort: Quick and Dirty)

ps | ? {$_.ws -gt 20MB }

alle Dienste, die mit i beginnen

"i*" | Get-Service

Dienst „gleich“ BITS

"BITS" | Get-Service

Anm.: Erklärung für dieses Verhalten mit Get-Help Get-Service –full (siehe nach -name Pipelineeingaben akzeptieren byValue und byPropertyName)

Pipeline-Bilder (nach Schwichtenberg; S. 62/63; s.a. it-visions.de - Cheat Sheet)

Pipeline Schwichtenberg - ehemals auf entwickler.de Portal

Übersicht PowerShell Technik

Pipeline Technik

Auch die klassischen Befehle lassen sich pipen (Select-String für reguläre Ausdrücke)

netstat | Select-String "HERGESTELLT" -case

Hier weitere Abschnitte zum Thema:

Eigenschaften

Eigenschaft der Objekte (Property)

Anzahl von Objekten in einer Pipeline am Beispiel Get-Date (Anm.: erzeugt nur ein Objekt)

Get-Date

Eigenschaften des Objekts ansprechen: (als auch .Month, .Hour, .Minute)

(Get-Date).Year

Keine Fehlermeldungen (wie bei klassischen PowerShell 1.0 / 2.0), falls man hier mal mit einem Einzelobjekt arbeitet).

Anzahl aller Prozesse

(Get-Process).count

Anzahl von Prozessen mit mehr als 20 MB im RAM

(Get-Process | Where-Object { $_.WorkingSet64 -gt 20MB }).Count

Objekte lassen sich dann auch mit Array-Technik einzeln ansprechen:

(Get-Process | Where-Object { $_.WorkingSet64 -gt 20MB })[5]

Gegenüberstellung „alte“ PowerShells und „neue“ PowerShell:

seit PowerShell 3.0: Automatic Unrolling – automatisches Durchlaufen eines Array durch eine Schleife mit Hilfe der Punktschreibweise)

(Get-Process).Name

Entspricht den folgenden beiden Aufrufen (abwärtskompatibel dann auch zu PowerShell 2.0)

Get-Process | Select-Object Name
Get-Process | ForEach-Object {$_.Name}

Hier ein ausführlicheres Beispiel aus „Weltner, PowerShell 5, S. 337)

PS E:\_temp> $dll = Get-ChildItem -Path "C:\Windows\System32\*.dll" | Select-Object -First 3
PS E:\_temp> $dll

Verzeichnis: C:\Windows\System32

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a---l       29.10.2014     03:00        3814400 accessibilitycpl.dll
-a---l       22.08.2013     13:45          39424 ACCTRES.dll
-a---l       29.10.2014     03:43          10240 acledit.dll

# Automatic Unrolling (ab PowerShell Version 3.0)
PS E:\_temp> $dll.VersionInfo

ProductVersion   FileVersion      FileName
--------------   -----------      --------
6.3.9600.16384   6.3.9600.1638... C:\Windows\System32\accessibilitycpl.dll
6.3.9600.16384   6.3.9600.1638... C:\Windows\System32\ACCTRES.dll
6.3.9600.16384   6.3.9600.1638... C:\Windows\System32\acledit.dll

# -ExpandProperty (alle PowerShell Versionen)
PS E:\_temp> $dll | Select-Object -ExpandProperty VersionInfo

ProductVersion   FileVersion      FileName
--------------   -----------      --------
6.3.9600.16384   6.3.9600.1638... C:\Windows\System32\accessibilitycpl.dll
6.3.9600.16384   6.3.9600.1638... C:\Windows\System32\ACCTRES.dll
6.3.9600.16384   6.3.9600.1638... C:\Windows\System32\acledit.dll

# Foreach-Object (alle PowerShell Versionen)
PS E:\_temp> $dll | ForEach-Object { $_.VersionInfo }

ProductVersion   FileVersion      FileName
--------------   -----------      --------
6.3.9600.16384   6.3.9600.1638... C:\Windows\System32\accessibilitycpl.dll
6.3.9600.16384   6.3.9600.1638... C:\Windows\System32\ACCTRES.dll
6.3.9600.16384   6.3.9600.1638... C:\Windows\System32\acledit.dll

Hinweis

Pfadübergabe hier in der ersten Konsolenzeile für den Pfad mit sauberer Testkette (String), damit das Syntaxhighlighting zufrieden ist. In der täglichen Praxis gerne auch ohne Quotes / Anführungszeichen, wenn der String ohne Leerzeichen!

Eine Analyse über vorhandene Eigenschaften/Methoden kann man über die unterschiedlichen Analysen mittels

$dll | Get-Member   # hier sieht man VersionInfo / ScriptProperty – nach der Pipeline!

im Vergleich mit

Get-Member –InputObject $dll   # Get-Member kennt kein VersionInfo

herausfinden.

Ergebnis: das Pipelining macht den Unterschied und beeinflusst auch die Technik der Codevervollständigung in der PowerShell Befehlszeile!

Für eine kombinierte Ausgabe benötigen wir immer die Pipeline-Technik:

Get-Process | Foreach-Object {$_.Name + ": " + $_.Workingset64 }

Methoden

Methode der Objekte (Method)

Hier also, was unsere Objekte „können“ (Funktionen, Methoden):

Get-Process iexplore | Foreach-Object { $_.Kill() }

seit PowerShell 3.0:

(Get-Process iexplore).Kill()

besseres Commandlet: Stop-Process (hier gibt es auch keine Fehler mehr, falls kein iexplore Prozess)

Get-Process | Where-Object { $_.Name -eq "iexplore" } | Stop-Process

Beispielmethoden für Get-Date - alle Methoden für Get-Date anzeigen lassen:

Get-Date | Get-Member

Analyse ergibt Methode ToLongDateString() (und viele Andere)

(Get-Date).ToLongDateString()

Analyse-Tools

Diverse Möglichkeiten zur Analyse: GetType(), Get-Member (Beispiel: Get-Process | Get-Member)

Anm.: wirklich alle Methoden anzeigen lassen (getter, setter) mit -force

Tool Get-PipelineInfo (aus den PS Extensions von it-visions.de); Anm.: registrierter Download!

Sicht einer Klasse:

  1. Method (Methode)

  2. Property (Eigenschaft)

  3. PropertySet (Eigenschaftssatz)

  4. NoteProperty (Notizeigenschaft)

  5. ScriptProperty (Skripteigenschaft)

  6. CodeProperty (Codeeigenschaft)

  7. AliasProperty (Aliaseigenschaft)

Übung / Vergleiche:

Get-Process | Get-Member -Membertype Properties
Get-Process | Get-Member -Membertype Property
Get-Process | Get-Member -Membertype Method
Get-Process | Get-Member *set*
Get-Process | Get-Member *name*

Speziell für die PowerShell (gibt es so nicht bei .NET):

Eigenschaftssätze (PropertySet - siehe Definitionen wieder in types.ps1xml in $PSHOME)

Get-Process | Select-Object psResources | Format-Table

Profithema: Pipeline-Analyse

Anm.: hier nur als Vervollständigung/Begleitung zur Literatur „Weltner oder Schwichtenberg“.

Weitere Analysemöglichkeit beim Pipelining:

Trace-Command -Name ParameterBinding -PSHost
    -Expression { Get-Childitem E:\_temp -filter *.txt | select -First 1 | Get-Content }

Die Ausgabezeilen zeigen das Binding.

Systemklassen

Get-Member kann dann auch helfen Zusammenhang von Cmdlets mit Systemklassen herzustellen:

Analyse / Vorbereitungen:

[System.Diagnostics.Process] | Get-Member
[DateTime] | Get-Member

Vergleiche dann bei Prozessen:

[System.Diagnostics.Process]::GetProcesses() | Sort-Object ProcessName      # mit Get-Process

und bei System-Datum-/Uhrzeit:

[DateTime]::Now
Get-Date        # erstaunlich nicht!?

Beispiele - Übungen

Praxisbeispiele zum Pipelining und diversen Ausgaben

  • Schwichtenberg PowerShell 4 - Kapitel 5 ab S. 59

  • Weltner PowerShell 5…

  • Sammlung „scriptlines“ Trainer J. Brandes

Filtern /Sortieren und Co

Ein paar erste einfache Beispiele - Prozesse, der Speicher größer als 10000000 Bytes

Get-Process | Where-Object {$_.ws -gt 10000000 }

Inklusive Sortierung und Auswahl der Ergebnissätze

Get-Process | Sort-Object ws -desc | Select-Object -first 5
Get-Process | Sort-Object ws -desc | Select-Object -last 5

Insbesondere bei der Nutzung der Regulären Ausdrücke (Regular Expression - Signalwort „match“) kratzen die folgenden Beispiele natürlich nur an der Oberfläche!

Links: Wikipedia, Microsoft

Systemdienste, deren Beschreibung aus zwei durch ein Leerzeichen getrennten Wörtern besteht.

Get-Service | Where-Object { $_.DisplayName -match "^\w* \w*$" }

Prozesse, deren Namen mit einem „i“ starten und danach drei Buchstaben

Get-Process | Where-Object { $_.ProcessName -match "^i\w{3}$" }

Hier weitere Abschnitte zum Thema:

Vergleichsoperatoren

(engl. Comparison Operators)

Hilfe: about_Comparison_Operators (oder natürlich online im MS Technet)

oder aber:

Get-Help about_Comparison_Operators

Übersicht:

  • -eq

  • -ne

  • -gt

  • -ge

  • -lt

  • -le

  • -Like

  • -NotLike

  • -Match

  • -Not Match

  • -Contains

  • -NotContains

  • -In

  • -NotIn

  • -Replace

klassische Filter:

Get-Service | Where-Object { $_.status -eq "running" }

können seit PowerShell 3.0 auch mit folgender Kurzschreibweise ermittelt werden

Get-Service | Where-Object status -eq "running"

aber bei Kombinationen mit and oder o*r* bitte wieder klassische, lange Schreibweisen

Get-Process | Where-Object { $_.Name -eq "iexplore" -or $_.name -eq "Chrome" -or $_.name -eq "Firefox" } | Stop-Process
Get-Service | Where-Object { $_.status -eq "running" -and $_.name -like "a*" }

Filter-/Sortier-Beispiele

Weitere Beispiel für Filtern/Sortieren…

Objekte für Ausgaben einschränken (“kastrieren“)

Get-Process | Select-Object processname, get_minworkingset, ws | Get-Member
Prozesse nach Speicherverbrauch sortieren
Get-Process | Sort-Object ws –desc

Mehrere Sortierfelder

Get-Service | Sort-Object Status, Displayname

Mehrfach vorkommende Elemente finden - man muss immer erst sortieren!

1,5,7,8,5,7 | Sort-Object | Get-Unique

Elemente gruppieren

Get-Service | Group-Object status

Dateien in C:WindowsSystem32 nach Erweiterungen gruppieren und sortiert ausgeben:

Get-ChildItem c:\windows\system32 | Group-Object extension | Sort-Object count –desc
Get-ChildItem c:\windows\system32 | Select-Object extension -Unique

Einsatz von Bool

Get-Childitem c:\Windows | Where { !$_.PsIsContainer } | Group-Object { $_.Length -gt 1MB}

Auswertungen mit Measure-Object - Standard ist count (also: Anzahl)

Get-ChildItem c:\windows | Measure-Object -Property length -min -max -average -sum

Variablen interaktiv

… also interaktiv in der PowerShell Konsole.

Einsatz von Variablen: Übersichtlichkeit schaffen - Vorarbeiten für Skripting

Get-Process | Where-Object {$_.name -eq "iexplore"} | Foreach-Object { $_.ws }

wird zu

$x = Get-Process
$y = $x | Where-Object {$_.name -eq "iexplore"}
$z = $y | Foreach-Object { $_.ws }

Ausgabe dann mit $z!

Anm. zu Prozessen ab Windows 10: bitte beachten, dass man zwei Microsoft Browser hat (Internet Explorer und Edge).

Verzweigungen („Tee“)

Verzweigungen mittels Tee-Object zu Variablen oder Dateien: Es wird eine Variable $a erstellt (Achtung: hier beim Teeing ohne $) und eine Datei dienste.txt erstellt.

Get-Service | Tee-Object -var a | Where-Object { $_.Status -eq "Running" } | select name | Tee-Object -filepath E:\_temp\dienste.txt | Format-Table name

alternative Lösung:

Get-Service -OutVariable a | Where-Object { $_.Status -eq "Running" } | select name |
    Set-Content E:\_temp\dienste.txt -PassThru | Format-Table name

Parameter -PipelineVariable

Der mit PowerShell-Version 4.0 eingeführte allgemeine Parameter –PipelineVariable (z.B. Quelle: Schwichtenberg S. 92ff) (kurz: -pv) sorgt dafür, dass das jeweils aktuelle Objekt nicht nur in der Pipeline weitergereicht wird, sondern zusätzlich auch in einer Variablen abgelegt wird.

Das folgende Beispiel setzt dies ein, um am Ende eine Liste von Ausgaben aus zwei verschiedenen Objekten zu liefern: den Namen und das Workingset eines Prozesses von Get-Process und den Namen und den zugehörigen Security Identifier des Benutzers, unter dem der Prozess läuft. Die Pipeline beginnt mit dem Holen der laufenden Prozesse unter Einbeziehung der Benutzeridentität, die in der Form „DomäneBenutzername“ geliefert wird. Dabei wird das aktuelle Process-Objekt mit –pv auch in der Variablen $p abgelegt. Im zweiten Schritt wird für den Benutzernamen das zugehörige WMI-Objekt Win32_User geholt. Im dritten Pipeline-Schritt werden dann zuerst die zwei Informationen aus dem Process- Objekt ausgegeben (das sich in $p befindet) sowie die Informationen aus dem Win32_User-Objekt, die sich nun in der Pipeline befinden ($_).

Get-Process -IncludeUserName -pv p |
    % { Get-WmiObject win32_useraccount –filter "name='$(($_.username -split "\\")[1])'" } |
    % { $p.name + ":" + $p.ws + ":" + $_.Name + ";" + $_.SID }

ACHTUNG: Der Parameter –PipelineVariable funktioniert nicht wie gewünscht, wenn Cmdlets in der Pipeline sind, die die Ergebnisse puffern (z. B. Sort-Object, Group-Object), da der Parameter –PipelineVariable sich ja immer nur auf das aktuelle Objekt bezieht, was in diesen Fällen also immer das letzte Objekt ist.

Objekte vergleichen

Szenario: Vergleich mit Process-Objekten „vorher“ vs. „nachher“

$Pre = Get-Process

Jetzt/Hier Programme/Prozesse starten/beenden

$Post = Get-Process
Compare-Object $Pre $Post

Beispielhaftes Ergebnis:

PS E:\_temp> $pre = Get-Process
PS E:\_temp> $post = Get-Process
PS E:\_temp> Compare-Object $pre $post

InputObject                                 SideIndicator
-----------                                 -------------
System.Diagnostics.Process (powershell_ise) =>
System.Diagnostics.Process (taskeng)        =>
System.Diagnostics.Process (notepad++)      <=

Die Objekte sollten von gleichem Typ sein!

Skripte 101

Skriptausführung sollte mit Level RemoteSigned erlaubt sein! Eine „neue“ PowerShell auf Windows-Systemen hat Level Restricted u nd lässt somit keine Ausführungen von Skripten zu.

Cmdlets: Get-ExecutionPolicy und Set-ExecutionPolicy (Setzen nur als Admin!)

Dateiformat (Dateiendung): *.ps1

Das erste Skript (nach Schwichtenberg PowerShell 4S.96)

Erstes Skript
1# Mein erstes Skript
2"Informationen über diesen Computer:"
3"Datum: " + (Get-Date).ToShortDateString()
4"Zeit: " + (Get-Date).ToLongTimeString()
5"Anzahl laufender Prozesse: " + (Get-Process).Count
6"Anzahl gestarteter Dienste: " + (Get-Service | where { $_.Status -eq "running" } ).Count

Zeichenkodierungen beachten: z.B. Notepad++ mit UTF (ohne BOM) vs. ANSI (mit Notepad, ISE, und Co)


Hier weitere Abschnitte zum Thema:

Skripte starten

Starten von Skripten mittels:

  • .skript.ps1 (ps1 Endung mit PowerShell „associated“?)

  • &.skript.ps1

  • Invoke-Expression .skript.ps1

  • powershell.exe –File .skript.ps1

  • . .skript.ps1 (Dot-sourcing - Aufrufen/Binden von Skripten mit dem „.“)

so lassen sich auch Zentral-Skripte mit Filial-Skripten bauen:

  • . („H:demoPowerShellBenutzerLocaluser_Create.ps1“)

  • . („H:demoPowerShellBenutzerLocalGroup.ps1“)

  • . („H:demoPowerShellBenutzerLocaluser_Delete.ps1“)s

Auch direkte Aufrufe mit powershell.exe g:\pfad\skript.ps1

Skripte lassen sich mit Alias zuweisen und dann aufrufen:

Set-Alias Get-ComputerInfo C:\temp\Skript.ps1

Tipp: externer Aufruf für PowerShell Skript (z.B. als Scheduled Task oder über Shortcut)

die lokalen Profile beim Aufruf aus dem Spiel nehmen:

powershell.exe –NoProfile –File E:\psskripte\myscript.ps1

Anm.: die $PROFILE-Dateien (Mehrzahl!) quasi Autoexec.bat für PowerShell

Tipp

Aufrufe für PowerShell.exe /? analysieren – siehe auch: -ExecutionPolicy Bypass

Parameter

Parameter an Skripte übergeben

  • per args[] (bei 0 beginnend) oder

  • param[] (Deklarationen am Anfang des Skripts)

Ergibt folgende Skriptzeilen für die Parameterübergaben

"Informationen über den Computer: " + $args[0]

und per Definitionen am Skriptbeginn (wie auch später bei Funktionen empfohlen)

param([string] $Computer)
"Informationen über den Computer: " + $Computer

Skripte pausieren lassen

# 10 Millisekunden:
Start-Sleep -m 10
# 10 Sekunden:
Start-Sleep -s 10

Hilfe zu PS-Befehlen und Syntax zu Skriptkonstruktionen siehe

Kommentare

mit # hinter Befehlen oder bei jedem Zeilenanfang - Seit PowerShell 2.0 auch gerne über mehrere Zeilen

<#
-----------------------------------
Ihr mehrzeiliger Kommentar
-----------------------------------
#>

Variablen

nicht erlaubt $_ (klar!) oder auch PSItem

Cmdlets:

  • Set-Variable und

  • Get-Variable sowie

  • Clear-Variable

Variablen Read-Only:

Set-Variable variablenname -Option readonly

Typisierungen: [int], [string], [byte], [char], [bool], …

Vordefinierte Variablen:

$true, $false, $Home, $PSHome, $host, …

mit z.B. $host.UI.RawUI.BackgroundColor = „darkgreen“

Skript Sicherheit

und wieder die Standard-Cmdlets:

Get-ExecutionPolicy und Set-ExecutionPolicy (als Admin!)

Registrierungseditor

Registrierungseditor

Sicherheitslevel: Restricted, RemoteSigned, AllSigned, Unrestricted

HKEY_CURRENT_USER\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell\ExecutionPolicy

mittels Set-ExecutionPolicy:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell\ExceutionPolicy

Skripte Signieren

Gute Anleitung mit aktuellen Werkzeugen der PowerShell 5

  • bei „Weltner , PowerShell 5“ (S. 210 ff.)

  • oder Schwichtenberg PowerShell 5 (S . 110 ff.)

Modifiziertes, aktualisiertes Basis-Cmdlet:

(voller Funktionsumfang ab Windows 10 bzw. Windows Server 2016; die Versionen unter Windows 8 und Windows Server 2012 R2 sehr eingeschränkt nutzbar)

New-SelfSignedCertificate    # Erstellen Selbstsignierter Zertifikate ab Win 10 bzw. 2016!

Alternativ gab/gibt es natürlich das Kommandozeilentool makecert.exe (aber: als deprecated bezeichnet).

Man kann auch die Funktion New-SelfSignedCertificateEx aus dem Microsoft Skript Center bereitstellen:

Download-Seite

Exemplarische Vorgehensweise(n): (getestet unter Windows 10 Pro)

Ausführlich: Weltner, PowerShell 5, Kapitel 5: Skripte einsetzen; Skripte digital signieren S. 210 ff.

In Kürze: Schwichtenberg S. 110 ff.

New-SelfSignedCertificate -CertStoreLocation "CERT:\Currentuser\MY" -Subject "CN=IhrNameCodeSigning" -TextExtension “2.5.29.37={text}1.3.6.1.5.5.7.3.3”
dir cert:/currentuser/my                                  # Anzeigen lassen
$cert = @(dir “cert:/currentuser/my/”)[0]                 # Zertifikat auswählen
Set-AuthenticodeSignature Softwareinventar3.ps1 $cert     # signieren

Zu beachten: die Zertifikate im CERT:CurrentUserMy gehören nicht zu den vertrauenswürdigen Zertifikaten. So erklären sich auch Fehlermeldungen, die man einfach per Kopieren der selbst ausgestellten Zertifikate „beheben“ kann. Im Firmenumfeld benötigt man hier natürlich andere Zertifkate und Vorgehensweisen.

PFX-Werkzeuge für Zertifikate: (siehe Signatur-Dateien im PFX-Format)

PS E:\_temp> Get-Command *pfxcert*
CommandType     Name                                    Version    Source
-----------     ----                                    -------    ------
Cmdlet          Export-PfxCertificate                   1.0.0.0    PKI
Cmdlet          Get-PfxCertificate                      3.0.0.0    Microsoft.PowerShell.Security
Cmdlet          Import-PfxCertificate                   1.0.0.0    PKI

PS E:\_temp> Get-Command *codesignature*

CommandType     Name                                    Version    Source
-----------     ----                                    -------    ------
Cmdlet          Get-AuthenticodeSignature               3.0.0.0    Microsoft.PowerShell.Security
Cmdlet          Set-AuthenticodeSignature               3.0.0.0    Microsoft.PowerShell.Security

Nochmals: leider unterscheiden sich die Werkzeuge und Ihre Fähigkeiten auf unterschiedlichen OS-Plattformen!

Profile

Sowohl die PowerShell als auch die ISE besitzen Profile (Profildateien / Konfigurationen)

Anzeigen der Profile jeweils (also je Host!) mit $PROFILE

PS E:\_temp> $PROFILE
C:\Users\joebr_000\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

in der ISE dann ebenfalls $PROFILE mit

PS E:\_temp> $profile
C:\Users\joebr_000\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1

Erstellen der Profile jeweils mit

New-Item $PROFILE -ItemType file –Force

Bearbeiten der Profile möglich mit

ise $PROFILE

Diese Profile sind für den jeweiligen Benutzer (CurrentUser) und die jeweilige PowerShell-Konsole (CurrentHost) gedacht.

Es gibt aber auch andere Profile – (Hosts: PowerShell bzw ISE):

PS C:\Users\joeb> $PROFILE
C:\Users\joeb\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

PS C:\Users\joeb> $PROFILE.CurrentUserCurrentHost
C:\Users\joeb\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

PS C:\Users\joeb> $PROFILE.CurrentUserAllHosts
C:\Users\joeb\Documents\WindowsPowerShell\profile.ps1

PS C:\Users\joeb> $PROFILE.AllUsersCurrentHost
C:\Windows\System32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1

PS C:\Users\joeb> $PROFILE.AllUsersAllHosts
C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1

Dieselben Aufrufe in der ISE ergeben die entsprechenden Profile-Dateien/Pfade für den ISE-Host!

Tabelle: PowerShell Profile - Übersicht

Übersicht PowerShell Profile

Übersicht PowerShell Profile

(siehe auch Literatur: Übersicht Schwichtenberg „PowerShell 5.0 – Praxisbuch“; Seite 506)

Übungen zu den PowerShell Profilen ziehen sich als Roter Faden durch die Seminare mit der PowerShell.


Hier weitere Abschnitte zum Thema:

Erste Übung

mit dem Standardprofil $PROFILE:

  • einstellen von Basisordner bei PowerShell–Start mit Cmdlet Set-Location und

  • setzen eines Alias procs für Get-Process

Lösung:

Set-Location $env:TEMP
Set-Alias procs Get-Process

Später mehr zu den Profilen und dem praktischen Einsatz in den unterschiedlichen System- und Benutzerumgebungen.

Profil erweitern

Erinnerung, falls wir noch keine Profilumgebung besitzen: (siehe Test-Path $PROFILE)

Schnell eine Profildatei für den aktuellen User (CurrentUser) und den aktuellen Host (CurrentHost; also PowerShell Konsole oder ISE) erstellen:

New-Item $PROFILE -ItemType file –Force                 # bzw. noch genauer:
New-Item $PROFILE.CurrentUserCurrentHost -ItemType file –Force

Eine kleine Beispiel-Profildatei mit:

  • Anpassungen Titelleister von Host Console

  • Alias für notepad++

  • Funktion cdd (Change Directory with Dialog)

Profilbeispiel
 1# Beispiel Profildatei $PROFILE
 2# Title der Shell einstellen - nach Schwichtenberg
 3$WI = [System.Security.Principal.WindowsIdentity]::GetCurrent()
 4$WP = New-Object System.Security.Principal.WindowsPrincipal($wi)
 5if ($WP.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))
 6{
 7 $Status = "[elevated user]"
 8}
 9else
10{
11 $Status = "[normal User]"
12}
13
14$Host.UI.RawUI.WindowTitle  = "PowerShell - " + [System.Environment]::UserName  + " " + $Status 
15
16# Beispielalias
17Set-Alias np++ 'C:\Program Files (x86)\Notepad++\notepad++.exe'
18
19# Beispielfunktion cdd - Change Dir with Dialog
20function cdd {
21$shell = New-Object -comObject "Shell.Application"
22$options = 0x51 # Nur Dateisystem-Ordner - inklusive Edit-Box
23$loc = $shell.BrowseForFolder(0, "Wohin soll es gehen?", $options)
24if($loc) {Set-Location $loc.Self.Path}
25}

Hier lassen sich jetzt beliebig die Techniken der PowerShell (Aliase, Provider/Drives, Funktionen) integrieren.

Ausdrücke (Expressions)

Ausdrücke stellen bei jeder „Shell-/Skript-Technik“ eine genau spezifizierte technische Umsetzung dar. Ein grundsätzliches Verständnis ist sinnvoll, damit spätere Fragen wie „Muss da jetzt eine Klammer gesetzt werden?“ einfach eingeschätzt und sinnvoll umgesetzt werden können.

Expression Mode

10* (8 + 6)
"Hello "+ " " + "World"

Command Mode

Write-Output 10* (8 + 6)

vergleichen mit

Write-Output (10* (8 + 6))

Bei Verschachtelungen helfen Subexpressions; Aufrufbeispiel:

"Anzahl der laufenden Prozesse: (Get-Process).Count"

vergleichen mit:

"Anzahl der laufenden Prozesse: $((Get-Process).Count)"

Anm.: das Dollarzeichen $ leitet Subexpression (Unterausdruck) ein und gibt somit die berechnete Anzahl aus!

Datentypen

Die PowerShell verfügt über eine schier endlose Anzahl von Datentypen zu den verschiedensten Techniken.

Wir konzentrieren uns hier auf die Klassiker für eine saubere Nutzung in Konsole und Skripts.


Hier weitere Abschnitte zum Thema:

Zahlen - Zeichen

Ein paar kleine Beispiele

2+3
2..5

Zahlen einfach implizit zuweisen mit

$i = ...
$i.GetType().Name
$i.GetType().FullName

Rundung

18 / 5
# 3,6
[Int](18/5)
# 4

Type holen

$a = 1
$a.GetType().FullName
# System.Int32
$a = 1.87
$a.GetType().FullName
# System.Double
$a = 623876378232
$a.GetType().FullName
# System.Int64
$a = ‘Hello’
$a.GetType().FullName
# System.String
$a = Get-Date
$a.GetType().FullName
# System.DateTime

Zahlen - Int

[Int32]::MaxValue
# 2147483647
[UInt32]::MaxValue
# 4294967295
[Int32]::MinValue
# -2147483648
[UInt32]::MinValue
# 0

Zeichen - Charakter

[Char]65
# A
[Byte][Char]’A’
# 65
[Byte[]][Char[]]’Hello’
# 72
#101
#108
#108
#111

[Char[]](65..90)
[Char[]]'Hello'
[Byte[]][Char[]]'Hello'

Datum / Uhrzeit

Ein paar kleine Beispiele…

Get-Date
Get-Date -displayhint date
Get-Date -displayhint time

$a = Get-Date "8/1/1972 12:11:10"
$a.DayOfWeek                  # Saturday
Get-Date $a –Format dddd      # Samstag

$Dauer = New-TimeSpan -Days 10 -hours 4 -minutes 3 -seconds 50
$jetzt = Get-Date
$zukunft = $jetzt + $Dauer

Systemzeit setzen mit Set-Date (bei entsprechenden Berechtigungen).

EventLog aus den letzten 12 Stunden

Get-EventLog -LogName System -EntryType Error -After (Get-Date).AddHours(-12)

Was kann Get-Date?

Get-Date | Get-Member -MemberType *Method
# Methode nutzen
(Get-Date).ToShortDateString()

Zeitspanne berechnen

[TimeSpan]5d

DateTime - statische Methoden

[DateTime]::DaysInMonth(2014, 2)
# 28
[DateTime]::DaysInMonth(2016, 2)
# 29

Installzeit (als Unix-Timestamp)

$Path = 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion'
Get-ItemProperty -Path $Path | Select-Object -ExpandProperty InstallDate

Funktionsbeispiel für Umrechnung in Echte Zeit: datetime_cookbook.pdf von Weltner:

function ConvertFrom-UnixTime
 1function ConvertFrom-UnixTime {
 2    param(
 3        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
 4        [Int32]
 5        $UnixTime
 6    )
 7    begin {
 8        # $startdate = Get-Date –Date 01.01.1970            # "01/01/1970"
 9        $startdate = Get-Date -Year 1970 -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0
10    }
11    process {
12        $timespan = New-TimeSpan -Seconds $UnixTime
13        startdate + $timespan
14    }
15}

Jetzt in echter Zeit:

$Path = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion"
Get-ItemProperty -Path $Path | Select-Object -ExpandProperty InstallDate |
    ConvertFrom-UnixTime

Installzeit in vergangenen Tagen

$Path = 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion'
Get-ItemProperty -Path $Path | Select-Object -ExpandProperty InstallDate |
    ConvertFrom-UnixTime | New-TimeSpan | Select-Object -ExpandProperty Days

Zeitzonen

[System.TimeZoneInfo]::GetSystemTimeZones()
[System.TimeZoneInfo]::Local
([System.TimeZoneInfo]::Local).StandardName

Lokalisierte Zeitinfos

[System.Enum]::GetNames([System.DayOfWeek])
# deutsch
0..6 | ForEach-Object { [Globalization.DatetimeFormatInfo]::CurrentInfo.DayNames[$_] }
0..11 | ForEach-Object { [Globalization.DatetimeFormatInfo]::CurrentInfo.MonthNames[$_] }

Verfügbare Culture IDs

[System.Globalization.CultureInfo]::GetCultures(‘InstalledWin32Cultures’)
# Übersetzen der IETF Language Tags
[System.Globalization.CultureInfo]::GetCultureInfoByIetfLanguageTag(‘de-DE’)

Spielerei - Lunch Time für die Titelzeile der Konsole!

function prompt
 1function prompt {
 2    $lunchtime = Get-Date -Hour 12 -Minute 30
 3    $timespan = New-TimeSpan -End $lunchtime
 4    [Int]$minutes = $timespan.TotalMinutes
 5    switch ($minutes) {
 6        { $_ -lt 0 } { $text = "Lunch is over. {0}"; continue }
 7        { $_ -lt 3 } { $text = "Prepare for lunch! {0}" }
 8    default { $text = "{1} minutes to go... {0}" }
 9    }
10    "PS> "
11    $Host.UI.RawUI.WindowTitle = $text -f (Get-Location), $minutes
12    if ($minutes -lt 3) { [System.Console]::Beep() }
13}

Noch eine Spielerei mit Uhrzeit in Konsole

function Add-Clock
 1function Add-Clock {
 2    $code = {
 3    $pattern = "\d{2}:\d{2}:\d{2}"
 4    do {
 5        $clock = Get-Date -Format "HH:mm:ss"
 6        $oldtitle = [system.console]::Title
 7        if ($oldtitle -match $pattern) {
 8            $newtitle = $oldtitle -replace $pattern, $clock
 9            } else {
10                $newtitle = "$clock $oldtitle"
11                }
12            [System.Console]::Title = $newtitle
13            Start-Sleep -Seconds 1
14        } while ($true)
15    }
16    $ps = [PowerShell]::Create()
17    $null = $ps.AddScript($code)
18    $ps.BeginInvoke()
19}
20
21# Aufrufen
22Add-Clock
23# auch gerne wieder
24$null = Add-Clock

Spezielle Daten

[System.Net.Mail.MailAddress]‘Some User<some.person@somewhere.com>‘

Hier mal beispielhaft ein Link zur Dokumentation dieser Klasse im Namespace System: https://msdn.microsoft.com/de-de/library/system.net.mail.mailaddress.aspx

Sortieren mit Typen

1,10,3,2 | Sort-Object
# 1
# 2
# 3
# 10
'1','10','3','2' | Sort-Object
# 1
# 10
# 2
# 3
# type conversion:
'1','10','3','2' | Sort-Object -Property { [Double]$_ }
# 1
# 2
# 3
# 10

Konvertieren

$binary = ‘1110111000010001’
[System.Convert]::ToInt64($binary, 2)
# 60945

0xFFFF
# 65535

Methode Großschreibung (und : entfernen)

$DriveList = 'a', 'b:', 'd', 'Z', 'x:'
$DriveList | ForEach-Object { $_.ToUpper()[0] } | Sort-Object

Zufallszahlen:

Get-Random -Min 100 -Max 200  # ehemals aus den PSCX - jetzt PS Utility

oder mit .NET-Klasse System.Random

$rnd = New-Object System.Random
$zufallszahl = $rnd.next(100)+100
$zufallszahl

Finde Statische Methoden

# [DateTime]::
[DateTime] | Get-Member -Static
[DateTime]::IsLeapYear(2012)

Statische Eigenschaften nutzen

[System.Environment] | Get-Member -Static -MemberType *property
[System.Environment]::SystemDirectory
[System.Environment]::OSVersion
[System.Environment]::OSVersion.ServicePack    # Null ab Windows 8
[System.Environment]::OSVersion.Version
[System.Environment]::Is64BitOperatingSystem
[System.Environment]::MachineName

Dot.Net-Link

[System.Enum]::GetNames([System.Environment+SpecialFolder])
[System.Environment]::GetFolderPath(‘CommonMusic’)

[System.Net.Dns]::GetHostByName(‘microsoft.com’)

Runtime Dir

[System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory()

Windows Updates auflisten – hier mit COM-Objekt (Link MS COM)

Updates mit COM-Objekt
1$Session = New-Object -ComObject Microsoft.Update.Session
2$Searcher = $Session.CreateUpdateSearcher()
3$HistoryCount = $Searcher.GetTotalHistoryCount()
4if ( $HistoryCount -gt 0)
5{
6    $Searcher.QueryHistory(1,$HistoryCount) |
7    Select-Object Date, Title, Description
8}

Moderne Alternative: Modul PSWindowsUpdate mit passenden Cmdlets

Nützliche .Net Types auflisten – deutlich mehr als array, byte, char, datetime, double und Co

$typename = ‘System.Management.Automation.TypeAccelerators’
$shortcut = [PSObject].Assembly.GetType($typename)::Get
$shortcut.Keys | Sort-Object | ForEach-Object { “[$_]” }

Here-String (über mehrere Zeilen - lange Texte)

#Here-String
@'
Eine lange Zeile
kann in spezielle
Begrenzer
verpackt werden
'@

Variablen funktionieren auch in Zeichenketten (doppelte Anführungszeichen) $ macht Ausdruck klar - nicht bei einfachen Limitern! Also wie bei PHP und Co Skripten

"1+3 = $(1+3)"
"Aktuelle Uhrzeit: $((Get-Date).ToShortTimeString())"
# vergleichen mit
"Anzahl der laufenden Prozesse: $((Get-Process).Count)"

Escape-Sequenzen - Sonderzeichen

  • ( Gravis a) Ton (Beep)

  • ( Gravis b) Backspace

  • ( Gravis f) Form Feed (für Drucker)

  • ( Gravis n) New Line

  • ( Gravis r) Carriage Return

  • ( Gravis r Gravis n) Carriage Return und New Line

  • ( Gravis t) Tabulator

Erste Ausgaben mit Write-Host: (mehr dann bei Ausgabetechnik)

# Das "Echo" für die PS: Write-Host
Write-Host "Guckst Du" -ForegroundColor Yellow

Zeichenketten Operationen (Methoden) ermitteln:

"" | Get-Member -m Method

Übung zu Datentyp

Anm.: Übungen / Beispiele ab Schwichtenberg S. 119 (Split / Join)

CSV mit der PowerShell
1[String] $CSVString = "Joe;Brandes;Braunschweig;Deutschland;seminare.firma.de"
2$CSVArray = $CSVString.Split(";")
3$Surname = $CSVArray[1]
4$Surname

Diese und weitere Beispiele auch in der PowerShell-Seminar-scriptlines-yyyymmdd.ps1 Datei für die Seminare und Teilnehmer.

Arrays

Eine wichtige Technik zum Verarbeiten von Daten (siehe auch Datensätzen) mit der PowerShell.

Array definieren

$a = 01,08,72,13,04,76

Das Array kann auch explizit mit [array] deklariert werden:

[array] $b
$b = 01,08,72,13,04,76
$b.Count

Letztes Element: benutze -1:

$myArray[-1]

Neues Element mit +=:

$myArray += 'new element'

Array Inhalte checken

'Peter', 'Mary', 'Martin' -contains 'Mary'
True
'Peter', 'Mary', 'Martin' -contains 'Ma*'
False
'Peter', 'Mary', 'Martin' -like 'Ma*'
Mary
Martin
@('Peter', 'Mary', 'Martin' -like 'Ma*').Count -gt 0
True

Array of Strings

'hostname' * 50
# vergleiche mit
@('hostname') * 50
Array reverse
$a = 1,2,3,4
[array]::Reverse($a)
$a

assoziatives Array

# Implicit Hashtable
$Computers = @{ E01 = "192.168.1.10"; E02 = "192.168.1.20"; E03 = "192.168.1.30"; }
# Explicit Hashtable
[Hashtable] $Computers = @{ E01 = "192.168.1.10";
E02 = "192.168.1.20"; E03 = "192.168.1.30"; }

Ausgaben

$Computers["E02"]
$Computers.E02

Hash für Nutzung in Cmdlets

$age = @{
    Name='Alter'
    Expression={ (New-TimeSpan $_.LastWriteTime).Days }
}

Get-ChildItem $env:windir | Select-Object Name, $age, Length -First 4
Get-ChildItem $env:windir | Select-Object Name, $age, Length |
    Where-Object { $_.Alter -lt 5 }

Hash bauen und Element entfernen

$myHash = @{}
$myHash.Name = 'Joe'
$myHash.ID = 12
$myHash.Location = 'Braunschweig'
$myHash
# remove
$myHash.Remove('Location')
$myHash

Hier weitere Abschnitte zum Thema:

XML-Special

XML für TN aus dem Netz beziehen:

Invoke-WebRequest -Uri http://www.welt.de/sport/fussball/?service=Rss -OutFile "welt_blog.xml"
# sauberes XML erzeugen
$xml = [xml](Get-Content welt_blog.xml)
# Testaufrufe für XML-Nutzung
$xml
$xml.rss
($xml.rss.channel.item).Count
($xml.rss.channel.item)[0]

Bitte nicht von den fehlerhaften Umlauten/Sonderzeichen irritieren lassen!

Wenn man sich die Original-XML-Datei in einem geeigneten Tool (z.B. Notepad++) anzeigen lässt, sieht man die deutschen Sonderzeichen und Umlaute sauber dargestellt!

Operatoren

Literatur: Schwichtenberg ab S. 132ff oder online https://technet.microsoft.com/de-de/library/hh847732.aspx

Anm.: Vergleichsoperatoren bereits (s.o.) behandelt

Hilfe mit Get-Help about_Operators

  • Arithmetische Operatoren (+, -, *, /, %)

  • Zuweisungsoperatoren (=, +=, -=, * =, /=, %=)

  • Vergleichsoperatoren (-eq, -ne, -gt, -lt, -le, -ge)

  • Logische Operatoren (-and, -or, -xor, -not, !)

  • Umleitungsoperatoren (>, >>, 2>, 2>, and 2>&1)

& Aufrufoperator

Führt einen Befehl, ein Skript oder einen Skriptblock aus.

C:\PS> $c = "get-executionpolicy"
C:\PS> $c
get-executionpolicy
C:\PS> & $c
AllSigned

. Punkt-Quellen-Operator, Dot Sourcing

Führt ein Skript im aktuellen Bereich aus, sodass alle vom Skript erstellten Funktionen, Aliase und Variablen dem aktuellen Bereich hinzugefügt werden.

. c:\scripts.sample.ps1

Formatoperator –f

Formatiert Zeichenfolgen mit der Formatmethode von Zeichenfolgeobjekten.

C:\PS> "{0} {1,-10} {2:N}" -f 1,"hello",[math]::pi
1 hello      3.14

Anm.: die Ausgabe durch den Formatoperator fühlt sich erst einmal etwas umständlich an, stellt aber tatsächlich eine sehr effiziente Ausgabetechnik dar und wird auch in anderen Skriptsprachen so oder ähnlich umgesetzt (z.B. PHP mit sprintf).

Indexoperator [ ]

Wählt Objekte aus indizierten Datengruppen wie Arrays und Hashtabellen aus

C:\PS> $a = 1, 2, 3
C:\PS> $a[0]
1

Pipeline-Operator |

Sendet die Ausgabe des vorangegangenen Befehls via Pipe an den nachfolgenden Befehl. Wenn die Ausgabe mehrere Objekte (eine Datengruppe) enthält, sendet der Pipeline-Operator die Objekte einzeln nacheinander.

.. Bereichsoperator

Stellt die ganzen Zahlen eines Ganzzahlen-Arrays der Reihe nach dar, wobei eine obere und untere Grenze gilt.

PS E:\_temp> 1..3
1
2
3

:: Operator für statische Member

Ruft den Operator für statische Eigenschaften und die Methoden der .NET Framework-Klasse auf.

[datetime]::now

Teilausdruckoperator $, Subexpression

Gibt das Ergebnis einer oder mehrerer Anweisungen zurück.

Funktionen

MS Technet Funktionen

Nutzung: eigene Befehlsroutinen erstellen und in der Umgebung zur Verfügung stellen mit Hilfe von

  • Modulen

  • Profil(en)

Konstruktion und Aufbau der Funktionen mit folgenden Befehlen:

  • function name {…}

  • break

  • continue

  • return

  • exit

Fehlerbehandlung:

  • trap Fehlerklasse { … } else { … }

  • throw „Fehlertext“

  • throw Fehlerklasse

Siehe hierzu auch wieder immer die Hilfen On- und Offline.

Tipp

Get-Help about_functions

Oder natürlich gerne auch Google ;-).


Hier weitere Abschnitte zum Thema:

Parameter für Funktionen

Das funktioniert prinzipiell wie bei der Übergabe von Parametern an Skripte.

Hier ein Beispiel mit Definition von einem Standardwert für den Parameter:

Function Get-SmallFiles.ps1
1function Get-SmallFiles {
2    param ( $Size = 100000 )                       # Best Practise
3    Get-ChildItem -path "E:\_temp" | where {$_.Length -lt $Size -and !$_.PSIsContainer} 
4}

Aufruf dann mittels:

Get-SmallFiles –Size 50000

Eine Übergabe sollte stets mit param Deklarationen erfolgen und möglichst nicht über die Übergabe in einer Klammer zur Funktion:

function Get-SmallFiles ($size = 100000) {           # nicht Best Practise
    Get-ChildItem E:\_temp | where {$_.Length -lt $Size -and !$_.PSIsContainer}
}

Mittels param kann man dann auch Mandatory – also benötigte – Parameter deklarieren und gleich noch den Datentyp festlegen (int) und Default-Werte sauber deklrieren.

Tipp

Tipp für Funktionsnamen: Bitte die Verb-Noun Syntax nutzen und auch gleich noch Such- und Hilfemerkmale für die eigenen Funktionen einbauen: Get-JBSmallFiles ; hier z.B. für die Autorenschaft oder andere Ideen.

Beispielhafte Funktion inklusive eingebauter Hilfe und einem Parameter vom Typ Switch (Schalter-Parameter):

Function Get-SmallFiles-02.ps1
1function Get-SmallFiles {
2param ( 
3    [Parameter(Mandatory=$true)]
4    [int]                                     # Typ Integer
5    $Size = 100000 
6    )
7Get-ChildItem -Path "E:\_temp" | where {$_.Length -lt $Size -and !$_.PSIsContainer} 
8}

Man testet am Besten gleich die Hilfen zur neuen Funktion (Cmdlet) Get-CriticalEvent

Function Get-CriticalEvent.ps1
 1# aus Weltner S. 480ff.
 2# komplette Funktionsdefinition mit Anfangsblock / Kommentierungen
 3# =============================
 4
 5function Get-CriticalEvent
 6{
 7<#
 8    .SYNOPSIS
 9        listet Fehler und Warnungen aus dem System-Ereignisprotokoll auf
10    .DESCRIPTION
11        liefert Fehler und Warnungen der letzten 48 Stunden aus dem 
12        System-Ereignisprotokoll,
13        die auf Wunsch in einem GridView angezeigt werden. Der Beobachtungszeitraum
14        kann mit dem Parameter -Hours geändert werden.
15    .PARAMETER  Hours
16        Anzahl der Stunden des Beobachtungszeitraums. Vorgabe ist 48.
17    .PARAMETER  ShowWindow
18        Wenn dieser Switch-Parameter angegeben wird, erscheint das Ergebnis in einem
19        eigenen Fenster und wird nicht in die Konsole ausgegeben
20    .EXAMPLE
21        Get-CriticalEvent
22        liefert Fehler und Warnungen der letzten 48 Stunden aus dem 
23        System-Ereignisprotokoll
24    .EXAMPLE
25        Get-CriticalEvent -Hours 100
26        liefert Fehler und Warnungen der letzten 100 Stunden aus dem 
27        System-Ereignisprotokoll
28    .EXAMPLE
29        Get-CriticalEvent -Hours 24 -ShowWindow
30        liefert Fehler und Warnungen der letzten 24 Stunden aus dem 
31        System-Ereignisprotokoll und stellt sie in einem eigenen Fenster dar
32    .NOTES
33        Dies ist ein Beispiel aus Tobias Weltners' PowerShell Buch
34    .LINK
35        http://www.powertheshell.com
36#>
37param(
38    [int32]    $Hours = 48, 
39    [Switch]   $ShowWindow
40    )
41  if ($ShowWindow)
42  {
43    Set-Alias Out-Default Out-GridView
44  }
45
46  $Heute = Get-Date
47  $Differenz = New-TimeSpan -Hours $Hours
48  $Stichtag = $Heute - $Differenz
49
50  Get-EventLog -LogName System -EntryType Error, Warning -After $Stichtag |
51    Select-Object -Property TimeGenerated, Message | Out-Default
52}

Bei manchen Funktionen erhält man ungewünschte Rückgabewerte aus den Funktionen. Diese lassen sich leicht unterdrücken.

# statt:
function Speak-Text($text) {
    $speaker = New-Object -COMObject SAPI.SPVoice
    $speaker.Speak($text)
    }
# besser:
function Speak-Text($text) {
    $speaker = New-Object -COMObject SAPI.SPVoice
    $null = $speaker.Speak($text)
    }

Funktionen: Übungen

Beispielfunktion Set-JBDir - Change Dir with Dialog

manuell in einer Session/einem Skript - oder natürlich später in einer Profildatei

Function Set-JBDir.ps1
1function Set-JBDir {
2    $shell = New-Object -comObject "Shell.Application"
3    $options = 0x51 # Nur Dateisystem-Ordner - inklusive Edit-Box
4    $loc = $shell.BrowseForFolder(0, "Wohin soll es gehen?", $options)
5    if($loc) {Set-Location $loc.Self.Path}
6}

Beispielfunktion Get-JBNewPix

Function Get-JBNewPix.ps1
1function Get-JBNewPix
2{
3    $start = Get-Date -Month 1 -Day 1 -Year 2015
4    $allpix = Get-ChildItem -Path $env:UserProfile\*.jpg -Recurse
5    $allpix | where {$_.LastWriteTime -gt $Start}
6}

Dieses kleine Beispiel zeigt uns alle Jpg-Dateien in unserem Benutzerprofil, die nach einem Startdatum geändert worden sind.

Funktionen bereitstellen

Unsere „persönlichen“ Funktionen lassen sich einfach über die $PROFILE Konfiguarationsdateien im System bereitstellen.

Eine andere attraktive Möglichkeit ist das Bereitstellen über Modul (quasi als Container für Befehle).

Kontrollstrukturen

Modellierung von Logikblöcken in Skripten oder auch in einer Befehlszeile.

Es geht also (verkürzt gesagt) um

  • Verzweigungen (if, switch) - mit Bedingungen

  • Schleifen (for, while, foreach) - wir wollen Aufgaben mehrfach erledigen/durchlaufen lassen

Beispiele aus den Hilfen zu den jeweiligen Kontrollstrukturen.

Ohne die Links mit Hilfe von Get-Help bitte einfach Online-Suche nach „PowerShell about_if“, „PowerShell about_switch“, …


Hier die Abschnitte zum Thema:

if

if (Bedingung) {…} else {…}

MS Technet if

Beispiel if
 1if ($a -gt 2)
 2{
 3    Write-Host "The value $a is greater than 2."
 4}
 5    elseif ($a -eq 2)
 6{
 7    Write-Host "The value $a is equal to 2."
 8}
 9    else
10{
11    Write-Host "The value $a is less than 2 or was not created or initialized."
12}

switch

switch ($var) {Wert {…} Wert {…} default {..} }

MS Technet switch

Beispiel switch
 1# switch Beispiel
 2"Welche Bewertung?"
 3$note = Read-Host
 4switch ($note)
 5{
 6    1 {"sehr gut"}
 7    2 {"gut"}
 8    3 {"befriedigend"}
 9    4 {"ausreichend"}
10    5 {"ungenügend"}
11    default { "Ungültige Note" }
12}

Tipp: Diese kleinen Beispiele auch mal gerne in der ISE testen.

for

for(Initialisierung;Bedingung;Schrittweite) { … }

MS Technet for

Beispiel for
1for ($i=1 ; $i -le 10 ; $i++ )
2    { Write-Host $i }

Fakultätsberechnung mit einer For-Schleife

Anm.: Fehler in Buch Schwichtenberg PS 4.0: -lt muss zu -le werden

Beispiel for Fakultätsberechnung
1"Bitte eine Zahl eingeben:"
2$Fakultaet = Read-Host
3$FakultaetErgebnis = 1
4for ($i = 1; $i -le $Fakultaet; $i++)
5    {
6    $FakultaetErgebnis = $FakultaetErgebnis * $i
7    }
8    "Die Fakultät von " + $Fakultaet + " ist " + $FakultaetErgebnis

Fakultätsberechnung mit einer For-Schleife und vorzeitiger Abbruchbedingung

Beispiel Fakultät mit Abbruchbedingung
 1"Bitte eine Zahl eingeben:"
 2$Fakultaet = Read-Host
 3$FakultaetErgebnis = 1
 4$Abbruch = $false
 5for ($i = 1; $i -lt $Fakultaet; $i++)
 6    {
 7    $FakultaetErgebnis = $FakultaetErgebnis * $i
 8    if ($FakultaetErgebnis -gt [System.Int32]::MaxValue) { $Abbruch = $true; break; }
 9    }
10if ($Abbruch) { "Werteüberlauf!" }
11else { "Die Fakultät von " + $Fakultaet + " ist " + $FakultaetErgebnis }

while

while (Bedingung) { … }

MS Technet while

Beispiel while
1while ($val -ne 3)
2    {
3    $val++
4    Write-Host $val
5    }

do while / until

do { … } while (Bedingung)

Beispiel do… while
1$a = 0
2$count = 0
3$x = 1,2,78,0
4do { $count++; $a++; } while ($x[$a] -ne 78)
5$count     # ergibt 2

do { … } until (Bedingung)

MS Technet do…until

Beispiel do…until
1$a = 0
2$count = 0
3$x = 1,2,78,0
4do { $count++; $a++; } until ($x[$a] -eq 0)
5$count     # ergibt 3

foreach

Die Automatik-Schleife für unsere Arrays und Objekte: foreach ($var in $menge) {…}

MS Technet foreach

Wir starten mit einmem einfachen nummerischen Array

$menge = 1,2,3,4,5
foreach ($i in $menge)
{ $i }

Beispiele aus PowerShell-Hilfe:

Beispiel foreach
 1$letterArray = "a","b","c","d"
 2foreach ($letter in $letterArray)
 3{
 4    Write-Host $letter
 5}
 6
 7foreach ($file in Get-ChildItem)
 8{
 9    if ($file.length -gt 100KB)
10    {
11    Write-Host $file
12    Write-Host $file.length
13    Write-Host $file.lastaccesstime
14    Write-Host ""
15    }
16}
17
18foreach ($file in Get-ChildItem)
19{
20    if ($file.length -gt 100KB)
21    {
22# ToString mit F0 meint 0 Dezimalstellen; F2 also mit 2 Dezimalstellen
23    Write-Host $file "file size:" ($file.length / 1024).ToString("F0") KB
24    }
25}

Array/Objekt aus Get-Service

$dienste = Get-Service
foreach ($dienst in $dienste)
{
    "{0,-20}: {1}" -f $dienst.Name , $dienst.Status
}  # Nutzung eines Ausgabeoperator -f

Natürlich kann man sich nach dem Unterschied zum Cmdlet ForEach-Object in Pipelines fragen. Hier eine kurze Darstellung zum Thema „ForEach-Object in Pipeline vs. „foreach im Skript“ [1]

# Pipeline-basierter Befehl ForEach-Object (asynchron)
Get-ChildItem c:\Windows -Recurse -Filter "*.txt" |
ForEach-Object { "{0,-20}: {1}" -f $_.Name , $_.length }

# vs. skriptbasierten Befehlsfolge (foreach-Schleife erst nach Get-ChildItem)
$Dateien = Get-ChildItem c:\Windows -Recurse -Filter "*.txt"
foreach ($datei in $Dateien)
{
    "{0,-20}: {1}" -f $datei.Name , $dienst.length
}

Zusammenfassung: Der Pipeline-Befehl beginnt sofort mit der Ausgabe der Dateiliste.

Die skriptbasierte Lösung braucht einige Zeit vor der ersten Ausgabe.

Der Pipeline-Befehl meldet zwischen den Ausgaben Fehler über Pfade, für die es kein Zutrittsrecht gibt. Die skriptbasierte Lösung zeigt erst alle Fehlermeldungen, die ja von Get-ChildItem kommen, und dann erst die Dateiausgabe, die aus der ForEach-Schleife stammt.

Hintergrundjobs

Mit den Hintergrundjobs kann man die Effizienz von Skriptausführungen optimieren.

Integrierte Hintergrundjobs mit Parameter AsJob

Get-Command -ParameterName AsJob    # oder
Get-Help * -Parameter AsJob         # findet auch in ungeladenen Modulen Cmdlets

Literatur: Weltner Kapitel 25 - Hintergrundjobs und Parallelverarbeitung

Übersicht über Cmdlets zum Thema Jobs:

Get-Command -Noun Job

Beispielhafte Skripts - hier erste Variante mit Aufrufen nacheinander:

# 3 Jobs nacheinander
# drei Aufgaben definieren
$code1 = { Start-Sleep -Seconds 5; "A" }
$code2 = { Start-Sleep -Seconds 6; "B" }
$code3 = { Start-Sleep -Seconds 7; "C" }

$start = Get-Date

& $code1
& $code2
& $code3

$end = Get-Date
$timespan = $end - $start
$seconds = $timespan.TotalSeconds
Write-Host "Gesamtdauer: $seconds sec."

Jetzt die Version mit Jobs:

$start = Get-Date

# drei Aufgaben definieren
$code1 = { Start-Sleep -Seconds 5; "A" }
$code2 = { Start-Sleep -Seconds 6; "B" }
$code3 = { Start-Sleep -Seconds 7; "C" }

# zwei Aufgaben in Hintergrundjobs verlagern und dort ausführen:
$job1 = Start-Job -ScriptBlock $code1
$job2 = Start-Job -ScriptBlock $code2

# die voraussichtlich längste Aufgabe in der eigenen PowerShell ausführen:
$result3 = & $code3

# warten, bis alle Hintergrundjobs ihre Aufgabe erledigt haben:
$alljobs = Wait-Job $job1, $job2

# Ergebnisse der Hintergrundjobs abfragen:
$result1 = Receive-Job $job1
$result2 = Receive-Job $job2

# Hintergrundjobs wieder entfernen
Remove-Job $alljobs

$end = Get-Date

# Ergebnisse ausgeben
$result1, $result2, $result3

$timespan = $end - $start
$seconds = $timespan.TotalSeconds
Write-Host "Gesamtdauer: $seconds sec."

In der Theorie: Zeit des längsten Skripte - hier 7sec bestimmt Gesamtlaufzeit!

In der Realität etwas länger, wegen Overhead - Kommunikation zwischen Hosts!

Anmerkungen:

Achtung: Hintergrundjobs, die viele Ergebnisse liefern, können Skriptabläufe sogar verlangsamen! Am Besten: nur Statusmeldung

Empfehlungen:

  • Langwierige Aufgaben - Overhead dann vernachlässigbar

  • Wenig Ergebnisse - diese müssten serialisiert werden für Austausch zwischen PSSessions

  • Kurze Lebensdauer - sonst muss man die PowerShell Session aufrechterhalten (Alternative: Task-Scheduling)

Modultechnik

Module sind Container (also Ordner) für eigene Funktionen und Cmdlets und lassen sich einbinden oder selber erstellen.

Get-Module -ListAvailable auf einem DC per Remote Session

Get-Module -ListAvailable auf einem DC per Remote Session

Damit die Module vom PowerShell-System erkannt und genutzt werden können, müssen die Module an entsprechenden Stellen etabliert werden.

Ermitteln der Modulpfade (Modul-Hauptordner im PowerShell-System) mit Hilfe von Umgebungsvariable PSModulPath:

PS E:\_temp> $env:PSModulePath -split ";"
C:\Users\joebr_000\Documents\WindowsPowerShell\Modules
C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\
C:\Program Files\WindowsPowerShell\Modules
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\

Hier sind offensichtlich die PSCX (PowerShell Community Extensions) installiert.

Die folgende Anleitungen orientieren sich an [1]


Hier die Abschnitte zum Thema:

Module 101

Unsere einfachen Module bestehen aus:

  • Ordner mit ModulName

  • im Ordner gleichnamig *.psm1

    Datei: ModulName.psm1

Für die folgenden Erstellungen muss der PowerShell-Host (Tipp: ISE) die Funktion kennen!

Hier: Funktion Get-CriticalEvent – Fehler und Warnungen aus System-Ereignisprotokoll – letzte 48 Stunden).

PS E:\_temp> Get-CriticalEvent

TimeGenerated       Message
-------------       -------
16.10.2016 09:06:36 Benutzerdefinierte DLLs werden für jede Anwendung geladen. Systemadminis...
16.10.2016 09:06:28 Für ein Zeigegerät fehlen Informationen zum Monitor, mit dem es ...
...

Erstellung des Modulcontainers (Ordner) und der *.psm1 Moduldatei:

Anm. zum Training: vor der Durchführung der Skriptzeilen bitte die einzelnen Zeilen analysieren!

Sehr einfaches Modul erstellen
1$name = "Get-CriticalEvent"
2$path = Split-Path -Path $profile
3$code = "function $name { $((Get-Item function:\$name).Definition) }"
4New-Item -Path $path\Modules\$name\$name.psm1 -ItemType File -Force -Value $code

Erster Test für die Verfügbarkeit des Cmdlet per Modul:

PS E:\_temp> Get-Module get-cr* -ListAvailable

Verzeichnis: C:\Users\joebr_000\Documents\WindowsPowerShell\Modules

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     0.0        Get-CriticalEvent                   Get-CriticalEvent

Ab jetzt erkennen auch die anderen PowerShell-Hosts den neuen Befehl und nach einem Aufruf des Befehls werden auch die Modul-Infos (ohne –ListAvailable) ausgegeben.

Analysen mit Get-Module

PS E:\_temp> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Computer, Add-Content, Checkpo...}
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variab...}
Script     1.0.0.13   PSReadline                          {Get-PSReadlineKeyHandler, Get-PSRe...

PS E:\_temp> Get-CriticalEvent -ShowWindow
PS E:\_temp> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     0.0        Get-CriticalEvent                   Get-CriticalEvent
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Computer, Add-Content, Checkpo...}
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variab...}
Script     1.0.0.13   PSReadline                          {Get-PSReadlineKeyHandler, Get-PSRe...

Ausführliche Darstellung der aktuellen Modultechniken bei Weltner

Modultechnik erweitern

Die folgende Kurzanleitung für die komplette Modultechnikdarstellung gemäß [1]

Wir benötigen für unser Modul einen Entwurfsordner. Diesen kannn man zum Testen einfach auch gerne auf dem Desktop platzieren für erste Tests mit dem neuen Modul und seinen Funktionen/Techniken.

Wir beginnen mit einem Beispielordner mit aussagekräftigem Modulnamen:

New-Item -Path $home\Desktop\JBSystemTools -ItemType Directory

Eine Funktion bereitstellen für das neue Modul:

Function Get-SoftwareUpdate.ps1
 1function Get-SoftwareUpdate
 2{
 3    $Filter = @{
 4      ProviderName="Microsoft-Windows-WindowsUpdateClient"
 5      ID=19
 6    }
 7
 8  Get-WinEvent -FilterHashtable $filter |
 9    ForEach-Object {
10      $rv = $_ | Select-Object -Property TimeCreated, Name, Activity, Status
11      $rv.Name = $_.Properties[0].Value
12      $rv.Activity = $_.KeywordsDisplayNames[0]
13      $rv.Status = $_.KeywordsDisplayNames[1]
14      $rv
15    }
16  
17}

Und diese Funktion als ps1-Datei im Modulordner speichern.

Die Funktion kann man nun erst einmal „manuell“ aufrufen und dann die neue Funktion Get-SoftwareUpdates nutzen.

Jetzt benötigen wir im Modulordner noch die eigentliche Moduldatei (Endung: psm1):

Hinweis

Die psm1-Datei muss denselben Namen haben, wie der übergeordnete Modulordner!

Hier:

  • Ordner: JBSystemTools

  • Moduldatei im Ordner: jbsystemtools.psm1

Inhalt der jbsystemtools.psm1 Datei:

. $PSScriptRoot\Get-SoftwareUpdate.ps1

Also einfach mit Dot-Sourcing die gewünschte Funktionen-Skriptdatei laden lassen.

Unser „Modul-Testordner“ befindet sich aktuell nicht in den PSProfilPfad-Ordner (s.o.) und daher müssen wir diese Modul-Technik noch manuell importieren:

Import-Module $HOME\Desktop\JBSystemTools -Verbose

Anm.: Parameter -Verbose für zusätzliche Infos beim Modul-Import (dt.: geschwätzig) und bitte keinen Backslash nach dem Modulordnernamen oder komplett die psm1-Datei angeben.

Damit unser Modul jetzt automatisch geladen (bzw. gefunden) werden kann, muss der Modul-Ordner nur noch an einen unserer $PSModulePath kopiert werden. Gerne einfach mit dem „robusten Universal- Werkzeug robocopy“:

robocopy $HOME\Desktop\JBSystemTools $HOME\Documents\WindowsPowerShell\Modules\JBSystemTools

Module komplett

Ziel: die dargestellten Modul-Basics mit Hilfe von weiteren Moduldateien automatisch in die PowerShell-Umgebung des Benutzers einbinden und mit weiteren Funktionen und Techniken erweitern können.

Für die inhaltliche und technische Beschreibung wird ein Modul-Manifest erstellt und konfiguriert.

Hier eine exemplarische Kurzanleitung:

Module komplettieren

Module erstellen (inkl. Manifest)

Beachten: bei Änderungen an den Modul-Techniken und Inhalten kann das Caching der PowerShell zum Problem werden. Hier kann man durch „forciertes manuelles“ Laden der Module gegensteuern.

Import-Modul .\Ordner-des-Moduls -Force

Für das Erweitern der eigenen Modultechniken kann jetzt noch eine Modul-Manifest-Datei angelegt werden:

New-ModuleManifest $HOME\Documents\WindowsPowerShell\Modules\MyTools\MyTools.psd1

Diese Manifestdatei muss jetzt an wichtigen Stellen mit Inhalten gefüllt werden. Für eine spätere Veröffentlichung in Repositories sollten auch individuelle Autoreninfos ausgefüllt werden.

Wichtige Inhalte der Manifest-Datei (technisch: eine Hashtabelle!)

  • RootModule (in PS 2.0: ModuleToProcess !!)

  • ModuleVersion

  • Author

  • Company

  • Copyright

  • FunctionsToExport

  • CommandsToExport

  • VariablesToExport

  • AliasesToExport

Manifestdatei ist - wie bereits gesagt - eine Hashtabelle und wird so auch technisch genutzt und kann entsprechend analysiert werden.

PS E:\_temp> $path = $HOME\Documents\WindowsPowerShell\Modules\MyTools\MyTools.psd1
PS E:\_temp> $content = Get-Content -Path $path -Raw
PS E:\_temp> $info = Invoke-Expression $content#
# Informationen dann mit:
PS E:\_temp> $info
PS E:\_temp> $info.Author
# Testen des Manifests mit:
PS E:\_temp> Test-ModuleManifest -Path $path

Die Wirkungsweise beim Laden des Moduls kann man mit „verbose“ beim Importieren darstellen:

Import-Module -Name MyTools -Verbose -Force

Weitere Verbesserungsmöglichkeit für Module:

  • ETS (Extended Type System) - festlegen der Formatierungs- und Typdefinitionen für Funktionen

  • …tbc…

Beispielmodule

Wenn wir uns den Markt für PowerShell Erweiterungen (aka Module) anschauen, dann findet man schnell ein paar Module für die eigene PowerShell und den eigenen Geschmack.

Tipp

Fertige WindowsPowerShell Umgebung Trainer Joe Brandes

Als Trainer stelle ich ein freies Gitlab Repo mit einer voll funktionstüchtigen WindowsPowerShell Profilumgebung mit eingebauten Modulen und Techniken zur Verfügung.

git clone https://gitlab.com/joebrandes/WindowsPowerShell.git

Greetings Screenshot Example Profile Trainer Joe Brandes

Greetings Screenshot Example Profile Trainer Joe Brandes

Das Klonen natürlich im Ordner C:\Users\%username%\Documents durchführen. Und auf frischen Systemen bitte auch Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser nicht vergessen bzw. checken!

Wir schauen uns ein paar der Module mal genauer an.

ZLocation

Eine wiederkehrende Aufgabe in Shells ist das Navigieren durch Ordnerstrukturen. Die klassischen Lösungen in Shells heißen z.B. autojump und nutzen den Kurzbefehl j zum Ordnerwechsel.

ZLocation ist der moderne Nachfolger (Nachbau) und lässt sich einfach bereitstellen: Github Repo for Zlocation

Kurzanleitung ZLocation:

Install-Module ZLocation -Scope CurrentUser

Einbau in der gewünschten Profiledatei $PROFILE:

Import-Module ZLocation
Write-Host -Foreground Green "`n[ZLocation] knows about $((Get-ZLocation).Keys.Count) locations.`n"

Hierdurch wird das Modul geladen und wir erhalten eine Kurzinfo über bereits bekannt Ordner-Sprungziele.

Die in Zlocation bekannten Ordner erhält man mittels z und diesen Aufruf nutzt man auch einfach als Ersatz für den üblichen Alias cd oder das PowerShell-Original Set-Location.

Mit z kann man dann die Gewichtung der Ordner auflisten lassen:

z | Sort-Object weight -Descending

Terminal-Icons

Ich möchte meine Shell weiter grafisch und farbig highlighten lassen. Hierfür gibt es diverse Tools / Module und ich finde Terminal Icons (Github) sehr ordentlich.

Und an dieser Stelle nochmal der Hinweis auf Nerd Fonts Downloads.

Install-Module Terminal-Icons -Scope CurrentUser

Einbau in $PROFILE - Terminal Icons nach Oh-My-Posh:

Einbau in der gewünschten Profiledatei $PROFILE:

Import-Module Terminal-Icons

Das kann dann so aussehen:

Terminal Icons

Terminal Icons

Hier in einer bildbearbeiteten Darstellung für diverse Icons: Show-TerminalIconsTheme

Oh-My-Posh

… und posh-git

Als Nutzer diverser Shells auf unterschiedlichen Betriebssystemen möchte ich mir auch die PowerShell grafisch und technisch aufwerten. Unter Linux mag ich deswegen auch die Zsh mit den Oh-My-Zsh Plugins. Auf dieser Idee beruht auch Oh-My-Posh.

Hinweis

Für die folgenden zwei (abhängigen) Module sollte auf dem System ebenfalls das Tool Git (Git Portal) installiert sein. Und natürlich muss ein vernünftiger Nerd-Font installiert sein!

Anleitung: https://docs.microsoft.com/de-de/windows/terminal/tutorials/powerline-setup

Englisches Original: https://docs.microsoft.com/en-us/windows/terminal/tutorials/powerline-setup

Anm.: Im englischen Original auch Videoanleitung von Scott Hanselmann

Kurzanleitung:

Install-Module posh-git -Scope CurrentUser
Install-Module oh-my-posh -Scope CurrentUser
# if on PowerShell core:
# Install-Module -Name PSReadLine -AllowPrerelease -Scope CurrentUser -Force -SkipPublisherCheck

Sicherstellen und Nutzen der Module über die $PROFILE:

Import-Module posh-git
Import-Module oh-my-posh
# OLD VERSION: Set-Theme Paradox
# Set-PoshPrompt -Theme powerlevel10k_classic
# Set-PoshPrompt -Theme jandedobbleer
Set-PoshPrompt -Theme paradox

In Windows Terminal kann das dann so aussehen:

Powerline for PowerShell

Powerline for PowerShell

Eine nötigen Nerd Font stelle ich für die Trainees bereit oder lässt sich leicht finden.

Mit Get-PoshThemes (OLD: Get-Themes) erhält man eine Übersicht über installierte Designs/Themes.

VirtualDesktop

Und mit diesem Modul kann man sich mal fix die Windows Virtual Desktops einrichten.

Ich habe - auf jedem Betriebssystem - gerne folgende Arbeitsoberflächen (aka Workspaces):

  1. Browser

  2. Konsole

  3. Coding

  4. VMS

Mit dem folgenden Skript kann man schnell gewünschte Programme auf den Virtual Desktops 0 bis 3 verteilen:

# Skript to initialize my Virtual Desktops
# Needs Module VirtualDesktop

Import-Module -Name VirtualDesktop -ErrorAction SilentlyContinue -WarningAction SilentlyContinue

Start-Process firefox
sleep 3
Switch-Desktop 1
sleep 3
Start-Process wt
sleep 3
Switch-Desktop 2
Start-Process explorer
sleep 3
Switch-Desktop 0

Und wenn man will, dann legt man sich noch eine Verknüpfung mit

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -file "C:\pfad\windows-on-desktops.ps1"

auf den Desktop - gerne auch noch mit Tastenkombination!

PSFzf

Der Fuzzy Finder unter Windows.

Github Junegunne/fzf

Denn wir sollten zuerst natürlich eine Windows-Binary für Fzf bereitstellen.

Fzf-Releases

Ich hätte das Tool fzf.exe gerne bei einem Git-Repo für meine PowerShell Umgebung von Windows:

Tool-Ordner: C:\Users\joeb\Documents\WindowsPowerShell\tools\...

Dann müssen wir natürlich den Pfad für die PowerShell erweitern, damit das Tools auch gestartet werden kann: $PROFILE

# Path for Joeb Tools - Attention: hard coded Path!
# -------------------
$env:PATH += ";C:\Users\joeb\Documents\WindowsPowerShell\tools"

Testen: Get-Command fzf.exe

Und jetzt brauchen wir den PowerShell Wrapper für fzf: das Modul PSFzf.

Install-Module -Name PSFzf -Scope CurrentUser

Wir vervollständigen noch die $PROFILE:

# PSFzf
# -----
# Windows Hilfe: https://github.com/kelleyma49/PSFzf
# Windows Fzf Binary in .\Documents\WindowsPowerShell\tools
Import-Module PSFzf
# replace 'Ctrl+t' and 'Ctrl+r' with your preferred bindings:
Set-PsFzfOption -PSReadlineChordProvider 'Ctrl+t' -PSReadlineChordReverseHistory 'Ctrl+r'


# ============================================================================
# Functions
# ============================================================================

# PSFzf functions

# To change to a user selected directory:
function fzdir {
    Get-ChildItem . -Recurse -Attributes Directory | Invoke-Fzf | Set-Location
    }
# To edit a file:
function fzfile {
    Get-ChildItem . -Recurse -Attributes !Directory | Invoke-Fzf | % { notepad $_
    }
}

Und hier haben wir auch gleich noch ein paar spielerische Functions eingebaut, damit wir mal schnell Ordner wechseln oder Dateien öffnen können.

Snap-Ins

Anmerkung zu Snap-Ins bzw. PSSnapins:

  • In PowerShell 1.0 der einzige Weg zusätzliche „Funktionen“ hinzuzufügen.

  • Snap-Ins müssen per Installation in das Windows System administrative integriert/installiert werden:

HKEY_LOCAL_MACHINE\Software\Microsoft\PowerShell\1\PowerShellSnapIns.
  • Übersicht über PSSnapins mit: Get-PSSnapin –Registered

  • Nachladen von Snap-Ins mit: Add-PSSnapin

Conclusio für eigene Erweiterungen rund um die PowerShell:
obsolete Technik, aber manchmal noch als $-SW in Firmen vorhanden!

Und man findet ja auch noch Snapin-Technik:

Get-PSSnapin -Name Microsoft.Powershell.Core
# oder auch nur
Get-PSSnapin

Name        : Microsoft.PowerShell.Core
PSVersion   : 5.1.19041.610
Description : Dieses Windows PowerShell-Snap-In enthält Cmdlets zum Verwalten von Windows PowerShell-Komponenten.

Get-PSSnapin -Name Microsoft.powershell.core | Select-Object *


Name                        : Microsoft.PowerShell.Core
IsDefault                   : True
ApplicationBase             : C:\Windows\System32\WindowsPowerShell\v1.0
AssemblyName                : System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL
ModuleName                  : C:\Windows\System32\WindowsPowerShell\v1.0\System.Management.Automation.dll
PSVersion                   : 5.1.19041.610
Version                     : 3.0.0.0
Types                       : {types.ps1xml, typesv3.ps1xml}
Formats                     : {Certificate.format.ps1xml, DotNetTypes.format.ps1xml, FileSystem.format.ps1xml, Help.format.ps1xml...}
Description                 : Dieses Windows PowerShell-Snap-In enthält Cmdlets zum Verwalten von Windows PowerShell-Komponenten.
Vendor                      : Microsoft Corporation
LogPipelineExecutionDetails : False

Das heißt zum Zeitpunkt dieser Tests (2020) steckt noch Kerntechnik in Form eines Snapins (und einer Windows-DLL) in der PowerShell: C:\Windows\System32\WindowsPowerShell\v1.0\System.Management.Automation.dll

Dienste Module

Für die allermeisten Dienste im Firmen- oder Cloud-Netz finden sich Erweiterungen - also spezielle Module - für die Nutzung der Dienste über die PowerShell.

Wir benötigen die folgenden Komponenten, um Services sauber mit der PowerShell verwalten zu können:

  1. PowerShell Kenntnisse

  2. Module / PowerShell-Technik für den Service

  3. Fachwissen über den eingesetzten Service

Entscheidend sind unsere Kenntnissse über die PowerShell! Die nötigen Erweiterungen / Module sind (heute / Anfang 2021) für nahezu alle Software-Einsätze verfügbar.

Die praktischen Umsetzungen will ich in meiner hier vorliegenden Ausarbeitung nur anreißen. In den Fachbüchern und im Netz gibt es tonnenweise Lösungen.

Für die Orientierung hier mal ein Bildauszug aus einem Info-PDF von Microsoft, auf dem die Techniken und Ihre Nutzungen durch einen Benutzer.

Microsoft 365

Microsoft 365

Die Bezeichung Office 365 beinhaltet die in der Abbildung erkennbaren Kerndienste von Microsoft 365:

  • Exchange Online

  • SharePoint Online

  • Microsoft Teams

Alle weiteren Ausstattungsmerkmale unterscheiden sich nach dem Office 365 Plan.

Exchange

An dieser Stelle müsste es eigentlich genauer heißen:

  • Exchange Server

  • Exchange Online

  • Exchange in Hybrid-Lösung

Cloud vs. Hybrid

Cloud vs. Hybrid - Literatur: Microsoft Exchange Server 2019 - Thomas Stensitzki

Literatur zu Exchange Online: Microsoft Office 365 Das umfassende Handbuch (Kap. 6) - Markus Widl

Spezifikationen für den Hybrid-Betrieb:

  • Rich-Hybrid

    Alle Zugriffe möglich: Intranet (Lan) und Internet (Wan)

    Postfächer dürfen aus verschiedenen Gründen nicht in die Cloud

    Öffentliche Ordner lokal - Zugriff auf Benutzer-Postfächer Online

  • Simple-Hybrid

    Immer alle Postfächer verschieben zu Office 365

Es ergeben sich unterschiedliche Anmerkungen in den verschiedenen Hilfen und Infos (online und offline) in der PowerShell bzw. der ExchangePowerShell.

  • Dieses Cmdlet ist nur lokal in Exchange verfügbar.

    Disable-MailUser - siehe: Disable-MailUser

  • Dieses Cmdlet ist nur im cloudbasierten Dienst verfügbar.

    Get-ApplicationAccessPolicy - siehe: Get-ApplicationAccessPolicy

  • Dieses Cmdlet ist der lokalen Bereitstellung von Exchange und im cloudbasierten Dienst verfügbar. Einige Parameter und Einstellungen gelten exklusiv für die eine oder andere Umgebung.

    Add-DistributionGroupMember - siehe: Add-DistributionGroupMember Hilfe

Und (leider) sind auch die Authentifizierungen sehr unterschiedlich und immer mal wieder Änderungen unterworfen!

Ich muss - und will - mich in dieser Ausarbeitung auf die PowerShell Technik beschränken und hierfür mal ein paar Themen und Einstiege in Exchange mit der PowerShell anbieten.

… tbc …

Exchange PowerShell

Dieses Kapitel kann man wörtlich nehmen, da Exchange mit einer eigenen (Power-)Shell ausgeliefert wird.

Man kann aber auch die Standard-PowerShell nutzen und die nötigen Module und Umgebungen laden.

Exchange Management Shell

Auszug aus Microsoft Exchange Server 2019 - Thomas Stensitzki - S. 359 ff.:

Die Exchange Management Shell (EMS) ist die zentrale Verwaltungskomponente von Exchange Server 2019 und ist ein Erweiterungsmodul zur Standard-PowerShell.

In der EMS stehen Ihnen nur die PowerShell-Cmdlets zur Verfügung, die aufgrund Ihrer persönlichen RBAC-Rollenmitgliedschaft während des Aufbaus der Session geladen wurden.

Die EMS war früher (bis Exchange Server 2010) lokal installiert und ist heute ebenfalls eine Umsetzung mittels PowerShell Session!

EMS - Exchange Management Shell

EMS - Exchange Management Shell - Literatur: Microsoft Exchange Server 2019 - Thomas Stensitzki

Das Bild zeigt den Status nach erfolgter Anmeldung am Exchange Server.

Remote Session

Als nächstes folgt die Nutzung der PowerShell mittels importierter Remote Session zum Exchange Server.

Import einer Remote-Power-Shell-Session

Import einer Remote-Power-Shell-Session - Literatur: Microsoft Exchange Server 2019 - Thomas Stensitzki

Hier erkennt man auch eine mögliche Authentifizierung mittels Kerberos und das Virtuelle Verzeichnis PowerShell auf dem IIS für die Remote Session.

Nach Abschluss der Arbeiten sollte man die Session mit Remove-PSSession zurückgeben!

… tbc …

Exchange PS Beispiele

Einstiegsthemen gibt aus unterschiedlichen Quellen - hier mal eine Website mit Best of:

https://sysadminguides.org/2017/05/08/useful-exchange-powershell-commands-the-ultimate-list/

SharePoint

Bei SharePoint wird es mal wieder (eigentlich) Zeit etwas genauer hinzuschauen:

  • SharePoint in Microsoft 365

  • SharePoint Server

Wieder einmal geht es also um den Cloud- oder firmeninternen Service.

Und auch hier wieder eine Einstiegsseite der Docs Microsoft Site: SharePoint PowerShell

Die Commands unterscheiden sich in den Benennungen:

Und der Umfang und die technischen Umsetzungen unterscheiden sich immens!

SharePoint und Exchange

Die Anbindung von SharePoint Server 2019 an Exchange Server 2019 ist für folgende Anwendungsfälle möglich: (Kap. 5.5 Exhange Server Fachbuch von T. Stensitzki)

  • einheitliche eDiscovery-Suche in SharePoint Server, Exchange Server und Skype for Business Server

  • Empfang und Zustellung von E-Mail für E-Mail-aktivierte SharePoint-Listen und SharePoint-Benachrichtungen

  • Nutzung von Site Mailboxes, einer kombinierten Funktion in Exchange Server und SharePoint Server

Für die Bereitstellung der nötigen PowerShell Technik will ich mich an dieser Stelle auf die Microsoft SharePoint PowerShell Übersicht beschränken:

  • Package Microsoft.Online.SharePoint.PowerShell

    Link zur PowerShellGallery Paket mit den *-SPO* Commands

  • SharePoint Online-Verwaltungsshell

    Die SharePoint Online-Verwaltungsshell ist ein Tool, das ein Windows PowerShell-Modul zum Verwalten Ihres SharePoint Online-Abonnements in Office 365 enthält.

  • Modul Microsoft.SharePoint.PowerShell für SharePoint Server on-Site

    Verfügbarkeit checken mit Get-Command -Module Microsoft.SharePoint.PowerShell

    Bei Problemen: Add-PSSnapin Microsoft.SharePoint.PowerShell

  • SharePoint Patterns and Practices (PnP)

    Bibliothek von PowerShell-Befehlen (PnP PowerShell)

    Die Befehle funktionieren sowohl in SharePoint Online als auch in lokalen SharePoint-Instanzen.

Einfacher SharePoint PowerShell Aufruf: Get-SPSite

… tbc …

SharePoint Beispiel

Auch hier will ich wieder nur kurz mal beispielhaft den möglichen Einsatz von PowerShell Aufrufen gegen ein SharePoint System darstellen.

Und ich werde auch gar nicht anfangen mir Gedanken über nötige Authentifizierungen oder ganze Authentication Systems and Services zu machen (siehe: Connect-SPOService ; Beispiele für Connect-SPOService )!

Funktionstüchtigkeit für Zugriff testen mit: Get-SPSite bzw. Get-SPOSite

SharePoint Infos

Link: Ausgabe von SharePoint Informationen

Get-SPSite "http://hallo" | Select-Object url, owner,
    @{Expression={$_.Usage.Storage}}, @{Expression={$_.Audit.AuditFlags}}, readonly,
    LastContentModifiedDate, @{Express={$_.QuotaStorageMaximumLevel}}

Die Ausgabe:

SharePoint Infos

SharePoint Infos (Quelle: entwickler.de)

Links:

… tbc …

Hyper-V

Für den Hyper-V - wie auch für andere Dienste - gibt es wieder eine mehr als ordentliche Dokumentation im Netz auf den neuen docs.microsoft.com Seiten: Arbeiten mit Hyper-V und Windows PowerShell

Und wie immer gibt es als Technikpartner ein (gleichnamiges) Modul mit passenden Aufrufen/Kommandos:

Get-Command -Module hyper-v | Out-GridView

Und ab hier geht es dann wieder nach PowerShell-Logik:

# alle VMs auflisten
Get-VM
# alle laufenden VMs auflisten
Get-VM | where {$_.State -eq 'Running'}

Bis hin zur vollständigen Erzeugung einer neuen VM:

$VMName = "VMNAME"

$VM = @{
    Name = $VMName
    MemoryStartupBytes = 2147483648
    Generation = 2
    NewVHDPath = "C:\Virtual Machines\$VMName\$VMName.vhdx"
    NewVHDSizeBytes = 53687091200
    BootDevice = "VHD"
    Path = "C:\Virtual Machines\$VMName"
    SwitchName = (Get-VMSwitch).Name
}

New-VM @VM

Anm.: Beim SwitchName sollte man bei mehr als einem Switch nacharbeiten!

Hyper-V Beispiel

Beispielhafte Umsetzung für den Hyper-V: Hyper-V auslesen

Im Code erkennt man viele Basics aus unseren Beschäftigungen mit der PowerShell.

# Festlegen der Hyper-V Server
$meineHyperVServer = "Server1","Server1"

# Informationen die wir darstellen wollen:
# VM Name (VMName)
# Status der VM (State)
# Hyper-V Server Host (Host)
# Anzahl verwendeter CPUs (ProcessorCount)
# Zugewiesener Arbeitsspeicher (MemoryAssigned)
# Maximaler Arbeitsspeicher (MemoryMaximum)
# Minimaler Arbeitsspeicher (MemoryMinimum)
# Dynamisches RAM zugewiesen? (DynamicMemoryEnabled)
# Notizen der virtuellen Maschine (Notes)

# Leeres Array um die VM Informationen darin zu speichern
$AlleVMs = @()

# Für jeden Hyper-V Server in $meineHyperVServer wird diese Schleife durchlaufen
foreach ($hyperv in $meineHyperVServer){

# Listet alle Virtuellen Maschinen auf dem entsprechenden Hyper-V Server auf
$AlleVMs += Get-VM -ComputerName $hyperv | Select VMName,`

# Unter "Status" wird mit Switch/Case geprüft ob es bestimmte Stati hat und übersetzt diese in deutsch
@{Label="Status";Expression={switch($_.State){"Running"{"Läuft"} "Off"{"Aus"}}}},`

# Host auf dem die Virtuelle Maschine läuft
@{Label="Host";Expression={$_.Computername}},`

# Anzahl Prozessorkerne die für die VM eingerichtet sind
@{Label="CPUCount";Expression={$_.ProcessorCount}}, `

# Aktuell verwendeter Arbeitsspeicher der VM
@{Label="MemAssign";Expression={[math]::Round($_.MemoryAssigned / 1GB,0)}}, `

# Maximal möglicher Arbeitsspeicher der VM
@{Label="MemMax";Expression={[math]::Round($_.MemoryMaximum / 1GB,0)}},`

# Minimaler Arbeitsspeicher der VM
@{Label="MemMin";Expression={[math]::Round($_.MemoryMinimum / 1GB,0)}},`

# Ist der VM ein dynamischer Arbeitsspeicher zugewiesen?
@{Label="DynamicRAM";Expression={if ($_.DynamicMemoryEnabled -eq $true){"Ja"} else {"Nein"}}},`

# Notizen der VM
@{Label="Notizen";Expression={$_.Notes}},`

# Grösse der HDDs pro VM Total (Sum) in GB
@{Label="TotalHDDGrösse";Expression={[math]::Round((((get-vm -ComputerName $hyperv -Name $_.VMName| Get-VMHardDiskDrive).path | Get-VHD -ComputerName $hyperv).FileSize | Measure-Object -Sum).Sum/ 1GB,2).toString() + " GB"}}
}

# Ausgabe der zusammengestellten VMs als GitterDarstellung (GridView)
$AlleVMs | Out-GridView -Title "VM Übersicht"

Das ergibt dann z.B. eine Gridview-Ausgabe:

Hyper-V VM Skript (Gridview)

Hyper-V VM Skript (Gridview)

Und einmal mehr: Beipiel im Netz … tbc …

SQL Server

Datenbanken sind fast immer das Rückgrat von Diensten / Services in der Firmeninfrastruktur.

Meine eigenen Vertiefungen spielen sich zwar fast immer beim MySQL / MariaDB Server ab. Aber auch ein Microsoft SQL Server oder besser gesagt der SQL Express Edition. Und spätestens im Rückgrat / Backbone mancher Serveranwendungen findet man den MS SQL Server.

Für die Nutzung des eines MS SQL Server kann man heute einfach die automatisch mit dem SQL Management Studio ausgelieferte SQL PowerShell SQLPS nutzen oder man installiert einfach das immer weiter aktualisierte und öffentlich entwickelte Modul SqlServer:

Die (klassische) SQL PowerShell SQLPS wird aus Gründen der Abwärtskompatibilität weiter ausgeliefert, aber nicht mehr aktiv weiterentwickelt.

In der MSSQL Praxis werden die unterschiedlichen Umsetzungen immer wieder auch gemischt und je nach gewünschter Lösung eingesetzt.

…tbc… in entsprechenden PowerShell Seminaren mit dieser Vertiefung.

SQL System Class

Wie in den Basics zur PowerShell dargestellt haben wir natürlich auch Systemklassen derer wir uns bedienen können - hier handelt es sich sozusagen um die On-Bord-Mittel.

SQL-Klasse (als ein Beispiel): System.Data.SqlClient.SqlConnection

Beispielhafte Umsetzung: Beispiel (inkl. Video) auf GermanPowerShell

# Anlegen der Datenquelle, also Server\Instanz
$Datenquelle = "RESERVE\GPS"
# Benutzer zum Verbinden
$Benutzer = "Administrator"
# Passwort zum Verbinden
$Passwort = "Start1234"
# Datenbank zum Verbinden
$Datenbank = "Adventure"
# Befehl zum späteren Verbinden zum Server
$VerbindungString = "Server=$Datenquelle;uid=$Benutzer; pwd=$Passwort;Database=$Datenbank;Integrated Security=true;"

# Connection Objekt erstellen
$Verbindung = New-Object System.Data.SqlClient.SqlConnection
# ConnectionString übergeben an Connection Objekt
$Verbindung.ConnectionString = $VerbindungString
# Öffnen der Verbindung
$Verbindung.Open()

# SQL Query zum aufrufen
$Query = "SELECT * FROM [dbo].[DimCustomer]"

# Command Objekt für Befehle erstellen
$Befehl = $Verbindung.CreateCommand()
# Query als CommandText übergeben
$Befehl.CommandText = $Query

# Query als Reader ausführen
$Resultat = $Befehl.ExecuteReader()

# DataTable Objekt für die SQL Daten erstellen
$Tabelle = new-object System.Data.DataTable
# Resultate in die DataTable laden
$Tabelle.Load($Resultat)

# Verbindung zum SQL Server wieder trennen
$Verbindung.Close()

# Zeilen zählen
$Tabelle.Rows.Count
# Spalten zählen
$Tabelle.Columns.Count
# Ausgabe der Daten auf IndexWert 10
$Tabelle.Rows[10]
# Suchen nach CustomerKey
$Tabelle.Rows | where {$_.CustomerKey -eq 11004}
# Prüfen ob Fehler vorhanden sind
$Tabelle.HasErrors

Einmal mehr: mit der PowerShell greifen wir direkt auf die Techniken unter der Windows Haube zu.

Alternativ gibt es auch spezielle DB-Provider Klassen.

Auflistung der verfügbaren Datenprovider auf einem Windows: (hier als Beispiel auf einem Windows 10 Client)

[System.Data.Common.DbProviderFactories]::GetFactoryClasses()

Name                       Description                                InvariantName            AssemblyQualifiedName
----                       -----------                                -------------            ---------------------
Odbc Data Provider         .Net Framework Data Provider for Odbc      System.Data.Odbc         System.Data.Odbc.OdbcFactory, ...
OleDb Data Provider        .Net Framework Data Provider for OleDb     System.Data.OleDb        System.Data.OleDb.OleDbFactory, ...
OracleClient Data Provider .Net Framework Data Provider for Oracle    System.Data.OracleClient System.Data.OracleClient.OracleClientFactory, ...
SqlClient Data Provider    .Net Framework Data Provider for SqlServer System.Data.SqlClient    System.Data.SqlClient.SqlClientFactory, ...

Und natürlich gibt es für die Rubrik ODBC dann wieder einzelne Unterstützungen für unterschiedliche Anbindungen: dBase, Excel, Access, …

Klassische SQLPS

Anm.: Ich habe diese klassische Anleitung einfach mal hier belassen, damit man über die Jahre auch immer mal erkennt, wo man her kam.

Auf Rechnern mit dem SQL Management Studio stehen PowerShell Umgebungen gleich zur Verfügung.

Das bevorzugte Modul für den SQL Server: SQLPS – es wird mit Hilfe des SQL Feature Pack installiert.

SQL 2017 Feature Pack - Downloadquelle

Vorgehensweise bei Installationen (siehe Abhängigkeiten):

  1. CLR Types for Microsoft SQL (SQLSysClrTypes.msi - benötigt Windows Installer 4.5)

  2. Shared Management Objects (SMO - SharedManagementObjects.msi - benötigt CLR Types)

  3. PowerShell Extensions for Microsoft SQL Server (PowerShellTools.msi - benötigt SMO)

Beispielhafte Abfrage mit Cmdlet Invoke-SqlCmd aus dem Modul SQLPS:

$SQLServer = "domvbox-sql" #use Server\Instance for named SQL instances!
$SQLDBName = "AdventureWorks2016CTP3"
$SQlQuery = "SELECT TOP (5) * FROM Person.Person"
$datatable = Invoke-Sqlcmd -Query $SQlQuery -Server $SQLServer -Database $SQLDBName

…tbc… in entsprechenden PowerShell Seminaren mit dieser Vertiefung.

Active Directory

Dieses PowerShell-Topic ist auf jeden Fall ein Extra-Seminar wert ;-). Und an dieser Stelle will ich der Pflege eines AD mit der PowerShell auch ein Extra-Kapitel widmen.

Hinweis

In den folgenden Abschnitten geht es um das klassische Active Directory on-Premise - also nicht um AzureAD, Office bzw. Microsoft 365 oder andere Microsoft Azure Cloud Lösungen mit Benutzerkontenverwaltungen.

Ich halte für Seminare im Bereich „Microsoft Active Directory mit der PowerShell“ weitere Infosammlungen und Codeschnippsel bereit. Die diversen Unterlagen werden den Teilnehmer in den entsprechenden Seminaren bereitgestellt.

  • Git Repo mit PowerShellCodes: git clone https://gitlab.com/joebrandes/powershellcodes.git

  • Screenshotsammlungen zu Seminaren - siehe OneDrive Trainer Joe Brandes https://tinyurl.com/maut9ud

  • diese PowerShell Trainingsunterlage in HTML-Version(en) oder PDF

Es folgt eine beispielhafte AD-Seminarumgebung als virtuelle Hyper-V Domäne. Über die Jahre wurden diese Virtuellen Seminarumgebungen weiter verfeinert und verbessert.

Die aktualisierten und für die jeweiligen Seminare maßgeschneiderten Seminarentwürfe gehen den Trainees direkt im Seminar als LibreOffice Draw und PDF zu.

AD Hyper-V

Active Directory Hyper-V Domäne

Es gibt unterschiedliche Techniken, um ein AD mit Hilfe der PowerShell zu verwalten.

Der Praxis am Nächsten ist das PowerShell Modul ActiveDirectory.


Hier die Abschnitte zum Thema:

Modul ADDSDeployment

Vor dem AD kommt die Installation/Bereitstellung (engl. oft Deployment) einer Gesamtstruktur (engl. Forest) und der ersten Stamm-Domäne (engl. Root-Domain).

Hier eine beispielhafte Erstellung bzw. ein Skript, das man am Ende einer dcpromo Aktion erhält.

Installationsskript und fertige Gesamtstruktur bzw. Domain

Installationsskript und fertige Gesamtstruktur bzw. Domain

Wenn man also vorweg die nötige Software mit dem entsprechenden PowerShell Kommando (siehe Install-WindowsFeature) installiert (siehe Rollen / Features) lässt sich jede Installations- und Deployment-Aktion per PowerShell automatisieren.

Modul ActiveDirectory

Übersicht über die Cmdlets / Techniken des Moduls ActiveDirectory Active Directory Powershell Overview - Archive 2009

AD Modul

PowerShell ActiveDirectory Modul (Microsoft PowerShell Blog 2009)

Wir wollen uns einen Überblick über das Modul ActiveDirectory und seine Nutzung verschaffen. Dabei werden wir auch Partner-Module für die Verwaltung von AD-Techniken kennenlernen.

Deploy ADPowerShell

Für die Bereitstellungen des Moduls ActiveDirectory sind unterschiedliche Schritte nötig. Das Deployment unterscheidet sich je nach genutzter Betriebssystemvariante und Rechnerfunktion in der Domäne.

Wir starten auf den Verwaltungsrechnern unsers Active Directory.

Domaincontroller:

Einfach über den Server-Manager – Tools – Active Directory-Modul für Windows PowerShell direkt aufrufen oder automatisch (AutoLoading für Module) oder manuell (Import-Module) laden.

Alternativ einfach mal die Hilfe für ein Cmdlet aus dem Modul ActiveDirectory aufrufen:

Get-Help Get-ADUser

Und schon listet Get-Module unser gewünschtes Modul!

Kommen wir nun zu Editionen Windows Server in unserer Domäne.

Memberserver:

Die entsprechenden Feature können mittels Server-Manager (GUI) oder natürlich mit der PowerShell nachinstalliert werden:

Import-Module servermanager
Add-WindowsFeature -Name "RSAT-AD-PowerShell" –IncludeAllSubFeature

Und zu guter Letzt suchen wir unsere Workstations in der Domänen auf.

Windows 10/11 Clients:

Bitte die passenden RSAT-Tool (Remote Server Administration Tools) für Ihre Windows Versionen installieren!

Das macht man in den letzten Jahren natürlich auch wieder über die PowerShell:

Get-WindowsCapability -online |
   Where { $_.name -like "*rsat*" } |
   Add-WindowsCapability -online

In der GUI heißt das irgendwie … Features - ich merke mir das immer nicht, wo Windows die Sachen versteckt ;-). Wir haben ja die PowerShell!

Dann kann man mit den AD-Werkzeugen loslegen.

Hinweis

Das Installieren der kompletten RSAT-Toolsammlung kann aktuell (Anm.: Ende 2023) eine knappe Stunde oder auch länger dauern! Über die GUI von Windows ließen sich die 4-5 RSAT Tools manuell auswählen und etwas Zeit sparen.

ADAC nutzen

Das AD Administrative Center - oder nur kurz ADAC - ermöglicht die grafische Nutzung der PowerShell. Im Grunde ist das ADAC einfach nur eine grafische Oberfläche (GUI) für die PowerShell.

Active Directory Administrative Center (ADAC)

Active Directory Administrative Center (ADAC)

In der unteren Hälfte kann man den PowerShell Verlauf für die umgesetzten Aktiven in der ADAC-GUI erkennen, die sich einfach dort herauskopieren und als Basis für eigene Code nutzen kann.

Übungsidee: man erstelle eine neue OU. In dieser OU werden eine neue Globale Gruppe und ein neuer User erstellt. Zuletzt soll der neue User Mitglied der neuen Gruppe werden.

Der folgende Code aus dem ADAC wurde aus Gründen der Lesbarkeit mit PowerShell Zeilenumbrüchen versehen.

Code aus der Verlaufsliste / der PowerShell-History des ADAC
New-ADOrganizationalUnit -Description:"Eine erste OU zum Testen" `
    -Name:"TestingOU" -Path:"DC=firma,DC=local" `
    -ProtectedFromAccidentalDeletion:$true -Server:"DC01.firma.local"

Set-ADObject -Identity:"OU=TestingOU,DC=firma,DC=local" `
    -ProtectedFromAccidentalDeletion:$true -Server:"DC01.firma.local"

New-ADGroup -Description:"Eine erste globale Testgruppe" `
    -GroupCategory:"Security" -GroupScope:"Global" `
    -Name:"TestGruppe" -Path:"OU=TestingOU,DC=firma,DC=local" `
    -SamAccountName:"TestGruppe" -Server:"DC01.firma.local"

New-ADUser -City:"Braunschweig" `
    -Description:"Ein Standarduser für die firma.local Domäne" `
    -DisplayName:"Joe Standard" -GivenName:"Joe" -Name:"Joe Standard" `
    -Path:"OU=TestingOU,DC=firma,DC=local" -SamAccountName:"joestandard" `
    -Server:"DC01.firma.local" -Surname:"Standard" -Type:"user"

# Set-ADAccountPassword -Identity:"CN=Joe Standard,OU=TestingOU,DC=firma,DC=local"
#   -NewPassword:"System.Security.SecureString"
#   -Reset:$true -Server:"DC01.firma.local"

Enable-ADAccount -Identity:"CN=Joe Standard,OU=TestingOU,DC=firma,DC=local" `
    -Server:"DC01.firma.local"

Set-ADAccountControl -AccountNotDelegated:$false `
    -AllowReversiblePasswordEncryption:$false `
    -CannotChangePassword:$false -DoesNotRequirePreAuth:$false `
    -Identity:"CN=Joe Standard,OU=TestingOU,DC=firma,DC=local" `
    -PasswordNeverExpires:$false -Server:"DC01.firma.local" -UseDESKeyOnly:$false

Set-ADUser -ChangePasswordAtLogon:$false `
    -Identity:"CN=Joe Standard,OU=TestingOU,DC=firma,DC=local" `
    -Server:"DC01.firma.local" -SmartcardLogonRequired:$false

Set-ADGroup -Add:@{'Member'="CN=Joe Standard,OU=TestingOU,DC=firma,DC=local"}
    -Identity:"CN=TestGruppe,OU=TestingOU,DC=firma,DC=local" `
    -Server:"DC01.firma.local"

Der Code enthält aufgrund der Automatisierungen innerhalb des ADAC diverse Redundanzen bei den Befehlen. So kann das ADAC beliebige Einträge in seinen Formularen für die AD-Objekte sauber abbilden.

Wir können das Ganze natürlich analysieren und auf eine gewünschte praktische Version shrinken.

Wir bilden also den ganzen Vorgang über Skripting mit eigenen Objekten für OU, User, Group und Membership ab.

Angepasster Code für eigenene neue AD-Objekte
# Neue OU erstellen: DienstagOU
# ------------------
New-ADOrganizationalUnit -Description:"Eine erste OU zum Testen"
    -Name:"DienstagOU" -Path:"DC=firma,DC=local"
    -ProtectedFromAccidentalDeletion:$true -Server:"DC01.firma.local"

# Neue Globale Gruppe erstellen: DienstagGruppe
# ------------------------------
New-ADGroup -Description:"Eine zweite globale Testgruppe" `
    -GroupCategory:"Security" -GroupScope:"Global" `
    -Name:"DienstagGruppe" -Path:"OU=DienstagOU,DC=firma,DC=local" `
    -SamAccountName:"DienstagGruppe" -Server:"DC01.firma.local"

# Neuen Benutzer erstellen: joedienstag
# ------------------------- (siehe folgende Recherchen...)
# s. z.B. https://blog.netwrix.de/2019/11/05/erstellen-neuer-active-directory-benutzer-mit-powershell/
# MS Learn: https://learn.microsoft.com/en-us/powershell/module/activedirectory/new-aduser?view=windowsserver2022-ps
New-ADUser -Name "Joe Dienstag" -GivenName "Joe" `
    -Surname "Dienstag" -SamAccountName "joedienstag" `
    -UserPrincipalName "joedienstag@firma.local" `
    -Path "OU=DienstagOU,DC=firma,DC=local" `
    -AccountPassword(Read-Host -AsSecureString "Bitte Passwort eingeben") `
    -Enabled $true
# ------------------------- (Frage: City / l einstellen -> Braunschwaach ?)

# Mitgliedschaft Benutzer (neu) in Gruppe (neu)
# ---------------------------------------------
Set-ADGroup -Add:@{'Member'="CN=Joe Dienstag,OU=DienstagOU,DC=firma,DC=local"} `
    -Identity:"CN=DienstagGruppe,OU=DienstagOU,DC=firma,DC=local" `
    -Server:"DC01.firma.local"

Und mit entsprechender Vorgehensweise können wir auch noch die Löschung (rekursiv) unserer erstellten Übungs-OU veranlassen.

ACHTUNG ACHTUNG - OU rekursiv löschen!
# ACHTUNG: OU rekursiv löschen! ACHTUNG ACHTUNG ACHTUNG ACHTUNG ACHTUNG ACHTUNG ACHTUNG ACHTUNG ACHTUNG
# -----------------------------------------------------------------------------------------------------
Set-ADObject -Identity:"OU=DienstagOU,DC=firma,DC=local"
    -ProtectedFromAccidentalDeletion:$false -Server:"DC01.firma.local"

Remove-ADObject -Confirm:$false
    -Identity:"OU=DienstagOU,DC=firma,DC=local"
    -Recursive:$true -Server:"DC01.firma.local"

Alle diese Skripte lassen sich natürlich effizient mit Parametern und mittels PowerShell-Funktionen umsetzen.

Gefahr

Insbesondere bei Lösch-Techniken sollte man dann natürlich große Sorgfalt an den Tag legen und entsprechende Nachfragen und Kontrollen einbauen!

LDAP Pfade

Hinweis zu den LDAP-Pfaden - das klären wir auch immer per Praxis in den Seminaren.

Set-Location 'DC=dom2012r2,DC=local'

Anm.: da stört die Vervollständigung mit Tab! Am Besten nutzt man wieder die Vervollständigung durch den Tabulator und entfernt einfach den letzten Backslash, bevor man den Set-Location Befehl mit Return abschließt:

Set-Location '.\DC=dom2012r2,DC=local'

Das letzte Beispiel zeigt die Vervollständigung durch Tab und den gelöschten Backslash am Ende. Das wird im Seminar in diversen Praxisbeispielen gezeigt und trainiert.

Hinweis

Tipp: Recherche zur AD-Verwaltung mit dem Active Directory-Verwaltungscenter (engl. Active Directory Administrative Center - ADAC; Tool: dsac.exe).

Dort kann man mittels der unten eingeblendeten Windows PowerShell-Verlauf History die nötigen PowerShell Aufrufe durch Tests mit AD-Objekten protokollieren lassen und für eigene Umsetzungen entnehmen (siehe Grafik unter ADAC nutzen).

Mit dem Modul Active Directory kann man auch AD LDS verwalten und - wie schon erwähnt - basiert das ADAC komplett auf der PowerShell. Das ADAC stellt quasi ein GUI für die PowerShell-Zugriff auf das AD dar.

Der Zugriff auf das AD findet mittels Webservices (genauer: ADWS - Active Directory Web Services) statt und nicht per LDAP!

Hierzu sind natürlich die entsprechenden Dienste und technische Zugriffsmöglichkeiten (TCP-Port 9389) nötig.

Das Modul stellt eigene Cmdlets (147 Windows Server 2016 Cmdlets) und mit einem PSProvider (ActiveDirectory) auch gleich ein PSDrive (AD:) bereit.

Hinweis

Übung: Bewegen im PSDrive AD: mit richtigen Bezeichner - also den LDAP-DN (Distinguished Name) statt der Namen!

Die Attribute („Eigenschaften“) im AD-Modul weichen von den LDAP-Namen ab.

Beispiel: LDAP l (klein L) ist im AD City und auf den deutschsprachigen AD-Dialogen natürlich Ort.

in Praxisbuch Schwichtenberg (PS 5.0) gibt es S.779 eine Gegenüberstellung mit weiteren Beispielen. Und natürlich findet sich auch mit ein wenig Internetrecherche eine passende Quelle.

Beispiel: https://activedirectorypro.com/ad-ldap-field-mapping/

Die dortigen Grafikerläuterungen habe ich hier mal auf einer Grafik zusammengefasst.

Gegenüberstellung von AD und LDAP-Bezeichnern

Gegenüberstellung von AD und LDAP-Bezeichnern

Für die LDAP-Analyse sei an die Tools ADSI-Editor und lpd.exe erinnert.

ADPowerShell 101

Das Modul ActiveDirectory wurde immer wieder mal Überarbeitungen unterworfen und verhält sich bei der Benutzung teilweise anders als die Standard-PowerShell-Cmdlets und Techniken.

  • AD-Cmdlets laden nicht alle Eigenschaften automatisch; man kann es aber mit immmer mit Wildcard „*“ versuchen

  • Rekursions-Parameter -Recursive (statt sonst -Recurse)

  • Bestätigungen vermeiden / Vorgänge erzwingen mit -confirm:$false (statt sonst -Force)

  • für Set-Location im PSDrive AD: bitte die LDAP-Pfade nutzen und sauber in Zeichenketten übergeben

    Tipp: hier entweder Tab` vermeiden oder geschickt korrigieren!

  • Cmdlets für neue Objekte (New-) geben das erstellte Objekt mit -PassThru zurück

  • Parameter -Server für Domänencontroller

  • Berechtigungen (Authentifizierungen) mit Parameter -Credential nach vormaligem Get-Credential

Zu allen Techniken werden in PowerShell - Active Directory - Seminaren Beispiele und Vertiefungen angeboten.

Erste beispielhafte Aufrufe:

# All commands Module ActiveDirectory
Get-Command -Module ActiveDirectory
# All Users with name (full name not SamAccountName !) like joe
Get-ADUser –Filter { name –like "*joe*" }
# All Computers with name like win
Get-ADComputers –Filter { name –like "*win*" }
# get Domain infos
Get-ADDomain
# get DC Infos
Get-ADDomainController

Wir werden weitere (und ausführlichere) Codebeispiele hierzu kennenlernen und in den Seminaren intensiven praktischen Tests unterziehen.

Bulk Users - Beispiele

Übungen Modul ActiveDirectory

Die meisten Code-Snippets werden von mir über entsprechende Dateien oder digitale Plattformen an die Trainess verteilt.

Hinweis

Die Trainerdateien (siehe „Snippets“; dt. Code-Schnippsel) biete ich über entsprechende Git Repos den Trainees in den Seminaren an. Gitlab Repo: https://gitlab.com/joebrandes/powershellcodes.git

Die Übungen/Beispiel behandeln die klassischen Umsetzungen rund um AD-User, AD-Groups und Organizational Units (OUs).

Praxisbeispiele:

Massenanlegen von OU mit Unter-OUs, Benutzern und Benutzergruppen mit einer CSV-Datei und AD-Skripting:

  • Create Bulk Users in Active Directory (Step-By-Step Guide inkl. Video)

    Ein Klassiker, den ich an dieser gerne kurz darstelle. Das Ganze lässt sich gerne auch als Video nachvollziehen.

    Anm.: in der dortigen Method 1 will der Autor ein Grafiktool vorstellen/bewerben. Wir konzentrieren uns natürlich auf die Method 2: How to Bulk Import AD Users with PowerShell from a CSV file.

  • Aus dem Praxisbuch von Holger Schwichtenberg mit verfeinerten Methoden und Techniken (Sub-Functions) für CSV-Importe oder MDB-Datenbanken.

Hier die Kurzdarstellung des Internet-Klassikers Create Bulk Users for AD

 1# Import active directory module for running AD cmdlets
 2Import-Module activedirectory
 3  
 4# Store the data from ADUsers.csv in the $ADUsers variable
 5$ADUsers = Import-csv C:\it\bulk_users1.csv
 6
 7# Loop through each row containing user details in the CSV file 
 8foreach ($User in $ADUsers) 
 9{
10    # Read user data from each field in each row and assign the data to a variable as below
11    $Username 	= $User.username
12    $Password 	= $User.password
13    $Firstname 	= $User.firstname
14    $Lastname 	= $User.lastname
15    $OU 		= $User.ou # This field refers to the OU the user account is to be created in
16    $email      = $User.email
17    $streetaddress = $User.streetaddress
18    $city       = $User.city
19    # $zipcode    = $User.zipcode
20    $state      = $User.state
21    # $country    = $User.country
22    $telephone  = $User.telephone
23    $jobtitle   = $User.jobtitle
24    $company    = $User.company
25    $department = $User.department
26    $Password = $User.Password
27
28
29	# Check to see if the user already exists in AD
30    if (Get-ADUser -Filter {SamAccountName -eq $Username}) 
31    {
32		 # If user does exist, give a warning
33		 Write-Warning "A user account with username $Username already exist in Active Directory."
34	}
35	else
36	{
37		# User does not exist then proceed to create the new user account
38		
39        # Account will be created in the OU provided by the $OU variable read from the CSV file
40		New-ADUser -SamAccountName $Username `
41            -UserPrincipalName "$Username@winadpro.com" `
42            -Name "$Firstname $Lastname" `
43            -GivenName $Firstname `
44            -Surname $Lastname `
45            -Enabled $True `
46            -DisplayName "$Lastname, $Firstname" `
47            -Path $OU `
48            -City $city `
49            -Company $company `
50            -State $state `
51            -StreetAddress $streetaddress `
52            -OfficePhone $telephone `
53            -EmailAddress $email `
54            -Title $jobtitle `
55            -Department $department `
56            -AccountPassword (convertto-securestring $Password -AsPlainText -Force) -ChangePasswordAtLogon $True
57            
58	}
59}

Und hier die bereitgestellte CSV-Datei:

1firstname,middleInitial,lastname,username,email,streetaddress,city,zipcode,state,country,department,password,telephone,jobtitle,company,ou
2Joshua,L,Lynch,JLynch,JLynch@activedirectorypro.com,2749 Liberty Street,Dallas,75202,TX,United States,Marketing,Roadfox2209,214-800-4820,Marking Specialist,AD Pro,"CN=Users,DC=ad,DC=activedirectorypro,DC=COM"
3Sam,A,smith,ssmith,ssmith@activedirectorypro.com,2749 Liberty Street,Dallas,75202,TX,United States,Marketing,Roadfox2208,214-800-4820,Marking Specialist,AD Pro,"CN=Users,DC=ad,DC=activedirectorypro,DC=COM"

Selbstverständlich müssen die nötigen Anpassungen in Skripten und Steuerdateien für die eigenen Umgebungen vorgenommen werden!

GPO - Beispiele

Die Erstellung, Verknüpfung und Bearbeitung von Group Policy Objects (GPO) ist natürlich ebenfalls eine Technik für die PowerShell.

Verantwortlich ist hier das Modul GroupPolicy mit seinen gut zwei Dutzend Kommandos.

Wer es genau wissen will tippt wieder einmal Get-Command -Module GroupPolicy und erhält Antwort.

Referenzen: Neben den in der Literatur angegebenen Büchern verweise ich hier auch noch auf Buch Gruppenrichtlinien Voges, Dausch aus dem Hanser Verlag und eine recht schöne kompakte Website zum Thema Manage group policies with PowerShell.

Wir steigen mit ein paar Basisbefehlen ein.

Get-Command -Module GroupPolicy

Get-GPO -all
Get-GPO -Name "Name der GP"
Get-GPO -all | Where-Object { $_.displayname -ilike "d*" }  # ilike - ignore CaseSensitivity

# Default Domain Policy
Get-Gpo -Id 31b2f340-016d-11d2-945f-00c04fb984f9

# Default Domain Controllers Policy
Get-Gpo -Id 6ac1786c-016f-11d2-945f-00c04fb984f9

# List all GPOs
Get-Gpo -All

# Filter by name
Get-Gpo -All | Where-Object DisplayName -match "Default Domain"

Backup & Restore

# Datensicherung für alle bestehenden FBI-Gruppenrichtlinien
Get-GPO -all | where { $_.displayname -like "*FBI*" } | Backup-GPO -Path –"~\Desktop\GPO_backups"

# WiederherstellenRestore-GPO "GP FBI" -Path "~\Desktop\GPO_backups"
Restore-GPO "GP FBI" -Path "~\Desktop\GPO_backups"
Restore-GPO -all -Path "~\Desktop\GPO_backups"

Berichte

GPO-Berichte lassen sich in HTML und XML Formaten erstelllen. Der Vorteil bei XML ist die mögliche Weiterverarbeitung mit der PowerShell.

Get-GPOReport -Id 31b2f340-016d-11d2-945f-00c04fb984f9 -ReportType Html -Path ~\Desktop\Report.html
Get-GPOReport -Name "GPO NAME" -ReportType Xml -Path ~\Desktop\Report.xml

Erstellen und Ändern von GPOs und Verknüpfungen

# New GPO
New-GPO -Name "TESTING 01" -Comment "Joe B. with PowerShell"

# Object of GPO
$GPO = Get-Gpo -Name "TESTING 01"

# Create a new link
New-GPLink -Guid $GPO.Id -Target "OU=TestingOU,$((Get-ADDomain).DistinguishedName)" -LinkEnabled Yes -Order 1
# Change/Remove existing link
Set-GPLink -Guid $GPO.Id -Target "OU=TestingOU,$((Get-ADDomain).DistinguishedName)" -LinkEnabled No

# which GPOs are assigned to OU
Get-GPInheritance "OU=TestingOU,$((Get-ADDomain).DistinguishedName)"

Berechtigungen

# Which Permissions for OU
Get-GPPermission -Name "TESTING 01" -All
GPO vs. Registry

Im Grunde handelt es sich bei Gruppenrichtlinien um Registry-Tweaks basierend auf unterschiedlichen Vorlagen und Vorgehensweisen.

Der Vorlagen-Charakter wird besonders deutlich, wenn man sich in der Domäne mit den sogenannten Adminstrativen Vorlagen / Administrative Templates beschäftigt.

Als Beispiel für GPO vs. Registry ein kleines Beispiel.

Wir wollen den Windows Rechner automatisch sperren lassen.

GPO

Computerkonfiguration / Richtlinien / Windows-Einstellungen
  / Sicherheitseinstellungen / Lokale Richtlinien / Sicherheitsoptionen

Registry

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
# Sollte es den folgenden Wert
InactivityTimeoutSecs
# hier noch nicht geben, so muss er als DWORD 32-Bit Wert erstellt werden

AD Dot.NET Klassen

Man nutzt die.NET Klasse System.DirectoryServices mit Sub-Klasse DirectoryEntry (oder DirectoryEntries) oder DirectorySearcher.

Technische Kurzerläuterung:

Die Klassen des .NET Namensraums System.DirectoryServices sind eine Kapselung des ADSI (Active Directory Service Interface).

Für die Nutzung greift man häufig auch einfach auf den Datentyp [ADSI] in der PowerShell zurück.

Kurzdarstellung / Gegenüberstellung: (Namensraum LDAP bitte in UpperCase)

$obj = New-Object System.DirectoryServices.directoryEntry("LDAP://domserver1")
# oder
$obj = [ADSI] "LDAP://domserver1"

Für die Anwendung dieser klassischen und direkten Umsetzung über die Dot.Net-Technik finden sich viele beispielhafte Aktionen mit der PowerShell im freien PowerShell Cookbook

Anm.: Cookbook bis PowerShell 3.0 - hier: Chapter 26 ab S. 669ff. Ich bleibe ab hier mal im englischen Original.

Problem: Create an Organizational Unit

You want to create an organizational unit (OU) in Active Directory.

Solution:

To create an organizational unit in a container, use the [adsi] type shortcut to bind to a part of the Active Directory, and then call the Create() method.

$domain = [adsi] "LDAP://localhost:389/dc=Fabrikam,dc=COM"
$salesOrg = $domain.Create("OrganizationalUnit", "OU=Sales")
$salesOrg.Put("Description", "Sales Headquarters, SF")
$salesOrg.Put("wwwHomePage", "http://fabrikam.com/sales")
$salesOrg.SetInfo()

Anm.: das besagte Cookbook aus dem Oreilly Verlag finden Sie bei Literatur PS Cookbook.

Wichtig

Meine Trainees bekommen hier weitergehende Infos und Unterlagen

AD WMI/CIM-Klassen

Viele beispielhafte Aktionen mit der PowerShell finden sich wieder auch im freien PowerShell Cookbook und in meinen Trainingsunterlagen.

Tipp

Man benutze Get-WmiObject für Remote/WinRM, denn Get-CimInstance kennt keinen Parameter -credential!

Hier ein paar Beispielzeilen für WMI/CIM:

# Alle Konten
Get-CimInstance Win32_Account
# bzw.
Invoke-Command -ComputerName domvbox2012r2 -Credential $cred -SkriptBlock { ... }

# Nur die Benutzerkonten erreicht man mit:
Get-CimInstance Win32_UserAccount
# Nur die Gruppen erreicht man mit:
Get-CimInstance Win32_Group

# gezielt Objekte herausfiltern:
# Name und Domäne der Benutzerkonten, deren Kennwort niemals verfällt
Get-CimInstance Win32_useraccount |
    Where-Object {$_.PasswordExpires -eq 0 } |
    Select-Object Name, Domain
# alternativ:
Get-CimInstance Win32_Useraccount -filter “PasswordExpires=’false’” |
    Select-Object Name, Domain

# ob Benutzer FBI\FoxMulder einen Bildschirmschoner
# auf dem Computer AgentPC04 aktiviert hat.
Get-CimInstance Win32_Desktop -computer AgentPC04 |
    Where-Object { $_.Name -eq “DBI\FoxMulder” } |
    select-Object screensaveractive

Erinnerung: wo diese Beispielzeilen herkommen (siehe Cookbook, Netz, …) gibt es noch tonnenweise solche und andere Lösungen!

Viele dieser Lösungen ließen sich auch mit den modernisierten PowerShell Cmdlets/Kommandos der Modultechniken ADPowerShell lösen.

AD mit PSCX

PSCX – PowerShell Community Extensions: PSCX auf powershellgallery.com

Gefahr

Bitte möglichst PSCX mit Version 4 nutzen! In den 3er Versionen von PSCX kann es zu Problemen mit gleichnamigen Cmdlets/Befehlen anderer PowerShell Module kommen:

Beispiel: Get-ADObject bei PSCX 3.x und ActiveDirectory Modul!

Beim Einsatz von PSCX auf Rechnern mit AD-Verwaltungstechnik sollte man ggf. mittels Get-Command checken, dass man die richtigen AD-Varianten (also: Microsoft Modul ActiveDirectory) nutzt.

Die hier für AD-Verwaltung integrierten Cmdlets werden durch die modernisierte AD-Modultechniken der PowerShell Standard-Module nicht mehr benötigt!

Aber natürlich interessiert man sich für auch die anderen Cmdlets der PSCX:

  • Show-Tree,

  • Out-Speech,

Im Grunde gehören die Umsetzungen des Kollegen Keith Hill zum guten Ton der PowerShell Profilgestaltung. Allerdings sind viele der Ideen und Umsetzungen mittlerweile auch im Standard der PowerShell zu finden.

Fernverwaltungen

Idee/Ziel: Fernzugriffe auf Remote-Systeme mit der PowerShell (Unsplash: kelly-sikkema-HprPUHnjDgk-unsplash - cropped)

Fernverwaltungen mit Windows und der PowerShell

Fernverwaltungen (Unsplash: kelly-sikkema-HprPUHnjDgk-unsplash - cropped)


Hier die Abschnitte zum Thema:

Remoting - Allgemein

Allgemeine Tools und Anmerkungen rund um die Fernverwaltung von Windows und Windows Servern.

Remoting ohne Domain

Oder anders gesagt: Remoting mit Problemchen ;-)

Kurzdarstellung von Problemen in NICHT-DOMAIN Umgebungen

Natürlich sind in der späteren praktischen Anwendung in einer sauberen Infrastruktur alle Fernaufrufe möglich und funktionieren.

Aber: in einer Seminarumgebung (oft mit P2P ohne Domäne) kann es zu diversen Problemen kommen und diese gilt es zu analysieren und zu beheben.

  • Alle Tools und Cmdlets entscheiden selbst über die Art der Netzwerkkommunikation mit dem Remotesystem – es gibt keine singuläre Technik hierfür. Die Konfiguration der Netzwerke und Sicherheitseinstellungen auf den beteiligten Systemen gestaltet sich somit unterschiedlich.

  • Distributed Component Object Model (DCOM):

    Erweiterungen für COM-Komponenten zur Kommunikation mittels Remote Procedure Calls (RPC)

    Nachteile: alt (mit NT 4.0 eingeführt), schwerfällig, unflexibel, Firewall problematisch wegen dynamischer Ports

    Einsatz bei: WMI (Windows Management Instrumentation), MMC (Microsoft Management Console)

  • Berechtigungen / Authentifizierungen:

    In manchen (Seminar)Umgebungen haben wir nur P2P ohne Domäne - also ohne zentrale Verwaltung von Benutzerkonten und Rechten und ohne passende Netzwerkkonfigurationsprofile (Domäne statt Privat)

    Anm.: bei Profil Öffentlich geht/ging oftmals gar nichts ohne saubere Anpassung der Profile und/oder Firewall-Konfigurationen. Diverse Problemlösungen/Ansätze (für Nicht-Domänen-Umgebungen) finden sich bei Weltner Kap. 22/23.

Hinweis

Die Anmerkungen zu den Problemen mit falschen Netzwerkprofiltypen (z.B. Privat statt Domäne) ist in aktuellen AD-Domains (Windows Server 2019/2022) vernachlässigbar.

Es folgen nun die unterschiedlichen Remotezugriffsmöglichkeiten.

Remoting mit CLI-Tools

Viele Tools/Cmdlets besitzen Parameter für die nötigen Remotezugriffe.

Beispiel: Einfache SMB-Zugriffe mit –Path

PS E:\_temp> Get-ChildItem -Path \\win10\testfreigabe\

Verzeichnis: \\win10\testfreigabe

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       11.10.2016     17:47         211225 Screenshot (1).png
-a----       11.10.2016     17:47         229877 Screenshot (2).png

Funktioniert aber natürlich nur, wenn man berechtigt ist auf die Freigabe zugreifen zu dürfen! sonst kommt:

PS E:\_temp> Get-ChildItem -Path \\win10\testfreigabe
Get-ChildItem : Der Pfad "\\win10\testfreigabe" kann nicht gefunden werden, da er nicht vorhanden ist.
In Zeile:1 Zeichen:1
+ Get-ChildItem -Path \\win10\testfreigabe
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (\\win10-\testfreigabe:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

Als Lösung hier einfach eine „net use“-Remoteanmeldung zuvor durchführen.

Wenn man kein Laufwerk mappen will, dann einfach:

UNC Fernanmeldung
PS E:\_temp> net use \\win10\ipc$ * /User:joeb
Geben Sie das Kennwort für \\win10\ipc$ ein:
Der Befehl wurde erfolgreich ausgeführt.

Konsolenbefehl wie systeminfo.exe (Remote hier ein Adminkonten nötig)

PS E:\_temp> systeminfo.exe /s win10 /U win10\joebadmin /P

Hostname:                                      WIN10
Betriebssystemname:                            Microsoft Windows 10 Pro
Betriebssystemversion:                         10.0.14393 Nicht zutreffend Build 14393
Betriebssystemhersteller:                      Microsoft Corporation
Betriebssystemkonfiguration:                   Eigenständige Arbeitsstation
Betriebssystem-Buildtyp:                       Multiprocessor Free
...

oder schtasks.exe

PS E:\_temp> schtasks.exe /query /s win10 /U joebadmin /p
Geben Sie das Kennwort für joebadmin ein, mit dem der Befehl ausgeführt wird: *******

Ordner: \
Aufgabenname                             Nächste Laufzeit       Status
======================================== ====================== ===============
OneDrive Standalone Update Task          13.10.2016 22:30:07    Bereit
Optimize Start Menu Cache Files-S-1-5-21 Nicht zutreffend       Bereit
User_Feed_Synchronization-{413A22B3-D61A 12.10.2016 23:16:38    Bereit
...

RSAT

Die RSAT (Remote Server Administration Tools) werden auch im entsprechenden Unterkapitel beim Active Directory beleuchtet.

Insbesondere die Bereitstellung der notwendigen Techniken auf unterschiedlichen Windows Betriebssystemen wird dargestellt (Deploy ADPowerShell).

Hinweis

Da die RSAT Tools auch die jeweiligen PowerShell Module für die gewünschten Verwaltungstechniken mitbringen, geht es hier auch um die Fernverwaltung mit der PowerShell.

Auf einem Windows Client kann man die grafische Verwaltung für die Bereitstellung der Tools nutzen.

RSAT auf Clients bereitstellen (über GUI)

RSAT auf Clients bereitstellen (über GUI)

Hinweis

Die Bereistellung/Installation kann sehr lange dauern.

Der nachfolgende Oneliner für alle RSAT-Tools bis zu 2 h!

Über die PowerShell kann man ALLE RSAT-Tools über einen Oneliner installieren lassen:

Get-WindowsCapability -Online | Where-Object { $_.Name -like "*rsat*" } |
   Add-WindowsCapability -Online

Beispielhafte Zusatz-Cmdlets:

  • Windows 8.1: 1264 Cmdlets/Funktionen

  • Windows 8.1 + RSAT: 2211 (!)

  • Windows 11 + RSAT (Winddows Server 2022): 3363 Aufrufe

Tipp

Erinnerung / Übungsszenario:

Active Directory-Verwaltungscenter nutzen

Im ADAC: neue OU / User und dann unten Windows PowerShell-Verlauf History auswerten!

Befehle/Kommandos kopieren und anpassen führt zu Skripting/Automatisierungen!

Beispielaufruf Modul ActiveDirectory

Get-ADUser -Filter { Name -like "*Joe*" }

OpenSSH Server

Microsoft hat sich seit dem Abschied von Steve Ballmer mit der neuen Führungsriege rund um Satya Nadella den Open Source Entwicklungen und der dortigen freien Software (siehe GNU/Linux) geöffnet.

Die PowerShell verfügt seit langem über den Standardclient dieser Entwicklerumgebungen - den OpenSSH Client aus der dortigen Umgebung für FreeBSD und Linux. OpenSSH ist für alle gängigen Betriebssysteme und Hardware-Plattformen einschließlich Windows verfügbar.

Microsoft stellt den OpenSSH-Client automatisch und den OpenSSH-Server per optionalem Feature bereit.

# Admin PowerShell oder alternative Admin-GUI
Get-WindowsCapability -Online | Where-Object { $_.Name -like "*openssh.server*" } |
   Add-WindowsCapability -Online

Der OpenSSH-Server sollte noch über die Dienste der Maschine auf Start und Starteigenschaften analysiert und konfiguriert werden.

PS C:\Users\Administrator.FIRMA> Get-Service -Name sshd

Status   Name               DisplayName
------   ----               -----------
Stopped  sshd               OpenSSH SSH Server


PS C:\Users\Administrator.FIRMA> Get-Service -Name sshd | Select-Object -Property *


Name                : sshd
RequiredServices    : {}
CanPauseAndContinue : False
CanShutdown         : False
CanStop             : False
DisplayName         : OpenSSH SSH Server
DependentServices   : {}
MachineName         : .
ServiceName         : sshd
ServicesDependedOn  : {}
ServiceHandle       : SafeServiceHandle
Status              : Stopped
ServiceType         : Win32OwnProcess
StartType           : Manual
Site                :
Container           :

Wir sollten also in diesem Fall noch den Server starten und natürlich auch für eine automatischen Start sorgen.

Start-Service -Name sshd
# Check Status
Get-Service -Name sshd | Select-Object -Property *
# Set StartType
Set-Service -Name sshd -StartupType Automatic

Die Verbindung zum OpenSSH-Server kann dann über einen beliebigen SSH-Client erfolgen:

  • SSH-CLI in PowerShell

  • Putty

  • MobaXterm (gerne auch mit SFTP/Dateihandling)

Beispielhafter Aufruf in Konsole:

ssh firma\Administrator@server-IP
# this is Standard CMD
# start a PowerShell session:
powershell

Und schon hat man eine sichere PowerShell Verbindung per SSH.

SSH mit MobaXterm auf eine Windows Gateway-Server

SSH mit MobaXterm auf eine Windows Gateway-Server

Remoting - PowerShell

Die folgenden Techniken konzentrieren sich auf die Umsetzung mit der PowerShell.

PS Remote Cmdlets

Die PowerShell stattet einige Kommandos mit einem Parameter aus, welcher den Zugriff auf andere Computer erlaubt. Natürlich nur, wenn entsprechende Berechtigungen und Authentifizierungen vorliegen.

Cmdlets mit Parameter –Computername: (einfache Suche - mehr s.u.)

Get-Command -ParameterName Computername

Wir erhalten Cmdlets mit eingebauter Fernwartung. Hier genauer: ohne WS Management, also bei Windows ohne WinRM (Windows Remote Management)! Erklärung: IT-Visions WS-Management

Übungen

Finde alle Cmdlets / Kommandos, die im Parameter ComputerName enthalten und gleichzeitig nicht den Begriff Session:

Get-Command | where { $_.parameters.keys -contains "ComputerName"
   -and $_.parameters.keys -notcontains "Session"}

Finde alle Cmdlets/Kommandos, die im Parameter credential enthalten, also eine eigene Authentifizierung erlauben.

Get-Command | where { $_.parameters.keys -contains "credential" }

Beispiel: Cmdlet Get-WmiObject (im Beispiel: Adminkonto benötigt mit Credential)

PS E:\_temp> Get-WmiObject -Class Win32_BIOS -ComputerName win10
Get-WmiObject : Zugriff verweigert (Ausnahme von HRESULT: 0x80070005 (E_ACCESSDENIED))
In Zeile:1 Zeichen:1
+ Get-WmiObject -Class Win32_BIOS -ComputerName win10-epz
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

PS E:\_temp> $cred = Get-Credential win10\joebadmin
PS E:\_temp> Get-WmiObject -Class Win32_BIOS -ComputerName win10 -Credential $cred

SMBIOSBIOSVersion : VirtualBox
Manufacturer      : innotek GmbH
Name              : Default System BIOS
SerialNumber      : 0
Version           : VBOX   - 1

Beispiel: Cmdlet Get-Hotfix (hier ebenfalls Adminkonto benötigt und Credential)

PS E:\_temp> Get-HotFix -ComputerName win10 -Credential $cred

Source        Description      HotFixID      InstalledBy          InstalledOn
------        -----------      --------      -----------          -----------
WIN10         Update           KB3176935     NT-AUTORITÄT\SYSTEM
WIN10         Update           KB3176936     NT-AUTORITÄT\SYSTEM
WIN10         Update           KB3176937     NT-AUTORITÄT\SYSTEM
WIN10         Security Update  KB3188128     NT-AUTORITÄT\SYSTEM
WIN10         Update           KB3194496     NT-AUTORITÄT\SYSTEM  10.05.2016 00:00:00

Anm.: Get-Process, Get-EventLog machen oft ohne Domäne Probleme, obwohl nach Problemlösungen (Troubleshooting) der Dienst RemoteRegistry auf dem Zielrechner aktiviert worden ist.

PS E:\_temp> $dienst = Get-WmiObject -Class Win32_service -Filter 'Name="RemoteRegistry"' -ComputerName win10 -Credential $cred
PS E:\_temp> $dienst

ExitCode  : 0
Name      : RemoteRegistry
ProcessId : 340
StartMode : Auto
State     : Running
Status    : OK

Testskript findet heraus, ob Ports

  • 137-139 (Namensauflösung),

  • 445 (SMB) und

  • 5985 (PowerShell Remoting via http)

verfügbar sind.

Weltner – 22.1.ps1 – Funktion: Test-NetworkPort - siehe PowerShellCodes

PS E:\_temp> Test-NetworkPort

Port Open Type ComputerName
---- ---- ---- ------------
139  True TCP  WIN10
445  True TCP  WIN10
5985 True TCP  WIN10

PS Remote Management

Jetzt haben wir keine Speziallösungen der einzelnen Tools und Cmdlets mehr, sondern eine einheitliche Fernverwaltungsumgebung (Remote Host) inklusive Sitzungsmanagement (Sessions).

Notwendige Technik: WinRM (Windows Remote Management)

Minimal-Anforderungen für WinRM Services (Versionen 2.0+)

  • Microsoft .NET Framework 2.0 oder höher

  • Windows PowerShell 2.0 oder höher

  • Windows Remote Management (WinRM) 2.0

WinRM-Systemdienst starten

  • inkl. Firewall

  • Netzwerkverbindungstyp beachten - (oft) kein Profil Öffentlich möglich!

  • LokalAccountTokenFilterPolicy setzen

  • Firmen/Domänen - die Gruppenrichtlinie (Group Policy)

    Computer Configuration\Administrative Templates\Windows Components\Windows Remote Management (WinRM)\WinRM service

Unterdrücken der Nachfragen und Problem mit „Öffentlichen Netzwerkadaptern“ umgehen:

Enable-PSRemoting –SkipNetworkProfileCheck –Force

Testen der Umgebungen mit

PS E:\_temp> Test-WSMan -ComputerName Win10

wsmid           : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor   : Microsoft Corporation
ProductVersion  : OS: 0.0.0 SP: 0.0 Stack: 3.0

Dieser Test benötigt keine Rechte, sondern checkt per geeignetem Request nur die Funktionalität.

Anm.: generell: WinRM-Service muss überhaupt laufen.

Get-Service –Name WinRM                            # Status abfragen
Set-Service –Name WinRM –StartupType Automatic     # Start mit Adminrechten

Falls man dann mal von einer Nicht-Domänen-Maschine auf eine Domänen-Maschine zugreifen muss/will, dann bekommt man Probleme mit dem WinRM-Systemdienst auf der Client-Maschine (P2P-Konf.), weil dem Partner nicht vertraut wird und kein Kerberos oder https genutzt wird (siehe später PSWA – PowerShell WebAccess).

Problemlösung auf P2P-Client (Zugriff auf Dom-Server mit PSSession gewünscht)

Set-Item WSMan:\localhost\Client\TrustedHosts -Value "10.0.2.33, Win10" –Force
Restart-Service WinRM

Hinweis

Benutzer mit Möglichkeiten zum Remote PowerShell nutzen, sollten Mitglieder der Gruppe Remotverwaltungsbenutzer sein!

PS Sessions

Ähnlich wie bei openSSH Technik verfügen wir nun über Interaktive Sitzungen basierend auf PowerShell/WinRM Techniken.

Enter-PSSession –Computername Win10

komplette Anmeldung inkl. –credential (bei P2P immer nötig!)

$cred = Get-Credential
Enter-PSSession -ComputerName Win10 -credential $cred

oder:

Enter-PSSession –ComputerName Win10 -Authentication Negotiate -credential Win10\joebadmin

aktuelle Konsolenmaschine ermitteln:

[System.Environment]::MachineName

Beenden der PowerShell Remote Session:

Exit-PSSession

Befehle über Remote absetzen mittels Invoke-Command:

Bei Berechtigungsproblemen immer wieder gerne mit der Credential Lösung.

Invoke-Command Aufrufe
Invoke-Command -ComputerName Win10 -scriptblock { Get-Service b* }
Invoke-Command -ComputerName Win10 -scriptblock { Get-Service | sort status | ft name,status }
Invoke-Command - ComputerName Win10
-Script { "Computername: " + [System.Environment]::MachineName ; "Zeit: " + [DateTime]::Now ; "Sprache: " + (Get-Culture) }
Invoke-Command - ComputerName Win10 -Script { ping www.it-visions.de }

Gerne natürlich auch ein entsprechendes Skript als Datei:

Invoke-Command -ComputerName Win10 -scriptblock { c:\temp\WPS2_Computername.ps1 }

Diese Aufrufe sind auch für mehrere Rechner gleichzeitig möglich!

Cmdlets zur Sitzungsverwaltung

Es folgt ein Überblick über die Cmdlets zur Sitzungsverwaltung:

Get-Command *PSSession*
  • New-PSSession
    Erzeugen einer neuen Sitzung auf dem lokalen oder einem entfernten Computer
  • Get-PSSession
    Liste aller Sitzungen, die aus der aktuellen Sitzung heraus gestartet wurden
    (zeigt aber nicht Sitzungen, die andere Computer auf dem lokalen Computer geöffnet haben)
  • Remove-PSSession
    entfernt eine Session oder alle Sessions (Remove-PSSession *)
  • Enter-PSSession
    Start einer interaktiven Sitzung auf dem lokalen oder einem entfernten Computer
  • Exit-PSSession
    Ende einer interaktiven Sitzung
  • Disable-PSSessionConfiguration
    Sperren einer/aller Sitzungskonfigurationen
  • Enable-PSSessionConfiguration
    Entsperren einer/aller Sitzungskonfigurationen
  • Get-PSSessionConfiguration
    Auflisten der Sitzungskonfigurationen
  • Register-PSSessionConfiguration
    permanente Registrierung einer Sitzungskonfiguration
  • Set-PSSessionConfiguration
    Setzen von Eigenschaften einer Sitzungskonfiguration
  • Unregister-PSSessionConfiguration
    Löschen einer Sitzungskonfiguration

alles Weitere:

  • ab S. 229 Schwichtenberg PowerShell 4.0

  • ab S. 742 Weltner PowerShell 5.0

PS Web Access

PSWA - PowerShell WebAcces

Die Idee: Fernzugriff über Browser auf Firmenrechner mit der PowerShell.

Diese Idee ist auch über das Admin Center umsetzbar!

Hier nur eine kurze Darstellung – gehört zu vertiefenden Betrachtungen mit Active Directory und Server.

Auf Server Rolle IIS und Feature PSWA nötig:

  • Rolle „Web Server (IIS)“

  • Feature „Windows PowerShell/Windows PowerShell Web Access“

Gerne auch per PowerShell installieren:

Install-WindowsFeature -name web-server, windowspowershellwebaccess -IncludeManagementTools
# Installieren/Bereitstellen von Test-Zertifikat
Install-PswaWebApplication -UseTestCertificate

Anm.: jetzt Server erreichbar unter https://localhost/pswa

Regel (hier sehr „frei“) für die Erreichbarkeit von PSWA erstellen:

Add-PswaAuthorizationRule -UserName * -ComputerName * -ConfigurationName *
Add-PswaAuthorizationRule -usergroupname domain\administrators -ComputerName * -ConfigurationName *

Konfiguration – hier nur 3 gleichzeitige Verbindungen

# C:\Windows\Web\PowerShellWebAccess\wwwroot\web.config
<appSettings>
   <add key="maxSessionsAllowedPerUser" value="3"/>
</appSettings>

Screenshots zur PSWA-Technik:

Warnung

Im Gegensatz zum folgenden Screenshot habe ich bei aktuellen Tests mit Windows Server 2022 und Windows 11 Clients immer wieder Probleme mit den selbst ausgestellten Test-Zertifikaten gehabt! Bitte alternative Browser wie Mozilla Firefox ausprobieren/bereithalten.

Bei der Nutzung des Admin Center ist es oft umgekehrt mit der Browserfunktionalität!

Hier die IE/Edge Screenshots:

PSWA Login

PowerShell WebAccess (PSWA) - Login

PSWA Konsole

PowerShell WebAccess (PSWA) - Konsole

Die bis hierhin dargestellten Remotetechniken will Microsoft gerne unter einem Dach vereinen. Das bringt es zum Admin Center.

Admin Center

Die Technik von Microsoft um alle Windows und Windows Server Verwaltungstechniken unter einer Haube zu vereinen. Und natürlich bringt Microsoft hier auch gleich noch die eigene Azure Cloud mit ein.

Links zu weiterführenden Infos zum Windows Admin Center:

Wenn man die Installation und Nachinstallation der AD-Extension vollzogen hat, dann kann man für das Active Directory die Verwaltung über das Admin Center durchführen.

Windows Admin Center mit AD-Verwaltung

Windows Admin Center mit AD-Verwaltung

Und eine der Standardtechniken des Windows Admin Center ist natürlich die PowerShell (als integrierte PSWA-Lösung).

Windows Admin Center mit PowerShell Konsole

Windows Admin Center mit PowerShell Konsole

Microsoft bietet für die Cloud basierten Dienste nur noch die jeweiligen Admin Center an. Die weiterführenden und detaillierteren Umsetzungen erwarten immer PowerShell Umsetzungen!

Specials

Diverse weitere Beispielskripte zu Themen

  • NTFS Sicherheitseinstellungen (NTFS-Berechtigungen – Get-ACL)
    Schwichtenberg Praxisbuch 5.0 Kap. 46 Sicherheitseinstellungen
  • Registrierungsdatenbank (Registry)
    Übung(en) zur Registry nach Weltner Cookbook oder Schwichtenberg Praxisbuch Kap. 37
  • WMI / CIM,

  • Weltner Cookbooks,

  • …tbc…

… in der bereitgestellten scriptlines.ps1-Datei von Trainer J. Brandes.

Literatur

Die aktuellen PowerShell Bücher (Autoren: Weltner, Schwichtenberg) liefern die Schwerpunkte zu unserer Seminarpraxis und den Übungen.

Hinweis

Texte und Anmerkungen zu den Büchern von Amazon bzw. Verlagen


Hier die Infos zu den Büchern:

Schwichtenberg - PS 5 - Core 7

Und mit dieser Auflage wurde die 1400-Seiten-Grenze knapp verpasst ;-)

Windows PowerShell 5 und PowerShell 7: Das Praxisbuch

Windows PowerShell 5 und PowerShell 7:: Das Praxisbuch
Gebundene Ausgabe – 11. Mai 2020
Dr. Holger Schwichtenberg
Gebundene Ausgabe: ca. 1400 Seiten (!!)
Verlag: Carl Hanser Verlag GmbH & Co. KG
Sprache: Deutsch
ISBN-10: 3446459138
ISBN-13:  978-3446459137

Das PowerShell-Praxisbuch für Einsteiger und Profis - jetzt in der 4. Auflage für PowerShell 5.

Windows PowerShell 5 und PowerShell 7: Das Praxisbuch

Windows PowerShell 5 und PowerShell 7: Das Praxisbuch

Das Windows PowerShell-Praxisbuch für Einsteiger und Profis

Die Windows PowerShell ist Microsofts mächtige Lösung für die kommandozeilenbasierte Administration und Scripting in Windows. Administratoren bietet diese aktualisierte und erweiterte Neuauflage eine umfassende Darstellung der vielfältigen Einsatzmöglichkeiten der PowerShell sowie ergänzender Commandlet- und Klassenbibliotheken. Sie enthält über 2.000 Code-Beispiele für die kommandozeilenbasierte Administration und das Scripting in Windows, Linux und macOS.

Profitieren Sie vom Know-how des bekannten .NET- und Scripting-Experten Dr. Holger Schwichtenberg

In Teil 1 und 2 des Buches erhalten Sie eine Einführung in die Konzepte der PowerShell und lernen dann in Teil 3, wie Sie PowerShell in zahlreichen Anwendungsgebieten praktisch einsetzen. Fortgeschrittene Administratoren erfahren schließlich in Teil 4, wie Sie die PowerShell erweitern können, u. a. durch die Entwicklung eigener Commandlets.

  • Das Buch wurde auf PowerShell 7 aktualisiert. Es kann aber auch für die Vorgängerversionen eingesetzt werden; die Unterschiede sind im Buch beschrieben.

  • Berücksichtigt werden alle Windows-Versionen ab Windows XP bzw. Windows Server 2003 einschließlich der neuesten Versionen von Windows 10 und Windows Server 2019.

  • Das Buch beschreibt auch die Verwendung von PowerShell Core auf macOS und Linux.

  • Codebeispiele, PowerShell-Kurzreferenz, Feedback-Möglichkeiten und Forum finden Sie auf der Website zum Buch.

EXTRA: E-Book inside. Systemvoraussetzungen für E-Book inside: Internet-Verbindung und Adobe-Reader oder Ebook-Reader bzw. Adobe Digital Editions.

(Back) Windows PowerShell 5 und PowerShell 7: Das Praxisbuch

(Back) Windows PowerShell 5 und PowerShell 7: Das Praxisbuch

AUS DEM INHALT: (übernommen aus Vorauflagen)

Konzepte: Commandlets, Pipelining, PowerShell-Navigationsmodell, Sprachsyntax und Skripte, PowerShell-Werkzeuge, Module, Zugriff auf .NET, COM und WMI, Fernzugriffe, Jobs, Workflows, Desired State Configuration, Fehlersuche Tipps und Tricks

Einsatzbeispiele: Dateisystem, Backup, Bitlocker, Dokumente, XML, Relationale Datenbanken, Registry, Computerverwaltung, Hardwareverwaltung, Softwareverwaltung, Prozessverwaltung, Systemdienste, Netzwerk, Sicherheit, Ereignisprotokolle, Leistungsdaten, Active Directory, Gruppenrichtlinien, Hyper-V, IIS, Benutzeroberflächen

Erweiterungen: Erweiterungen installieren, Entwickeln von eigenen Commandlets, Erstellen von Modulen, Hosting der PowerShell

Schwichtenberg - PS 5 - Core 6

Windows PowerShell 5 und PowerShell Core: Das Praxisbuch

Windows PowerShell 5 und PowerShell Core:: Das Praxisbuch
Gebundene Ausgabe – 06. November 2017
Dr. Holger Schwichtenberg
Gebundene Ausgabe: 1231 Seiten
Verlag: Carl Hanser Verlag GmbH & Co. KG
Sprache: Deutsch
ISBN-10: 3446453318
ISBN-13: 978-3444453319

Das PowerShell-Praxisbuch für Einsteiger und Profis - jetzt in der insgesamt 6. Auflage.

Das Windows PowerShell-Praxisbuch für Einsteiger und Profis

Administratoren bietet diese aktualisierte und erweiterte Neuauflage eine kompakte Darstellung der vielfältigen Einsatzmöglichkeiten der PowerShell sowie ergänzender Commandlet- und Klassenbibliotheken. Sie enthält über 2.000 Code-Beispiele und beschreibt 640 Commandlets für die kommandozeilenbasierte Administration und das Scripting in Windows, Linux und MacOS.

Diese 2. Auflage (des PowerShell 5 Praxisbuchs) behandelt Windows PowerShell 5 und PowerShell Core 6, kann aber auch für die Vorgängerversionen verwendet werden; die Unterschiede sind im Buch beschrieben. Zusätzlich aufgenommen wurden die Themen Docker-Verwaltung mit PowerShell, PowerShell mit Windows Nano Server.

  • Berücksichtigt werden alle Windows-Versionen ab Windows XP bzw. Windows Server 2003 einschließlich der neuesten Versionen Windows 10 und Windows Server 2016

  • Codebeispiele, PowerShell-Kurzreferenz, Feedbackmöglichkeiten und Forum finden Sie auf der Website zum Buch.

  • EXTRA: E-Book inside

Windows PowerShell 5 und Core 6: Das Praxisbuch

Windows PowerShell 5 und Core 6: Das Praxisbuch

AUS DEM INHALT:

Konzepte: Commandlets, Pipelining, PowerShell-Navigationsmodell, Sprachsyntax und Skripte, PowerShell-Werkzeuge, Module, Zugriff auf .NET, COM und WMI, Fernzugriffe, Jobs, Workflows, Desired State Configuration, Fehlersuche Tipps und Tricks

Einsatzbeispiele: Dateisystem, Backup, Bitlocker, Dokumente, XML, Relationale Datenbanken, Registry, Computerverwaltung, Hardwareverwaltung, Softwareverwaltung, Prozessverwaltung, Systemdienste, Netzwerk, Sicherheit, Ereignisprotokolle, Leistungsdaten, Active Directory, Gruppenrichtlinien, Hyper-V, IIS, Benutzeroberflächen

Erweiterungen: Erweiterungen installieren, Entwickeln von eigenen Commandlets, Erstellen von Modulen, Hosting der PowerShell

Weltner - PS 5

PowerShell 5: Windows Automation

PowerShell 5: Windows Automation für Einsteiger und Profis
Gebundene Ausgabe – 2. Juni 2016
Dr. Tobias Weltner: 1158 Seiten
Verlag: O'Reilly; Auflage: 2., akt. Aufl. (2. Juni 2016)
Sprache: Deutsch
ISBN-10: 3960090099
ISBN-13: 978-3960090090

In diesem Standardwerk zu PowerShell finden Einsteiger und Profis fundiertes Hintergrundwissen kombiniert mit praxisnahen und sofort einsetzbaren Codebeispielen. Der klare Aufbau und das umfassende Themenspektrum des Buchs vermitteln, wie die vielfältigen Funktionen der PowerShell zusammenhängen und aufeinander aufbauen.

Einsteiger finden sofort Zugang zur PowerShell. Autodidaktisch erworbene Vorkenntnisse werden komplettiert und vertieft. Profis entdecken unzählige wertvolle Hinweise, Praxistipps und »Best Practices« für professionelles und sicheres Skripten.

PowerShell 5: Windows Automation

PowerShell 5: Windows Automation

Aus dem Inhalt:

  • Schnelleinstieg: PowerShell-Grundlagen und rasche Erfolge mit interaktiven Kommandos

  • PowerShell-Skripte, Sicherheitseinstellungen und digitale Signaturen

  • Durchdachter Einsatz der objektorientierten Pipeline

  • Textoperationen, Parsing und Reguläre Ausdrücke

  • Mit Objekten und Typen direkt auf das .NET Framework zugreifen

  • Wiederkehrende Aufgaben als eigene Befehle in Modulen verfügbar machen

  • Mit PowerShellGet Module und Skripte zentral verwalten

  • Prozessübergreifendes Debugging, Fehlerbehandlung und Logging

  • Abgesicherte Fernzugriffe und Sicherheitsstrategien (JEA)

  • Hintergrundjobs, Multithreading und Performancesteigerung

  • Workflows und Desired State Configuration (DSC)

  • Benutzeroberflächen mit WPF gestalten

  • Professionelles Test-Driven Development (TDD) mit Pester

PowerShell Cookbook

Und ja: diese Auflage geht nur bis PowerShell Version 3!

Windows PowerShell Cookbook:
The Complete Guide to Scripting Microsoft's Command Shell (Englisch)
8. Januar 2013
Lee Holmes
Taschenbuch: 1034 Seiten
Verlag: O'Reilly & Associates; Auflage: 3 (8. Januar 2013)
Sprache: Englisch
ISBN-10: 1449320686
ISBN-13: 978-1449320683

Tipp: Suche nach PowerShell Cookbook oder „PowerShell Cookbook pdf“ suchen…

How do you use Windows PowerShell to navigate the filesystem, manage files and folders, or retrieve a web page? This introduction to the PowerShell language and scripting environment provides more than 400 task-oriented recipes to help you solve all kinds of problems. Intermediate to advanced system administrators will find more than 100 tried-and-tested scripts they can copy and use immediately.

PowerShell Cookbook

PowerShell Cookbook

Updated for PowerShell 3.0, this comprehensive cookbook includes hands-on recipes for common tasks and administrative jobs that you can apply whether you’re on the client or server version of Windows. You also get quick references to technologies used in conjunction with PowerShell, including format specifiers and frequently referenced registry keys to selected .NET, COM, and WMI classes.

  • Learn how to use PowerShell on Windows 8 and Windows Server 2012

  • Tour PowerShell’s core features, including the command model, object-based pipeline, and ubiquitous scripting

  • Master fundamentals such as the interactive shell, pipeline, and object concepts

  • Perform common tasks that involve working with files, Internet-connected scripts, user interaction, and more

  • Solve tasks in systems and enterprise management, such as working with Active Directory and the filesystem

Oakley - Schnelleinstieg

Schnelleinstieg in die PowerShell

Anm.: SEHR Old! Aber ich finde die „Anreißertexte“ (s.u.) noch gut - und die Zukunft ist ja jetzt ;-)!

Schnelleinstieg in die Windows PowerShell.
oreillys basics Broschiert – 28. März 2007
Andy Oakley
(Anm.: als Beispiel für eine sehr ordentliche Einstiegslektüre - natürlich nicht mehr aktuell!)
Broschiert: 240 Seiten
Verlag: O'Reilly; Auflage: 1 (28. März 2007)
Sprache: Deutsch
ISBN-10: 3897214873 (nicht mehr lieferbar)
ISBN-13: 978-3897214873

Die Windows PowerShell ist die Zukunft der Windows-Administration - jetzt ist die Zeit, damit zu starten. Mit der PowerShell, Microsofts neuer interaktiver Kommandozeilen-Shell für Windows, lassen sich nicht nur Aufgaben jeder Art schneller erledigen und automatisieren.

Sie bietet darüber hinaus auch die Möglichkeit, tief in das Betriebssystem einzutauchen, um dort eine breite Palette von Prozessen und Diensten zu steuern. Dieses Buch ist die praktische Anleitung, die Sie benötigen, um die PowerShell sofort zu nutzen.

Es führt Sie in die Arbeit mit der neuen Shell ein und demonstriert Ihnen ihre Flexibilität und Leistungsfähigkeit. Das Buch mit Workshop-Charakter: Mehr als vierzig praxisbezogene Übungen und Skripte bieten Einführungen in die Schlüsselkonzepte, klare Schritt-für-Schritt-Anleitungen und genaue Erläuterungen der Ergebnisse.

Schnelleinstieg in die PowerShell

Schnelleinstieg in die PowerShell

Lernen Sie die PowerShell kennen:

Alle Grundlagen der PowerShell-Umgebung und ihrer Sprachfunktionen werden behandelt:

  • die Installation der Shell

  • das Konzept von Cmdlets und Pipelines

  • die Elemente der Skriptsprache und das Schreiben von PowerShell-Skripten

  • die Automatisierung sich wiederholender Vorgänge

Nutzen Sie unterschiedlichste PowerShell-Techniken:

Zu den behandelten Themen gehören: * das Laden und Speichern von Daten * der Einsatz von .NET Framework und COM * die Arbeit mit der Windows-Infrastruktur inklusive Ereignisprotokoll, Systemdienste und WMI * die Zusammenarbeit mit cmd.exe-basierten Tools * Strategien für die Umwandlung vorhandener Batch-Dateien und Skripte in PowerShell-Skripte

Mit Kurzreferenz zu Syntax und Grammatik: Eine Kurzreferenz zu PowerShell-Syntax und -Grammatik sowie zu den Standard-Cmdlets, Funktionen und Aliasen rundet diesen Schnelleinstieg ab. Mit einem Vorwort des Microsoft PowerShell-Architekten Jeffrey Snover.

ReStructuredText

Dokumenttechnik: restructuredText

Seit 2017 erstelle ich neue Seminarunterlagen in restructuredText (RST) und wandele bestehende Dokumentationen und Seminarbegleitungen in RST um.

Für gelegentliche „Typos“, die schon verhanden waren oder beim Konvertieren entstanden sind, bitte ich um Verständnis. Bitte einfach unter Angabe der Kapitel-Info an mich übermitteln. Hierfür Danke im Voraus.

Für Kenner meiner Seminarunterlagen hier kurz die wichtigsten Gründe für die teils aufwändigen Arbeiten:

Flexibilität

Word- (.docx), LibreOffice- (.odt) und PDF-Dokumente lassen sich zwar einfach erstellen!

Aber solche Dokumente lassen sich leider überhaupt nicht geeignet und sauber in HTML (gegliedert / oder als eine Seite), JSON, XML, Manpages, Texinfo oder gar EPUB wandeln!

Metainfos

Meta-Techniken, Fußnoten oder Indizes lassen sich einheitlich in den unterschiedlichen Formaten pflegen.

Versionsmanagement

Eine Versionsverwaltung wie Git (Plattform: github.com) arbeitet am effizientesten mit einfachen Textdokumenten - kann aber natürlich auch binäre Objekte handeln. Auch manuelles „Diffen“ ist mit Rohtexten eine mächtige und einfache Technik, während bei Word/PDF-Dokumenten immer sehr aufwändige und unübersichtliche Techniken eingesetzt werden müssen.

Conclusio: man nutze ein einziges grundlegendes Dokumentformat restructuredText und Werkzeuge (RstTools, DocUtils, Pandoc oder Sphinx) zum sauberen Erzeugen der gewünschten Dokumentformate (HTML, SingleHTML, Latex, PDF, EPUB, ODT, DOCX,…)

Ihr Trainer Joe Brandes - Braunschweig, 2020


Hier folgen abschließend noch die Meta-Infos zur Dokumentenversionspflege:

Version:

3.2-2022

Language:

de

Description:
Unterlagen zu PowerShell Seminaren Trainer Joe Brandes.
Erstellt mit restructuredText / Sphinx / sphinx_rtd_theme
bzw. sphinx_typo3_theme!
Keywords:

PowerShell, Seminarunterlage, J. Brandes

Copyright:

Joe Brandes

Author:

Joe Brandes

License:

GNU General Public License, either version 2 of the License or any later version.

Rendered:

17.12.2023