| | 0

Powershell: PSCustomObject / PSObject Arrays

Für ein IoT Projekt lese ich Schalterzustände einer Web-Relay-Box aus (8 Relais mit eigener Bezeichnung, die per http an- und ausgeschaltet werden können): Kanal, Beschriftung und Zustand. Die Zustände lese ich in einem Azure Web Job mit C# aus und speichere diese in einem Array einer erstellten Klasse.

Mit PowerShell lese ich die Zustände zusätzlich aus (für ein Administrationstool). Das Speichern der Zustände in einem Array ging mir nicht so leicht von der Hand. Daher anbei meine Lösung.

Ziel

Ein Array von Objekten, welches wie folgt aussieht:

1
2
3
4
5
6
7
8
9
10
11
12
13
Channel Name                        IsOn
------- -------------------------   ----
      1 Switch Corridor             True
      2 Switch Kitchen              True
      3 Switch Door Buzzer Inside   True
      4 Switch Door Buzzer Street   True

Meine Lösung

Deklaration eines Arrays:

1
$Box =  @()

Definition eine Custom Objects und zuweisen der einzelnen Werte:

1
2
3
4
5
6
7
$rc1 = New-Object PSCustomObject
$rc1 | Add-Member -type NoteProperty -name Channel -Value 1
$rc1 | Add-Member -type NoteProperty -name Name -Value "Switch Corridor"
$rc1 | Add-Member -type NoteProperty -name IsOn -Value $True

Hinzufügen des Objekts zum Array:

1
$Box += $rc1

Definition eines weiteren Custom Objects und zuweisen der einzelnen Werte:

1
2
3
4
5
6
7
$rc2 = New-Object PSCustomObject
$rc2 | Add-Member -type NoteProperty -name Channel -Value 2
$rc2 | Add-Member -type NoteProperty -name Name -Value "Switch Kitchen "
$rc2 | Add-Member -type NoteProperty -name IsOn -Value $True

Hinzufügen des Objekts zum Array:

1
$Box += $rc2

Ergebnis:

1
2
3
4
5
6
7
Channel Name                    IsOn
------- ---------------------   ----
      1 Switch Corridor         True
      2 Switch Kitchen          True

ACHTUNG: Es geht nicht, dass $rc1 zum Array hinzugefügt wird, dann $rc1 verändert und erneut hinzugefügt wird! Das führt dazu, dass die Inhalte gleich sind:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
### FAIL ###
$Box =  @()
$rc1 = New-Object PSCustomObject
$rc1 | Add-Member -type NoteProperty -name Channel -Value 1
$rc1 | Add-Member -type NoteProperty -name Name -Value "Switch Corridor"
$rc1 | Add-Member -type NoteProperty -name IsOn -Value $True
$Box += $rc1
$rc1.Channel = 2
$rc1.Name = "Switch Kitchen"
$rc1.IsOn = $True
$Box += $rc1
$Box
Channel Name                    IsOn
------- ---------------------   ----
      2 Switch Kitchen          True
      2 Switch Kitchen          True

Es ist aber folgendes möglich:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
### WORKS ###
$Box =  @()
$rc1 = New-Object PSCustomObject
$rc1 | Add-Member -type NoteProperty -name Channel -Value 1
$rc1 | Add-Member -type NoteProperty -name Name -Value "Switch Corridor"
$rc1 | Add-Member -type NoteProperty -name IsOn -Value $True
$Box += $rc1
$rc1 = New-Object PSCustomObject
$rc1 | Add-Member -type NoteProperty -name Channel -Value 2
$rc1 | Add-Member -type NoteProperty -name Name -Value "Switch Kitchen "
$rc1 | Add-Member -type NoteProperty -name IsOn -Value $True
$Box += $rc1
$Box
Channel Name                    IsOn
------- ---------------------   ----
      1 Switch Corridor         True
      2 Switch Kitchen          True

Oder auch im Skript (Auszug):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$Box =  @()
foreach ($Line in $Lines)
{   ...
    if ( ... )
    {
        [int]$Channel=...
        [bool]$IsOn=...
        [string]$Name="...."
        $rc = New-Object PSObject
        $rc | Add-Member -type NoteProperty -name Channel -Value $Channel
        $rc | Add-Member -type NoteProperty -name Name -Value $Name
        $rc | Add-Member -type NoteProperty -name IsOn -Value $IsOn
        $Box += $rc
        remove-variable rc
    }
}