Im Zuge meiner täglichen Arbeit an komplexen IT-Infrastrukturen und Automatisierungen entstehen nützliche kleine Helfer und Module. Ich teile diese Werkzeuge auf GitHub und über die PowerShell Gallery, um die Administration und Entwicklung für andere zu erleichtern.

Split-Array

PowerShell-Modul
Repository auf GitHub

Sequenzielle Verarbeitung großer Datenmengen kann lange dauern — gerade bei Cloud-APIs. Die Lösung ist Parallelisierung, und dafür müssen die Daten zuerst in Portionen (Chunks) zerlegt werden.

Damit dieses Rad nicht in jedem Skript neu erfunden wird, übernimmt Split-Array genau diesen Schritt: Es teilt ein Array in ein Array von Arrays — wahlweise nach maximaler Chunk-Größe oder in eine feste Anzahl von Chunks.

Klein, aber fein: Edge Cases sind berücksichtigt, die Eingabe funktioniert als Argument ebenso wie über die Pipeline.

EIN ARRAY · 8 ELEMENTE 1 2 3 4 5 6 7 8 Split-Array 1 2 3 4 5 6 7 8 ARRAY VON ARRAYS · 3 CHUNKS

Installation

Das Modul wird direkt aus der PowerShell Gallery installiert:

Install-Module SplitArray          # PowerShellGet
Install-PSResource SplitArray      # PSResourceGet

Vorausgesetzt wird PowerShell 5.1 oder neuer. Alternativ lässt sich das Repository klonen und das Modul über sein Manifest SplitArray.psd1 importieren.

Hinweis: In der PowerShell Gallery veröffentlicht als SplitArray.

Nutzungsbeispiele

1. Aufteilen nach maximaler Chunk-Größe (-ChunkSize)

Bestimmt, wie viele Elemente maximal in einem Unter-Array liegen dürfen. Ideal für API-Batches.

# Greedy-Verteilung (Standard): Füllt Chunks maximal auf
Split-Array -InputObject 1..10 -ChunkSize 3
# Ergebnis: (1,2,3), (4,5,6), (7,8,9), (10)

# Even-Verteilung: Verteilt den Rest gleichmäßig
Split-Array -InputObject 1..10 -ChunkSize 3 -Distribution Even
# Ergebnis: (1,2,3), (4,5,6), (7,8), (9,10)

2. Aufteilen in genau N Chunks (-MaxChunk)

Teilt das Array in eine feste Anzahl von Chunks auf.

# Even-Verteilung (Standard): Erzeugt exakt 4 ausgeglichene Chunks
Split-Array -InputObject 1..10 -MaxChunk 4
# Ergebnis: (1,2,3), (4,5,6), (7,8), (9,10)

3. Letzten Chunk auffüllen (-Pad)

Füllt den letzten Chunk mit einem Wert auf, bis er die Größe des ersten Chunks erreicht — praktisch, wenn nachgelagerter Code gleich große Chunks erwartet.

# Mit $null auf die volle Chunk-Größe auffüllen
Split-Array -InputObject 1..10 -ChunkSize 3 -Pad $null
# Ergebnis: (1,2,3), (4,5,6), (7,8,9), (10,$null,$null)

Verteilungsstrategien

Vergleich der Verteilungsstrategien Greedy und Even
Strategie Verhalten Standard für
Greedy Füllt jeden Chunk bis zum Maximum; der letzte Chunk erhält den verbleibenden Rest. -ChunkSize
Even Verteilt den Rest elementweise auf die ersten Chunks; erzeugt immer exakt die gewünschte Anzahl an Chunks. -MaxChunk

Parameter

Übersicht der Parameter von Split-Array
Parameter Funktion
InputObject Das Array bzw. die Elemente, die zerlegt werden. Nimmt Pipeline-Eingabe entgegen.
ChunkSize Maximale Anzahl Elemente pro Chunk. Schließt -MaxChunk aus.
MaxChunk Gewünschte Anzahl an Chunks. Schließt -ChunkSize aus.
Distribution Verteilungsstrategie Greedy oder Even — steuert, wie der Rest verteilt wird.
Pad Wert, mit dem der letzte Chunk auf einheitliche Größe aufgefüllt wird (z. B. $null, 0, "x").

Join-Object

PowerShell-Modul
Repository auf GitHub

Innerhalb eines Cmdlets ist die PowerShell-Pipeline elegant. Sobald aber die Ausgaben mehrerer Cmdlets zusammengeführt werden müssen, beginnt die Handarbeit: Schleifen, Zwischenspeicher und von Hand gepflegte Hashtable-Lookups.

Join-Object verbindet die Ausgaben zweier Cmdlets anhand einer gemeinsamen Identität — etwa einer SMTP-Adresse oder GUID — zu einem einzigen Objekt, direkt in der Pipeline.

Jedes Cmdlet wird dabei genau einmal aufgerufen, ganz ohne explizite Schleifen. Das Ergebnis bleibt ein kompakter, lesbarer One-Liner.

CMDLET A · ID + A + B ID A B CMDLET B · ID + C + D ID C D per Identität ID A B C D EIN OBJEKT · ID + A + B + C + D

Installation

Das Modul wird direkt aus der PowerShell Gallery installiert:

Install-Module JoinObject          # PowerShellGet
Install-PSResource JoinObject      # PSResourceGet

Vorausgesetzt wird PowerShell 5.1 oder neuer. Für den Aufruf steht der kurze Alias Join bereit.

Hinweis: In der PowerShell Gallery veröffentlicht als JoinObject.

Nutzungsbeispiele

1. Dienste mit Prozessinformationen verbinden

