An der VHS Braunschweig findet vom 16. bis 20. Dezember 2019 ein Bildungsurlaub zum Thema "PowerShell - die Befehlszeile für den Windows-Profi" statt. In einem praxisorientiertem Seminar und mit den aktuellen Betriebssystemen und Anwendungen aus dem Hause Microsoft werden wir uns die moderne und zukunftsorientierte "Konsole - Kommandozeile - Shell" erarbeiten.

powershell win 10 ps50 800px

Hier die Rahmendaten unseres Seminars:

Ort: VHS Braunschweig, Heydenstraße 2, Raum 2.11
Termine: Mo., 16.12. bis Fr., 20.12.2019; jeweils 08.30 - 16.00 Uhr

Ich werde unsere Seminarthemen an dieser Stelle ausführlich begleiten und die Infos rund um die PowerShell nachhaltig verfügbar machen.
Ihr Trainer Joe Brandes

 

Tag 01

Montag, 16.12.2019, 08.30 - 16.00 Uhr

Orientierungsphase, Teilnehmer-Themen

Bereitstellung ausführlicher Trainingsmaterialien:

  • über 2000 Zeilen / Scriptlines
  • Roter Faden als HTML/PDF
  • Extra-Website zur PowerShell

 

Allgemeines

Wir setzen als Betriebssyteme Windows 10 Pro ein - später (vielleicht) auch in einer Windows Server 2016 Active Directory Domänenumgebung (AD mit entsprechenden PowerShell AD-Modulen)

PowerShell "Downloads" für Pre-Win-10: PowerShell Version 5.1 oder eigentlich:
Microsoft Windows Management Framework 5.1 (Link zum MS Download)

PowerShell Core.: es gibt auch bereits eine plattformunabhängige Version PowerShell Core 6.x (und Core 7.x) für Betriebssysteme Linux / MacOS! (Link / Link Pakete) / Link PowerShell Core Releases )

Übersicht zu PowerShell-Versionen und deren Betriebssystemverfügbarkeiten: Wikipedia
Deutsche Einstiegsseite zum Thema Microsoft PowerShell: Microsoft Dokumentation / Skriptcenter

Installationsverzeichnis: C:\Windows\System32\WindowsPowerShell\v1.0  
Anm.: ja immer noch Version 1.0 ;-) im Pfad

siehe vordefinierte Variable $PSHome

View source
  1. # PS-Version anzeigen lassen
  2. echo $PSVersionTable
  3. # Host - in Console und ISE testen
  4. $host.Version
  5. # Installationsverzeichnis
  6. Write-Host $PSHome
und hier ist die 64-Bit-Variante auf 64-Bit-OS zu finden (Tipp: Systemeigenschaften mit Win + Pause)

Die 32-Bit-Variante im SysWoW64-Ordner (!):
C:\Windows\SysWOW64\WindowsPowerShell\v1.0  
Warum ist das wichtig? Z. B. beim Zugriff auf eine 32-Bit Access Datenbank

Anm.: Die PowerShell (PS) kennt keine Groß-/Kleinschreibung (non case-sensitive).

Architektur der PowerShell

Projektname "Monad" - der Versuch das "Beste aus allen Welten" zu kombinieren und zu verbinden!
smart art ps 800px

In PowerShell Integrierte Techniken (siehe Planungen bei Urprojekt Monad):

  • DOS-Shell (Befehle, Oberfläche, klassische Programme)
  • Unix-Shells (Pipelinig, Syntax, Befehlsnamen)
  • Andere Skriptsprachen z.B. Perl oder auch Hochsprachen C# (Syntax)
  • Dot.NET Framework (Objektorientierung, Klassen)
  • Windows Scripting Host - WSH (Klassen, Sicherheit; Einsatz bis ca. 2020! - PS bis min. 2030)
  • Windows Management Interface - WMI (Klassen, Tool wmic.exe)

Die Idee: alle möglichen Techniken in einer "Umgebung" zu vereinen!

Abarbeitungsreihenfolge bei Aufrufen in der PowerShell

  1. Aliase (dir, md)
  2. Funktionen (mkdir, C:)
  3. Commandlets (Get-Process)
  4. Externe Befehle / Applications (netstat, ipconfig, notepad, ...)

Hinweis: durch diese Reihenfolge "überschreiben" Aliase wie notepad die Aufrufe der Applikationen mit gleichem Namen!

Hilfe in der PowerShell

mit Tabulator Codevervollständigung (auch Umschalten + TAB rückwärts) inkl. Wildcards:

View source
  1. Get-?e* TAB
  2. Get-Command Get-*
  3. Get-Command [gs]et-*
  4. Get-Command *-Service
  5. Get-Command –Noun Service
  6. Get-Command *wmi*
  7.  
  8.  
  9. # Beispiel mit mehr Tiefe als Vorbereitung auf Pipelining und Filterungen
  10. Get-Command | Where-Object { $_.name -like "*cim*" -or $_.name -like "*wmi*" }
  11.  
  12.  
  13. Get-Command ps # Alias
  14. Get-Command notepad.exe # Tool
  15. Get-Command C: # Function
  16.  
  17.  
  18. # Anzahl von Cmdlets und Funktionen (so seit PS 2.0)
  19. Get-Command | Group-Object CommandType
  20. # Cmdlets und Funktionen exportieren:
  21. Get-Command | Format-Table name -HideTableHeaders | Out-File E:\_temp\pscommands.txt
  22.  
  23.  
  24.  
  25. # Hilfe aktualisieren mit Update-Help Commandlet
  26. Update-Help –UICulture En-US -force
  27. # Beachten: Admin-PowerShell nötig! Anm.: Autor Weltner empfiehlt En-US Schalter!
  28.  
  29.  
  30. Get-Help Get-Command
  31. # mit Parametern auch
  32. Get-Help Get-Command -Detailed # -Full, -Examples, -Online, -ShowWindow
  33. Get-Help Get-Process -parameter "*"
  34.  
  35.  
  36. # Show-Command
  37. Show-Command Get-Process

Grafische Oberfläche mit Show-Command seit PS 3.0: Show-Command Get-Process 

Hilfe aktualisieren mit Update-Help Commandlet
Beachten: Administrator-PowerShell nötig!

Websites: Skripting mit der PowerShell - Windows PowerShell for Server
Hilfe zu PS-Befehlen und den Techniken für das spätere Skripting:
Get-Help about_for
Get-Help about_foreach
Get-Help about (alle verfügbaren Hilfen)

Empfehlung: auch einfach online suchen mit "PowerShell about_for, ...
Online-Hilfe-Portal zur PowerShell (Technet - Skripterstellung mit Windows PowerShell)

PSReadline

... ein PowerShell-Modul für das Verbessern der PowerShell Konsole

Seit PS 5.0 hat man außerdem mit PowerShellGet, ein Modul, das die Fähigkeiten von NuGet (einem Paketmanager) bereitstellt.

In älteren PowerShells: falls man kein Modul PSReadline vorfindet, dann einfach neues Cmdlet Install-Modul zum Installieren nutzen: (in einer Administrator-Shell)
Install-Modul -Name PSReadline  

Wichtig: Abfragen nach Installation von Paketmanagement-Tool und Vertrauenswürdigkeit des Paketrepositories mit "Y" bestätigen! Zu diesen Modul-Techniken im Seminar später mehr!

Verbesserungen in der PowerShell-Konsole durch PSReadline: (Beispiel-Link)

  • farbiges Syntax-Highlighting
  • im Prompt wird ">" in Rot angezeigt, wenn die Eingabe noch unvollständig ist
  • PS Konsole nimmt jetzt auch Strg + V an
  • mit Strg + Leertaste kann man in der Konsole Code-Completion (Syntax Vervollständigungen) nutzen
  • einfacheres "Error"-Handling (bei kleinen Vertippern nicht gleich mehrzeilige "Fehlermonster")
  • besserer Mehrzeilenmodus
  • mit Strg + L erreicht man ein cls (clear screen)
  • ESC löscht Zeile
  • zusätzlich belegbare Tastenkombinationen (siehe cmdlet Get-PSReadlineKeyHandler bzw. das Pendant Set-PSReadlineKeyHandler)

