PowerShell hat ein sogenanntes PSObject, das ein Wrapper um ein beliebiges .NET-Objekt ist (oder ein vollständig benutzerdefiniertes Objekt). Wenn Sie Add-Member aufrufen, umschließt PowerShell das reale .NET-Objekt implizit mit einem PSObject.
Die Funktionsweise von Add-Member hängt davon ab, ob Sie mit einem PSObject begonnen haben oder nicht. Wenn Sie nicht mit einem PSObject begonnen haben, wird Add-Member die Eingabe in ein PSObject umbrechen, und Sie müssen die Variable neu zuweisen, um das angepasste Objekt zu sehen.
So zum Beispiel:
$x = [Environment]::OSVersion
$x | Add-Member NoteProperty IsVista $true
$x | Format-List # does not show the new property
Dies liegt daran, OSVersion nicht gewickelt ist, ein PSObject ist. Add-Member umschließt es, aber dieser Wrapper geht verloren, weil Sie dem umschlossenen Objekt $ x nicht neu zuweisen. Kontrast zu diesem Verhalten:
$x = New-Object OperatingSystem ('Win32NT', '6.0')
$x | Add-Member NoteProperty IsVista $true
$x | Format-List # DOES show the new property
Dies ist, weil New-Object implizit die neue Instanz in einem PSObject umschließt. Daher fügt Ihr Add-Member-Aufruf dem vorhandenen Wrapper Elemente hinzu.
zurück zum ersten Beispiel gehen, können Sie es zu, indem es erwartet funktioniert:
$x = [Environment]::OSVersion
$x = $x | Add-Member NoteProperty IsVista $true -PassThru
$x | Format-List # DOES show the new property
Jetzt, nach all dem, den Grund, dass die Hashtable funktioniert nicht wie erwartet, weil Hashtabellen werden von PowerShell speziell behandelt, und der Adapter für Hashtables verwendet die Schlüssel als Eigenschaften (irgendwie), und Add-Member funktioniert nicht wie erwartet mit dieser Art von Objekt.
Vielen Dank für die Erklärung! – alex2k8