PowerShell und Arrays
Oft muss man sich zwischen Arrays und Hashtables entscheiden. Eine Hashtable bietet natürlich einen schnellen direkten Zugriff auf ein individuelles Element, wenn man den "Key" dazu nutzt. Dieser muss dann aber auch eindeutig sein. Ein Arrays ist eine Liste, in der Elemente auch mehrfach vorkommen können. Sobald ein Array dann zweidimensional ist, entspricht es eher einer Tabelle.
Das einfache Array
Ein einfaches "Array" mit Werten ist aber relativ unspektakulär. Hier definiere ich eine Variable und belege sie gleich
PS C:\> [int[]]$table PS C:\> $table=1,2,3,4 PS C:\> $table 1 2 3 4
Es geht natürlich auch in einer Zeile
[int[]] $table1 = 1,2,3,4,5,6,7,8,9
Ein Array kann aber auch durch den Kurzcode "@()" erstellt werden.
$status = @("OK","WARN","ERROR","FAIL",0)
Dabei muss nicht mal der Typ identisch sein
PS C:\> 0..4 | %{$status[$_].gettype()} IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True String System.Object True True String System.Object True True String System.Object True True String System.Object True True Int32 System.ValueType
Das müssen Sie natürlich bei der weiteren Betrachtung berücksichtigen.
Eine Tabelle als Array
Interessant wird ein Array, wenn jede Zeile selbst ein PSObject darstellt und man diese einfach aneinander ketten kann:
[array]$result=@() $result+= [pscustomobject][ordered]@{Vorname = "Frank"; Nachname = "Carius"} $result+= [pscustomobject][ordered]@{Vorname = "Uwe"; Nachname = "Ulbrich"} $result Vorname Nachname ------- -------- Frank Carius Uwe Ulbrich
So schnell kann man dann eine Liste aufbauen, die mit Export-CSV etc. Natürlich auch sehr einfach ausgegeben und weiter verarbeitet werden kann. Einträge können hier im Gegensatz zur Hashtable auch mehrfach erscheinen. Allerdings ist ein Array in der Regel "Statisch", wie man mit einer Abfrage auch sehen kann.
$result.isfixedsize true
Ein Zugriff mit der ADD oder REMOVE-Methode funktioniert nicht. Irritierend kann aber sein, dass ein Erweitern mit "+=" dennoch möglich ist. So ganz konsistent ist das nicht.
Beim Export-CSV werden die Feldnamen des ersten Eintrags als Tabellenüberschrift genutzt.
Arraylist
Microsoft rät mittlerweile davon ab, die
Klasse "Arraylist" zu nutzen
https://docs.microsoft.com/en-us/dotnet/api/system.collections.arraylist?redirectedfrom=MSDN&view=netframework-4.8#remarks
https://stackoverflow.com/questions/2309694/arraylist-vs-list-in-c-sharp
Besser ist nur Nutzung der generischen Listen "[generic.list]"
Eine Erweiterung von Arrays ist eine Arrayliste. Manchmal stört bei einem Arrays, dass es eine statisch Größe hat und nicht einfach erweitert werden kann. Dann kann so eine Liste eine Lösung sein. Hier kann dann auch mit ADD und REMOVE gearbeitet werden.
PS C:\> [System.Collections.ArrayList]$ArrayList=@() PS C:\> $ArrayList.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True ArrayList System.Object PS C:\> $ArrayList.add("Frank") 0 PS C:\> $ArrayList.add("Carsten") 1 PS C:\> $ArrayList Frank Carsten PS C:\> $ArrayList.remove("Otto")
Beim "Add" wird als Rückgabe die aktuell Größe ausgegeben. Ein Remove eines nicht vorhandenen Elements liefert keine Fehlermeldung. Es ist auch nicht vorgeschrieben, dass die Elemente der Liste vom gleichen Typ sind. Das kann schon "verwirren", wie das folgende Beispiel zeigt, indem ich ein "Array" als drittes Element addiere
PS C:\> $ArrayList.add((1,2)) 2 PS C:\> $ArrayList Frank Carsten 1 2 PS C:\> $ArrayList.Count 3
Bei der Ausgabe sieht es aus, also ob hier vier Elemente drin sind. Real sind es aber nur drei, bei der Powershell das dritte Element entsprechend ausgibt. Wer aber Element für Element durchläuft, bekommt die Information schon einzeln
PS C:\> $ArrayList[2] 1 2
- ArrayList Class
https://msdn.microsoft.com/de-de/library/system.collections.arraylist(v=vs.110).aspx - Adding and Removing Items
from a PowerShell Array
http://www.jonathanmedd.net/2014/01/adding-and-removing-items-from-a-PowerShell-array.html
Arrays in Funktionen
Etwas Vorsicht ist bei der Verwendung von Arrays als Rückgabe von Funktionen zu beachten. Der folgende Beispielcode soll das demonstrieren.
#Test-Arrayresult function get-array{ # Lere einfaches Array an $myarray=@(1,"eins",2) write-host "Typ1 = $($result.gettype())" 0..2 | %{write-host $myarray[$_].gettype()} $myarray } $ergebnis=get-array write-host "Typ2 = $($ergebnis.gettype())" 0..2 | %{$ergebnis[$_].gettype()}
Beim Aufruf ist sichtbar, dass in der Funktion noch ein Array vorhanden ist aber das aufrufende Programm ein Array von System.Object
Der Inhalt ist dann wieder die "Objket-Version" des Basetype
Weitere Links
- Arrays in PowerShell: anlegen, ändern,
auslesen, sortieren, löschen
https://www.windowspro.de/script/arrays-powershell-anlegen-aendern-auslesen-sortieren-loeschen - Powershell - Pass array from one
function to another
https://community.spiceworks.com/topic/410183-powershell-pass-array-from-one-function-to-another - Arrays in PowerShell: anlegen, ändern,
auslesen, sortieren, löschen
https://www.windowspro.de/script/arrays-powershell-anlegen-aendern-auslesen-sortieren-loeschen