Strg und Leertaste 800px

Wichtig für effiziente PowerShell-Nutzung: Tastenkombinationen
Tab (Vervollständigungen) und Strg + Leertaste (Code-Completion/Vervollständigung - siehe Bild) ständig nutzen!

PowerShell History

Die PowerShell hat eine eigene History-Umgebung und stellt entsprechende Cmdlets zur Nutzung.

Am Besten aber nutzt man die History-Technik von Modul PSReadline

View source
  1. # PSReadline
  2. (Get-PSReadlineOption).HistorySavePath
  3. $a = (Get-PSReadlineOption).HistorySavePath
  4. notepad.exe $a # oder besser mit dem ISE
  5. ise $a
Es ist also mit der History.txt-Datei von PSReadline ein kompletter Fundus unserer/Ihrer Aufrufe am Ende der Seminarwoche automatisch verfügbar!

Erste Aufrufe in der PS

Interaktive Aufrufe vergleichen:

Get-Process vs. Get-EventLog (hier dann Parameter als Eingabe möglich: Application, System, ...)

View source
  1. # Parameter - und einfache Parameter-Switches nutzen
  2. # Alle Aufrufe gleich:
  3. Get-ChildItem C:\temp *.txt # Hier: Reihenfolge entscheidend!
  4. Get-ChildItem -Path C:\temp -Filter *.txt
  5. Get-ChildItem -Filter *.txt -Path C:\temp
  6. # Verschiedene Platzhalter / Wildcards:
  7. Get-Process i*
  8. Get-Process i*ore
  9. Get-Process [st]*
  10. Get-Process [st][vf]*
  11. # Aktivieren / Deaktivieren von Schaltern:
  12. Get-ChildItem C:\temp -recurse
  13. Get-ChildItem C:\temp -recurse:$false
