An der VHS Braunschweig findet vom 20. bis 24. Oktober 2014 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.

dienstag-41

Für die Koordination und Planung dieses Seminars wurde aus Teilnehmerinteressen in - und nach - IT-Seminaren in 2013 eine Interessentenliste erstellt und durch mich koordiniert. Diese "Interessentenliste PowerShell" führte uns nun also zu unserem Seminar in dieser Woche.

Hier die Rahmendaten unseres Seminars:

Ort: VHS Braunschweig, Heydenstraße 2, Raum 2.11
Termine: Mo., 20.10. bis Fr., 24.10.2014; jeweils 08.30 - 16.00 Uhr
Ankündigung: nach dem Seminar ist vor dem Seminar - für Alle, die diesen Termin verpasst haben:
nächster PowerShell BU an der VHS Braunschweig ab 14. Dezember 2015!

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, 20.10.2014, 08.30 - 16.00 Uhr

  • Orientierungsphase, Teilnehmer-Themen: Roter Faden Seminarankündigung,
    TN-Thema: XML
  • Allgemeines
    Wir setzen als Betriebssytem Windows 8.1 Pro (und später noch Server 2012 R2) ein.
    Aktuell: PowerShell Version 4.0 oder eigentlich:
    Microsoft Windows Management Framework 4.0 (Link zum MS Download)
    Anm.: es gibt auch bereits eine 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
    # PS-Version anzeigen lassen
    $PSVersionTable
    # Installationsverzeichnis 
    $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
    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 siehe F7)
    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:
    Aliase (dir, md)
    Funktionen (mkdir, C:)
    Commandlets (Get-Process)
    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
  • PowerShell Konsolenfenster
    Größe/Aussehen PS-Fenster über Eigenschaften
    STRG + C unterbricht Befehlsausführung
    kein Nutzen der Zwischenablage mit Shortcuts Strg + V und Co
    Letzte Befehle mit Cursor oder letzter Befehl mit F3
    Fenster mit Befehlen mit F7
    Konsolen im Kommandomodus ("1-zeilig") vs. Interpretermodus ("mehrzeilig")
    Rechte in der Konsole beachten:
    whoami (bzw. whoami /all); im Fenstertitel "Administrator: ..." für PS mit hohen Admin-Rechten
    Alternative: erster Start der ISE (powershell_ise.exe - Skripting Environment; auch hier 32-/64-Bit)
  • Erste Aufrufe in der PS
    Interaktive Aufrufe vergleichen: Get-Process vs. Get-EventLog (hier dann Parameter: Application, System, ...)
    # 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
    

    Allgemeine Parameter: -Force, -Whatif, -Confirm, ...
    Aufrufe lassen sich zusammensetzen (später sinnvoll mit Variablen in Skripten)
    Get-ChildItem ("c:\" + "temp") *.txt –Recurse
    Erste Pipes getestet und Probleme recherchiert/behoben:
    # geht nicht wegen Kernel-General als Source
    Get-EventLog system | Where-Object { $_.source -eq "Kernel-General" } | Select-Object -first 10
    # funktioniert mit richtiger Quellen-Angabe
    Get-EventLog system | Where-Object { $_.source -eq "Microsoft-Windows-Kernel-General" } | Select-Object -first 10
    

    Eine genaue Erläuterung der angewendeten Techniken folgt natürlich noch!
  • 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)
    # Neue Aliase mit:
    Set-Alias procs Get-Process  # neu oder überschreiben
    New-Alias procs Get-Process
    

    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:
    Export-Alias c:\meinealias.csv  # also in eine Textdatei
    Export-Alias c:\meinealias.ps1 -as script  # in ein PS-Skript
    # Laden:
    Import-Alias c:\meinealias.csv
    . c:\meinealias.ps1  # Punktoperator - "Dot sourcing"
    

    Es werden alle Aliase exportiert/importiert, was zu "Fehlermeldungen" führt - manuelle Anpassungen der Exportdateien gezeigt, so werden die Aliase "sauber" importiert - Später: in den PS-Profilen sauber hinterlegen!
    Auch Aliase für Parameter (types.ps1xml im Installordner PS) möglich:
    Get-Process | Format-Table ProcessName, WorkingSet -AutoSize
    wird zu
    Get-Process | Format-Table name, ws -AutoSize
  • Hilfe in der PowerShell
    mit Tabulator Codevervollständigung (auch Umschalten + TAB rückwärts) inkl. Wildcards: Get-?e*
    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.
    Get-Command –noun Service # liefert ebenfalls alle Befehle, die das Substantiv Service besitzen.
    Get-Command *wmi* # liefert alle Befehle, die die Buchstabenfolge wmi enthalten (und mutmaßlich mit der Windows Management Instrumentation zu tun haben).
    Get-Command | Where-Object { $_.name -like "*cim*" -or $_.name -like "*wmi*" } # liefert alle Befehle, die die Buchstabenfolge wmi“ oder cmi enthalten
    Get-Command ps
    Get-Command notepad.exe
    Get-Command C:
    

    Anzahl von Commandlets und Funktionen (so seit PS 2.0)
    (Get-Command) | group commandtype
    Commandlets und Funktionen exportieren
    Einfache Hilfe zu Kommandos
    Get-Command -?
    Über das spezielle Commandlet:
    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 ist nur für Kern-Commandlets der PS verfügbar.
    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:
    http://technet.microsoft.com/en-us/library/bb978526.aspx
    http://technet.microsoft.com/en-us/library/hh801904.aspx (zu Server und Co)
    Extra-Hilfen zu .NET-Techniken verfügbar
    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)
  • Ausdrücke
    eine erste Annäherung mit () im Expression bzw. Command Mode
    Vergleiche: Write-Output 10 * (8 + 6)  mit Write-Output (10 * (8 + 6))
    mehr dazu dann morgen früh...

 

  • Update-HelpUpdate-Help
  • AusdrückeAusdrücke
  • F7F7
  • Admin PowershellAdmin Powershell
  • Aliase exportierenAliase exportieren
  • ExportskriptExportskript

