An der VHS Braunschweig findet vom 14. bis 18. Dezember 2015 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 basis screenshot 800px

Hier die Rahmendaten unseres Seminars:

Ort: VHS Braunschweig, Heydenstraße 2, Raum 2.11
Termine: Mo., 14.12. bis Fr., 18.12.2015; 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, 14.12.2015, 08.30 - 16.00 Uhr

  • Orientierungsphase, Teilnehmer-Themen: Roter Faden Seminarankündigung,
    TN-Thema: kein spezielles Thema bei erster Orientierung genannt.
  • Allgemeines
    Wir setzen als Betriebssyteme Windows 7 Professional in einer Windows Server 2012 R2 Domänenumgebung ein.
    Aktuell: PowerShell Version 4.0 oder eigentlich:
    Microsoft Windows Management Framework 4.0 (Link zum MS Download)
    Praxisumgebung.: es gibt auch bereits die Produkt Vorschauf auf Version 5.0 (Link)
    Übersicht zu PowerShell-Versionen und deren Betriebssystemverfügbarkeiten: Wikipedia
    Deutsche Einstiegsseite zum Thema Microsoft PowerShell: Microsoft Skriptcenter
    Installationsverzeichnis: C:\Windows\System32\WindowsPowerShell\v1.0
    Anm.: ja immer noch Version 1.0 ;-) im Pfad; siehe vordefinierte Variable $PSHome
    {code lang:powershell showtitle:false lines:true hidden:false}# PS-Version anzeigen lassen
    echo $PSVersionTable
    # Installationsverzeichnis
    Write-Host $PSHome{/code} 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:
    der Versuch das "Beste aus allen Welten" zu kombinieren und zu verbinden
    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)
  • Abarbeitungsreihenfolge bei Aufrufen in der PS:
    1) Aliase (dir, md)
    2) Funktionen (mkdir, C:)
    3) Commandlets (Get-Process)
    4) Externe Befehle (netstat, ipconfig, notepad, ...)
  • Commandlets
    abhängig vom jeweiligen Betriebssystem (Operating System - OS) in PS 4.0 über 1000 Commandlets
    Aufbau: Verb-Substantiv [-Parameterliste]  
    Get, Set, Add, New, Remove, Clear, Push, Pop, Write, Export, Select, Sort, Update, Start, Stop, Invoke, ...
    Ausgabekommandos wie Out und Format
    Cmdlets können ohne Verb aufgerufen werden (alias statt Get-Alias) - dann werden also die Get-Cmdlets ausgeführt
    PSCX: zusätzliche Cmdlets für die Woche bereitgestellt mit den PSCX (PowerShell Community Extensions
    z.B. Ping-Host oder auch Get-DomainController
  • PSReadline - ein Modul für das Verbessern der PowerShell Konsole
    in PS 5.0 hat man PowerShellGet, ein Modul, das die Fähigkeiten von OneGet (einem Paketmanager) bereitstellt
    daher einfach neues Cmdlet nutzen: (in einer Administrator-Shell)
    Install-Modul -Name PSReadline  
    Wichtig: Abfragen nach Installation von Paketmanagement-Tool und Vertrauenswürdigkeit des Paketrepositories mit "Y"
    Verbesserungen in der PowerShell-Konsole: (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)
    - belegbare Tastenkombinationen (siehe cmdlet Get-PSReadlineKeyHandler bzw. das Pendant Set-PSReadlineKeyHandler)
  • Erste Aufrufe in der PS
    Interaktive Aufrufe vergleichen:
    Get-Process vs. Get-EventLog (hier dann Parameter als Eingabe möglich: Application, System, ...)
    {code lang:powershell showtitle:false lines:true hidden:false}# Parameter - und einfache Parameter-Switches nutzen
    # Alle Aufrufe gleich:
    Get-ChildItem C:\temp *.txt # Hier: Reihenfolge entscheidend!
    Get-ChildItem -Path C:\temp -Filter *.txt
    Get-ChildItem -Filter *.txt -Path C:\temp
    # Verschiedene Platzhalter / Wildcards:
    Get-Process i*
    Get-Process i*ore
    Get-Process [st]*
    Get-Process [st][vf]*
    # Aktivieren / Deaktivieren von Schaltern:
    Get-ChildItem C:\temp -recurse
    Get-ChildItem C:\temp -recurse:$false{/code} 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)
    {code lang:powershell showtitle:false lines:true hidden:false}# Neue Aliase mit:
    Set-Alias procs Get-Process # neu oder überschreiben
    New-Alias procs Get-Process{/code} Wichtig: keine Parameter festlegbar - da brauchen wir später Funktionen!
    Die Aliase gelten nur in der aktuellen PS-Sitzung (Instanz), bei späterer Nutzung dann in Profile integrieren oder manuell exportieren / importieren:
    {code lang:powershell showtitle:false lines:true hidden:false}Export-Alias c:\temp\meinealias.csv # also in eine Textdatei
    Export-Alias c:\temp\meinealias.ps1 -as script # in ein PS-Skript
    # Laden:
    Import-Alias c:\temp\meinealias.csv
    . c:\meinealias.ps1 # Punktoperator - "Dot sourcing"{/code} Es werden alle Aliase exportiert und wieder importiert, was zu "Fehlermeldungen" beim Import führt - manuelle Anpassungen der Exportdateien gezeigt, so werden die Aliase "sauber" importiert - Später: in den PS-Profilen sauber hinterlegen!
  • Ausdrücke
    eine erste Annäherung mit () im Expression bzw. Command Mode
    Vergleiche:
    {code lang:powershell showtitle:false lines:true hidden:false}Write-Output 10 * (8 + 6) # mit
    Write-Output (10 * (8 + 6))
    # Aufrufe mit Unterausdruck:
    "Anzahl der laufenden Prozesse: (Get-Process).Count"
    # vergleichen mit:
    "Anzahl der laufenden Prozesse: $((Get-Process).Count)"{/code}Anm.: $ leitet 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
    Intellisense Eingabeunterstützung - 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
    Unterschiede zu PowerShell-Konsole:
    Wichtige Unterschiede zur "normalen" PowerShell:
    keine interaktiven Tools/Programme möglich: ftp, nslookup, ...
    kein Blättern mit more, keine Soundausgaben
    {code lang:powershell showtitle:false lines:true hidden:false}# Eigene Farbgebungen in ISE mittels:
    $psISE.Options.ConsolePaneBackgroundColor = "red"
    # alternativ:
    $host.ui.RawUI.BackgroundColor = "red"{/code} siehe auch $psISE.options für die möglichen Einstellungen / Optionen der ISE
    Tipp: Einstellungen mittels Tools - Optionen bearbeiten bzw. auf Standard zurückstellen
  • Profile (Part I)
    Sowohl die PowerShell als auch die ISE besitzen Profile (Profildateien/Konfigurationen)
    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   
    {code lang:powershell showtitle:false lines:true hidden:false}# Erstellen der Profile jeweils mit
    New-Item $profile -ItemType file –Force
    # Bearbeiten der Profile möglich mit
    ise $profile{/code} Anpassen der Profile dann in weiteren Übungen, wenn wir das Skripten im Griff haben.
    Erste Übung mit Aliasen (Set-Alias) und Stardverzeichnis für die PowerShell mit Set-Location

 

  • Alias, Func, Cmdlet, AppsAlias, Func, Cmdlet, Apps
  • $PROFILE$PROFILE
  • PS 5.0 als UpdatePS 5.0 als Update
  • Modul PSReadlineModul PSReadline
  • PSCXPSCX
  • Get-EventLogGet-EventLog

 

