16 KiB
Table of Contents
- PowerShell
- Installation Ubuntu
- Einführung
- PowerShell-Provider
- Datentypen
- Variablen und Arrays
- Ausgabe
- Vorbereitung für dieses Tutorial
- Txt Datei auslesen
- Ausgabe in TXT speichern
- Ausgabe als CSV speichern
- Ausgabe als JSON speichern
- Ausgabe als HTML speichern
- Ausgabe in Windows-Presentation-Foundation (WPF)
- Ausgabe filtern
- Sortierung (Alternativ zu Sortierung bei der Abfrage, bei "Vorbereitung")
- Sortierung mit Unique
- Gruppierung
- Ausgabe formatieren
- Write-Host
- Vergleichsoperatoren
- Arbeiten mit Text
- Letztes Zeichen löschen
- Random String aus Buchstaben/Zahlen generieren
- Erhalte Text zwischen zwei Zeichen in einem String
- Lese Datei aus und zeige alle 2-stelligen Zahlen an (regex)
- IPs oder URLs aus TXT herauslesen und auflisten (regex)
- Arbeiten mit Zahlen
- Kontrollstrukturen
- Datum / Zeit
- Dateien
- Hash aus Datei generieren
- Die 5 grössten Dateien in einem Verzeichnis auflisten (rekursiv)
- Show files larger than X
- Datei-Liste, sortiert
- Klassen
- Powershell als Datei
- Beispiel PS-Schnippsel
PowerShell
Installation Ubuntu
https://learn.microsoft.com/en-us/powershell/scripting/install/install-ubuntu?view=powershell-7.4
Einführung
get version
Get-Host | Select-Object Version
Objekte mit Properties und Methoden
Alle Cmdlets (Commandlets) sind Objekte. Da die PowerShell auf dem .NET Framework basiert, arbeitet sie durchgehend mit Objekten. Jedes Resultat eines ausgeführten Cmdlets ist ein Objekt, also eine Instanz einer .NET-Klasse oder einer .NET-Collection. Somit kann mit der bekannten Punktnotation auf Members des Objekts, wie Properties oder Methoden, zugegriffen werden.
Gibt das Datum in voller Länge aus. Es ist ein Objekt:
Get-Date
Zeigt alle Properties und Methoden des Objekts an:
Get-Date | Get-Member
Zugriff auf Property Year:
(Get-Date).Year
Zugriff auf Methode ToLongTimeString()
(Get-Date).ToLongTimeString()
Kommentare
# einzeilig
<# ein
block #>
PS Special-Characters
Alle Special-Charakter von Powershell auf einen Blick
PowerShell-Provider
Auflisten aller Provider, wie Registry, Umgebungsvariablen, Variablen, Funktionen etc.
Get-PSProvider
Name Capabilities Drives
---- ------------ ------
Registry ShouldProcess, Transactions {HKLM, HKCU}
Alias ShouldProcess {Alias}
Environment ShouldProcess {Env}
FileSystem Filter, ShouldProcess, Credentials {C, H, J, K...}
Function ShouldProcess {Function}
Variable ShouldProcess {Variable}
Certificate ShouldProcess {Cert}
WSMan Credentials {WSMan}
Sie werden wie Drives verwendet. Man kann z.B. wechseln mit cd Env: # immer mit Doppelpunkt
Datentypen
Datentypen müssen nicht zwingend angegeben werden, können aber:
[Array] Array
[Bool] Wert ist TRUE oder FALSE
[DateTime] Datum und Zeit
[Guid] Global eindeutige 32-Byte ID
[HashTable] Hash-Tabelle, Sammlung von Schlüssel-Wert-Paaren
[Int32], [Int] 32-bit Integer
[PsObject] PowerShell-Objekt
[Regex] Regular expression
[ScriptBlock] PowerShell script block
[Single], [Float] Fließkommazahlen
[String] Zeichenkette
[Switch] PowerShell Switch-Parameter
[TimeSpan] Zeitintervall
[XmlDocument] XML-Dokument
Datentyp ermitteln
$t = "bla"; $t.getType()
Variablen und Arrays
Variable
Variablen beginnen mit Dollar $
Zuweisung mit =
$files = Get-ChildItem c:\xampp\htdocs -Recurse | Sort-Object Length -Descending | Select-Object Fullname, Length -First 5
$()
Anweisung in () werden zuerst ausgeführt.
$name = "Kevin"; "Hello, $name, there are $($name.length) characters in your name"
$_
THIS, typischerweise in einer foreach Schleife
$
Declare or use a variable with non-standard characters in it
${,&} = 5
Arrays
Siehe auch hier
leeres Array erstellen
$t = @()
Werte an Array zuweisen
# vermischte Datentypen:
$t = "a","b",22
# Alternativ ("richtig"):
$t = @("a","b",22)
# mit Typenbegrenzung:
[Int[]]$t=2,1
Bei Strings wird ohne Angabe des Datentyps ein Object gemacht. Siehe $variable.getType()
Array erweitern
$t += 3
Länge eines Arrays
$t.Length
2 Arrays zusammenführen
$u = "a","b","c"; $u2 = "d","e"; $u += $u2
Element in Array über Index ansprechen
$t[0]
$t[0,3,5]
$t[1..3]
Array Element finden
$a = "aaa","bbb","ccc","ddd"
$a -contains "aaa" # liefert TRUE. -ccontains berücksichtigt Gross-/Kleinschreibung
# oder
$a -like "aa*" # gibt Wert zurück (kein Boolean wie oben)
# oder
$a.Where{$_ -like "bbb"}
# siehe Where Parameter wie skipUntil oder last.
Array Elemente sortieren
$t | sort
Array Elemente löschen
Möchte man einzelne Elemente entfernen, dann muss man den Umweg über das Filtern und Neuzuweisen gehen:
$a = $a | where {$_ -ne "aaa"}
Array löschen
$t = $null
Array ausgeben
$a[0] -join ','
#oder
$array -join '|'
Ausgabe
echo und Write-Output ist das selbe. Kann für Weiterverarbeitung verwendet werden. Write-Host nur für Ausgabe in Console.
Vorbereitung für dieses Tutorial
$files = Get-ChildItem c:\xampp\htdocs -Recurse | Sort-Object Length -Descending | Select-Object Fullname, Length, CreationTime -First 5
$files2 = Get-ChildItem c:\xampp\htdocs -Recurse | Sort-Object Length -Descending | Select-Object -First 25
Txt Datei auslesen
Get-Content -Path C:\Test\ServerNames.txt
# UTF-8 encodiert:
Get-Content -Encoding UTF8 -Path C:\Test\ServerNames.txt
Ausgabe in TXT speichern
Write-Output "hallÖ" | Out-File c:\Roger\hallo.txt -Encoding UTF8
# oder einfacher:
"hallÖ" > C:\Roger\hallo.txt
Ausgabe als CSV speichern
$files | Export-Csv c:\Roger\files.csv
Ausgabe als JSON speichern
$files | ConvertTo-Json | Out-File c:\Roger\files.json
Ausgabe als HTML speichern
$files | ConvertTo-Html | Out-File c:\Roger\files.html
Ausgabe in Windows-Presentation-Foundation (WPF)
$files | Out-GridView
Ausgabe filtern
Im Beispiel sollen alle Windows-Services angezeigt werden, welche den Status Running besitzen und den Text Network im Namen enthalten:
Get-Service | Where-Object {($_.Status -eq "Running") -and ($_.Name -match "wpn")}
$files | Where-Object {$_.Length -lt 20000000}
$files | Where-Object {(Get-Date $_.CreationTime) -lt (Get-Date 20.05.2015)}
($_ enthält den Wert des in der Schlaufe durchlaufenen Objekts)
Filtermöglichkeiten:
Gleich (equal): -eq
Ungleich (not equal): -ne
Kleiner (less than): -lt
Kleiner oder gleich (less than or equal): -le
Größer (greater than): -gt
Größer oder gleich (greater than or equal): -ge
Enthält (contains): -contains
Enthält nicht (not contains): -notcontains
Ähnlich (like): -like, -notlike
Match (match/notmatch) für regex: -match, -notmatch
Ersetzen (replace): -replace
Sortierung (Alternativ zu Sortierung bei der Abfrage, bei "Vorbereitung")
$files2 | Sort-Object CreationTime | Format-List Fullname, Length, CreationTime
Sortierung mit Unique
$files2 | Sort-Object CreationTime -Unique | Format-List Fullname, Length, CreationTime
Gruppierung
$files2 | Format-List Fullname, Length, CreationTime -GroupBy CreationTime
Ausgabe formatieren
# Ausgabe als Tabelle (Standard). Hierzu ist es nötig, die Felder bei der Abfrage schon angegeben zu haben (Fullname, Length, CreationTime)
$files # ist das gleiche wie:
$files | Format-Table # oder
$files | ft
# Ausgabe als Liste
$files | Format-List # oder, wenn Felder bei Abfrage noch nicht angegeben:
$files2 | Format-List # Standard-Felder
$files2 | Format-List * # Alle möglichen Felder
$files2 | Format-List Fullname, Length, CreationTime # nur die benötigten Felder
Write-Host
Formatierung
Mit Write-Host kann die Ausgabe noch weiter formatiert werden
# Farben:
Get-Content -Encoding UTF8 -Path C:\Roger\regex-examples.txt | Write-Host -BackgroundColor("DarkGray")
# ohne neue Linien:
Write-Host "aaaaa" -NoNewline; Write-Host "bbbbbb"
# Separator für Array Elemente:
Write-Host (1,44,"abc",9) -Separator "|"
Ausgabe von Zeichen, die als PS Befehle interpretiert werden könnten
# mit --%
Write-Host --% %USERNAME%,this=$something{weird}
# zum Vergleich:
Write-Host %USERNAME%,this=$something{weird}
Vergleichsoperatoren
Zahlen
-eq gleich
-ne ungleich
-lt kleiner
-le kleiner oder gleich
-gt größer # bsp: "Dies ist ein Text".length -gt 10 # ergibt TRUE
-ge größer oder gleich
Strings
-like/-notlikemit oder ohne Wildcards"PowerShell" -like "Pow*"-contains/-notcontainsfür Arrays."Dezember","Januar","Februar" -contains "Februar"-match/-notmatch"PowerShell" -match "ower"
Arbeiten mit Text
Letztes Zeichen löschen
$a = $a.Substring(0, $a.Length - 1)
# falls noch geprüft werden muss, ob das letzte Zeichen ein | ist:
if ($a.LastIndexOf("|") -eq ($a.Length - 1)) {
$a = $a.Substring(0, $a.Length - 1)
}
Random String aus Buchstaben/Zahlen generieren
# mit 12 Zeichen:
$randomString = -join (((48..57)+(65..90)+(97..122)) * 80 |Get-Random -Count 12 |%{[char]$_})
Erhalte Text zwischen zwei Zeichen in einem String
$b = $FolderPath.LastIndexOf("/")
$b = $FolderPath.LastIndexOf("/", $b - 1)
$a = $FolderPath.LastIndexOf("/", $b - 1)
$a++
$derGesuchteText = $FolderPath.SubString($a, $b - $a)
Lese Datei aus und zeige alle 2-stelligen Zahlen an (regex)
$regex = [regex]"\b\d\d\b"
Select-String -Path C:\Roger\zahlentest.txt -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value }
# oder regex direkt in Anweisung:
Select-String -Path C:\Roger\zahlentest.txt -Pattern "\b\d\d\b" -AllMatches | % { $_.Matches } | % { $_.Value }
# zusätzlich als Datei speichern:
Select-String -Path C:\Roger\zahlentest.txt -Pattern "\b\d\d\b" -AllMatches | % { $_.Matches } | % { $_.Value } > C:\Roger\zahlentest_output.txt
IPs oder URLs aus TXT herauslesen und auflisten (regex)
# Erstellen wir zuerst eine TXT-Datei, z.B. aus einem tracert.exe Befehl:
TRACERT.EXE fuw.ch | Out-File c:\Roger\tracert-fuw-ch.txt -Encoding UTF8
# Nun das Auslesen:
Select-String -Path C:\Roger\tracert-fuw-ch.txt -Pattern '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b' -AllMatches | % { $_.Matches } | % { $_.Value } > C:\Roger\tracert-fuw-ch-only-ips.txt
## URL's
$regex = '([a-zA-Z]{3,})://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)*?'
Arbeiten mit Zahlen
Modulo (Remainder of a Division)
5 % 2
Kontrollstrukturen
if then else
if($test) {
echo "Value of test: " $test}
else {
echo "Value of test is zero or undefined"
}
# Boolean gegenteilig prüfen: mit ! davor.
$a="xyz"; $b="b"
if($a -like "a") {
echo "a OK"
} elseif($b -like "b") {
echo "b OK"
} else {
echo "else"
}
switch
switch is used for testing equality only. Thus, you can't use comparison operators in switch statements.
switch(Read-Host "Select a menu item"){
1 {"File will be deleted"}
2 {"File will be displayed"}
3 {"File is write protected"}
default {"Invalid entry"}
}
# wenn bei einem match nicht mehr weiter gesucht werden soll, muss break angefügt werden:
1 {"File will be deleted"; break}
# switch mit wildcards
switch -wildcard("PowerShell"){
"Power*" {echo "'*' stands for 'shell'"}
"*ersh*" {echo "'*' replaces 'Pow' and 'ell'"}
"PowerShe?" {echo "Pattern matches because ?? replaces two 'l' "}
}
for loop
$colors = @("Red","Orange","Yellow","Green","Blue","Indigo","Violet")
For ($i=0; $i -lt $colors.Length; $i++) {
$colors[$i]
}
foreach loop
$myDocuments = Get-ChildItem C:\Roger -File
# Ausgabe mit foreach:
foreach($ele in $myDocuments) { $ele.FullName }
# Ausgabe mit Pipe:
$myDocuments | ForEach-Object {$_.FullName}
# oder Ausgabe mit -InputObject:
ForEach-Object -InputObject $myDocuments {$_.FullName}
# Shorthands:
Get-WMIObject Win32_LogicalDisk | ForEach-Object {$_.FreeSpace}
Get-WMIObject Win32_LogicalDisk | ForEach {$_.FreeSpace}
Get-WMIObject Win32_LogicalDisk | % FreeSpace
# gleich wie
foreach($ele in Get-WMIObject Win32_LogicalDisk) { $ele.FreeSpace }
all loops explained
Objekt zählen
($svgs | measure).Count
Datum / Zeit
Anzahl Tage von einem bestimmten Datum bis heute
[DateTime]$Date = "28. February 2015"
$Today = Get-Date
$Days = ($Today - $Date).Days
Write-Host "Vergangene Tage seit" $Date":" $Days
Dateien
Hash aus Datei generieren
get-filehash -algorithm sha512 .\SAB_2018-03-29_Einzelstuecke.pdf
Die 5 grössten Dateien in einem Verzeichnis auflisten (rekursiv)
Get-ChildItem c:\xampp -Recurse | Sort-Object Length -Descending | Select-Object Fullname, Length -First 5
Show files larger than X
Get-ChildItem -Path C:\ -File -Recurse -ErrorAction SilentlyContinue | Where-Object {$_.Length -gt 2GB} | Sort-Object length -Descending | Select-Object Name,Directory,@{n='GB';e={"{0:N2}" -F ($_.length / 1GB)}} | Out-GridView -Title "Large Files"
Datei-Liste, sortiert
# This command sorts text files in descending order by the time span between CreationTime and LastWriteTime.
Get-ChildItem -Recurse -Path C:\Roger\*.txt | Sort-Object -Property @{Expression = {$_.CreationTime - $_.LastWriteTime}; Descending = $True} | Format-Table CreationTime, LastWriteTime, FullName
Klassen
Aufruf von Static Methode einer Klasse
The class name must be enclosed in square brackets.
[string]::Equals("a", "b")
Powershell als Datei
Dateiendung .ps1
Aufruf
& script.ps1
# oder als Verknüpfung
powershell.exe -File c:\roger\script.ps1
# Allenfalls noch Rechte setzen:
Set-ExecutionPolicy RemoteSigned
# Restricted — Stops any script from running.
# RemoteSigned — Runs scripts created on the device. However, scripts created on another computer won't run unless they include a signature of a trusted publisher.
# AllSigned — All the scripts will run as long as they've been signed by a trusted publisher.
# Unrestricted — Runs any script without any restrictions.
# in konsole dauerhaft (pro session):
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
Externes Script einbinden
#line 1 of your script
. ./script.ps1 #include from current directory
#line 2
#use function or variable from script.ps1
Beispiel PS-Schnippsel
Find encrypted files
$path=$args[0]
Write-Host "checking: $path"
$p = Get-ChildItem -Path $path -Recurse -Force -Attributes Encrypted
if ($p) {
Write-Host "Found" $p.Name.Count "encrypted files"
Write-Output $p.Name
exit 1
}
else {
Write-Host "No encrypted files found"
exit 0
}
Find password protected zip files
# check for password protected ZIP archives
Get-ChildItem -Path $path -Recurse -Filter *.zip | Where-Object { ` | 7z t $_.FullName *>$null; if ($LASTEXITCODE -ge 1) { Write-Host "$_ ! password protected zip archive"} }
$LASTEXITCODE
if ($LASTEXITCODE -ge 1) {
Exit 1
}
find corrupt data in fedora objectStore
Get-ChildItem -Path "\\gds-ms-vbas025.media.int\Archive_Fedora\fedora-data\objectStore" -File -Recurse |
Foreach-Object {
$fullname = $_.FullName
$lastmod = $_.LastWriteTime
try {
$content = Get-Content $fullname -ErrorAction Stop
}
catch {
Add-Content -Path C:\docuteam\apps\corrupt-fedora-data.txt -Value $lastmod" - "$fullname
}
}
file convert to utf8
(Get-Content -path static-fileformat-triples.nt) | Set-Content -Encoding UTF8NoBOM -Path static-fileformat-triples.nt
MD5 checksum of a string
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$utf8 = New-Object -TypeName System.Text.UTF8Encoding
$String = "Hello, world!"
$Hash = ([System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($String)))).replace("-","").ToLower()
MD5 checksum of a file
Get-FileHash <filepath> -Algorithm MD5