An der VHS Wolfenbüttel findet ab dem 16. Januar 2017 ein Veranstaltungsreihe 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" für Mitarbeiter/Innen des IUK LK Wolfenbüttel erarbeiten.

Hier die Rahmendaten unseres Seminars:
Ort: VHS Wolfenbüttel, Harzstraße 2-5, Raum MacOS
Termine:
Mo., 16.01. bis Fr., 20.01.2017; jeweils 08.30 - 15.30 Uhr und Fr. - 12.30 Uhr und
Mo., 23.01. bis Fr., 27.01.2017; jeweils 08.30 - 15.30 Uhr und Fr. - 12.30 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.01.2017, 08.30 - 15.30 Uhr
- Orientierungsphase, Teilnehmer-Themen: Roter Faden Seminarankündigung,
TN-Themen: wurden jeweils am Anfang der Seminarwochen mit den Teilnehmern evaluiert
TN-Themen Woche 01: Registry, NTFS-Berechtigungen (Sicherheitseinstellungen)
Anm.: falls die Themen sich nicht in dieser Webausarbeitung wiederfinden, dann wurden Sie in das entsprechende Hand-Out (PDF) und die begleitende Scriptlines.ps1 Datei integriert. - "Roter Faden" für die PowerShell
hier mal ein exemplarischer systemischer Überblick über Themen rund um die PowerShell
Bereitstellung von Informationen auf diesem Portal und auch als Hand-Out (PDF) - Allgemeines
Wir setzen als Betriebssyteme Windows 10 Pro ein; später auch in einer Windows Server 2016 Active Directory Domänenumgebung (AD mit entsprechenden PowerShell AD-Modulen)
PowerShell-Versionen: Übersicht auf MSDN-Portal
Beachten: Aufruf für PowerShell möglich:powershell -version 2
Aktuelle PowerShell: PowerShell Version 5.0 (bzw. 5.1) oder eigentlich:
Microsoft Windows Management Framework 5.0 (Link zum MS Download)
Praxisumgebung.: es gibt auch bereits die Produkt Vorschauf auf Version 6.0 für Linux-Betriebssysteme! (Link / Link Linux Pakete)
Ü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
# Host - in Console und ISE testen
$host.Version
# 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 PowerShell:
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 5.0 weit ü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 - 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-?e* TAB
Get-Command Get-*
Get-Command [gs]et-*
Get-Command *-Service
Get-Command –Noun Service
Get-Command *wmi*# Beispiel mit mehr Tiefe als Vorbereitung auf Pipelining und Filterungen
Get-Command | Where-Object { $_.name -like "*cim*" -or $_.name -like "*wmi*" }Get-Command ps # Alias
Get-Command notepad.exe # Tool
Get-Command C: # Function# Anzahl von Cmdlets und Funktionen (so seit PS 2.0)
Get-Command | Group-Object CommandType
# Cmdlets und Funktionen exportieren:
Get-Command | Format-Table name -HideTableHeaders | Out-File E:\_temp\pscommands.txt
# Hilfe aktualisieren mit Update-Help Commandlet
Update-Help –UICulture En-US -force
# Beachten: Admin-PowerShell nötig! Anm.: Autor Weltner empfiehlt En-US Schalter!Get-Help Get-Command
# mit Parametern auch
Get-Help Get-Command -Detailed # -Full, -Examples, -Online, -ShowWindow
Get-Help Get-Process -parameter "*"# Show-Command
Show-Command Get-Process{/code}Grafische Oberfläche mit Show-Command seit PS 3.0:Show-Command Get-Process
Hilfe aktualisieren mitUpdate-HelpCommandlet - 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 - hier leider wieder Einschränkungen in der Production Preview 5.0);
Empfehlung: auch einfach online suchen mit "PowerShell about_for, ...
Online-Hilfe-Portal zur PowerShell (Technet - Skripterstellung mit Windows PowerShell) - PSReadline - das PowerShell-Modul für das Verbessern der PowerShell Konsole
in PS 5.0 hat man außerdem mit PowerShellGet, ein Modul, das die Fähigkeiten von NuGet (einem Paketmanager) bereitstellt
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!
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)
- belegbare Tastenkombinationen (siehe cmdlet Get-PSReadlineKeyHandler bzw. das Pendant Set-PSReadlineKeyHandler) - PowerShell History
Die PowerShell hat eine eigene History-Umgebung und entsprechende Cmdlets zur Nutzung.
Am Besten aber nutzt man die History-Technik von Modul PSReadline{code lang:powershell showtitle:false lines:true hidden:false}# PSReadline
(Get-PSReadlineOption).HistorySavePath
$a = (Get-PSReadlineOption).HistorySavePath
notepad.exe $a # oder besser mit dem ISE
ise $a{/code}Es ist also mit der History.txt-Datei von PSReadline ein kompletter Fundus unserer/Ihrer Aufrufe 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, ...){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. 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:{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 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
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
Wichtige Unterschiede zur "normalen" PowerShell Console:
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 - ExecutionPolicy für die PowerShell-Skripte
Sicherheitlevel beachten (Restricted, RemoteSigned, Unrestricted, ...)
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: mitSet-ExcecutionPolicy Remotesigned(in einer Administrator PowerShell !)
eine Möglichkeit zur Ausführung lokaler Skripte - bei Skripten aus Netzressourcen wäre eine Signatur notwendig
Anm.: bitte nicht die 32-Bit-PowerShell (x86) vergessen! - 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.
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 mitC:\Users\joeb\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1
{code lang:powershell showtitle:false lines:true hidden:false}$PROFILE
# genauer: (Anm.: siehe auch ISE)
$PROFILE
$PROFILE.CurrentUserCurrentHost
$PROFILE.CurrentUserAllHosts
$PROFILE.AllUsersCurrentHost
$PROFILE.AllUsersAllHosts{/code}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.
Übersichtstabelle Profile:
ConsoleHost ISE Benutzer
Pfad: C:\Users\Benutzer\Documents\WindowsPowerShell\
Datei:profile.ps1Datei: Microsoft.PowerShell_profile.ps1Datei: Microsoft.PowerShellISE_profile.ps1Alle
BenutzerPfad: C:\Windows\System32\WindowsPowerShell\v1.0\
Datei:profile.ps1Datei: Microsoft.PowerShell_profile.ps1Datei: Microsoft.PowerShellISE_profile.ps1
Erste Übung mit Aliasen (Set-Alias) und Startverzeichnis für die PowerShell mit Set-Location
Tag 02
Dienstag, 17.01.2017, 08.30 - 15.30 Uhr
- Rekapitulation: sehr ausführlich - Timing des Seminars auf TN-Feedback angepasst
Bereitstellungen Unterlagen angesprochen
Anm.: Downloads - HandOut "PowerShell" auf diesem Portal jederzeit verfügbar
Aber: nach dem Seminar das passende und komplette inhaltliche PDF (HandOut) und die Skrptlines vollständig,
TN-Fragen: NTFS-Berechtigungen (siehe Get-ACL), Registry (siehe PSProvider Registry) - Provider und Drives
Übersichten und beispielhafte Aufrufe zu den PowerShell Providern und Drives ("Laufwerken") mittels{code lang:powershell showtitle:false lines:true hidden:false}Get-PSProvider # PSProvider Übersicht
Get-PSDrive # PSDrives Übersicht
Get-PSDrive -PSProvider FileSystem # PSDrives Filesystem
Set-Location Cert:\CurrentUser\Root # Wechsel in LW Cert:
# Bei der Registry kann man den Provider auch direkt ansprechen:
Get-ChildItem "REGISTRY::HKEY_CLASSES_ROOT\" -ErrorAction SilentlyContinue{/code}Befehle zu Laufwerken, Items, Inhaltsobjekten und PfadenGet-Command –Noun *childitem, item*, path, content, location
Übungen mit New-Item , New-PSDrive, Remove-PSDrive
Erstellung eines neuen PSDrive:New-PSDrive -Name Skripte -PSProvider FileSystem -Root c:\temp\ps-skripte
in der Profiltechnik unserer PowerShell (hier alle Hosts des aktuellen Users: $PROFILE.CurrentUserAllHosts) - Übungen zu Datei- und Ordnerbehandlungen
Quelle: Dr. Tobias Weltner, Free PowerShell Cookbooks, www.powertheshell.com; filesystem_cookbook.pdf; Power Tips Monthly Vol.1 | June 2013
{code lang:powershell showtitle:false lines:true hidden:false}# Desktop Ordner finden mit [Systemklassen]:Methoden
[Environment]::GetFolderPath('Desktop')
# Folder anzeigen für GetFolderPath:
[System.Enum]::GetNames([System.Environment+SpecialFolder])
# also:
[Environment]::GetFolderPath('Cookies')
# Dateien umbenennen - die Win8/10 Screenshots haben Leerzeichen!
$global:i = 1
$path = "$env:userprofile\Pictures\Screenshots"
Get-ChildItem -Path $path -Filter *.png |
Rename-Item -NewName { "screenshot_$i.png"; $global:i++}
# 1GB Datei in Sekundenbruchteil
$path = ”$env:temp\testfile.txt”
$file = [io.file]::Create($path)
$file.SetLength(1gb)
$file.Close()
Get-Item $path{/code}Übung (mit erweitertem Pipelining){code lang:powershell showtitle:false lines:true hidden:false}$folder = "$env:userprofile\Downloads"
>>> Get-ChildItem -Path $folder -Recurse -Force -Erroraction SilentlyContinue |
>>> Measure-Object -Property Length -Sum |
>>> ForEach-Object {
>>> $sum = $_.Sum / 1MB
>>> "Der Download-Ordner enthaelt derzeit {0:#,##0.0} MB storage." -f $sum
>>> }{/code} - Pipelining (Online-Beitrag - inkl. Pipeline-Bild - von Schwichtenberg auf entwickler.de)
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:$PSItemals gleichwertiger Ersatz zu $_ (seit PS 3.0) {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) - Objektanalyse in der PowerShell
Heranführung an das Thema Objeke / Objekttechniken:
Objektmember sind klassisch:
→ Property - Eigenschaft (z.B. Get-ChildItem Objekte: LastTimeWrite )
Beispiel:(Get-ChildItem C:\temp).LastWriteTime# Ausgaben Datum/Uhrzeit letzte Änderungen
→ Method - Methode/Funktionalität (z.B. Get-Date Objekt: AddYear() )
Beispiel:(Get-Date).AddYears(5)# Aktuelles Datum um 5 Jahre addieren
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 CmdletGet-Member:Get-Process | Get-Member# Member nach dem Pipeline-Processing (s.o.)
bitte TypeName beachten: System.Diagnostics.ProcessGet-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()
ergibt genau das Ergebnis des PowerShell CmdletGet-Process!
Hilfe in der ISE (F1)
ISE Konfigurieren
$PROFILE.CurrentUserAllHosts
PSDrive Cert:
Pipelining
Where-Objekt (Filtern)
Tag 03
Mittwoch, 18.01.2017, 08.30 - 15.30 Uhr
- Rekapitulation, TN-Fragen
- Pipelining (Fortsetzung / Wiederholung)
Hinweis auf Pipeline Prozessor - Übungen
{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)
Automatic Unrolling (seit PowerShell 3.0)
{code lang:powershell showtitle:false lines:true hidden:false}# Beispiel zu Automatic Unrolling
$dll = Get-ChildItem C:\Windows\System32\*.dll | Select-Object -First 3
$dll # Ausgabe
# wieder 3 Versionen
$dll.VersionInfo # ab PS 3.0
$dll | Select-Object -ExpandProperty VersionInfo
$dll | ForEach-Object { $_.VersionInfo }# Analyse
$dll | Get-Member # hier sieht man VersionInfo / ScriptProperty – nach der Pipeline!
# im Vergleich mit
Get-Member –InputObject $dll # Get-Member kennt kein VersionInfo{/code}
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-ExecutionPolicyundSet-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-JBComputerInfo C:\ps-skripte\01-dienstag.ps1
Übung: das Ganze verdrahtet und auch gerne in die $PROFILE packen - 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:
Lösung mittels Parameter/Argumente-Arrayargs[..](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, [int32] $zahlvar2)
"Informationen über den Computer: " + $Computer{/code}oder mittelsparam( [datatype] $var )- Deklarationen am Anfang des Skript
Empfehlung (siehe Übungen Tag 04): bitte die param-Definitionen nutzen - 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"}
$z = $y | Foreach-Object { $_.ws }{/code}Übungen zu den Variablen in Bezug auf Sichtbarkeit (Console vs. ISE) und mitGet-ChildItem Variable:Übersicht über die vorhandenen Variablen in einer PowerShell Host-Session - 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), ... - Variablen (Part II)
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], [string], [byte], [char], [bool], [xml], ...
Vordefinierte Variablen: $true, $false, $Home, $PSHome, $host, ...
mit z.B. $host.UI.RawUI.BackgroundColor = "darkgreen"
Variablen werden bei/in Zeichenketten mit doppelten Anführungszeichen ausgewertet! - Verschiedene Datentypen: Int, Byte, Char, ...
- Übungen und Tests
Wir haben zu den unterschiedlichen Typen diverse Aufrufe und Funktionen (Klassen) kennengelernt{code lang:powershell showtitle:false lines:true hidden:false}# Zahlen - Int
[Int32]::MaxValue
# 2147483647
[UInt32]::MaxValue
# 4294967295
[Int32]::MinValue
# -2147483648
[Byte][Char]’A’
# 65
[Byte[]][Char[]]’Hello’
# 72 #101 #108 #108 #111 (untereinander)
[Char[]](65..90)
[Char[]]'Hello'
[Byte[]][Char[]]'Hello'
# Spezielle Daten mit Klasse System.Net.Mail.MailAddress
$email = [System.Net.Mail.MailAddress]'Some User<Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!;'{/code}Weitere Aufrufe und Techniken wurden den Teilnehmern zur Verfügung gestellt!
Insbesondere mit$email.Displaynamebzw. 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:{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} - Funktionen (eine erste Annäherung - mehr dann morgen;
Anm.: erste Funktion heute war function ConvertFrom-UnixTime)
Die Funktionen "kapseln" mehrere Abarbeitungsschritte und können später dann auch Parameter übergeben bekommen (s.a.o) und Werte zurückgeben.
Tag 04
Donnerstag, 19.01.2017, 08.30 - 15.30 Uhr
- Rekapitulation, TN-Fragen
- Bücher / Literatur zur PowerShell
siehe eigene Registerkarte "Bücher und Co"; Hinweis auf Buchhandlung Graff und Online terrashop.de (Mängel-/Resteexemplare) - 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) - XML
Die PowerShell bietet natürlich auch die Verarbeitung von XML-Objekten an: {code lang:powershell showtitle:false lines:true hidden:false}# XML für TN aus dem Netz beziehen:
Invoke-WebRequest http://www.welt.de/sport/fussball/?service=Rss -OutFile welt_blog.xml
# sauberes XML erzeugen:
$xml = [xml](Get-Content welt_blog.xml)
# Testaufrufe für XML-Nutzung
$xml
$xml.rss
($xml.rss.channel.item).Count
($xml.rss.channel.item)[0]{/code}Beachten: die Zeichen der XML-Daten sind in UTF-8 codiert und somit werden leider in dieser Kombination Umlaute nicht sauber in ISE oder ConsoleHost angezeigt. Ein Test mit Notepad++ ergibt saubere Umlaute/Sonderzeichen. - 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), ... - 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 - Vergleichsoperatoren
siehe Google-Recherche "powershell vergleichsoperatoren" - beispielhafter Ergebnislink
mit eingebauter PS-Hilfe:get-help about_Comparison_Operators -ShowWindow
-gt (greater than), -lt (less than), -eq (equal), -ne (not equal), -ge (greater equal), -le (less 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)
Vorgriff auf Vertiefung zu Funktionen: function, return (eine kleine erste Einführung)
Ü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 auch 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 - 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} - Eingaben in der PowerShell (Interaktionen)
Unterschiedliche Eingaben / Interaktionen mit der PowerShell durchgespielt:{code lang:powershell showtitle:false lines:true hidden:false}# Eingaben
# ========# 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.Console]::Beep(15440, 30)
[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!" }{/code}
Wichtig: die besondere Bedeutung von Parameter -Credential bzw. Cmdlet Get-Credential für Zugriffe per "Remote"-Authentifizierungen - Funktionen (Fortsetzung)
Hier erst einmal ein paar Beispiele 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}Das Beispiel kann über Suchbegriffe "Shell.Application" und/oder "BrowseForFolder" analysiert: 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:{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 jpg-Dateien in unserem Benutzerprofil, die nach einem Startdatum geändert worden sind. Für eine stetige Verfügbarkeit der FunktionGet-NewPixbrauchen wir nur den Code in unser$PROFILEStartskript zu packen. -
Funktionen (ausführlich kommentiert)
Durch die saubere Zuweisung mit Kommentarblock in einer Funktion wird die komplette Hilfe und Intellisense nutzbar.{code lang:powershell showtitle:false lines:true hidden:false}# aus Weltner S. 478
function Get-CriticalEvent
{
<#
.SYNOPSIS
listet Fehler und Warnungen aus dem System-Ereignisprotokoll auf
.DESCRIPTION
liefert Fehler und Warnungen der letzten 48 Stunden aus dem
System-Ereignisprotokoll,
die auf Wunsch in einem GridView angezeigt werden. Der Beobachtungszeitraum
kann mit dem Parameter -Hours geändert werden.
.PARAMETER Hours
Anzahl der Stunden des Beobachtungszeitraums. Vorgabe ist 48.
.PARAMETER ShowWindow
Wenn dieser Switch-Parameter angegeben wird, erscheint das Ergebnis in einem
eigenen Fenster und wird nicht in die Konsole ausgegeben
.EXAMPLE
Get-CriticalEvent
liefert Fehler und Warnungen der letzten 48 Stunden aus dem
System-Ereignisprotokoll
.EXAMPLE
Get-CriticalEvent -Hours 100
liefert Fehler und Warnungen der letzten 100 Stunden aus dem
System-Ereignisprotokoll
.EXAMPLE
Get-CriticalEvent -Hours 24 -ShowWindow
liefert Fehler und Warnungen der letzten 24 Stunden aus dem
System-Ereignisprotokoll und stellt sie in einem eigenen Fenster dar
.NOTES
Dies ist ein Beispiel aus Tobias Weltners' PowerShell Buch
.LINK
http://www.powertheshell.com
#>
param($Hours=48, [Switch]$ShowWindow)if ($ShowWindow)
{
Set-Alias Out-Default Out-GridView
}$Heute = Get-Date
$Differenz = New-TimeSpan -Hours $Hours
$Stichtag = $Heute - $DifferenzGet-EventLog -LogName System -EntryType Error, Warning -After $Stichtag |
Select-Object -Property TimeGenerated, Message | Out-Default
}{/code}Ausführliche Tests mit zusätzlichen Parameter $LogName. - PowerShell Module
mitGet-Moduleerhält man eine Übersicht der aktuell geladenen (importierten) Module
mitGet-Module -ListAvailableerhält man eine Übersicht über alle ladbaren (importierbaren) Module
In PowerShell 5.0 hat man außerdem mit PowerShellGet, ein Modul, das die Fähigkeiten von NuGet (einem Paketmanager) bereitstellt,
Man kann somit einfach mittelsInstall-Module -Name Pscx(hier: PowerShell Community Extensions)
ein Modul seiner Wahl nachinstallieren (Admin-PowerShell nötig!).
Beim ersten Einsatz vonInstall-Modulemuss die Nutzung des Paketmanager und des Modul-Repositories (hier: PSGallery) positiv quittiert werden. Das Modul Pscx wird automatisch beim Aufruf einer Technik des Moduls nachgeladen (Autoloading).
Beispiel Cmdlet:Get-Content .\ansage.txt | Out-Speech(Sprachausgabe einer Textdatei)
Alle Pfade für Modules (-Ordner): $env:PSModulePath aufrufen und mit ($env:PSModulePath).split(";") einzeln darstellen lassen{code lang:powershell showtitle:false lines:true hidden:false}($env:PSModulePath).Split(";")
# C:\Users\Benutzer\Documents\WindowsPowerShell\Modules
# C:\Program Files\WindowsPowerShell\Modules
# C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\{/code}Die Module können also auch in einem Benutzerkonto-Ordner (Documents) abgelegt werden.
Nutzer können also einfach 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
UTF-8 XML-Datei
Vergleichsoperatoren
Get-Member Analyse
Dialogfenster
comObject Shell.Application
Modul-Ordner
Tag 05
Freitag, 20.01.2017, 08.30 - 12.30 Uhr
- Rekapitulation, TN-Fragen
Themen-"Fahrplan": PowerShell Remoting (PSSessions, PSWA), Active Directory (Massenerstellung AD-Konten per Skript), Registry, WMI/CIM, ... - WMI / CIM (
Get-WmiObjectundGet-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 -TechnikenGet-WmiObject -Class Win32_Bios -Computername DC01(also gleich mit eingebautem "Fernzugriff")
Auf aktuellen Windows-Betriebssystemen kann man auf rund 1200 Klassen zugreifen.
Auflistung aller Klassen mitGet-WmiObject -List
Bei CIM nutze manGet-CimClass
Beispielhafte Aufrufe: {code lang:powershell showtitle:false lines:true hidden:false}# Service Start Modi - Anmerkung: Get-Service kann keinen StartMode!
Get-WmiObject Win32_Service | Select-Object Name, StartMode
# ein spezieller Startmodus
([wmi]'Win32_Service.Name="Spooler"').StartMode
# eingeloggte User
$ComputerName = ‘localhost’
Get-WmiObject Win32_ComputerSystem -ComputerName $ComputerName | Select-Object -ExpandProperty UserName
# Netzwerkanalyse
function Get-NetworkConfig {
Get-WmiObject Win32_NetworkAdapter -Filter ‘NetConnectionStatus=2’ |
ForEach-Object {
$result = 1 | Select-Object Name, IP, MAC
$result.Name = $_.Name
$result.MAC = $_.MacAddress
$config = $_.GetRelated(‘Win32_NetworkAdapterConfiguration’)
$result.IP = $config | Select-Object -ExpandProperty IPAddress
$result
}
}
# Lokale Gruppen
Get-WmiObject Win32_Group -Filter "domain='$env:computername'" | Select-Object Name,SID
# Uptime Os
$os = Get-WmiObject -Class Win32_OperatingSystem
$boottime = [System.Management.ManagementDateTimeConverter]::ToDateTime($os.LastBootupTime)
$timedifference = New-TimeSpan -Start $boottime
$days = $timedifference.TotalDays
'Das System läuft seit {0:0.000} Tagen.' -f $days
# Freier Speicher auf Disks
Get-WmiObject Win32_LogicalDisk |
ForEach-Object { ‘Disk {0} hat {1,20:0.00} MB Platz frei’ -f $_.Caption, ($_.FreeSpace / 1MB)
}{/code}Vergleich WMI vs. CIM - Scripting Guy Blog (Link)
Introduction to CIM - PowerShell Blog (Link)
Hinweis auf PowerShell Cookbook PDFs von Autor Weltner (Link) -
Fernverwaltungen
Vier unterschiedliche Techniken gezeigt und genutzt:
1) 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"}
# Aufrufbeispiel: (auch gerne gleichzeiig auf mehreren Maschinen)
Get-Service -ComputerName domvbox-2012r2 i*{/code} 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. -
2) RSAT (Remoteserver Administration Tools - Download RSAT für Windows 10 - bitte Windows-Version beachten!)
3) PowerShell Sessions - die moderne MS Terminalsitzung / Shellsession
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 "*Joe*" }
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 und aktueller Netzwerkprofile-Checks mit
Enable-PSRemoting -SkipNetworkProfileCheck -force
# Testen der Fähigkeit:
New-PSSession # bzw.: Test-WSMan{/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 CommandletInvoke-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 Webseitehttps: // dc-server/pswamuss man natürlich das Zertifikat im Browser anerkennen (lassen) - Modul "ActiveDirectory"
stellt auf einem AD Domain Controller direkt Cmdlets zur AD-Verwaltung bereit
auf einem Mitgliedsserver über hinzufügen von Features das PowerShell-Modul "ActiveDirectory" hinzufügen
auf Clients (Windows 7 Professional, Windows 10 Pro) die passenden RSAT-Tools installieren
exemplarische Codebeispiele gezeigt:
a) Erstellen einer neuen OU mit Unter-OUs, neuen Benutzern und Gruppen in einem Rutsch aus einer CSV-Dateivorlage
b) 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. - Modul "SQLPS"
Beispielhafter Zugriff über die Tools aus dem SQL-Featurepack gezeigt:Invoke-SqlCommand
Installation - Downloadquelle (Link)
1) CLR Types for Microsoft SQL (SQLSysClrTypes.msi- benötigt Windows Installer 4.5)
2) Shared Management Objects (SMO -SharedManagementObjects.msi- benötigt CLR Types)
3) PowerShell Extensions for Microsoft SQL Server (PowerShellTools.msi- benötigt SMO) -
Letzte TN-Fragen, Feedback-Bögen, TN-Bescheinigungen
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 wurden auch im Seminar vorgestellt und mit den Teilnehmern eingeschätzt:
PowerShell 5: Windows Automation für Einsteiger und Profis Gebundene Ausgabe2. 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.0: Das Praxisbuch Gebundene Ausgabe
von Dr. Holger Schwichtenberg
Gebundene Ausgabe: 1015 Seiten
Verlag: Carl Hanser Verlag GmbH & Co. KG (17. Mai 2016)
Sprache: Deutsch
ISBN-10: 3446446435
ISBN-13: 978-3446446434
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
Falls Sie Anregungen hinsichtlich Büchern und Webseiten haben, dann bitte einfach per Mail an mich melden.
Bereitstellung Downloads zu
Vielen Dank für Ihr positives persönliches Feedback...
Ihr Trainer Joe Brandes