Tag 02

Dienstag, 15.12.2015, 08.30 - 16.00 Uhr

  • Rekapitulation, TN-Fragen
    ausführliche Darstellung von Tag 01
  • Hilfe in der PowerShell
    mit Tabulator Codevervollständigung (auch Umschalten + TAB rückwärts) inkl. Wildcards: Get-?e*
    {code lang:powershell showtitle:false lines:true hidden:false}Get-Command Get-* # liefert alle Befehle, die mit get anfangen.
    Get-Command [gs]et-* # liefert alle Befehle, die mit get oder set anfangen.
    Get-Command *-Service # liefert alle Befehle, die das Substantiv Service besitzen.
    # Befehle, die das Substantiv Service besitzen:
    Get-Command –noun Service
    # Befehle, die die Buchstabenfolge wmi enthalten
    # (und mutmaßlich mit der Windows Management Instrumentation zu tun haben).
    Get-Command *wmi*
    # Befehle, die die Buchstabenfolge wmi“ oder cmi enthalten
    Get-Command | Where-Object { $_.name -like "*cim*" -or $_.name -like "*wmi*" }
    Get-Command ps
    Get-Command notepad.exe
    Get-Command C:{/code}Anzahl von Commandlets und Funktionen (so seit PS 2.0)
    (Get-Command) | group commandtype
    Einfache Hilfe zu Kommandos: Get-Command -?
    Über das spezielle Commandlet Get-Help:
    Get-Help Get-Command
    mit Parametern auch: Get-Help Get-Command -Detailed (-Full, -Examples, -Online, -ShowWindow)
    Anm.: unbedingt die "neuen" -Online, -ShowWindow Optionen durchspielen!
    Die Option -Online steht nicht für alle Commandlets der PS zur Verfügung.
    Hilfe zu den Parametern der Commandlets:
    Get-Help Get-Process -parameter "*"
    Grafische Oberfläche mit Show-Command seit PS 3.0: Show-Command Get-Process 
    Hilfe aktualisieren mit Update-Help Commandlet - Beachten: Admin-PS 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 - hier leider wieder Einschränkungen in der Production Preview 5.0);
    Empfehlung: auch einfach online suchen mit "PowerShell about_for, ...
  • Pipelining
    in der PS ist alles objektorientiert bearbeitbar und eben auch weitergegeben (siehe Pipeline) Anm.: das besondere Konstrukt $_greift auf das aktuelle Objekt zu{code lang:powershell showtitle:false lines:true hidden:false}# komplexere Pipeline:
    Get-ChildItem c:\temp –r -filter *.txt |
    >>> Where-Object { $_.Length -gt 40000 } |
    >>> Select-Object Name, Length |
    >>> Sort-Object Length |
    >>> Format-List{/code}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){code lang:powershell showtitle:false lines:true hidden:false}# Ein paar Beispiel für Pipeline-Aufrufe:
    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
    ps | ? {$_.ws -gt 20MB }
    # alle Dienste, die mit i beginnen
    "i*" | Get-Service
    # Dienst "gleich" BITS
    "BITS" | Get-Service{/code}
    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)
    {code lang:powershell showtitle:false lines:true hidden:false}# 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 mit Array-Technik einzeln ansprechen:
    (Get-Process | where-object { $_.WorkingSet64 -gt 20MB })[5]
    # früher:
    Get-Process | foreach-object {$_.Name }
    # seit PS 3.0:
    (Get-Process).Name
    # Für eine kombinierte Ausgabe ist foreach-Commandlet nötig:
    Get-Process | foreach-object {$_.Name + ": " + $_.Workingset64 }{/code} Methoden der Objekte: (also Funktionen zu denen die Objekte fähig sind) Alle Techniken praktisch erprobt.
    {code lang:powershell showtitle:false lines:true hidden:false}# alle iexplore "killen"
    Get-Process iexplore | Foreach-Object { $_.Kill() }
    # seit PS 3.0:
    (Get-Process iexplore).Kill()
    # besseres Commandlet: Stop-Process
    # hier gibt es auch keine Fehler mehr, falls kein iexplore
    Get-Process | Where-Object { $_.Name -eq "iexplore" } | Stop-Process
    # Alle Methoden für Get-Date anzeigen lassen:
    Get-Date | Get-Member
    (Get-Date).ToLongDateString() # und viele Andere{/code}Anm.: die Fehlerbehandlung in unsere PowerShell Konsole wird durch Einsatz von PSReadline optimiert.
  • Skripting (Part I)
    Skriptausführung muss mit geeigneter ExecutionPolicy (RemoteSigned) erlaubt sein;
    Commandlets: Get-ExecutionPolicy und Set-ExecutionPolicy  (als Admin!)
    Dateiformat (Dateiendung): *.ps1
    Das erste Skript (nach Schwichtenberg - Quelle/Buch des Microsoft-Experten zeige ich noch)
    {code lang:powershell showtitle:false lines:true hidden:false}# Mein erstes Skript
    "Informationen über diesen Computer:"
    "Datum: " + (Get-Date).ToShortDateString()
    "Zeit: " + (Get-Date).ToLongTimeString()
    "Anzahl laufender Prozesse: " + (Get-Process).Count
    "Anzahl lauf. Dienste: " + (Get-Service | where { $_.Status -eq "running" } ).Count{/code} Anm.: Zeichenkodierungen bei alternativen Editoren (also nicht ISE) beachten:
    z.B. Notepad++ mit UTF (ohne BOM) vs. ANSI (mit Notepad, ISE, und Co)
    Starten von Skripten mittels:
    {code lang:powershell showtitle:false lines:true hidden:false}.\skript.ps1
    &.\skript.ps1
    Invoke-Expression .\skript.ps1{/code}Auch direkte Aufrufe mit powershell.exe g:\pfad\skript.ps1
    Skripte lassen sich mit Alias zuweisen:
    Set-Alias Get-ComputerInfo C:\temp\Skript.ps1
    Übung: das Ganze verdrahtet und in die $PROFILE gepackt

 

  • Modul PscxModul Pscx
  • Out-GridViewOut-GridView
  • AliaseAliase
  • Select-StringSelect-String
  • Reguläre AusdrückeReguläre Ausdrücke
  • SkriptingSkripting

 