Allgemeine Parameter: -Force, -Whatif, -Confirm, ...
Aufrufe lassen sich zusammensetzen (später sinnvoll mit Variablen in Skripten)
Get-ChildItem ("c:\" + "temp") *.txt –Recurse

Aliase

ps ersetzt Get-Process   (Unix-Shell lässt grüßen)

Befehle: Get-Alias ; Get-Alias ps
Standardanzahl für Aliase: 4096  (siehe Variable $MaximumAliasCount)

View source
  1. # Neue Aliase mit:
  2. Set-Alias procs Get-Process # neu oder überschreiben
  3. New-Alias procs Get-Process
Wichtig: keine Parameter festlegbar - da brauchen wir später Funktionen!

Die Aliase gelten nur in der aktuellen PS-Sitzung (Session, Instanz), bei späterer Nutzung dann in Profile integrieren oder manuell exportieren / importieren:

View source
  1. Export-Alias c:\temp\meinealias.csv # also in eine Textdatei
  2. Export-Alias c:\temp\meinealias.ps1 -as script # in ein PS-Skript
  3. # Laden:
  4. Import-Alias c:\temp\meinealias.csv
  5. . c:\meinealias.ps1 # Punktoperator - "Dot sourcing"
Es werden alle Aliase exportiert und wieder importiert, was zu "Fehlermeldungen" beim Import führt.

Man kann entweder manuelle Anpassungen der Exportdateien durchführen, so werden die Aliase "sauber" importiert, oder aber einfach später die gewünschten Aliase in den PS-Profilen sauber hinterlegen!
Tipp Unterdrückung der Fehlerausgaben: -ErrorAction SilentlyContinue

Ausdrücke

eine erste Annäherung mit () im Expression bzw. Command Mode
Vergleiche:

View source
  1. Write-Output 10 * (8 + 6) # mit
  2. Write-Output (10 * (8 + 6))
  3. # Aufrufe mit Unterausdruck:
  4. "Anzahl der laufenden Prozesse: (Get-Process).Count"
  5. # vergleichen mit:
  6. "Anzahl der laufenden Prozesse: $((Get-Process).Count)"
Anm.: $ leitet also Subexpression (Unterausdruck) ein

ISE - Integrated Scripting Environment

Auch hier wieder 32- und 64-Bit-Variante beachten!
Integrated Scripting Environment (ISE - powershell_ise.exe) ist der Name des Skripteditors - mit PS 3.0 nochmals verbessert

Stichworte zur ISE:

  • Intellisense Eingabeunterstützung - automatisch oder vervollständigen mit Tab, Strg + Leertaste
  • Eigene Remote-Konsole (siehe Menü Datei)
  • Copy & Paste: Hier funktionieren die Zwischenablage-Tastenkombinationen Strg + C / V
  • Hilfe zu Befehlen mit F1; Show-Command mit Strg + F1
  • Diverse Addons verfügbar - hier eine Link zu einer Microsoft Quelle: Link
  • Skripte ausführen (Später auch "Debuggen Ausführen/Fortsetzen") oder F5
  • Skriptauswahl (manuell markieren) ausführen mit F8
  • Vorgriff auf Debugging: (heute noch nicht behandelt)
  • Haltepunkte mit F9; mehr im Menü Debugging des ISE

Wichtige Unterschiede zur "normalen" PowerShell Console:

  • keine interaktiven Tools/Programme möglich: ftp, nslookup, ...
  • kein Blättern mit more, klassisch: keine Soundausgaben; in aktuellen PS 5.1 ISE Umgebungen mit Sound

Konfiguration der ISE:

View source
  1. # Eigene Farbgebungen in ISE mittels:
  2. $psISE.Options.ConsolePaneBackgroundColor = "red"
  3. # alternativ:
  4. $host.ui.RawUI.BackgroundColor = "red"
siehe auch $psISE.options für die möglichen Einstellungen / Optionen der ISE
Tipp: Einstellungen mittels Tools - Optionen bearbeiten bzw. auf Standard zurückstellen

PSProvider und PSDrives

Übersichten und beispielhafte Aufrufe zu den PowerShell Providern und Drives ("Laufwerken") mittels

View source
  1. Get-PSProvider # PSProvider Übersicht
  2. Get-PSDrive # PSDrives Übersicht
  3. Get-PSDrive -PSProvider FileSystem # PSDrives Filesystem
  4. Set-Location Cert:\CurrentUser\Root # Wechsel in LW Cert:
  5. # Bei der Registry kann man den Provider auch direkt ansprechen:
  6. Get-ChildItem "REGISTRY::HKEY_CLASSES_ROOT\" -ErrorAction SilentlyContinue
Befehle zu Laufwerken, Items, Inhaltsobjekten und Pfaden
Get-Command –Noun *childitem, item*, path, content, location  
Übungen mit New-Item , New-PSDrive,  Remove-PSDrive

Erstellung eines neuen PSDrive: (in Folgeübungen)
New-PSDrive -Name Skripte -PSProvider FileSystem -Root c:\temp\ps-skripte 
in der Profiltechnik unserer PowerShell (hier aktueller Host Console des aktuellen Users: $PROFILE)

ExecutionPolicy für die PowerShell-Skripte

Sicherheitlevel beachten: siehe auch Get-Help Set-ExecutionPolicy

  • Restricted - Voreinstellung durch die PowerShell
    Wirkung: keine Skriptausführung möglich
  • RemoteSigned - hier: gewünschte Policy
    Wirkung: lokale Skripte ausführbar, bei Skripten aus Netzressourcen ist eine Signatur notwendig
  • Unrestricted - sehr Unsicher
  • AllSigned - sehr aufwändig

Cmdlets:

  • Get-ExecutionPolicy
  • Set-ExecutionPolicy

Die voreingestellte Policy (Richtlinie): Restricted
das würde aber gleich alle PowerShell-Skriptaufrufe (auch für unsere Profilskripte!) verhindern

Also: mit  Set-ExecutionPolicy (am Besten ohne Administrator Rechte!) die gewünschte Berechtigung RemoteSigned einstellen.

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser  

Anm.: ohne Angabe des Scope wäre es automatisch eine Konfiguration für die Maschine und somit nur mit Admin-Rechten möglich.
Und gleich mit Get-ExecutionPolicy testen. Vollständige Analyse der PowerShell Policies mit

PS C:\Users\joeb> Get-ExecutionPolicy -List

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

Die Policy-Level werden der Reihe nach von unten (LocalMachine) nach oben (GPO MachinePolicy für Computer) durchlaufen!

Anm.: bitte ggf. nicht die 32-Bit-PowerShell (x86) ExecutionPolicy vergessen!

 

  • Get-CommandGet-Command
  • Get-HelpGet-Help
  • $PSVersionTable$PSVersionTable
  • Get-PSReadlineOptionGet-PSReadlineOption
  • ConsoleHost vs. ISEConsoleHost vs. ISE
  • Get-EventLog vs. eventvwrGet-EventLog vs. eventvwr
  • PowerShell Core 6PowerShell Core 6
  • ISE konfigurierenISE konfigurieren
  • ExecutionPolicyExecutionPolicy

 

Tag 02

Dienstag, 17.12.2019, 08.30 - 16.00 Uhr

Ausführliche Rekapitulation zu Tag 01, Teilnehmer-Fragen

Profile (Part I)

PowerShell-Hosts: Sowohl die PowerShell (console host) als auch die ISE (Windows PowerShell ISE) besitzen Profile (Profildateien / Konfigurationen). Außerdem kann man auch generelle Profile für alle User (AllUser) oder nur für den aktuellen (CurrentUser) konfigurieren.
profiles 800px
Anzeigen der Profile jeweils (!) mit $PROFILE in der PowerShell ergibt:
C:\Users\joeb\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
in der ISE dann ebenfalls $PROFILE mit
C:\Users\joeb\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1

View source
  1. $PROFILE
  2. # genauer: (Anm.: siehe auch ISE)
  3. $PROFILE
  4. $PROFILE.CurrentUserCurrentHost
  5. $PROFILE.CurrentUserAllHosts
  6. $PROFILE.AllUsersCurrentHost
  7. $PROFILE.AllUsersAllHosts
Cleveres Erstellen der $PROFILE inklusive notwendiger Ordner/Unterordner:
New-Item -Path $PROFILE -ItemType File -force    
Anpassen der Profile dann in weiteren Übungen, wenn wir das Skripten im Griff haben.

Erste Übung mit Aliasen (Set-Alias) und Konfigurationen für die PowerShell...

Anm.: Seminarraum VHS BS hat Benutzerordner (untypisch): D:\TN-Bibliotheken\Dokumente\WindowsPowerShell\...

Objektanalyse in der PowerShell

Heranführung an das Thema Objeke / Objekttechniken:
Objektmember sind klassisch:

  • Property - Eigenschaft (z.B. Get-ChildItem Objekte: LastWriteTime)
    Beispiel:  (Get-ChildItem C:\temp).LastWriteTime      # Ausgaben Datum/Uhrzeit letzte Änderungen
  • Method - Methode/Funktionalität (z.B. Get-Date Objekt: AddYears() )
    Beispiel:  (Get-Date).AddYears(5)    # Aktuelles Datum um 5 Jahre addieren

objekte erklaerung 800px

Die PowerShell kennt noch weitere Member für die Objekte außer Property und Method:
AliasProperty, Event, NoteProperty, ScriptProperty, PropertySet
Anm.: genauere Betrachtungen obliegen anderen PowerShell-Vertiefungen (bzw. siehe PowerShell Literatur)

Anzeige von Eigenschaften mit Cmdlet Get-Member :
Get-Process | Get-Member     # Member nach dem Pipeline-Processing (s.o.)

bitte TypeName (System-Klasse) beachten: System.Diagnostics.Process

Spezialität: Eigenschaften vor Pipeline-Processing
Get-Member -InputObject (Get-Process)   # Member eines Get-Process-Objects (vor einem möglichen Pipelining)

Und für die Verbindung von PowerShell zu System-Klassen kann man mal
[System.Diagnostics.Process]::GetProcesses()  
ausprobieren - ergibt genau das Ergebnis des PowerShell Cmdlet Get-Process  !

Oder aber
[System.DateTime]::Now 
ergibt das PowerShell Cmdlet Get-Date !

Die Ausgabe der Dot.Net-Systemklassen regelt eine XML-Datei für die PowerShell (systemweit):
$PSHOME\DotNetTypes.format.ps1xml   
Einfach in dieser Datei nach den Klassen suchen (Strg + F) und schon kann man die Ausgaben nachvollziehen und/oder nach eigenen Wünschen mit zusätzlichen, eigenen Konfigurationen anpassen lassen!
Tipp: Hilfe mit Get-Help about_Format.ps1xml  aufrufen - lokal oder mit Parameter -Online .

Pipelining

(Online-Beitrag - inkl. Pipeline-Bild - von Schwichtenberg auf entwickler.de)

In der PS ist alles objektorientiert bearbeitbar und wird über Pipeline-Processing weitergegeben.

Anm.: das besondere Konstrukt $_ greift auf das aktuelle Objekt zu.

View source
  1. # komplexere Pipeline:
  2. Get-ChildItem c:\temp –r -filter *.txt |
  3. >>> Where-Object { $_.Length -gt 40000 } |
  4. >>> Select-Object Name, Length |
  5. >>> Sort-Object Length |
  6. >>> Format-List
Neu: $PSItem als gleichwertiger Ersatz zu $_ (seit PS 3.0) Anm.: Erklärung für dieses Verhalten mit Get-Help Get-Service -full  (siehe nach -name byValue und byPropertyName)
View source
  1. # Ein paar Beispiel für Pipeline-Aufrufe:
  2. Get-Process |
  3. >>> Where-Object {$_.name -eq "iexplore"} |
  4. >>> Format-Table ProcessName, WorkingSet64
  5. # Alle Prozesse, die mehr als 20 MB verbrauchen
  6. Get-Process | Where-Object {$_.WorkingSet64 -gt 20*1024*1024 }
  7. # kurze Variante
  8. ps | ? {$_.ws -gt 20MB }
  9. # alle Dienste, die mit i beginnen
  10. "i*" | Get-Service
  11. # Dienst "gleich" BITS
  12. "BITS" | Get-Service

Auch die klassischen Befehle lassen sich "pipen":
netstat -an | Select-String "HERGESTELLT" -case  (Select-String für reguläre Ausdrücke)
Anzahl von Objekten in einer Pipeline: Get-Date  (erzeugt nur ein Objekt)
Eigenschaften des Objekts ansprechen:
(Get-Date).Year  (als auch .Month, .Hour, .Minute)
Anm.: keine Probleme mehr (also keine Fehlermeldungen, falls man denn mal mit einem Einzelobjekt arbeitet)
View source
  1. # Anzahl aller Prozesse
  2. (Get-Process).count
  3. # Anzahl von Prozessen mit mehr als 20 MB im RAM
  4. (Get-Process | where-object { $_.WorkingSet64 -gt 20MB }).Count
  5. # Objekte lassen sich dann mit Array-Technik einzeln ansprechen:
  6. (Get-Process | where-object { $_.WorkingSet64 -gt 20MB })[5]
  7. # früher:
  8. Get-Process | foreach-object {$_.Name }
  9. # seit PS 3.0:
  10. (Get-Process).Name
  11. # Für eine kombinierte Ausgabe ist foreach-Commandlet nötig:
  12. Get-Process | foreach-object {$_.Name + ": " + $_.Workingset64 }
Methoden der Objekte: (also Funktionen zu denen die Objekte fähig sind)
Automatic Unrolling (seit PowerShell 3.0)
View source
  1. # Beispiel zu Automatic Unrolling
  2. $dll = Get-ChildItem C:\Windows\System32\*.dll | Select-Object -First 3
  3. $dll # Ausgabe
  4. # wieder 3 Versionen
  5. $dll.VersionInfo # ab PS 3.0
  6. $dll | Select-Object -ExpandProperty VersionInfo
  7. $dll | ForEach-Object { $_.VersionInfo }
  8.  
  9.  
  10. # Analyse
  11. $dll | Get-Member # hier sieht man VersionInfo / ScriptProperty – nach der Pipeline!
  12. # im Vergleich mit
  13. Get-Member –InputObject $dll # Get-Member kennt kein VersionInfo

Alle Techniken praktisch erprobt.
View source
  1. # alle iexplore "killen"
  2. Get-Process iexplore | Foreach-Object { $_.Kill() }
  3. # seit PS 3.0:
  4. (Get-Process iexplore).Kill()
  5. # besseres Commandlet: Stop-Process
  6. # hier gibt es auch keine Fehler mehr, falls kein iexplore
  7. Get-Process | Where-Object { $_.Name -eq "iexplore" } | Stop-Process
  8. # Alle Methoden für Get-Date anzeigen lassen:
  9. Get-Date | Get-Member
  10. (Get-Date).ToLongDateString() # und viele Andere
Anm.: die Fehlerbehandlung in unsere PowerShell Konsole wird durch Einsatz von PSReadline optimiert

Vergleichsoperatoren

siehe auch Google-Recherche "powershell vergleichsoperatoren" - beispielhafter Ergebnislink

mit eingebauter PS-Hilfe: get-help about_Comparison_Operators -ShowWindow  

Kleine Übersicht:

  • -gt (greater than), -ge (greater equal),
    -lt (less than),  -le (less equal),
    -eq (equal), -ne (not equal)
  • -Like, -NotLike (kann mit *, ? und [] umgehen)
  • -Match, -NotMatch (Reguläre Ausdrücke, Regular Expressions)

Mit vorgesetztem "c" (dann also -clike) kann man die Case-Sensitivity erzwingen.

Variablen

Hier werden wir Variablen erst einmal interaktiv in der PS nutzen:

View source
  1. # Übersichtlichkeit schaffen - Vorarbeiten für Skripting
  2. Get-Process |
  3. >>> Where-Object {$_.name -eq "iexplore"} |
  4. >>> Foreach-Object { $_.ws }
  5. # wird zu
  6. $x = Get-Process
  7. $y = $x | Where-Object {$_.name -eq "iexplore"}
  8. $z = $y | Foreach-Object { $_.ws }
Übungen zu den Variablen in Bezug auf Sichtbarkeit (Console vs. ISE) und mit Get-ChildItem Variable:  Übersicht über die vorhandenen Variablen in einer PowerShell Host-Session

bestimmte Variablennamen nicht erlaubt $_  oder $PSItem (klar - brauchen wir für die Objekte)
Commandlets: Set-Variable und Get-Variable sowie Clear-Variable

Variablen Read-Only: Set-Variable variablenname -Option readonly

Typisierungen: [int], [double], [string], [byte], [char], [bool], [xml], ...
Fachbegriff bei Programmiersprache (C, Java): Cast Operator

Vordefinierte Variablen: $true, $false, $Home, $PSHome, $host, ...
mit z.B. $host.UI.RawUI.BackgroundColor = "darkgreen"

Erinnerung: Variablen werden bei/in Zeichenketten mit doppelten Anführungszeichen ausgewertet - bei einfachen Zeichenketten nicht!

Filtern, Sortieren, Gruppieren

Mit den Standard-Cmdlets (Verben: Where-, Sort-, Group-) praktische Übungen durchgeführt:

View source
  1. # Prozesse, der Speicher größer als 10000000 Bytes
  2. Get-Process | Where-Object {$_.ws -gt 10000000 }
  3. # Inklusive Sortierung und Auswahl der Ergebnissätze
  4. Get-Process | Sort-Object ws -desc | Select-Object -first 5
  5. Get-Process | Sort-Object ws -desc | Select-Object -last 5
  6. # mit Regulären Ausdrücken
  7. # Systemdienste, deren Beschreibung aus zwei durch ein Leerzeichen getrennten Wörtern besteht.
  8. Get-Service | Where-Object { $_.DisplayName -match "^\w* \w*$" }
  9. # Prozesse, deren Namen mit einem "i" starten und danach drei Buchstaben
  10. Get-Process | Where-Object { $_.ProcessName -match "^i\w{3}$" }
  11. Vergleichsoperatoren (s. about_Comparison_Operator)
  12. # klassische Filter:
  13. Get-Service | where-object { $_.status -eq "running" }
  14. # können seit PS 3.0 auch mit
  15. Get-Service | where-object status -eq "running"
  16. # aber bei Kombinationen mit and oder or bitte wieder klassisch:
  17. Get-Process | Where-Object { $_.Name -eq "iexplore" -or $_.name -eq "Chrome" -or $_.name -eq "Firefox" } | Stop-Process
  18. Get-Service | where-object { $_.status -eq "running" -and $_.name -like "a*" }
  19. #Objekte für Ausgaben einschränken ("kastrieren")
  20. Get-Process | Select-Object processname, minworkingset, ws | Get-Member
  21. # Prozesse nach Speicherverbrauch sortieren
  22. Get-Process | Sort-Object ws –desc
  23. # Mehrere Sortierfelder
  24. Get-Service | Sort-Object Status, Displayname
  25. # mehrfach-Elemente finden - man muss immer erst sortieren!
  26. 1,5,7,8,5,7 | Sort-Object | Get-Unique
  27. # Elemente gruppieren
  28. Get-Service | Group-Object status
  29. # Dateien in System32 nach Erweiterungen gruppieren und sortiert ausgeben
  30. Get-ChildItem c:\windows\system32 | Group-Object extension | Sort-Object count –desc
  31. Get-ChildItem c:\windows\system32 | Select-Object extension -Unique
  32. # Auswertungen mit Measure-Object - Standard ist count, also Anzahl
  33. Get-ChildItem c:\windows | Measure-Object -Property length -min -max -average -sum
Insbesondere bei der Nutzung der Regulären Ausdrücke (Regular Expression - Wikipedia Link - Signalwort "match") kratzen diese Beispiele natürlich nur an der Oberfläche.

 

  • $PROFILE$PROFILE
  • Alle ProfileAlle Profile
  • New-ItemNew-Item
  • Get-MemberGet-Member
  • System.DateTimeSystem.DateTime
  • VergleichsoperatorenVergleichsoperatoren

 

Tag 03

Mittwoch, 18.12.2019, 08.30 - 16.00 Uhr

Rekapitulation, Teilnehmer-Fragen

Datentypen - Übungen und Tests

Wir haben zu den unterschiedlichen Typen diverse Aufrufe und Funktionen (Klassen) kennengelernt.\'";

View source
  1. # Zahlen - Int
  2. [Int32]::MaxValue
  3. # 2147483647
  4. [UInt32]::MaxValue
  5. # 4294967295
  6. [Int32]::MinValue
  7. # -2147483648
  8. [Byte][Char]’A’
  9. # 65
  10. [Byte[]][Char[]]’Hello’
  11. # 72 #101 #108 #108 #111 (untereinander)
  12. [Char[]](65..90)
  13. [Char[]]'Hello'
  14. [Byte[]][Char[]]'Hello'
  15. # Spezielle Daten mit Klasse System.Net.Mail.MailAddress
  16. $email = [System.Net.Mail.MailAddress]'Some User<Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!'
Weitere ausführliche Aufrufe und Techniken wurden den Teilnehmern zur Verfügung gestellt!
Insbesondere mit $email.Displayname  bzw. mit $email. Strg+Leertaste (PSReadline - Intellisense) erkennt man immer wieder die "Objekte / Eigenschaften", die in der PowerShell nutzbar sind.

Zeichen / Strings

siehe auch wieder die Online-Hilfen zu den Vorgehensweisen und Methoden:

View source
  1. # Das "Echo" für die PS: Write-Host
  2. Write-Host "Guckst Du" -ForegroundColor Yellow
  3. # Zeichenketten Operationen (Methoden)
  4. "" | Get-Member -m Method
  5. [String] $CSVString = "Joe;Brandes;Braunschweig;Deutschland;www.pcsystembetreuer.de"
  6. $CSVArray = $CSVString.Split(";")
  7. $Surname = $CSVArray[1]
  8. $Surname
Das ließe sich dann auch gerne auf viele Datensätze/Zeilen anwenden.

Arrays

$a = 01,08,72,13,04,76
Das Array kann auch explizit mit [array] deklariert werden: [array] $b
Oder einach als "Aufzählung: $b = 01,08,72,13,04,76
Anzahl der Elemente in einem Array: $b.Count

arrays 800px

assoziatives Array: (eine Hashtabelle)

View source
  1. # Implicit Hashtable
  2. $Computers = @{ E01 = "192.168.1.10"; E02 = "192.168.1.20"; E03 = "192.168.1.30"; }
  3. # Explicit Hashtable
  4. [Hashtable] $Computers = @{ E01 = "192.168.1.10"; E02 = "192.168.1.20"; E03 = "192.168.1.30"; }
  5. $Computers["E02"]
  6. $Computers.E02
Also: Arrays sind 2-spaltige Tabellen mit Indizes (Linke Spalte) und Werten (Rechte Spalte)

Datum / Uhrzeit

... mit der PowerShell verarbeiten. Ein paar kleine Beispiele…

View source
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()  

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:

View source
function ConvertFrom-UnixTime {
 param(
 [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
 [Int32]
 $UnixTime
 )
 begin {
 # $startdate = Get-Date –Date 01.01.1970 # "01/01/1970"
 $startdate = Get-Date -Year 1970 -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0
 }
 process {
 $timespan = New-TimeSpan -Seconds $UnixTime
 startdate + $timespan
 }
}
Jetzt in echter Zeit:
$Path = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion"  
Get-ItemProperty -Path $Path | Select-Object -ExpandProperty InstallDate | ConvertFrom-UnixTime  

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’)

Funktionen I (Einführung)

Die Funktionen "kapseln" mehrere Abarbeitungsschritte und können später dann auch Parameter übergeben bekommen und Werte zurückgeben.

Hier erst einmal ein paar Beispiele ohne Parameterübergabe - bitte einfach wieder zu den "Hilfen" greifen

View source
  1. # Beispielfunktion cdd - Change Dir with Dialog
  2. function cdd {
  3.     $shell = New-Object -comObject "Shell.Application"
  4.     $options = 0x51 # Nur Dateisystem-Ordner - inklusive Edit-Box
  5.     $loc = $shell.BrowseForFolder(0, "Wohin soll es gehen?", $options)
  6.     if($loc) {Set-Location $loc.Self.Path}
  7. }
Das Beispiel kann über Suchbegriffe "Shell.Application" und/oder "BrowseForFolder" analysiert werden:
bei $options = 0x41  entfernt man die Edit-Box am unteren Rand des cdd-Dialogfensters

Das folgende Beispiel kann über die "Online-/Offline-Dokumentation about_functions" entnommen werden:

View source
  1. function Get-NewPix
  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.

Für eine stetige Verfügbarkeit der Funktionen brauchen wir erst einmal nur den Code in unser $PROFILE Startskript zu packen. Für eine große Anzahl an Funktionen wird dieses aber später störend und wir werden uns die Module für PowerShell erarbeiten.

Funktionen II (komplett)

Jetzt: ausführlich kommentiert und sauber implementiert!

Durch die saubere Zuweisung mit Kommentarblock in einer Funktion wird die komplette Hilfe und Intellisense nutzbar.

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

Ausführliche Hilfe lässt sich durch die Kommentierungen nutzen:
Get-Help Get-CriticalEvent -Full  

Die Funktionen lassen sich auch über das Laufwerk function: analysieren:
(Get-Item function:\Get-CriticalEvent).Definition   
oder auch
Get-Content function:\Get-CriticalEvent  

Diese Techniken werden wir immer wieder benötigen.

 

  • Is64BitOperatingSystemIs64BitOperatingSystem
  • Get-CultureGet-Culture
  • Hash für SpalteHash für Spalte
  • Ansi vs UTF-8Ansi vs UTF-8
  • Parameter -WhatIfParameter -WhatIf
  • Formatoperator -fFormatoperator -f
  • Parameter deklarierenParameter deklarieren
  • FunktionenFunktionen
  • cdd - comObjectcdd - comObject

 

Tag 04

Donnertstag, 19.12.2019, 08.30 - 16.00 Uhr

Rekapitulation, Teilnehmer-Fragen, Bücher & Co (siehe eigene Registerkarte)

Forts. Übungen Funktionen

... Verständnis zu den Beispiel-Funktionen

  • Get-SmallFiles
  • Get-CriticalEvents (komplette Syntax mit Hilfe)

Besonders: Datentyp [Switch] zum Überschreiben eines Cmdlet Out-Default mit Alias Out-Default (= Out-GridView)

 

Kontrollstrukturen

Beispiele auch über die PowerShell-Hilfe: (siehe) Get-Help about_if -Full  oder Get-Help about_for -Full 

Verzweigungen

  • if - then - else
  • switch

Schleifen

  • do - while - until
  • for
  • foreach

Beispiele für TN digital verteilt und durchgesprochen. Hinweis auf Darstellungen eigener PowerShell-Website/-Doku von Trainer Joe Brandes.

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 &
  • Dot-Operator .

& 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).