Verknüpft Get-Service und Get-Process über die gemeinsame Eigenschaft Name.

Get-Service | Join Get-Process -IdentityProperty Name |
    Select-Object Name, Status, CPU, WorkingSet

2. Mailbox-Statistiken anreichern

Ergänzt jede Shared Mailbox um ihre Statistikwerte — ein Aufruf je Cmdlet, ohne Schleife.

Get-Mailbox -RecipientTypeDetails SharedMailbox |
    Join-Object Get-MailboxStatistics |
    Select-Object PrimarySmtpAddress, TotalItemSize, ItemCount

3. Parameter durchreichen und Felder überschreiben

Über -Options (Alias -With) gehen zusätzliche Parameter an das Ziel-Cmdlet; -Force überschreibt gleichnamige Felder, statt sie zu suffixieren.

$Users | Join-Object Get-ADUser -With @{ Properties = 'Department', 'Office' } -Force

Parameter

Übersicht der Parameter von Join-Object
Parameter Funktion
Cmdlet Name des Cmdlets, dessen Ausgabe verbunden wird.
InputObject Das Objekt aus der Pipeline; wird automatisch übergeben.
IdentityProperty Explizite Identitätseigenschaft, falls sie nicht automatisch erkannt wird.
Options (With) Hashtable zusätzlicher Parameter für das Ziel-Cmdlet.
Force Überschreibt gleichnamige Felder, statt sie zu suffixieren.

Invoke-WithEcho

PowerShell-Modul
Repository auf GitHub

Was DOS-Batchdateien mit ECHO ON immer konnten, fehlt PowerShell bis heute: ein Protokoll, das vor jedem Befehl festhält, was gleich ausgeführt wird. In langen Logs lässt sich Ausgabe deshalb oft nicht mehr dem Befehl zuordnen, der sie erzeugt hat.

Invoke-WithEcho führt einen Scriptblock aus und protokolliert vorab den Befehlstext — zusammen mit Typ und aktuellem Wert jeder Variablen, die der Block liest. In Kombination mit Start-Transcript wird so jede Zeile im Log ihrem Auslöser zuordenbar.

Die Auflösung liest die Variablen nur aus dem Scope des Aufrufers — nichts wird doppelt ausgeführt, keine Nebeneffekte. SecureStrings und Credentials erscheinen maskiert, die Rückgabe des Blocks läuft unverändert durch die Pipeline.

EIN SCRIPTBLOCK { Get-ChildItem $sourcePath } Invoke-WithEcho >> Get-ChildItem $sourcePath $sourcePath = C:\data\import a.csv · b.csv ECHO IM TRANSKRIPT RÜCKGABE UNVERÄNDERT

Installation

Das Modul wird direkt aus der PowerShell Gallery installiert:

Install-Module InvokeWithEcho          # PowerShellGet
Install-PSResource InvokeWithEcho      # PSResourceGet

Vorausgesetzt wird PowerShell 5.1 oder neuer.

Hinweis: In der PowerShell Gallery veröffentlicht als InvokeWithEcho.

Nutzungsbeispiele

1. Befehl samt Variablenwerten protokollieren

Der Befehlstext erscheint wörtlich wie geschrieben, darunter Typ und Wert jeder gelesenen Variablen. Die Zuweisung gehört vor den Aufruf — der Block läuft in einem Kindscope, Zuweisungen im Block verpuffen.

$sourcePath = 'C:\data\import'
$files = Invoke-WithEcho { Get-ChildItem $sourcePath -Filter *.csv }

# Echo-Ausgabe (landet auch im Transkript):
# >> Get-ChildItem $sourcePath -Filter *.csv
#    $sourcePath  String  1  C:\data\import

2. Zusammenspiel mit Start-Transcript

Die Echo-Zeilen laufen über den Information-Stream und landen damit im Transkript — jede Ausgabe im Log ist dem Befehl zuordenbar, der sie erzeugt hat.

Start-Transcript deploy.log
Invoke-WithEcho { Copy-Item $source $target -Recurse }
Invoke-WithEcho { Restart-Service $serviceName }
Stop-Transcript
# deploy.log enthält jeden Befehl samt Werten — vor seiner Ausgabe

3. Ausgabe steuern und umlenken

Mit -NoExpand bleibt es beim reinen Befehlstext; per 6> lassen sich die Echo-Zeilen in eine Datei umlenken oder unterdrücken — die Rückgabe bleibt davon unberührt.

# Nur den Befehlstext protokollieren, ohne Variablenwerte
Invoke-WithEcho { Get-Content $configPath } -NoExpand

# Echo-Zeilen in eine Datei umlenken statt in die Konsole
$result = Invoke-WithEcho { Get-Process } 6> echo.log

Parameter

Übersicht der Parameter von Invoke-WithEcho
Parameter Funktion
ScriptBlock Der auszuführende Block. Pflichtparameter, auch positional übergebbar.
MaxValueLength Maximale Länge je protokolliertem Variablenwert (Standard 100); längere Werte enden mit „…“.
NoExpand Protokolliert nur den Befehlstext, ohne Variablenwerte.
CommandColor Konsolenfarbe der Befehlszeilen (Standard Cyan) — wirkt nur in der Konsole, das Transkript bleibt unformatiert.
ValueColor Konsolenfarbe der Variablenzeilen (Standard DarkGray).
NoColor Gibt die Echo-Zeilen in der Standardfarbe der Konsole aus.
Ausblick

Nach und nach mehr

Ich habe mir vorgenommen, hier nach und nach kleine Helfer aus meinem Arbeitsalltag zu teilen. Was sich in der Praxis bewährt, bekommt seinen Platz auf dieser Seite.