Tag 03

Mittwoch, 16.12.2015, 08.30 - 16.00 Uhr

  • Rekapitulation, TN-Fragen
    Wiederholungen und Übung zu unseren ersten Einträgen und Skriptings (mit $PROFILE)
  • Filtern, Sortieren, Gruppieren
    Mit den Standard-Cmdlets (Verben: Where-, Sort-, Group-) praktische Übungen durchgeführt:
    {code lang:powershell showtitle:false lines:true hidden:false}# 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
    # mit Regulären Ausdrücken
    # 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}$" }
    Vergleichsoperatoren (s. about_Comparison_Operator)
    # klassische Filter:
    Get-Service | where-object { $_.status -eq "running" }
    # können seit PS 3.0 auch mit
    Get-Service | where-object status -eq "running"
    # aber bei Kombinationen mit and oder or bitte wieder klassisch:
    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*" }
    #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-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 System32 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
    # Auswertungen mit Measure-Object - Standard ist count, also Anzahl
    Get-ChildItem c:\windows | Measure-Object -Property length -min -max -average -sum{/code}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
  • Parameter an Skripte übergeben:
    per args[] (bei 0 beginnend){code lang:powershell showtitle:false lines:true hidden:false}"Informationen über den Computer: " + $args[0]
    # oder aber mit param Deklaration und Variablenname
    param([string] $Computer)
    "Informationen über den Computer: " + $Computer{/code}oder mittels param[] - Deklarationen am Anfang des Skript
  • Variablen (Part I)
    Hier werden wir Variablen erst einmal interaktiv in der PS nutzen:{code lang:powershell showtitle:false lines:true hidden:false}# Ü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"}
    $y | Foreach-Object { $_.ws }{/code}
    Erste Tests mit Set-Location Variable: (quasi einem "Laufwerk/Drive" für die Variablen), wo wir mit Get-ChildItem die Variablen auflisten lassen können; alternativ: Get-Variable  
  • Variablen (Part II)
    bestimmte Variabnlennamen 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], [string], [byte], [char], [bool], [xml], ...
    Vordefinierte Variablen: $true, $false, $Home, $PSHome, $host, ...
    mit z.B. $host.UI.RawUI.BackgroundColor = "darkgreen"
    Variablen werden in Zeichenketten mit doppelten Anführungszeichen ausgewertet!
  • Skripting (Part II - einfache Ein- und Ausgaben)
    Auf den Unterschied achten zwischen einfachen und doppelten Anführungszeichen{code lang:powershell showtitle:false lines:true hidden:false}[int] $a = Read-Host "Bitte geben Sie Wert A ein"
    [int] $b = Read-Host "Bitte geben Sie Wert B ein"
    $c = $a + $b
    Start-Sleep -Seconds 10
    Write-Output 'Das Ergebnis lautet: $c mit einf. Anführungszeichen!'
    "Das Ergebnis lautet: $c mit doppelten Anführungszeichen!"
    'Das Ergebnis lautet: ' + $c + ' mit einfachen Anführungszeichen!'{/code}Als Ausgabe gilt klassisch echo - und das ist bei unserer PowerShell ja der Alias für Write-Output
    Typ-Operatoren:
    wir sollten mit [int] den Datentyp (hier: Integer32) festlegen; Alternativ: [string], [boolean], ...
  • Zeichen / Strings
    siehe auch wieder die Online-Hilfen zu den Vorgehensweisen und Methoden:{code lang:powershell showtitle:false lines:true hidden:false}# Das "Echo" für die PS: Write-Host
    Write-Host "Guckst Du" -ForegroundColor Yellow
    # Zeichenketten Operationen (Methoden)
    "" | Get-Member -m Method
    [String] $CSVString = "Joe;Brandes;Braunschweig;Deutschland;www.pcsystembetreuer.de"
    $CSVArray = $CSVString.Split(";")
    $Surname = $CSVArray[1]
    $Surname{/code}
  • Arrays
    $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
    assoziatives Array: (eine Hashtabelle){code lang:powershell showtitle:false lines:true hidden:false}# 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"; }
    $Computers["E02"]
    $Computers.E02{/code} Also: Arrays sind 2-spaltige Tabellen mit Indizes (Linke Spalte) und Werten (Rechte Spalte)
  • Vergleichsoperatoren
    siehe Google-Recherche "powershell vergleichsoperatoren" - beispielhafter Ergebnislink
    mit eingebauter PS-Hilfe: get-help about_Comparison_Operators -ShowWindow  
    -gt (greater than), -lt (lighter than), -eq (equal), -ne (not equal), -ge (greater equal), -le (lighter equal), ...
  • Kontrollstrukturen
    siehe hierzu auch Nassi-Shneiderman Diagramme (Wikipedia-Link)
    Verzweigungen: if,, switch
    Schleifen: for, do, while  (Abbruchbedingen am Anfang oder Ende der Schleifen)
    Speziell: foreach (automatische Schleifen für Arrays/Objekte)
    Funktionen: function, return (eine kleine erste Einführung s.u.)
    Übungen zu if, switch, for, foreach
    weitere Beispielcodes aus den Online-Hilfen "kopiert", angepasst und getetstet
  • for (ein kleines Codebeispiel)
    Bitte wieder Hilfen beachten: Get-Help about_for 
    Beispiel-Codes aus den Hilfedateien durchgespielt {code lang:powershell showtitle:false lines:true hidden:false}# Fakultätsberechnung mit einer For-Schleife und vorzeitiger Abbruchbedingung
    # -------------------
    "Bitte eine Zahl eingeben:"
    $Fakultaet = Read-Host
    $FakultaetErgebnis = 1
    $Abbruch = $false
    for ($i = 1; $i -lt $Fakultaet; $i++)
    {
    $FakultaetErgebnis = $FakultaetErgebnis * $i
    if ($FakultaetErgebnis -gt [System.Int32]::MaxValue) { $Abbruch = $true; break; }
    }
    if ($Abbruch) { "Werteüberlauf!" }
    else { "Die Fakultät von " + $Fakultaet + " ist " + $FakultaetErgebnis }{/code}Code hier als Beispiel - im Seminar wurden andere Codes behandelt!
  • foreach (automatische Schleifen)
    automatischer Schleifenmechanismus{code lang:powershell showtitle:false lines:true hidden:false}# einfaches nummerisches Array
    $menge = 1,2,3,4,5
    foreach ($i in $menge)
    { $i }
    # Array/Objekt aus Get-Service
    $dienste = Get-Service
    foreach ($dienst in $dienste)
    { # Nutzung eines Ausgabeoperator -f
    "{0,-20}: {1}" -f $dienst.Name , $dienst.Status
    } {/code} Ausgabeoperator -f siehe später auch bei verbesserten Ausgabetechniken
  • Funktionen (eine erste Annäherung - mehr dann morgen)
    Die Funktionen "kapseln" mehrere Abarbeitungsschritte und können später dann auch Parameter übergeben bekommen und Werte zurückgeben.
    Das Beispiel hier wurde der "Online-Dokumentation about_functions" entnommen:{code lang:powershell showtitle:false lines:true hidden:false}function Get-NewPix
    {
    $start = Get-Date -Month 1 -Day 1 -Year 2015
    $allpix = Get-ChildItem -Path $env:UserProfile\*.jpg -Recurse
    $allpix | where {$_.LastWriteTime -gt $Start}
    } {/code}Dieses kleine Beispiel zeigt uns alle Jpeg-Dateien in unserem Benutzerprofil, die nach einem Startdatum geändert worden sind.
    Für eine stetige Verfügbarkeit der Funktion Get-NewPix  brauchen wir nur den Code in unser $PROFILE Startskript zu packen.

 

  • Holger SchwichtenbergHolger Schwichtenberg
  • Gruppieren - SortierenGruppieren - Sortieren
  • Get-MemberGet-Member
  • if Verzweigungif Verzweigung
  • for, foreach - Schleifenfor, foreach - Schleifen
  • $env:...$env:...

 