Formatoperator -f 800px

Indexoperator [ ]

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

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

.. 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

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.

:: 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.

Ausgaben / Umleitungen in Datei

Verschiedene Wege führen hier zum Ziel:
Umleitungsoperator ist > (Ersetzen) bzw. >> (Anhängen):

View source
  1. Get-Process | Out-File "c:\temp\prozessliste.txt"
  2. # Ausgaben anhängen mit -Append
  3. Get-Process | Out-File "c:\temp\prozessliste.txt" -Append
> 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!)Anm.: Umleitung an  Drucker mit Out-Printer
View source
  1. # Fehler in Datei umleiten
  2. cat c:\temp\datei-exist-nicht.txt 2>> C:\temp\fehler.txt
  3. # Ausgabeströme umleiten
  4. dir u:\Daten 2>&1 | Format-Table > C:\temp\prozessliste.txt
Ebenfalls noch testen: Tee-Object zweigt Zwischenergebnisse in Dateien oder Variablen ab

Ausgaben (Ausgabeformate und Formatierungen)

weitere Ausgabtechniken - siehe wieder Get-Command Out-*

Cmdlets für Formatierungen:
Format-Wide (kurz: fw): zweispaltige Liste
Format-List (kurz: fl): detaillierte Liste
Format-Table (kurz: ft):