Tag 02

Dienstag, 21.10.2014, 08.30 - 16.00 Uhr

  • Rekapitulationen, Teilnehmer-Fragen
    Anm.: im Seminar wurden PS-Codes durch mich über OneDrive bereitgestellt (nach Seminar deaktiviert)
  • Ausdrücke (Forts.)
    Expression Mode:
    10* (8 + 6)
    "Hello "+ " " + "World"
    Command Mode: siehe Write-Output Aufrufe gestern
    # Aufruf:
    "Anzahl der laufenden Prozesse: (Get-Process).Count"
    # vergleichen mit:
    "Anzahl der laufenden Prozesse: $((Get-Process).Count)"
    

    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:
    keine interaktiven Tools/Programme möglich: ftp, nslookup, ...
    kein Blättern mit more, keine Soundausgaben
    # Eigene Farbgebungen in ISE mittels:
    $psISE.Options.ConsolePaneBackgroundColor = "red"
    # alternativ:
    $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
  • 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
    # Erstellen der Profile jeweils mit
    New-Item $profile -ItemType file –Force
    # Bearbeiten der Profile möglich mit
    ise $profile
    

    Anpassen der Profile dann in weiteren Übungen, wenn wir das Skripten im Griff haben.
  • Pipelining
    in der PS ist alles objektorientiert bearbeitbar und eben auch weitergegeben (siehe Pipeline)
    # komplexere Pipeline:
    Get-ChildItem c:\temp –r -filter *.txt | Where-Object { $_.Length -gt 40000 } | Select-Object Name, Length | Sort-Object Length | Format-List
    

    Anm.: das besondere Konstrukt $_ greift auf das aktuelle Objekt zu
    Neu: $PSItem als gleichwertiger Ersatz zu $_ (seit PS 3.0)
    # 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
    

    Anm.: Erklärung für dieses Verhalten mit Get-Help Get-Service -full  (siehe nach -name byValue und byPropertyName)
    Auch die klassischen Befehle lassen sich "pipen":
    netstat | 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)
    # 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 }
    

    Methoden der Objekte: (also Funktionen zu denen die Objekte fähig sind)
    # 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
    

    Alle Techniken praktisch erprobt - die Codes wurden über OneDrive bereitgestellt, damit die "Tipperei" sich in Grenzen hält!
    Aber: Üben der Eingaben ist natürlich wichtig!
  • Filtern, Sortieren, Gruppieren
    Mit den Standard-Cmdlets (Verben: Where-, Sort-, Group-) praktische Übungen durchgeführt:
    # 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. Seite 83 Tabelle)
    # 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
    

    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.
  • Variablen (Part I)
    Hier werden wir Variablen erst einmal interaktiv in der PS nutzen:
    # Übersichtlichkeit schaffen - Vorarbeiten für Skripting
    Get-Process | Where-Object {$_.name -eq "iexplore"} | Foreach-Object { $_.ws }
    # wird zu
    $x = Get-Process
    $y = $x | Where-Object {$_.name -eq "iexplore"}
    $z | Foreach-Object { $_.ws }
    

    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
  • Objekte vergleichen
    # eine kleine Fingerübung zwischendurch:
    $Pre = Get-Process
    # Hier Programme/Prozesse starten/beenden
    $Post = Get-Process
    Compare-Object $Pre $Post
    

    Bei dieser Compare-Object brauchen wir aber natürlich - wie immer (!) - Objekte!
  • Skripting (Part I)
    Skriptausführung muss mit geeignetem Level (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 Donnerstag)
    # Mein erstes Skript
    "Informationen über diesen Computer:"
    "Datum: " + (Get-Date).ToShortDateString()
    "Zeit: " + (Get-Date).ToLongTimeString()
    "Anzahl laufender Prozesse: " + (Get-Process).Count
    "Anzahl gestarteter Dienste: " + (Get-Service | where { $_.Status -eq "running" } ).Count
    

    Anm.: Zeichenkodierungen beachten:
    z.B. Notepad++ mit UTF (ohne BOM) vs. ANSI (mit Notepad, ISE, und Co)
    Starten von Skripten mittels:
    .\skript.ps1
    &.\skript.ps1
    Invoke-Expression .\skript.ps1
    Auch direkte Aufrufe mit powershell.exe g:\pfad\skript.ps1
    Skripte lassen sich mit Alias zuweisen:
    Set-Alias Get-ComputerInfo C:\temp\Skript.ps1
    Parameter an Skripte übergeben: per args[] (bei 0 beginnend) oder mittels param[]  (Deklarationen am Anfang des Skripts
    "Informationen über den Computer: " + $args[0]
    # oder aber mit param Deklaration und Variablenname
    param([string] $Computer)
    "Informationen über den Computer: " + $Computer
    

 

  • IntellisenseIntellisense
  • *.ps1*.ps1
  • dienstag-137dienstag-137
  • $PROFILE$PROFILE
  • Get-ChildItemGet-ChildItem
  • Group-ObjectGroup-Object
 

Tag 03

Mittwoch, 22.10.2014, 08.30 - 16.00 Uhr

  • Rekapitulationen, Teilnehmer-Fragen
    Wiederholung der Darstellungen zu Parametern/Argumenten für Skripte ($args[] oder Deklaration param() mit Variablennamen)
  • Skripting (Part II - Forts.)
    Skripte pausieren lassen:
    # 10 Millisekunden:
    Start-Sleep -m 10
    # 10 Sekunden:
    Start-Sleep -s 10
    

    Kommentare mit # oder aber mit <# ... #> über mehrere Zeilen
    Hilfe zu PS-Befehlen
    Get-Help about_for
    Get-Help about_foreach
    Get-Help about (alle verfügbaren Hilfen)
    Mehrere Befehle pro Zeile möglich - würde ich nicht empfehlen - man kann auch jede Zeile abschließen, was aber nicht nötig ist: Get-Process ; Get-Service
  • Sicherheit beim Skripting
    und wieder: Commandlets: Get-ExecutionPolicy und Set-ExecutionPolicy (als Admin!)
    Sicherheitslevel: Restricted, RemoteSigned, AllSigned, Unrestricted
    in Registry:
    HKEY_CURRENT_USER\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell\ExecutionPolicy (nicht auf lokal verwaltetem System)
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell\ExceutionPolicy
  • 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 funzen auch in Zeichenketten
    # $ macht Ausdruck klar - nicht bei einfachen Limitern! Also wie bei PHP und Co
    "1+3 = $(1+3)"
    "Aktuelle Uhrzeit: $((Get-Date).ToShortTimeString())"
    "Anzahl der laufenden Prozesse: $((Get-Process).Count)"
  • Zahlen
    Eingaben: 2..5 ; 5 +3
    Zahlen einfach implizit zuweisen mit $i = 6.5   (bei Kommazahlen bitte Punkt benutzen im Skript)
    # Typ bestimmen
    $i.GetType().Name
    # Zufallszahlen:
    Get-Random -Min 100 -Max 200  # aus den PS Community Extensions (PSCX)
    # oder mit .NET-Klasse System.Random
    $rnd = New-Object System.Random
    $zufallszahl = $rnd.next(100)+100
    $zufallszahl
    

    Bitte beachten: Get-Random gehört zu PSCX (PowerShell Community Extension)
  • Zeichen / Strings
    # 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
    

    Escape-Sequenzen anrangieren mit dem Gravis-Zeichen (z. B. `a für ein Beep)
  • Datum / Uhrzeit
    Get-Date
    Get-Date -displayhint date
    Get-Date -displayhint time
    $a = Get-Date "8/1/1972 12:11:10"
    $Dauer = New-TimeSpan -Days 10 -hours 4 -minutes 3 -seconds 50
    $jetzt = Get-Date
    $zukunft = $jetzt + $Dauer
    Systemzeit setzen mit Set-Date
  • 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)
    # 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
    

    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 (leighter equal), ...
  • Kontrollstrukturen
    siehe hierzu auch Nassi-Shneiderman Diagramme (Wikipedia-Link)
    Verzweigungen: if, then, else, switch
    Schleifen: for, do, while, until, break, continue, exit
    Funktionen: function, return
  • Übungen zu if, switch, for, foreach
    weitere Beispielcodes:
  • for
    Bitte wieder Hilfen beachten: Get-Help about_for
    Beispiel-Codes aus den Hilfedateien durchgespielt
    # 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 - wie immer - angepasst und diskutiert
  • foreach
    automatischer Schleifenmechanismus
    # 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
    }  
    

    Ausgabeoperator -f siehe auch bei Ausgabetechniken
  • Eingaben in PowerShell
    Beispielcode für Eingaben mittels Read-Host, GUI per VB und DOT.NET
    # in Shell: Standardeingaben mittels Read-Host (Typ: System.String)
    $name = read-host "Bitte Benutzernamen eingeben:"
    # Standardeingaben verschlüssel mittels Read-Host (Typ: System.Security.SecureString)
    $kennwort_verschluesselt = read-host -assecurestring "Bitte Kennwort eingeben:"
    # Das verschlüsselte Kennwort wieder zurückholen
    [String]$kennwort_unverschluesselt = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($kennwort_verschluesselt))
    "Kennwort: " + $kennwort_unverschluesselt
    # GUI: mittels .NET Framework in der Klasse Microsoft.VisualBasic.Interaction
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic")
    $eingabe = [Microsoft.VisualBasic.Interaction]::InputBox("Bitte geben Sie Ihren Namen ein!")
    "Hallo $Eingabe!"
    # Dialogfenster (auch mit DOT.NET)
    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
    [System.Windows.Forms.MessageBox]::Show("Gleich kommt eine Frage","Vorwarnung",
    [System.Windows.Forms.MessageBoxButtons]::OK)
    $antwort = [System.Windows.Forms.MessageBox]::Show("Nachricht","Ueberschrift", [System.Windows.Forms.MessageBoxButtons]::YesNo)
    if ($antwort -eq "Yes") { "Sie haben zugestimmt!" } else { "Sie haben abgelehnt!" }
    

    Authentifizierungsdialog mit Get-Credential erzeugt Instanz von System.Management.Automation.PSCredential - hat aber hier nichts mit "echten User-Auth" mit Windows zu tun
  • Ausgaben (Part I)
    diverse Ausgabe-Cmdlets: Get-Command Out-*
    Erste Versuche mit Out-Host -paging (der PowerShell More Mechanismus), Out-GridView (seit PS 2.0), Out-Speech (Vorlesen lassen mit einer Funktion aus den Community Extensions PSCX), Out-Null (Ausgabe ins "Leere")

 

  • ISE nutzenISE nutzen
  • ArraysArrays
  • VergleichsoperatorenVergleichsoperatoren
  • foreachforeach
  • Out-GridViewOut-GridView
  • Out-Host -PagingOut-Host -Paging
 

Tag 04

Donnerstag, 23.10.2014, 08.30 - 16.00 Uhr

  • Rekapitulationen, Teilnehmer-Fragen
  • 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
    # 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
    
  • 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
    $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 }
    

    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:
    # Out-Null verwenden:
    Commandlet | Commandlet | Out-Null
    # Variable zugewiesen:
    $a = Commandlet | Commandlet
    # Typ [void] nutzen:
    [void] (Commandlet | Commandlet)
    # $null zuweisen:
    $null = Commandlet | Commandlet
  • Ausgaben in Datei:
    verschiedene Wege führen hier zum Ziel:

    Get-Process | Out-File "c:\temp\prozessliste.txt"
    # Ausgaben anhängen mit -Append
    Get-Process | Out-File "c:\temp\prozessliste.txt" -Append
    

    Umleitungsoperator ist > (Ersetzen) bzw. >> (Anhängen):
    > Umleitung der Pipeline-Ausgabe
    2> Umleiten der Ausgabe von Fehlern
    3> Umleiten der Ausgabe von Warnungen (seit PowerShell-Version 3.0!)
    4> Umleiten der Ausgabe von Verbose-Texten (seit PowerShell-Version 3.0!)
    5> Umleiten der Ausgabe von Debug-Texten (seit PowerShell-Version 3.0!)
    *> Umleiten aller Ausgaben (seit PowerShell-Version 3.0!)
    # 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
    

    Anm.: Umleitung an  Drucker mit Out-Printer
    Ebenfalls getestet: Tee-Object zweigt Zwischenergebnisse in Dateien oder Variablen ab

  • Funktionen
    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
    # 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}
    }
    

    Am schönsten wäre jetzt, wenn wir das Ganze stets zur Verfügung hätten und nicht nur während ener PS-Sitzung.
  • Profile
    bitte die Profile (jeweils $PROFILE) der PowerShell und der ISE beachten
    bearbeiten der Datei mit (z.B.): notepad.exe $PROFILE
    Übungen: Setzten von Alias, Bereitstellen von Funktionen, Setzen von Eigenschaften für das PowerShell-Fenster (siehe Buch Schwichtenberg)
    Tipp / Erinnerung: bei ausgelagerten Skripten Aufruf der externen Skripte ("Includes") mittels "Dot Sourcing" also mit dem "." zum Einbinden der externen PS1-Dateien
  • Provider und Drives (Laufwerke - Part I - morgen dann die Cmdlets komplett)
    eine Übersicht zu den vorhandenen Providern (Get-PSProvider) und den Laufwerken (Get-PSDrive) anzeigen lassen:
    # 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
    

    Nutzen der "Laufwerke" wie eben bei einem echten Datenspeicher/Datenträger/Laufwerk
    Übung mit HKLM: Navigieren in den Pfad zu den Eigenschaften der PS hinsichtlich ExecutionPolicy (Pfad: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds und dann einfach Get-ChildItem/dir/ls)
    Morgen dann Übungen rund um die "Item-Tools"

 

  • Provider - DrivesProvider - Drives
  • dcpromo per PSdcpromo per PS
  • PropertySetPropertySet
  • PSCX ausfilternPSCX ausfiltern
  • Ausgabe formatierenAusgabe formatieren
  • Autor Dr. H. SchwichtenbergAutor Dr. H. Schwichtenberg

Tag 05

Freitag, 24.10.2014, 08.30 - 16.00 Uhr

  • Rekapitulationen, Teilnehmer-Fragen
  • Plan für Freitag:
    "Items" behandeln am Beispiel von Datei- und Ordner-Operationen, Spezial: XML verarbeiten, PowerShell aus der Ferne (Cmdlets für Remoteaufrufe, PS-Remoting als Sessions, PS Web Access), Active Directory mit der PowerShell, Kurze Anm. zu Buch Schwichtenberg
  • Wichtig (Erinnerung für Übungen mit Active Directory über Windows Server 2012 R2):
    Netzkonfigurationen für die Win81-Clients auf den AD-DNS (192.168.11.58) - vor den Domänenbeitritten konfigurieren und testen (mit nslookup)
  • 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
    # 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
    

    Analyse der Techniken Commandlet New-Item vs. Function mkdir vs. Alias md
    Funktion mkdir: (Get-Childitem funcition:\mkdir).Definition
  • Fernverwaltungen
    Vier unterschiedliche Techniken gezeigt und genutzt:

    1) RSAT (Remoteserver Administration Tools - Download RSAT für Windows 8.1 - bite 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 "*Test*" }

    2) Commandlets mit eingebauter Funktionalität (-ComputerName) für Fernaufrufe auf anderen Maschinen
    # 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*
    

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

    in Firmen/Domänen kann man die folgende Gruppenrichtlinie nutzen:
    Computer Configuration\Administrative Templates\Windows Components\Windows Remote Management (WinRM)\WinRM service
    Beispielhafte Nutzung:
    # 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
    

    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
    # 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 *
    

    Beim Aufruf der Webseite https://dc-server/pswa muss man natürlich das Zertifikat anerkennen (lassen).
  • XML (TN-Thema - allgemein: Handling von geformten Texten mit der PowerShell)
    Letztendlich wollte TN etwas zu den "OpenXML" Formaten (siehe Office-Formate) an die Hand bekommen.
    Hier ein paar Beispielskriptzeilen aus dem "PowerShell Cookbook - 3. Auflage":
    # Cookbook S. 282 - XML erst einmal aus dem Netz beziehen:
    Invoke-WebRequest blogs.msdn.com/b/powershell/rss.aspx -OutFile powershell_blog.xml
    # sauberes XML erzeugen:
    $xml = [xml] (Get-Content powershell_blog.xml)
    # Testaufrufe für XML-Nutzung
    $xml
    $xml.rss
    ($xml.rss.channel.item).Count
    ($xml.rss.channel.item)[0]
    

    Mit der letzten Zeile erhielt man also einen einzelnen RSS-Feed mit allen Einzelheiten und Inhalten und mit Hilfe von Schleifen ließe sich das Objekt/Array ($xml.rss.channel.item) einfach durch laufen (siehe Commandlet Foreach-Object)
  • Übungen in einer Wndows 8.1 / Server 2012 R2 Domäne
    Aufrufe von diversen Commandlets und Nutzung des "Active Directory-Verwaltungscenter" und des "Server-Manager" auf den Clients Windows 8.1 mit RSAT; Nuten des PSRemting und von PSWA (Techniken s.o.)
  • Hinweise auf Online-Quellen und Links zur PowerShell
    siehe hierzu auch Infos zu Büchern und Linksammlung PowerShell auf dieser Seite bzw. in diesem Beitrag
  • Letzte Übungen mit "Cookbook"
  • Letzte TN-Fragen, Feedback-Bögen, TN-Bescheinigungen

 

  • function:function:
  • New-PSDriveNew-PSDrive
  • AD-VerwaltungscenterAD-Verwaltungscenter
  • ÜbernahmeÜbernahme
  • Enable-PSRemotingEnable-PSRemoting
  • PS WebAccessPS WebAccess

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 04 - Donnerstag) 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
  • 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:

Linksammlung - Onlinequellen PowerShell

 

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

Vielen Dank für die freundlichen Feedback-Bögen und persönlichen Worte zum Ende unseres Seminars. Viel Spaß weiterhin mit der Microsoft PowerShell wünscht Ihnen
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"

© 2017 - Websitedesign und Layout seit 07/2015 - Impressum
Nach oben