Tag 04

Donnerstag, 17.12.2015, 08.30 - 16.00 Uhr

  • Rekapitulation, TN-Fragen
  • Seminarnetz mit Domänen
    • windows-server-plan-20151130-740px
    Ab heute ist der Seminarraum mit einem Domänen-Umgebung für das PowerShell-Seminar ausgestattet.
    Die Dokumentation der bereitgestellten Umgebung entnehmen Sie dem Vorseminar "Windows Server / VHS BS / 30.11. - 04.12.15"

    Wichtig
    : wir konzentrieren uns auf die PowerShell und lassen die "Server-Domänen-Active-Directory-Technik" beiseite
  • Analyse und Inbetriebnahme der PowerShell Umgebung
    PowerShell-Versionen? ( $PSVersionTable )
    Excecution Policy? (Get-ExecutionPolicy / Set-ExecutionPolicy)
    Hinweis auf Gruppenrichtlinie in dombu.local für Verteilung von Policy "RemoteSigned"
    PowerShell Umgebung: $PROFILE bereitstellen (Tipp: New-Item -ItemType File $PROFILE -Force )
    PSReadline bereitstellen (Kurzanleiitung: siehe Tafelbild Trainer)
    PowerShell Hilfe aktualisieren (Update-Help - als Administrator) und in Konsole nutzen
  • Ausgaben (Part II - Forts. 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{code lang:powershell showtitle:false lines:true hidden:false}# Gezieltes Ausgeben der Tabellen - Propierties (Methoden)
    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
    # Standardausgabe gemäß DotNetTypes.Format.ps1xml (eigentlich also DOT.NET Formate!)
    Get-ViewDefinition System.Diagnostics.Process
    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 - oft sehr viel geschickter als altes more
    Get-Service | Out-Host -Paging{/code}
  • 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
  • Spezielle Formate/Formatierungen
    ein paar beispielhafte Codes{code lang:powershell showtitle:false lines:true hidden:false}$a = "Joe Brandes"
    $b = "info(at)pcsystembetreuer.de"
    $c = Get-Date
    # wieder: in doppelten Zeichenketten sind Variablen nutzbar
    $a + " ist erreichbar unter " + $b + ". Diese Information hat den Stand: " + $c + "."
    "$a ist erreichbar unter $b. Diese Information hat den Stand: $c."
    # Neu: mit Platzhaltern und Formatbezeichnern: Ausgabeoperator -f
    "{0} ist erreichbar unter {1}. Diese Information hat den Stand: {2:D}." -f $a, $b, $c
    # weitere Formatierungen
    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 Ausgabeformatierung mit @-Symbol:
    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}" }
    # Unterobjekt mit eigenen Methoden und Eigenschaften richtig ausgeben:
    Get-Process | ft ProcessName, { $_.TotalProcessorTime.Hours }{/code}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:{code lang:powershell showtitle:false lines:true hidden:false}# Out-Null verwenden:
    Commandlet | Commandlet | Out-Null
    # Variable zugewiesen:
    $a = Commandlet | Commandlet
    # Typ [void] nutzen:
    [void] (Commandlet | Commandlet)
    # $null zuweisen:
    $null = Commandlet | Commandlet{/code}
  • Funktionen (Übungen und weitere Techniken inklusive Aufruf mit Werten)
    manuell oder in einer Session/einem Skript und natürlich später in einer Profildatei
    hier erst einmal ein Beispiel ohne Parameterübergabe - bitte einfach wieder zu den Hilfen greifen{code lang:powershell showtitle:false lines:true hidden:false}# Beispielfunktion cdd - Change Dir with Dialog
    function cdd {
        $shell = New-Object -comObject "Shell.Application"
        $options = 0x51 # Nur Dateisystem-Ordner - inklusive Edit-Box
        $loc = $shell.BrowseForFolder(0, "Wohin soll es gehen?", $options)
        if($loc) {Set-Location $loc.Self.Path}
    }{/code}Am schönsten wäre jetzt, wenn wir das Ganze stets zur Verfügung hätten und nicht nur während ener PS-Sitzung - Also bitte in die $PROFILE einbauen
  • 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")
    Nur mal so zum Schnuppern - morgen dann mehr: siehe Auflistung aller Klassen mit Get-WmiObject -List  (!!)
    Bei CIM nutze man Get-CimClass  (!!)

 

  • PS 4.0 einrichtenPS 4.0 einrichten
  • Update-HelpUpdate-Help
  • GP für ExecutionPolicyGP für ExecutionPolicy
  • FunctionFunction
  • Formatierte Ausgabe -fFormatierte Ausgabe -f
  • WMI & CIMWMI & CIM

 

