Archiv vom 2. September 2018

02 | 09 | 2018

PowerShell-Quirks: Das erste Element bestimmt den Typ, Object Edition

Geschrieben von um 23:19 Uhr

Wir wissen ja schon lange, dass in PowerShell das erste Element in einem Ausdruck in der Regel den Typ des Ergebnisses bestimmt.

(Wem das noch nicht klar ist, probiert bitte das folgende Beispiel aus:

$a = 1
$b = "1"
$a + $b
$b + $a

)

Besonders perfide ist dieses Phänomen allerdings bei inzwischen sehr beliebten Arrays aus PSCustomObjects, die man anfertigt, um das Ganze dann in einheitlich strukturierter Art und Weise auszugeben, z.B. nach Out-GridView oder Export-CSV. Die Konstruktion sieht dann z.B. so aus:

$output = @()
Get-Irgendwas | foreach {
    $object = New-Object PSCustomObject
    if (eine Bedingung) {
        $object | Add-Member -MemberType NoteProperty -Name "eine Property" -Value "ein Wert"
    }
    if (eine andere Bedingung) {
        $object | Add-Member -MemberType NoteProperty -Name "eine andere Property" -Value "ein anderer Wert"
    }
    <# ... usw. #>
    $output += $object
}

oder auch moderner und performanter mit Hashtables:

$output = @()
Get-Irgendwas | foreach {
    $hashtable = @{}
    if (eine Bedingung) {
       $hashtable.Add("eine Property","ein Wert")
    }
    if (eine andere Bedingung) {
        $hashtable.Add("eine andere Property","ein anderer Wert")
    }
    <# ... usw. #>
    $object = New-Object PSCustomObject -Property $hashtable
    $output += $object
}

Für die weitere Verarbeitung entsteht, wenn man nicht aufpasst und das wirklich so schreibt wie oben abgebildet, eine blöde Situation: Das Array enthält Objekte gleichen Typs (PSCustomObject), die aber unterschiedliche Properties haben. Adressiert man die Elemente einzeln, hat man Zugriff auf alle Properties des jeweiligen Objektes. Gibt man das array als Ganzes aus, diktiert das erste Element den Satz an Properties, und die Restlichen sind nicht sichtbar! Probiert es aus:

$a1 = New-Object PSCustomObject -Property @{"prop1"="prop1val1";"prop2"="prop2val1"}
$a2 = New-Object PSCustomObject -Property @{"prop1"="prop1val2";"prop2"="prop2val2"}
$a3 = New-Object PSCustomObject -Property @{"prop1"="prop1val3";"prop3"="prop3val3"}
$a4 = New-Object PSCustomObject -Property @{"prop1"="prop1val4";"prop3"="prop3val4"}
$a5 = New-Object PSCustomObject -Property @{"prop4"="prop4val5";"prop3"="prop3val5"}
$a6 = New-Object PSCustomObject -Property @{"prop4"="prop4val6";"prop3"="prop3val6"}
$arr1 = @($a1,$a2,$a3,$a4,$a5,$a6)
$arr2 = @($a6,$a5,$a4,$a3,$a2,$a1)
$arr1 | Out-GridView
$arr2 | Out-GridView

Das gleiche passiert bei Format-Table, Export-CSV und – das hat mich überrascht – selbst dann, wenn man die Elemente einfach nacheinander ausgibt, also einfach nach dem obigen Beispiel

$a1
$a3
$a5

schreibt. Explizite Out-Default und Out-Host Befehle funktionieren hingegen korrekt und geben für das jeweilige Objekt alle dort enthaltenen Properties aus, ebenso Format-List.

Man sollte also in solchen PSCustomObject-Konstrukten stets jedem Objekt alle Properties mitgeben, auch wenn manche davon leer bleiben. Im obigen Pseudocode-Beispiel würde man folgendes machen:

$output = @()
Get-Irgendwas | foreach {
    $hashtable = @{"eine Property"=$null;"eine andere Property"=$null;...;"die letzte Property"="Vorgabewert"}
    if (eine Bedingung) {
       $hashtable["eine Property"] = "ein Wert"
    }
    if (eine andere Bedingung) {
        $hashtable["eine andere Property"] = "ein anderer Wert"
    }
    <# ... usw. #>
    $object = New-Object PSCustomObject -Property $hashtable
    $output += $object
}

Dann haben alle Objekte im Array alle Properties, ggfls. nur mit Vorgabewerten, und die Ausgabe-Welt ist in Ordnung.
Happy scripting!

Tags » , , «

+

02 | 09 | 2018

CIM Lingen 2018 – das war schön

Geschrieben von um 8:17 Uhr

Gestern hatte ich die Ehre, auf der CIM Lingen 2018 zu „Running Scripts in the Enterprise“ (was sonst?) zu sprechen. Bis dato hatte ich die CIM gar nicht auf dem Schirm gehabt, aber die Emsländer Community-Konferenz hat sich als eine ganz tolle Veranstaltung entpuppt. Trotz einer ordentlichen Größe von 300 Teilnehmern ist die Atmosphäre eines User Group-Treffens unverkennbar vorhanden. An dieser Stelle nochmals vielen Dank an das Orga-Team und natürlich an die Sponsoren, zu denen sowohl mein jetziger als auch mein ehemaliger Arbeitgeber gehören.

Ich habe einige tolle Menschen kennengelernt und einige bisher nur aus dem Online-Geschehen bekannte endlich in Person getroffen. Etwas traurig war es zu sehen, dass langjährigen MVPs und absoluten Grundsteinen der deutschen Microsoft-Community die Auszeichnung mit der Begründung „too little cloud content“ entzogen wurde. Schämt euch, Microsoft! Ihr werdet schon sehen, was ihr davon habt.

Nächstes Jahr soll die (nunmehr 15.) CIM an zwei Tagen stattfinden – 13. + 14.09.2019 (save the date!) und über acht Tracks gehen. Es sind 50 Sessions angekündigt, es ergeben sich also rechnerisch, abzüglich der Opening und der Closing Keynote, drei Slots pro Tag in jedem Track. Somit hätte jeder Slot voraussichtlich eine Länge, die einen deutlich tieferen Einstieg in das jeweilige Thema erlaubt. Drückt mir die Daumen – das wäre genau mein Ding, denn diesmal bin ich etwas aus der Zeit geraten und musste am Ende des 45-minütigen Slots ganz schön hetzen.

Also: auf zur nächsten CIM: #cimlingen #communityrocks

 

Tags » , , , «

+