PowerShell Multiline-Befehle: Eingabe und Skripting leicht gemacht

PowerShell bietet verschiedene Möglichkeiten, mehrzeilige Befehle zu erstellen und auszuführen. Dies ist besonders nützlich bei komplexeren Operationen, langen Pipelines oder wenn Sie Ihre Befehle strukturiert und lesbar gestalten möchten. Direkte Eingabe in der PowerShell-Konsole Backtick für Zeilenwrapping Der einfachste Weg, einen Befehl über mehrere Zeilen zu schreiben, ist die Verwendung des Backtick-Zeichens (`) am Ende einer Zeile: Get-ChildItem -Path C:\Users ` -Recurse ` -Filter "*.txt" ` | Where-Object { $_.Length -gt 1000 } Das Backtick teilt PowerShell mit, dass der Befehl in der nächsten Zeile fortgesetzt wird. ...

Mai 31, 2025

PowerShell Scripts zeitversetzt ausführen: Der komplette Einsteiger-Guide für Windows und Linux

PowerShell Scripts sind ein mächtiges Werkzeug zur Automatisierung wiederkehrender Aufgaben. Doch was, wenn diese Scripts nicht sofort, sondern zu bestimmten Zeiten oder in regelmäßigen Abständen ausgeführt werden sollen? In diesem Artikel zeige ich dir, wie du PowerShell Scripts auf Windows und Linux zeitversetzt ausführen kannst. Was bedeutet “zeitversetzt ausführen”? Zeitversetzte Ausführung bedeutet, dass ein Script nicht manuell gestartet wird, sondern automatisch zu einem vordefinierten Zeitpunkt oder in regelmäßigen Intervallen läuft. Das ist besonders nützlich für: ...

Mai 31, 2025

PowerShell: Die 25 wichtigen Cmdlets für fortgeschrittene Benutzer

Nachdem die grundlegenden PowerShell Cmdlets in PowerSell Top 25 Befehle vorgestellt wurden, geht es jetzt auf das nächste Level. Diese 25 fortgeschrittenen Cmdlets erweitern Ihre PowerShell-Toolbox erheblich und ermöglichen komplexere Automatisierungs- und Verwaltungsaufgaben. Erweiterte PowerShell Cmdlets 26. Invoke-Command Führt Befehle auf lokalen oder entfernten Computern aus. Invoke-Command -ComputerName "Server01" -ScriptBlock {Get-Process} Invoke-Command -ComputerName "Server01", "Server02" -ScriptBlock {Get-Service -Name "Spooler"} icm -ComputerName $servers -FilePath "C:\Scripts\maintenance.ps1" Console Output: ProcessName Id MachineName ----------- -- ----------- ApplicationHost 1234 Server01 chrome 5678 Server01 27. Enter-PSSession / Exit-PSSession Startet/beendet eine interaktive Sitzung mit einem entfernten Computer. ...

Mai 29, 2025

PowerShell: Die 25 wichtigsten Cmdlets mit Beispielen

PowerShell ist eine mächtige Kommandozeilen-Shell und Skriptsprache, die Systemadministratoren und Entwicklern hilft, komplexe Aufgaben zu automatisieren. In diesem Artikel stellen wir die 25 wichtigsten PowerShell Cmdlets vor, die jeder PowerShell-Benutzer kennen sollte. Was sind Cmdlets? Cmdlets (Command-lets) sind spezielle .NET-Klassen in PowerShell, die eine bestimmte Funktion ausführen. Sie folgen dem Verb-Substantiv-Schema (z.B. Get-Process, Set-Location) und sind die Grundbausteine für PowerShell-Befehle. Die 25 wichtigsten PowerShell Cmdlets 1. Get-Help Zeigt Hilfeinformationen zu PowerShell Cmdlets und Konzepten an. ...

Mai 28, 2025

Powershell Cheatsheet

PowerShell hat sich über die Jahre erheblich weiterentwickelt und leistungsstarke Sprachfeatures eingeführt, die das Skripting effizienter und lesbarer machen. Egal ob Sie Systemadministrator, DevOps-Ingenieur oder Entwickler sind - die Beherrschung dieser Sprachkonstrukte wird Ihre PowerShell-Produktivität dramatisch verbessern. Variablen und Datentypen Grundlegende Variablenzuweisung # Einfache Zuweisung $name = "Max Mustermann" $alter = 30 $istAktiv = $true # Typ-Einschränkungen [string]$benutzername = "admin" [int]$anzahl = 0 [datetime]$startZeit = Get-Date Arrays und Sammlungen # Arrays $server = @("web01", "web02", "db01") $zahlen = 1..10 # Hash-Tabellen $konfiguration = @{ Server = "localhost" Port = 8080 SSL = $true } # Auf Elemente zugreifen Write-Host $server[0] # web01 Write-Host $konfiguration.Server # localhost Write-Host $konfiguration["Port"] # 8080 Erweiterte Sammlungen # ArrayList für dynamische Arrays $liste = [System.Collections.ArrayList]@() $liste.Add("element1") | Out-Null $liste.AddRange(@("element2", "element3")) # Geordnete Hash-Tabelle $geordneteKonfig = [ordered]@{ Erster = "wert1" Zweiter = "wert2" } Operatoren Vergleichsoperatoren # Grundlegende Vergleiche $a -eq $b # Gleich $a -ne $b # Ungleich $a -gt $b # Größer als $a -lt $b # Kleiner als $a -ge $b # Größer oder gleich $a -le $b # Kleiner oder gleich # String-Operationen $text -like "*muster*" # Platzhalter-Abgleich $text -match "regex" # Regulärer Ausdruck $text -contains "teilstring" # Enthält-Prüfung $text -in @("a", "b", "c") # Mitgliedschaftstest Logische Operatoren # Logische Operationen $bedingung1 -and $bedingung2 $bedingung1 -or $bedingung2 -not $bedingung # Praktisches Beispiel if (($alter -gt 18) -and ($hatFuehrerschein -eq $true)) { Write-Host "Darf Auto fahren" } Moderne Operatoren (PowerShell 7+) # Ternärer Operator $status = ($punkte -gt 80) ? "Bestanden" : "Durchgefallen" # Null-Koaleszierende Operatoren $benutzername = $env:USER ?? $env:USERNAME ?? "Unbekannt" # Null-Koaleszierende Zuweisung $konfiguration.Timeout ??= 30 Bedingte Logik If-Else-Anweisungen # Grundlegendes if-else if ($punkte -gt 90) { Write-Host "Ausgezeichnet!" } elseif ($punkte -gt 70) { Write-Host "Gute Arbeit!" } else { Write-Host "Weiter üben!" } # Einzeiler-Bedingungen if ($debug) { Write-Host "Debug-Modus aktiviert" } Switch-Anweisungen # Grundlegender Switch switch ($status) { "Running" { Write-Host "Dienst ist aktiv" } "Stopped" { Write-Host "Dienst ist inaktiv" } "Paused" { Write-Host "Dienst ist pausiert" } default { Write-Host "Unbekannter Status" } } # Erweiterter Switch mit Regex switch -Regex ($logEintrag) { "ERROR" { Write-Host "Fehler gefunden" -ForegroundColor Red } "WARNING" { Write-Host "Warnung gefunden" -ForegroundColor Yellow } "INFO" { Write-Host "Information protokolliert" } } Schleifen und Iteration ForEach-Schleifen # Traditionelle foreach foreach ($server in $server) { Test-Connection -ComputerName $server -Count 1 } # Pipeline foreach $server | ForEach-Object { Write-Host "Verarbeite $_" Test-Connection -ComputerName $_ -Count 1 } # Parallele Verarbeitung (PowerShell 7+) $server | ForEach-Object -Parallel { Test-Connection -ComputerName $_ -Count 1 } -ThrottleLimit 5 For- und While-Schleifen # For-Schleife for ($i = 0; $i -lt 10; $i++) { Write-Host "Iteration $i" } # While-Schleife $zaehler = 0 while ($zaehler -lt 5) { Write-Host "Zähler: $zaehler" $zaehler++ } # Do-While-Schleife do { $eingabe = Read-Host "Geben Sie 'beenden' ein zum Verlassen" } while ($eingabe -ne "beenden") Funktionen und Parameter Grundlegende Funktionen # Einfache Funktion function Get-SystemInfo { $os = Get-CimInstance -ClassName Win32_OperatingSystem return @{ Computername = $env:COMPUTERNAME Betriebssystem = $os.Caption FreierSpeicher = [math]::Round($os.FreePhysicalMemory / 1MB, 2) } } # Funktion aufrufen $info = Get-SystemInfo Write-Host "Computer: $($info.Computername)" Erweiterte Funktionen mit Parametern function Test-DienstStatus { [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [string[]]$DienstName, [ValidateSet("Running", "Stopped", "All")] [string]$Status = "All", [switch]$Detailliert ) process { foreach ($dienst in $DienstName) { $svc = Get-Service -Name $dienst -ErrorAction SilentlyContinue if ($svc) { if ($Status -eq "All" -or $svc.Status -eq $Status) { if ($Detailliert) { $svc | Select-Object Name, Status, StartType, DisplayName } else { "$($svc.Name): $($svc.Status)" } } } else { Write-Warning "Dienst '$dienst' nicht gefunden" } } } } # Verwendungsbeispiele Test-DienstStatus -DienstName "Spooler", "BITS" "Spooler", "BITS" | Test-DienstStatus -Status Running -Detailliert Fehlerbehandlung Try-Catch-Finally try { $inhalt = Get-Content -Path "C:\nichtvorhanden.txt" -ErrorAction Stop Write-Host "Datei erfolgreich gelesen" } catch [System.IO.FileNotFoundException] { Write-Host "Datei nicht gefunden - erstelle neue Datei" New-Item -Path "C:\nichtvorhanden.txt" -ItemType File } catch { Write-Host "Ein unerwarteter Fehler ist aufgetreten: $($_.Exception.Message)" } finally { Write-Host "Aufräumarbeiten abgeschlossen" } Fehleraktions-Einstellungen # Globale Fehlereinstellung setzen $ErrorActionPreference = "Stop" # Pro-Befehl Fehlerbehandlung Get-Process -Name "Nichtvorhanden" -ErrorAction SilentlyContinue Get-Service -Name "Ungueltig" -ErrorAction Ignore # Fehler erfassen Get-Process -Name "Nichtvorhanden" -ErrorAction SilentlyContinue -ErrorVariable meineFehler if ($meineFehler) { Write-Host "Fehler aufgetreten: $($meineFehler.Count)" } Objektmanipulation Benutzerdefinierte Objekte erstellen # PSCustomObject (empfohlen) $server = [PSCustomObject]@{ Name = "WEB01" IP = "192.168.1.10" Rolle = "Webserver" LetzerNeustart = (Get-Date).AddDays(-7) } # Methoden zu Objekten hinzufügen $server | Add-Member -MemberType ScriptMethod -Name "GetBetriebszeit" -Value { (Get-Date) - $this.LetzerNeustart } # Methode verwenden $betriebszeit = $server.GetBetriebszeit() Write-Host "Server-Betriebszeit: $($betriebszeit.Days) Tage" Objektfilterung und -auswahl # Laufende Dienste mit spezifischen Eigenschaften abrufen $dienste = Get-Service | Where-Object { $_.Status -eq "Running" -and $_.Name -like "Win*" } | Select-Object Name, Status, StartType # Objekte gruppieren und sortieren $prozesse = Get-Process | Group-Object ProcessName | Sort-Object Count -Descending | Select-Object -First 5 # Objekte messen $speicherVerbrauch = Get-Process | Measure-Object WorkingSet -Sum -Average Write-Host "Gesamtspeicher: $([math]::Round($speicherVerbrauch.Sum / 1MB, 2)) MB" Pipeline-Operationen Pipeline-Grundlagen # Befehle mit Pipeline verketten Get-Service | Where-Object Status -eq "Running" | Sort-Object Name | Select-Object Name, Status | Format-Table -AutoSize # Pipeline-Variable $_ Get-ChildItem -Path C:\Logs -Filter "*.log" | ForEach-Object { $groesse = [math]::Round($_.Length / 1KB, 2) Write-Host "$($_.Name): ${groesse} KB" } Erweiterte Pipeline-Techniken # Tee-Object für Pipeline-Verzweigung Get-Process | Tee-Object -FilePath "prozesse.txt" | Where-Object CPU -gt 100 | Sort-Object CPU -Descending # Out-GridView für interaktive Filterung Get-EventLog -LogName System -Newest 100 | Out-GridView -Title "Systemereignisse" -PassThru | Export-Csv -Path "ausgewaehlte_ereignisse.csv" Klassen und Methoden Klassen definieren class Server { [string]$Name [string]$IP [string]$Rolle [datetime]$LetzerNeustart # Konstruktor Server([string]$name, [string]$ip, [string]$rolle) { $this.Name = $name $this.IP = $ip $this.Rolle = $rolle $this.LetzerNeustart = Get-Date } # Methoden [timespan]GetBetriebszeit() { return (Get-Date) - $this.LetzerNeustart } [void]Neustart() { Write-Host "Starte Server $($this.Name) neu..." $this.LetzerNeustart = Get-Date } [string]ToString() { return "$($this.Name) ($($this.IP)) - $($this.Rolle)" } } # Klasse verwenden $webServer = [Server]::new("WEB01", "192.168.1.10", "Webserver") Write-Host $webServer.ToString() Write-Host "Betriebszeit: $($webServer.GetBetriebszeit().TotalHours) Stunden" Vererbung class DatenbankServer : Server { [string]$DatenbankEngine [int]$Port DatenbankServer([string]$name, [string]$ip, [string]$engine, [int]$port) : base($name, $ip, "Datenbank") { $this.DatenbankEngine = $engine $this.Port = $port } [void]DatenbankSichern() { Write-Host "Sichere $($this.DatenbankEngine) Datenbank auf $($this.Name)" } } $dbServer = [DatenbankServer]::new("DB01", "192.168.1.20", "SQL Server", 1433) $dbServer.DatenbankSichern() Moderne Sprachfeatures Splatting # Parameter-Splatting $parameter = @{ Path = "C:\Logs" Filter = "*.log" Recurse = $true } Get-ChildItem @parameter # Array-Splatting $argumente = @("notepad.exe", "C:\temp\datei.txt") Start-Process @argumente String-Interpolation und Here-Strings # String-Interpolation $name = "Hans" $alter = 30 Write-Host "Hallo, $name! Du bist $alter Jahre alt." # Unterausdrucks-Operator Write-Host "Aktuelle Zeit: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" # Here-Strings für mehrzeiligen Text $skript = @" Get-Service | Where-Object { $_.Status -eq "Running" } | Select-Object Name, Status "@ # Here-String als Skriptblock ausführen Invoke-Expression $skript Reguläre Ausdrücke # Grundlegender Regex-Abgleich $text = "Fehler: Verbindung fehlgeschlagen um 2024-01-15 10:30:25" if ($text -match "(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})") { Write-Host "Zeitstempel gefunden: $($Matches[1])" } # Ersetzen mit Regex $logEintrag = "FEHLER: Datenbankverbindung fehlgeschlagen" $bereinigterEintrag = $logEintrag -replace "FEHLER:", "Warnung:" # Aufteilen mit Regex $daten = "apfel,banane;orange:traube" $fruechte = $daten -split "[,;:]" Pipeline-Ketten-Operatoren (PowerShell 7+) # Erfolgskette (&&) Get-Service -Name "Spooler" && Write-Host "Spooler-Dienst existiert" # Fehlerkette (||) Get-Service -Name "Nichtvorhanden" 2>$null || Write-Host "Dienst nicht gefunden" # Ketten kombinieren Test-Path "C:\temp" && Write-Host "Temp existiert" || Write-Host "Temp fehlt" Praktische Beispiele System-Überwachungsskript function Get-SystemGesundheit { [CmdletBinding()] param( [string[]]$ComputerName = $env:COMPUTERNAME, [int]$CPUSchwellwert = 80, [int]$SpeicherSchwellwert = 90 ) $ergebnisse = foreach ($computer in $ComputerName) { try { # Systeminformationen abrufen $os = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $computer $cpu = Get-CimInstance -ClassName Win32_Processor -ComputerName $computer # Metriken berechnen $speicherVerwendet = [math]::Round((($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / $os.TotalVisibleMemorySize) * 100, 2) $cpuAuslastung = Get-Counter "\Processor(_Total)\% Processor Time" -ComputerName $computer -SampleInterval 1 -MaxSamples 1 | Select-Object -ExpandProperty CounterSamples | Select-Object -ExpandProperty CookedValue # Ergebnisobjekt erstellen [PSCustomObject]@{ Computername = $computer CPUAuslastung = [math]::Round($cpuAuslastung, 2) SpeicherVerwendung = $speicherVerwendet Status = if ($cpuAuslastung -gt $CPUSchwellwert -or $speicherVerwendet -gt $SpeicherSchwellwert) { "Warnung" } else { "OK" } Zeitstempel = Get-Date } } catch { [PSCustomObject]@{ Computername = $computer CPUAuslastung = "Fehler" SpeicherVerwendung = "Fehler" Status = "Nicht erreichbar" Zeitstempel = Get-Date } } } return $ergebnisse } # Verwendung $gesundheitsPruefung = Get-SystemGesundheit -ComputerName @("localhost", "server01") -CPUSchwellwert 70 $gesundheitsPruefung | Format-Table -AutoSize Log-Analyseskript function Analyze-Logs { [CmdletBinding()] param( [Parameter(Mandatory)] [string]$LogPfad, [string]$Muster = "FEHLER|WARNUNG|KRITISCH", [int]$LetzteStunden = 24 ) $stichzeit = (Get-Date).AddHours(-$LetzteStunden) Get-ChildItem -Path $LogPfad -Filter "*.log" | ForEach-Object { $inhalt = Get-Content -Path $_.FullName $treffer = $inhalt | Where-Object { $_ -match $Muster } if ($treffer) { [PSCustomObject]@{ LogDatei = $_.Name FehlerAnzahl = ($treffer | Measure-Object).Count Fehler = $treffer LetztGeaendert = $_.LastWriteTime } } } | Where-Object { $_.LetztGeaendert -gt $stichzeit } | Sort-Object FehlerAnzahl -Descending } # Verwendung $logAnalyse = Analyze-Logs -LogPfad "C:\Logs" -LetzteStunden 8 $logAnalyse | Select-Object LogDatei, FehlerAnzahl, LetztGeaendert | Format-Table Best Practices und Tipps Performance-Tipps # ArrayList statt Array für häufige Hinzufügungen verwenden $liste = [System.Collections.ArrayList]@() # Anstatt: $array += $element (langsam) $liste.Add($element) | Out-Null # Viel schneller # -contains statt -in für Einzelelement-Prüfungen verwenden if ($server -contains $zielServer) { } # Schneller # Anstatt: if ($zielServer -in $server) { } # Arrays vorab zuweisen wenn Größe bekannt ist $ergebnisse = New-Object System.Object[] 1000 Code-Organisation # Regionen für große Skripte verwenden #region Hilfsfunktionen function Get-Konfiguration { # Implementierung } #endregion #region Hauptlogik # Hauptskript-Logik hier #endregion Best Practices für Fehlerbehandlung # Immer spezifische Fehlertypen verwenden wenn möglich try { # Riskante Operation } catch [System.UnauthorizedAccessException] { Write-Warning "Zugriff verweigert - Berechtigungen prüfen" } catch [System.IO.FileNotFoundException] { Write-Error "Erforderliche Datei nicht gefunden" } catch { Write-Error "Unerwarteter Fehler: $($_.Exception.Message)" throw # Weiterwerfen wenn nicht behandelbar } Fazit PowerShells Sprachfeatures bieten mächtige Werkzeuge für Automatisierung, Systemadministration und Entwicklungsaufgaben. Die modernen Features wie ternäre Operatoren, Null-Koaleszierende Operatoren und parallele Verarbeitung machen PowerShell konkurrenzfähig zu anderen Skriptsprachen, während die objektorientierte Natur und Pipeline-Philosophie erhalten bleiben. ...

Mai 25, 2025