Tabellenausgabe

View source
  1. # Gezieltes Ausgeben der Tabellen - Propierties (Methoden)
  2. Get-Service | Select-Object -first 5 | Format-Table
  3. Get-Service | Select-Object -first 5 | Format-Table *
  4. Get-Service | Select-Object -first 5 | Format-Table -property Name, CanStop
  5. # Standardausgabe gemäß DotNetTypes.Format.ps1xml (eigentlich also DOT.NET Formate!)
  6. Get-ViewDefinition System.Diagnostics.Process
  7. Get-Process | Format-Table –view priority
  8. # Ausgaben einschränken
  9. Get-Process | Format-Table -Property id,processname,workingset
  10. # als auch
  11. Get-Process | Select-Object id, processname, workingset | Format-Table
  12. # Seitenweise Ausgabe - oft sehr viel geschickter als altes more
  13. Get-Service | Out-Host -Paging

Ausgabe-Commandlets in Host/Konsole

Write-Host, Write-Warning und Write-Error
Mit Write-Host manuelle Konfiguration möglich
Write-Host "Hallo Joe" -foregroundcolor red -backgroundcolor white

Interessanter Parameter: -NoNewLine (kein Zeilenumbruch mit Write-Host)

Spezielle Formate/Formatierungen

... ein paar beispielhafte Codes - Highlight: Benutzerdefinierte Ausgabeformatierung mit @-Symbol