Tag 05

Freitag, 18.12.2015, 08.30 - 16.00 Uhr

  • Rekapitulation, TN-Fragen
  • To-Do-List für Freitag:
    WMI / CMI (Testing siehe Einf. gestern)
    Analyse Eventlog (Hinweis auf XML infos)
    Profile komplettieren (Titelleiste,Hinweis auf If für Import-Module bei $host.name gleich ConsoleHost, ...)
    Ausgaben in Datei(en)
    Provider und Drives
    Active Directory (Modul, AD Verwaltungscenter mit PS-Ausgaben, ...)
    Remoting (Hinweis RSAT, Cmdlets mit eingebauter Remote-Funktionalität / Computername, PSSessions, PSWA)
    Freie Übungen: Beispiel XML, ... (siehe Cookbook !)
  • Forts. Get-WmiObject  und  Get-CimInstance
    Übungen zu den "Super-Commandlets" der PowerShell zur Systemanalyse
    Aufrufe und Tests zu diversen Klassen für WMI und CIM
    Hinweis: bei Get-CimInstance existiet ein Parameter -Query mit SQL-Abfragen wie "SELECT * from Win32_Process WHERE name Like 'p%'"
    Tipp: Internetsuche ergibt schnell beispielhafte Aufrufe für Fragen rund um unsere Systeme
  • $Host.Name  
    die PowerShell hat unterschiedliche Bezeichner in unterschiedlichen Umgebungen
    ConsoleHost - die eigentliche PowerShell
    Windows PowerShell ISE Host - in der PowerShell ISE
    ServerRemoteHost - in einer Remote Shell (z.B. über den Server-Manager initiiert)
    Tipp: das Laden spezieller (nur lokal verfügbarer) Module mittels If-Verzweigung in $PROFILE berücksichtigen
  • Forts. Übungen $PROFILE - Funktion cdd (Change Directory Dialogue)
    siehe Laden von Modulen
    Einbau einer speziellen Funktion cdd , welche die Nutzung von Grafik und Maus zum Wechseln von Verzeichnissen in der PowerShell ermöglicht{code lang:powershell showtitle:false lines:true hidden:false}# Beispielfunktion cdd - Change Dir with Dialog
    function cdd {
    $shell = New-Object -comObject "Shell.Application"
    $options = 0x51 # Nur Dateisystem-Ordner - inklusive Edit-Box
    $loc = $shell.BrowseForFolder(0, "Was gibts Schorse?", $options)
    if($loc) {Set-Location $loc.Self.Path}
    } {/code}Hintergrund: "Proof of Concept - Zeigen, was so geht in der PowerShell" und Analyse des Quellcodes der bereitgestellen Funktion und Recherche der genutzten Klassen und Objekte (hier: Methode BrowseForFolder ) - Experimente mit Hex-Optionen: 0x41 deaktiviert die Editoreingabe unten im Dialogfenster
  • Analyse EventLog mit cmdlet Get-EventLog 
    hier wieder Analyse der Ergebnisobjekte von Get-EventLog wichtig (siehe Get-Member)
    Dann sieht man auch die richtigen Properties und kann die richtige Quelle (Source) filtern: Microsoft-Windows-Kernel-General haben wir gesucht
    Im Eventvwr.msc (Grafische Ereignisanzeige) sieht man als "Quelle" nur Kernel-General; Tipp: XML-Eigenschaften/Beschreibungen zu Eventeintrag analysieren
  • Ausgaben in Datei:
    verschiedene Wege führen hier zum Ziel:Umleitungsoperator ist > (Ersetzen) bzw. >> (Anhängen):{code lang:powershell showtitle:false lines:true hidden:false}Get-Process | Out-File "c:\temp\prozessliste.txt"
    # Ausgaben anhängen mit -Append
    Get-Process | Out-File "c:\temp\prozessliste.txt" -Append{/code}> 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{code lang:powershell showtitle:false lines:true hidden:false}# Fehler in Datei umleiten
    cat c:\temp\datei-exist-nicht.txt 2>> C:\temp\fehler.txt
    # Ausgabeströme umleiten
    dir u:\Daten 2>&1 | Format-Table > C:\temp\prozessliste.txt{/code}Ebenfalls getestet: Tee-Object zweigt Zwischenergebnisse in Dateien oder Variablen ab
  • Provider und Drives (Laufwerke - Part I - Einführung)
    eine Übersicht zu den vorhandenen Providern (Get-PSProvider) und den Laufwerken (Get-PSDrive) anzeigen lassen:{code lang:powershell showtitle:false lines:true hidden:false}# Alle Provider anzeigen
    Get-PSProvider
    # vereinheitlichte Bewegung/Navigation in den Drives
    Get-PSDrive
    # speziellen Provider anzeigen
    Get-PSDrive -PSProvider FileSystem
    # Drive Cert:
    Set-Location cert:\CurrentUser\Root
    Get-ChildItem{/code} Nutzen der "Laufwerke" wie eben bei einem echten Datenspeicher/Datenträger/Laufwerk
  • Provider und Drives (Laufwerke - Part II - Komplettierung und Übungen)
    Anzeige von Cmdlets mit Texhnik "*item*": Get-Command *item*
    Auflistung von Befehlen rund um die "Drives / Laufwerke" (s. Schwichtenberg Übersichtstabelle ab S. 180 ff.)
    Get-Location (pwd) Abrufen des aktuellen Standorts
    Set-Location (cd) Festlegung des aktuellen Standorts
    Get-Item (gi) Holt ein Element
    Get-ChildItem (dir, ls, gpi) Auflisten der Unterelemente
    Get-Content (type, cat, gc) Abruf eines Elementinhalts
    Set-Content (sc) Elementinhalt festlegen
    Add-Content (ac) Elementinhalt ergänzen
    New-Item (ni, mkdir, md) Erstellen eines Elements (Ast oder Blatt)
    Get-ItemProperty (gp) Attribut abrufen
    Set-ItemProperty (sp) Attribut eines Elements festlegen bzw. anlegen, wenn nicht vorhanden
    Remove-Item (del, ri, rmdir, rm, erase) Element löschen
    Move-Item (move, mv) Element verschieben
    Copy-Item (copy, cp, cpi) Element kopieren
    Rename-Item (rni, ren) Element umbenennen
    Commandlets für die Pfade: Test-Path, Resolve-Path, Convert-Path{code lang:powershell showtitle:false lines:true hidden:false}# Beispielhafte Aufrufe
    New-Item -Path c:\temp -Name Testing -ItemType directory
    # einfacher natürlich mit md (alias) und mkdir (function)
    mkdir Testing
    # Neues Drive erstellen:
    New-PSDrive -Name Skripte -PSProvider FileSystem -Root "G:\material\60-os\powershell-2014\_seminar\skripte\"
    # gerne auch für Registry
    New-PSDrive -Name Software -PSProvider Registry -Root HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
    # Entfernen mit
    Remove-PSDrive -Name Skripte{/code}Analyse der Techniken Commandlet New-Item vs. Function mkdir vs. Alias md
    Funktion mkdir: (Get-Childitem function:\mkdir).Definition 
    oder natürlich Get-Content function:\mkdir
  • Fernverwaltungen
    Vier unterschiedliche Techniken gezeigt und genutzt:

    1) RSAT (Remoteserver Administration Tools - Download RSAT für Windows 8.1 - bitte Windows-Version beachten!)
    Analyse Anzahl Commandlets/Functions: Windows 8.1 hatte 1264
    ein 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 "*Teilnehmer*" }

    2) Commandlets mit eingebauter Funktionalität (-ComputerName) für Fernaufrufe auf anderen Maschinen{code lang:powershell showtitle:false lines:true hidden:false}# Commandlets mit eingebauter "Fernwartung"
    Get-Command | where { $_.parameters.keys -contains "ComputerName" -and $_.parameters.keys -notcontains "Session"}
    # Aufrufsbeispiel: (auch gerne gleichzeiig auf mehreren Maschinen)
    Get-Service -ComputerName domvbox-2012r2 i*{/code}

    3) PowerShell Sessions - die moderne MS Terminalsitzung / Shellsession
    Technikhintergrund: WinRM (Windows Remote Management); 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
    Rechner für PowerShell Sessions (PSRemoting) vorbereiten:{code lang:powershell showtitle:false lines:true hidden:false}# WinRM-Systemdienst starten (inkl. Firewall - Netzwerkverbindungstyp beachten - kein Öffentliches Profil!)
    Enable-PSRemoting
    # Unterdrücken der Nachfragen mit
    Enable-PSRemoting -force
    # Testen der Fähigkeit:
    New-PSSession{/code}
    in Firmen/Domänen kann man die folgende Gruppenrichtlinie nutzen:
    Computer Configuration\Administrative Templates\Windows Components\Windows Remote Management (WinRM)\WinRM service
    Beispielhafte Nutzung:{code lang:powershell showtitle:false lines:true hidden:false}# Interaktiv Sitzung:
    Enter-PSSession –Computername domvbox-2012r2
    # komplette Anmeldung inkl. -credential
    Enter-PSSession domvbox-2012r2 -Authentication Negotiate -credential dom2012r2\Administrator
    # Beenden:
    Exit-PSSession
    # aktuelle Konsolenmaschine
    [System.Environment]::MachineName{/code}Alternative Aufrufe und weitere technische Möglichkeiten mittels Commandlet Invoke-Command
    Anregung: Recherche nach Cmdlets mit *PSSession*

    4) PowerShell WebAccess (PSWA)
    Installation auf Server von Rolle "Web Server (IIS)" und Feature "Windows PowerShell/Windows PowerShell Web Access"
    alternativ mit PowerShell: Install-WindowsFeature -name web-server, windowspowershellwebaccess{code lang:powershell showtitle:false lines:true hidden:false}# 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 *{/code}
    Beim Aufruf der Webseite https://dc-server/pswa muss man natürlich das Zertifikat anerkennen (lassen)

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

 

  • PowerShell WebAccessPowerShell WebAccess
  • Get-CimInstanceGet-CimInstance
  • $Host.Name$Host.Name
  • AusgabenAusgaben
  • Drive HKCU:Drive HKCU:
  • Get-CredentialGet-Credential

 

