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.
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:
Basics - Einführung in die PowerShell und mein „Roter Faden“
Hosts - Die Ausführumgebungen der PowerShell: ConsoleHost, ISE
Cmdlets - Die Cmdlets und alle Techniken für die effiziente Nutzung von PowerShell-Aufrufen
Scripting - Die PowerShell Profile und die Erstellung eigener PowerShell Logik
Module - Module kapseln unsere PowerShell Techniken
Remoting - Die PowerShell im Netzwerk nutzen
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:
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!
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:
Aliase
Funktionen
Cmdlets
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.
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.
PowerShell Links¶
Microsoft PowerShell Links
Links: (Anm.: alle docs.microsoft Links mit fast gleichen Targets)
https://de.wikipedia.org/wiki/PowerShell
Powershell Wiki
http://www.microsoft.com/powershell
PowerShell bei Microsoft
http://docs.microsoft.com/de-de/powershell
PowerShell Documentation
-
PowerShell Core 6.0
https://technet.microsoft.com/de-de/library/bb978526.aspx
PowerShell Technet
https://msdn.microsoft.com/en-us/powershell
PowerShell MSDN
https://github.com/powershell/powershell
PowerShell Github die PowerShell Core 6, Core 7 Varianten als Downloads: PowerShell Releases
-
PowerShell Gallery (Modules)
Aktuelle PowerShell Version 5.1 Windows 10
PowerShell eigentlich:
Microsoft Windows Management Framework in den Versionen WMF 5.0 bzw. WMF 5.1
WMF 5.0 erhältlich für Windows 7 Service Pack 1, Windows Server 2008 R2 SP1, Windows 8.1, Windows Server 2012 R2Windows Server 2012,
Hinweis
Links - wie immer ;-) - ohne Gewähr…
siehe auch:
https://www.microsoft.com/en-us/download/details.aspx?id=50395 (WMF 5.0)
WMF 5.1 (beachten: aktuelle Dot.Net 4.6 nötig)
https://www.microsoft.com/en-us/download/details.aspx?id=54616
Installieren und konfigurieren:
https://msdn.microsoft.com/de-de/powershell/wmf/5.1/install-configure
Whats new in PowerShell v5
https://mva.microsoft.com/en-US/training-courses/what-s-new-in-powershell-v5-16434
Und Google liefert sicherlich gerne weitere Quellen und Portale ;-)
Hilfen¶
Es gibt sehr viele Möglichkeiten in der PowerShell unterstützen zu lassen.
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
Alias
Function
Cmdled
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
Hilfe Links¶
Online-Resourcen / Websites:
Skripterstellung mit Windows PowerShell
Windows PowerShell-Unterstützung für Windows Server
http://technet.microsoft.com/en-us/library/hh801904.aspx (zu Server und Co)
PowerShell Module
Anm.: Extra-Hilfen zu Dot.NET-Techniken verfügbar - z.B.
https://msdn.microsoft.com/de-de/library/gg145045(v=vs.110).aspx
Und heute funktioniert ja natürlich auch eine effiziente „Internet-Recherche“.
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-NullDie 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:
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:
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
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
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:
Method (Methode)
Property (Eigenschaft)
PropertySet (Eigenschaftssatz)
NoteProperty (Notizeigenschaft)
ScriptProperty (Skripteigenschaft)
CodeProperty (Codeeigenschaft)
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!
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)
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
Get-Help about_for
Get-Help about_foreach
Get-Help about (alle verfügbaren Hilfen)
MS PowerShell Help (help - about Topics)
MS PowerShell Hilfe (help DE - about Topics)
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!)
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:
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
(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)
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:
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!
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
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
[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)
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)
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¶
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:
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):
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
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
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
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 BedingungenSchleifen (
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 {…}
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 {..} }
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) { … }
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
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
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) { … }
1while ($val -ne 3)
2 {
3 $val++
4 Write-Host $val
5 }
do while / until¶
do { … } while (Bedingung)
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)
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) {…}
Wir starten mit einmem einfachen nummerischen Array
$menge = 1,2,3,4,5
foreach ($i in $menge)
{ $i }
Beispiele aus PowerShell-Hilfe:
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.
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]
Anleitung Weltner PowerShell 5.0 Kapitel 12 S. 476ff.
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!
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]
Anleitung Weltner PowerShell 5.0 Kapitel 17 ab S. 589ff.
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:
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:
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
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:
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:
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):
Browser
Konsole
Coding
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.
Denn wir sollten zuerst natürlich eine Windows-Binary für Fzf bereitstellen.
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
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¶
Mit den Kenntnissen rund um die PowerShell Technik können wir uns neben den bordeigenen Anwendungen natürlich auch um weitere Software (aka Dienste) kümmern.
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:
PowerShell Kenntnisse
Module / PowerShell-Technik für den Service
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.
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
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-MailUserDieses Cmdlet ist nur im cloudbasierten Dienst verfügbar.
Get-ApplicationAccessPolicy
- siehe: Get-ApplicationAccessPolicyDieses 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!
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.
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/
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:
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¶
Für SQL Server Management Studio (SSMS) 17.0 und höher immer das PowerShell Modul SqlServer nutzen.
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):
CLR Types for Microsoft SQL (SQLSysClrTypes.msi - benötigt Windows Installer 4.5)
Shared Management Objects (SMO - SharedManagementObjects.msi - benötigt CLR Types)
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.
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.
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
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.
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.
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.
# 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: 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.
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 übergebenTipp: hier entweder Tab` vermeiden oder geschickt korrigieren!
Cmdlets für neue Objekte (
New-
) geben das erstellte Objekt mit-PassThru
zurückParameter
-Server
für DomänencontrollerBerechtigungen (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)
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:
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.
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.
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 -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-PSSessionErzeugen einer neuen Sitzung auf dem lokalen oder einem entfernten Computer
- Get-PSSessionListe 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-PSSessionentfernt eine Session oder alle Sessions (Remove-PSSession
*
) - Enter-PSSessionStart einer interaktiven Sitzung auf dem lokalen oder einem entfernten Computer
- Exit-PSSessionEnde einer interaktiven Sitzung
- Disable-PSSessionConfigurationSperren einer/aller Sitzungskonfigurationen
- Enable-PSSessionConfigurationEntsperren einer/aller Sitzungskonfigurationen
- Get-PSSessionConfigurationAuflisten der Sitzungskonfigurationen
- Register-PSSessionConfigurationpermanente Registrierung einer Sitzungskonfiguration
- Set-PSSessionConfigurationSetzen von Eigenschaften einer Sitzungskonfiguration
- Unregister-PSSessionConfigurationLöschen einer Sitzungskonfiguration
alles Weitere:
ab S. 229 Schwichtenberg PowerShell 4.0
ab S. 742 Weltner PowerShell 5.0
PS Web Access¶
Die IIS/PSWA Techniken können nicht auf Rechnern kombiniert werden, auf denen bereits Web-Server konfiguriert wurden. Das trifft eben auch auf Gateway Admin Center zu.
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:
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:
-
Trick: einfach in URL von Evaluate Seite evaluate- gegen download- austauschen, dann vermeidet man die Vorschaltseite von Microsoft mit der Abfrage von Nutzerdaten.
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.
Und eine der Standardtechniken des Windows Admin Center ist natürlich die PowerShell (als integrierte PSWA-Lösung).
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.
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.
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
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.
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.
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.
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
Infos zu 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_themebzw. 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