View source
  1. $a = "Joe Brandes"
  2. $b = "info(at)pcsystembetreuer.de"
  3. $c = Get-Date
  4. # wieder: in doppelten Zeichenketten sind Variablen nutzbar
  5. $a + " ist erreichbar unter " + $b + ". Diese Information hat den Stand: " + $c + "."
  6. "$a ist erreichbar unter $b. Diese Information hat den Stand: $c."
  7. # Neu: mit Platzhaltern und Formatbezeichnern: Ausgabeoperator -f
  8. "{0} ist erreichbar unter {1}. Diese Information hat den Stand: {2:D}." -f $a, $b, $c
  9. # weitere Formatierungen
  10. Get-Process | ForEach-Object { "{0,-40} | {1}" -f $_.Name, ($_.ws/1MB)}
  11. Get-Process | ForEach-Object { "{0,-40} | {1:n}" -f $_.Name, ($_.ws/1MB)}
  12. Get-Process | ForEach-Object { "{0,-40} | {1:0.000}" -f $_.Name, ($_.ws/1MB)}
  13. # Benutzerdefinierte Ausgabeformatierung mit @-Symbol:
  14. Get-Process | sort workingset64 -desc | ft @{Label="Nr"; Expression={$_.ID}; Width=5}, @{Label="Name"; Expression={$_.Processname}; Width=20 }, @{Label="Speicher MB"; Expression={$_.WorkingSet64 / 1MB}; Width=11; Format="{0:0.0}" }
  15. # Unterobjekt mit eigenen Methoden und Eigenschaften richtig ausgeben:
  16. Get-Process | ft ProcessName, { $_.TotalProcessorTime.Hours }
Bitte immer wieder mit manuellen Anpassungen die Wirkungen testen und Hilfen bemühen.

Ausgaben unterdrücken

Unterschiedliche Techniken, um die Ausgabe von Skriptcode zu verhindern:

View source
  1. # Out-Null verwenden:
  2. Commandlet | Commandlet | Out-Null
  3. # Variable zugewiesen:
  4. $a = Commandlet | Commandlet
  5. # Typ [void] nutzen:
  6. [void] (Commandlet | Commandlet)
  7. # $null zuweisen:
  8. $null = Commandlet | Commandlet

Eingaben in der PowerShell (Interaktionen)

Unterschiedliche Eingaben / Interaktionen mit der PowerShell durchgespielt:

View source
  1. # Eingaben
  2. # ========
  3.  
  4.  
  5. # in Shell: Standardeingaben mittels Read-Host (Typ: System.String)
  6. $name = read-host "Bitte Benutzernamen eingeben:"
  7. # Standardeingaben verschlüssel mittels Read-Host (Typ: System.Security.SecureString)
  8. $kennwort_verschluesselt = read-host -assecurestring "Bitte Kennwort eingeben:"
  9. # Das verschlüsselte Kennwort wieder zurückholen
  10. [String]$kennwort_unverschluesselt = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($kennwort_verschluesselt))
  11. "Kennwort: " + $kennwort_unverschluesselt
  12.  
  13.  
  14. # GUI: mittels .NET Framework in der Klasse Microsoft.VisualBasic.Interaction
  15. [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic")
  16. $eingabe = [Microsoft.VisualBasic.Interaction]::InputBox("Bitte geben Sie Ihren Namen ein!")
  17. "Hallo $Eingabe!"
  18.  
  19.  
  20. # Dialogfenster (auch mit Dot.NET)
  21. [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
  22. [System.Console]::Beep(15440, 30)
  23. [System.Windows.Forms.MessageBox]::Show("Gleich kommt eine Frage","Vorwarnung",
  24. [System.Windows.Forms.MessageBoxButtons]::OK)
  25. $antwort = [System.Windows.Forms.MessageBox]::Show("Nachricht","Ueberschrift", [System.Windows.Forms.MessageBoxButtons]::YesNo)
  26. if ($antwort -eq "Yes") { "Sie haben zugestimmt!" } else { "Sie haben abgelehnt!" }

Wichtig: die besondere Bedeutung von Parameter -Credential bzw. Cmdlet Get-Credential  für Zugriffe per "Remote"-Authentifizierungen

Module

mit Get-Module  erhält man eine Übersicht der aktuell geladenen (importierten) Module
mit Get-Module -ListAvailable  erhält man eine Übersicht über alle ladbaren (importierbaren) Module 

Alle Pfade für Modules (-Ordner): $env:PSModulePath  aufrufen und mit
$env:PSModulePath.split(";") einzeln darstellen lassen

View source
  1. ($env:PSModulePath).Split(";")
  2. # C:\Users\Benutzer\Documents\WindowsPowerShell\Modules
  3. # C:\Program Files\WindowsPowerShell\Modules
  4. # C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\
Die Module können also auch in einem Benutzerkonto-Ordner (Documents) abgelegt werden.

Der notwendige Ordner ist schnell angelegt:
New-Item -path $env:PSModulePath.split(";")[0] -ItemType Directory -Force        

Die Module sind dann später jeweils in Unter-Ordnern organisiert. In den bestehenden (System-)Modul-Ordnern kann man hierfür auch Beispiele einsehen.

Nutzer können also mit Cmdlet Save-Module eigene Module suchen (Find-Module) und bereitstellen:
Save-Module -Path ($env:PSModulePath).Split(";")[0] -Name PSWindowsUpdate  
Es lohnt sich die automatisch entstandene Ordner-/Dokument-Struktur zu analysieren:
Ordnerstruktur; *.ps1, *.psd1, *.psm1, *.ps1xml
Empfehlung: Modul PSCX (PowerShell Community Extension)

Einfacher Bauplan:
hier: ein Modul mit nur einer Funktion! - in diesem Seminar nicht als Praxis, sondern gleich die komplette Modultechnik (s.u.)

Für die folgenden Erstellungen muss der PowerShell-Host die Funktion kennen!
Hier: Get-CriticalEvent – Fehler und Warnungen aus System-Ereignisprotokoll – letzte 48 Stunden).

View source
  1. # folgende Befehle in Umgebung, wo Funktion Get-CriticalEvent bekannt ist!
  2. # Funktion siehe oben...
  3. $name = 'Get-CriticalEvent'
  4. $path = Split-Path -Path $profile
  5. $code = "function $name { $((Get-Item function:\$name).Definition) }"
  6. New-Item -Path $path\Modules\$name\$name.psm1 -ItemType File -Force -Value $code
  7. # Erster Test für die Verfügbarkeit des Cmdlet per Modul:
  8. Get-Module get-cr* -ListAvailable
Natürlich möchte man nicht nur eine Funktion pro Modul!

Praxis/Übung: Bauplan für komplette Modultechnik:
(im Seminar als ausführliche Praxisübung inklusive PDF-Print-Anleitung!)
module erstellen 800pxAnm.: Ausführliche Darstellung zu kompletten Modulen Siehe auch "Weltner, Kapitel 17 - Eigene Module erstellen; ab S. 589ff" oder auch in meinen "Scriptlines" als digitales Begleitmaterial für unsere Teilnehmer.

Modul-Ordner: C:\Users\username\Documents\Windows PowerShell\Modules\MyTools 
bzw. $HOME\Documents\Windows Powershell\Modules\MyTools   
oder $env:PSModulePath.split(";")[0]  

mit Manifest-Datei: .\MyTools.psd1  (erstellt mit Cmdlet New-ModuleManifest )
und Konfigurationen für RootModule='MyTools.psm1' und FunctionsToExport='*'

und Module-Datei: .\MyTools.psm1  mit Aufrufen für die einzelnen Funktionsdateien

View source
. $PSScriptRoot\myfunc1.ps1
. $PSScriptRoot\myfunc2.ps1

mit Funktionen-Dateien: myfunc1.ps1, myfunc2.ps1, ...  (enthalten die Funktions-/Cmdlet-Definitionen)

 

  • Datentyp SwitchDatentyp Switch
  • AusgabeformatierungenAusgabeformatierungen
  • Windows FormsWindows Forms
  • Modul-OrdnerModul-Ordner
  • PowerShell GalleryPowerShell Gallery
  • New-ModuleManifestNew-ModuleManifest

 

Tag 05

Freitag, 20.12.2019, 08.30 - 16.00 Uhr

Rekapitulation (Schwerpunkt-Thema: Module), Teilnehmer-Fragen

Plan / To-Do-List für Freitag:

  • WMI / CIM
  • Hintergrundjobs
  • Registry
  • Remoting
  • PowerShell im AD

... schauen wir mal ...

WMI / CIM (Get-WmiObject  Get-CimClass)

die klassische WMI (Windows Management Interface) und die "allgemeine" Variante CIM (Common Information Model) bieten Zugriff auf Tausende von Klassen mit Zugriff auf Systeminformationen und -Techniken:
Get-WmiObject -Class Win32_Bios -Computername DC01   (also gleich mit eingebautem "Fernzugriff")

Auf aktuellen Windows-Betriebssystemen kann man mit WMI/CIM-Techniken auf rund 1200 Klassen zugreifen.

Auflistung aller WMI-Klassen mit Get-WmiObject -List 

Bei CIM nutze man Get-CimClass und Get-CimInstance 

Beispielhafte Aufrufe:

View source
  1. # Service Start Modi - Anmerkung: Get-Service kannte keinen StartMode!
  2. Get-WmiObject Win32_Service | Select-Object Name, StartMode
  3. # ein spezieller Startmodus
  4. ([wmi]'Win32_Service.Name="Spooler"').StartMode
  5. # eingeloggte User
  6. $ComputerName = ‘localhost’
  7. Get-WmiObject Win32_ComputerSystem -ComputerName $ComputerName | Select-Object -ExpandProperty UserName
  8. # Netzwerkanalyse
  9. function Get-NetworkConfig {
  10. Get-WmiObject Win32_NetworkAdapter -Filter ‘NetConnectionStatus=2|
  11. ForEach-Object {
  12. $result = 1 | Select-Object Name, IP, MAC
  13. $result.Name = $_.Name
  14. $result.MAC = $_.MacAddress
  15. $config = $_.GetRelated(‘Win32_NetworkAdapterConfiguration’)
  16. $result.IP = $config | Select-Object -ExpandProperty IPAddress
  17. $result
  18. }
  19. }
  20. # Lokale Gruppen
  21. Get-WmiObject Win32_Group -Filter "domain='$env:computername'" | Select-Object Name,SID
  22. # Uptime Os
  23. $os = Get-WmiObject -Class Win32_OperatingSystem
  24. $boottime = [System.Management.ManagementDateTimeConverter]::ToDateTime($os.LastBootupTime)
  25. $timedifference = New-TimeSpan -Start $boottime
  26. $days = $timedifference.TotalDays
  27. 'Das System läuft seit {0:0.000} Tagen.' -f $days
  28. # Freier Speicher auf Disks
  29. Get-WmiObject Win32_LogicalDisk |
  30. ForEach-Object { ‘Disk {0} hat {1,20:0.00} MB Platz frei’ -f $_.Caption, ($_.FreeSpace / 1MB)
  31. }
Vergleich WMI vs. CIM - Scripting Guy Blog (Link)
Introduction to CIM - PowerShell Blog (Link)
Hinweis auf PowerShell Cookbook PDFs von Autor Weltner (Link)

Hintergrundjobs

... Backgroundjobs - können möglicherweise Skriptlaufzeiten (massic) positiv beeinflussen

Vorbereitete Übung ... Siehe Übungsdateien TN und Script-Sammlung für TN

Registry

... mit der PowerShell verwalten.

Vorbereitete Übung ... Siehe Übungsdateien TN und Script-Sammlung für TN

Fernverwaltungen / Remoting

Unterschiedliche Techniken möglich:

Commandlets mit eingebauter Funktionalität (Parameter -ComputerName) für Fernaufrufe

auf anderen Maschinen

View source
  1. # Commandlets mit eingebauter "Fernwartung"
  2. Get-Command | where { $_.parameters.keys -contains "ComputerName" -and $_.parameters.keys -notcontains "Session"}
  3. # Aufrufbeispiel: (auch gerne gleichzeiig auf mehreren Maschinen)
  4. Get-Service -ComputerName domvbox-2012r2 i*
Bedenken: nur in Domänenumgebungen sind die Authentifizierungen vorhanden - ansonsten werden Übergaben von "Credentials" mit Comdlet Get-Credential benötigt.

Praktische Übungen mit den WMI/CIM-Cmdlets: hier beachten, dass Get-WmiObject "Credentials" übergeben kann. Aber Get-CimInstance kann keine Credentials übergeben.

PowerShell Sessions - die moderne MS Terminalsitzung / Shellsession

Wichtig: in P2P-Netzen - also ohne Windows Domäne - muss auch die Erlaubnis der gegenseitigen Zugriffe mittels TrustedHosts im WSMan(ager) konfigurieren und Testen, bevor man die Zugriffe per WinRM nutzen kann! Kurzanleitung:

View source
  1. Set-Item WSMan:\localhost\Client\TrustedHosts -Value "10.100.211.116, Win10" -Force
  2. #ggf. Testen/Restarten WinRM: Restart-Service WinRM
  3. # Einfacher Test
  4. Test-WSMan -ComputerName # eigener Rechner
  5. Test-WSMan -ComputerName 10.100.211.116 # Gegenstelle
  6.  
Technikhintergrund: WinRM (Windows Remote Management);
Mindest-Anforderungen für WinRM Services:
Microsoft .NET Framework 2.0 oder höher; Windows PowerShell 2.0 oder höher; Windows Remote Management (WinRM) 2.0

ps remoting 800px

Rechner für PowerShell Sessions (PSRemoting) vorbereiten:

View source
  1. # WinRM-Systemdienst starten (inkl. Firewall - Netzwerkverbindungstyp beachten - kein Öffentliches Profil!)
  2. Enable-PSRemoting
  3. # Unterdrücken der Nachfragen und aktueller Netzwerkprofile-Checks mit
  4. Enable-PSRemoting -SkipNetworkProfileCheck -force
  5. # Testen der Fähigkeit:
  6. New-PSSession   # bzw.: Test-WSMan
in Firmen/Domänen kann man die folgende Gruppenrichtlinie nutzen:
Computer Configuration\Administrative Templates\Windows Components\Windows Remote Management (WinRM)\WinRM service
Beispielhafte Nutzung:
View source
  1. # Interaktiv Sitzung:
  2. Enter-PSSession –Computername domvbox-2012r2
  3. # komplette Anmeldung inkl. -Credential und oft auch -Authentication
  4. # in Domänen: zentrale Verwaltung der Rechte! Normaler Weise kein Cred nötig!
  5. Enter-PSSession domvbox-2012r2 -Authentication Negotiate -credential dom2012r2\Administrator
  6. # Beenden:
  7. Exit-PSSession
  8. # aktuelle Konsolenmaschine
  9. [System.Environment]::MachineName
Alternative Aufrufe und weitere technische Möglichkeiten mittels Commandlet Invoke-Command 
Anregung: Recherche nach Cmdlets mit *PSSession*

PowerShell WebAccess (PSWA)

Zugriff auf PowerShell-Console mittels https-Web-Client (Browser) vergleichbar zu OWA (Outlook Web Access)
Notwendige Installationen:

  • Rolle "Web Server (IIS)"
  • Feature "Windows PowerShell/Windows PowerShell Web Access"

mit PowerShell: Install-WindowsFeature -name web-server, windowspowershellwebaccess   

Weitere Konfigurationen:

View source
  1. # Installieren/Bereitstellen von Test-Zertifikat
  2. Install-PswaWebApplication -UseTestCertificate
  3. # Anm.: jetzt Server erreichbar unter https://localhost/pswa # Regel (hier sehr "frei") für die Erreichbarkeit von PSWA erstellen:
  4. Add-PswaAuthorizationRule –UserName * -ComputerName * -ConfigurationName *
Beim Aufruf der Webseite https: // dc-server/pswa  muss man natürlich das Zertifikat im Browser anerkennen (lassen).

pswa 800px

Für den Zugriff auf einen "Server" benötigt man also nur einen Web-Client und schon kann es losgehen.

RSAT in Windows Domänen auf WinClients

RSAT - Remoteserver Administration Tools - Download RSAT für Windows 10 - bitte Windows-Version beachten!
Ab Windows 10 (1809) kein eigenständiger Download mehr (Info-Link), sondern "WindowsCapability" Erweiterungen hinzufügen:

View source
Get-WindowsCapability -Online |
    Where-Object {$_.Name -like "*RSAT*" -and $_.State -eq "NotPresent"} |
    Add-WindowsCapability -Online

Analyse Anzahl Commandlets/Functions: Windows 8.1 hatte 1264
Mit Windows 8.1 + RSAT zählte dann 2211 (!)  und RSAT stellt mit dem "Active Directory-Verwaltungscenter" die moderne AD-Verwaltung mit Sicht auf die PowerShell-Befehle bereit (Windows PowerShell Verlauf History)

Beispiel für AD-Commandlet aus Modul "ActiveDirectory": Get-ADUser -Filter { Name -like "*Joe*" } 

Modul "ActiveDirectory"

... stellt auf einem AD Domain Controller (DC) direkt Cmdlets zur AD-Verwaltung bereit.

Auf einem Mitgliedsserver über hinzufügen von Features das PowerShell-Modul "ActiveDirectory" bereitstellen oder auf Clients (Windows 7 Professional, Windows 10 Pro) die passenden RSAT-Tools installieren/bereitstellen.

Exemplarische Codebeispiele / PowerShell-Nutzungen:

  • Erstellen einer neuen OU mit Unter-OUs, neuen Benutzern und Gruppen in einem Rutsch aus einer CSV-Dateivorlage
  • Rekursives Nutzen mit Lösch-Cmdlets (Remove-ADObject)

Hinweise zu den AD-Cmdlets:

  • benutzen von -recursive (statt -recurse)
  • Bestätigungen vermeiden / Vorgänge "erzwingen" mit -confirm:$false (statt sonst -force)
  • für Set-Location in AD: bitte die LDAP-Pfade sauber in Zeichenketten:
    Set-Location 'DC=dom2012r2,DC=local' 

Recherche auf DC-Verwaltung mit Active Directory-Verwaltungscenter (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.

 

Digitale Unterlagen für TN

Hand-Outs Trainer J. Brandes

  • Ausarbeitung zur PowerShell PDF >100 S. (und als HTML-Versionen)
  • PowerShell "Trainer Snippets/Scriptlines" ca. 2000+ Zeilen)
  • PowerShell "Scripts Seminarwoche (Tage 01 - 05)"
  • Website zum Thema PowerShell von Trainer J. Brandes

ps joe-brandes.de 800px

Allgemeine Unterlagen

  • Screenshots Seminarwoche ("Diashow" zum Seminar)
  • Diverse PDF / Workshops

Letzte TN-Fragen, Feedback-Bögen, TN-Bescheinigungen

 

  • Get-WmiObjectGet-WmiObject
  • Skript repariertSkript repariert
  • PSProvider RegistryPSProvider Registry
  • Enable-PSRemotingEnable-PSRemoting
  • P2P RemotingP2P Remoting
  • PSSessionPSSession

 

Bücher und Co

Für die Quellen, die ich an dieser Stelle darstellen möchte.

Die Bücher werden auch im Seminar mit den Teilnehmern eingeschätzt:

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

Windows PowerShell 5 und PowerShell Core 6: Das Praxisbuch Gebundenes Buch – 6. November 2017
von Dr. Holger Schwichtenberg
Gebundene Ausgabe: 1231 Seiten
Verlag: Carl Hanser Verlag GmbH & Co. KG (6. November 2017)
Sprache: Deutsch
ISBN-10: 3446453318
ISBN-13: 978-3446453319

Windows PowerShell Cookbook: The Complete Guide to Scripting Microsoft's Command Shell (Englisch) Taschenbuch – 8. Januar 2013
von Lee Holmes
Taschenbuch: 1034 Seiten
Verlag: O'Reilly & Associates; Auflage: 3 (8. Januar 2013)
Sprache: Englisch
ISBN-10: 1449320686
ISBN-13: 978-1449320683

Schnelleinstieg in die Windows PowerShell. oreillys basics Broschiert – 28. März 2007
von 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
ISBN-13: 978-3897214873

  • Lee Holmes
  • Cookbook
  • Tobias Weltner
  • Windows Automation
  • powershell50-praxis-00
  • powershell50-praxis-01
  • Dr. H. Schwichtenberg
  • Das Praxibuch
  • Andy Oakley
  • Schnelleinstieg

Falls Sie Anregungen hinsichtlich Büchern und Webseiten haben, dann bitte einfach per Mail an mich melden.

 

Nochmals von dieser Stelle schönen Dank für die großartigen Feedbacks und Ihr Interesse an weiteren Seminaren.
Ihr Trainer Joe Brandes

 

  Privates

... zu Joe Brandes

Sie finden auf dieser Seite - als auch auf meiner privaten Visitenkarte joe-brandes.de einige Hintergrundinformationen zu mir und meinem Background.
Natürlich stellt die IT einen Schwerpunkt in meinem Leben dar - aber eben nicht nur ...

joe brandes 600px

Private Visitenkarte / Technik: HTML & CSS /
  joe-brandes.de

  Jobs

... IT-Trainer & Dozent

Ich erarbeite und konzipiere seit über 20 Jahren IT-Seminare und -Konzepte. Hierfür stehen der "PC-Systembetreuer / FITSN" und der "CMS Online Designer / CMSOD". Ich stehe Ihnen gerne als Ansprechpartner für Ihre Fragen rund um diese und andere IT-Themen zur Verfügung!

becss 600px

BECSS Visitenkarte / Technik: HTML & CSS /
  becss.de

  Hobby

... Snooker & more

Wer einmal zum Snookerqueue gegriffen hat, der wird es wohl nicht wieder weglegen. Und ich spiele auch immer wieder gerne eine Partie Billard mit den Kumpels und Vereinskameraden. Der Verein freut sich über jeden, der einmal in unserem schicken Vereinsheim vorbeischauen möchte.

bsb 2011 600px

Billard Sport BS / Joomla 3.x /
  billard-bs.de

PC Systembetreuer ist J. Brandes - IT seit über 35 Jahren - Technik: Joomla 3.4+, Bootstrap 3.3.4 und "Knowledge"

© 2020 - Websitedesign und Layout seit 07/2015 - Impressum - Datenschutzerklärung
Nach oben