Bücher und Co

Ich habe in der Woche auch immer wieder auf online und offline Quellen hingewiesen, die ich an dieser Stelle nochmal darstellen möchte.

Die folgenden Bücher hatte ich auch im Seminar (Tag 03 - Mittwoch) vorgestellt und mit den Teilnehmern eingeschätzt:


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 

  • Dr. H. SchwichtenbergDr. H. Schwichtenberg

Windows PowerShell 4.0: Das Praxisbuch Gebundene Ausgabe – 8. Mai 2014
von Dr. Holger Schwichtenberg
Gebundene Ausgabe: 926 Seiten
Verlag: Carl Hanser Verlag GmbH & Co. KG (8. Mai 2014)
Sprache: Deutsch
ISBN-10: 3446440704
ISBN-13: 978-3446440708

Mit diesem Werk stellt Hr. Schwichtenberg sicherlich die aktuelle Standardlektüre für Alle, die sich intensiv und aktuell mit der Microsoft PowerShell auseinandersetzen wollen.

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
  • powershell-5-core-7-00
  • powershell-5-core-7-01
  • Tobias Weltner
  • Windows Automation
  • powershell50-praxis-00
  • powershell50-praxis-01
  • Dr. H. Schwichtenberg
  • Das Praxibuch
  • Andy Oakley
  • Schnelleinstieg

Für die PowerShell habe ich auch eine Linksammlung auf dieser Seite "verdrahtet", sodass auch weitere Online-Quellen für die weitere Auseinandersetzung mit der PS zur Verfügung stehen:

... wird noch verlinkt ...

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

 

 

Vielen Dank für Ihr überaus positives Feedback und das laute Klopfen zum Ende des Seminars.
Ihr Trainer Joe Brandes