about_Hash_Tables
Kurze Beschreibung
Beschreibt, wie Hashtables in PowerShell erstellt, verwendet und sortiert werden.
Lange Beschreibung
Eine Hashtabelle, auch als Wörterbuch oder assoziatives Array bezeichnet, ist eine kompakte Datenstruktur, die ein oder mehrere Schlüsselwertpaare speichert. Beispielsweise kann eine Hashtabelle eine Reihe von IP-Adressen und Computernamen enthalten, wobei die IP-Adressen die Schlüssel und die Computernamen die Werte sind oder umgekehrt.
In PowerShell ist jede Hashtabelle ein [System.Collections.Hashtable]
-Objekt. Sie können die Eigenschaften und Methoden von Hashtable Objekten in PowerShell verwenden.
Ab PowerShell 3.0 können Sie die [ordered]
Typbeschleuniger verwenden, um ein [System.Collections.Specialized.OrderedDictionary]
Objekt in PowerShell zu erstellen.
Sortierte Wörterbücher unterscheiden sich von Hashtables darin, dass die Schlüssel immer in der Reihenfolge angezeigt werden, in der Sie sie auflisten. Die Reihenfolge der Schlüssel in einer Hashtabelle ist nicht deterministisch.
Die Schlüssel und der Wert in Hashtables sind auch .NET-Objekte. Sie sind am häufigsten Zeichenfolgen oder ganze Zahlen, aber sie können einen beliebigen Objekttyp aufweisen. Sie können auch geschachtelte Hashtables erstellen, bei denen der Wert eines Schlüssels eine andere Hashtabelle ist.
Hashtables werden häufig verwendet, da sie effizient zum Suchen und Abrufen von Daten sind. Sie können Hashtables verwenden, um Listen zu speichern und berechnete Eigenschaften in PowerShell zu erstellen. Außerdem konvertiert das Cmdlet ConvertFrom-StringData
strukturierte Zeichenfolgendaten in eine Hashtabelle.
Syntax
Die Syntax einer Hashtabelle lautet wie folgt:
@{ <name> = <value>; [<name> = <value> ] ...}
Die Syntax eines sortierten Wörterbuchs lautet wie folgt:
[ordered]@{ <name> = <value>; [<name> = <value> ] ...}
Die [ordered]
Typbeschleuniger wurde in PowerShell 3.0 eingeführt.
Befolgen Sie die folgenden Richtlinien, um eine Hashtabelle zu erstellen:
- Beginnen Sie die Hashtable mit einem At-Zeichen (
@
). - Schließen Sie die Hashtabelle in geschweifte Klammern ein (
{}
). - Geben Sie ein oder mehrere Schlüsselwertpaare für den Inhalt der Hashtabelle ein.
- Verwenden Sie ein Gleichheitszeichen (
=
), um jeden Schlüssel vom Wert zu trennen. - Verwenden Sie ein Semikolon (
;
) oder einen Zeilenumbruch, um die Schlüsselwertpaare zu trennen. - Schlüssel, die Leerzeichen enthalten, müssen in Anführungszeichen eingeschlossen werden. Werte müssen gültige PowerShell-Ausdrücke sein. Zeichenfolgen müssen in Anführungszeichen angezeigt werden, auch wenn sie keine Leerzeichen enthalten.
- Um die Hashtabelle zu verwalten, speichern Sie sie in einer Variablen.
- Wenn Sie einer Variablen eine geordnete Hashtable zuweisen, platzieren Sie den
[ordered]
Typ vor dem@
-Symbol. Wenn Sie ihn vor dem Variablennamen platzieren, schlägt der Befehl fehl.
Sie können sortierte Wörterbücher auf die gleiche Weise wie Hashtables verwenden. Jeder Typ kann als Wert von Parametern verwendet werden, die Objekte vom Typ Hashtabelle oder Wörterbuch (iDictionary) verwenden.
Erstellen von Hashtables und sortierten Wörterbüchern
Betrachten Sie die folgenden Hashtable- und geordneten Wörterbuchbeispiele:
$hash = @{
1 = 'one'
2 = 'two'
'three' = 3
}
$hash
Name Value
---- -----
three 3
2 two
1 one
Wie Sie sehen können, werden die Schlüsselwertpaare in einer Hashtabelle nicht in der Reihenfolge angezeigt, in der sie definiert wurden.
Die einfachste Möglichkeit zum Erstellen eines sortierten Wörterbuchs besteht darin, das [ordered]
Attribut zu verwenden. Platzieren Sie das Attribut unmittelbar vor dem @
Symbol.
$dictionary = [ordered]@{
1 = 'one'
2 = 'two'
'three' = 3
}
$dictionary
Name Value
---- -----
1 one
2 two
three 3
Im Gegensatz zu Hashtables behalten sortierte Wörterbücher die Reihenfolge des Schlüsselwerts bei.
Konvertieren von Hashtables und sortierten Wörterbüchern
Zum Konvertieren oder Umwandeln einer Hashtabelle können Sie den Typbeschleuniger [ordered]
nicht verwenden.
Wenn Sie das sortierte Attribut vor dem Variablennamen platzieren, schlägt der Befehl mit der folgenden Fehlermeldung fehl.
[ordered]$orderedhash = @{}
ParserError:
Line |
1 | [ordered]$orderedhash = @{}
| ~~~~~~~~~~~~~~
| The ordered attribute can be specified only on a hash literal node.
Um den Ausdruck zu korrigieren, verschieben Sie das [sortierte] Attribut.
$orderedhash = [ordered]@{}
Sie können ein sortiertes Wörterbuch in eine Hashtabelle umwandeln, aber Sie können die Reihenfolge der Mitglieder nicht garantieren.
[hashtable]$newhash = [ordered]@{
Number = 1
Shape = "Square"
Color = "Blue"
}
$newhash
Name Value
---- -----
Color Blue
Shape Square
Number 1
Hashtable und Wörterbucheigenschaften
Hashtables und sortierte Wörterbücher verwenden mehrere Eigenschaften. Berücksichtigen Sie die $hash
in den vorherigen Beispielen definierten Variablen $dictionary
.
$hash | Get-Member -MemberType Properties, ParameterizedProperty
TypeName: System.Collections.Hashtable
Name MemberType Definition
---- ---------- ----------
Item ParameterizedProperty System.Object Item(System.Object key) {get;set;}
Count Property int Count {get;}
IsFixedSize Property bool IsFixedSize {get;}
IsReadOnly Property bool IsReadOnly {get;}
IsSynchronized Property bool IsSynchronized {get;}
Keys Property System.Collections.ICollection Keys {get;}
SyncRoot Property System.Object SyncRoot {get;}
Values Property System.Collections.ICollection Values {get;}
$dictionary | Get-Member -MemberType Properties, ParameterizedProperty
TypeName: System.Collections.Specialized.OrderedDictionary
Name MemberType Definition
---- ---------- ----------
Item ParameterizedProperty System.Object Item(int index) {get;set;},
System.Object Item(System.Object key) {get;set;}
Count Property int Count {get;}
IsFixedSize Property bool IsFixedSize {get;}
IsReadOnly Property bool IsReadOnly {get;}
IsSynchronized Property bool IsSynchronized {get;}
Keys Property System.Collections.ICollection Keys {get;}
SyncRoot Property System.Object SyncRoot {get;}
Values Property System.Collections.ICollection Values {get;}
Die am häufigsten verwendeten Eigenschaften sind Count, Keys, Values und Item.
Die Count-Eigenschaft , die die Anzahl der Schlüsselwertpaare im Objekt angibt.
Die Keys-Eigenschaft ist eine Auflistung der Schlüsselnamen in der Hashtable oder im Wörterbuch.
PS> $hash.Keys three 2 1 PS> $dictionary.Keys 1 2 three
Die Values-Eigenschaft ist eine Auflistung der Werte in der Hashtabelle oder im Wörterbuch.
PS> $hash.Values 3 two one PS> $dictionary.Values one two 3
Die Item-Eigenschaft ist eine parametrisierte Eigenschaft, die den Wert des von Ihnen angegebenen Elements zurückgibt. Hashtables verwenden den Schlüssel als Parameter für die parametrisierte Eigenschaft, während Wörterbücher standardmäßig den Index verwenden. Dieser Unterschied wirkt sich darauf aus, wie Sie auf die Werte für jeden Typ zugreifen.
Zugreifen auf Werte
Es gibt zwei gängige Methoden für den Zugriff auf die Werte in einer Hashtabelle oder eines Wörterbuchs: Membernotation oder Arrayindexnotation.
Membernotation – Auf Werte kann mithilfe des Schlüsselnamens als Membereigenschaft des Objekts zugegriffen werden. Zum Beispiel:
PS> $hash.1 one PS> $dictionary.2 two
Arrayindexnotation – Auf Werte kann mithilfe der Indexnotation zugegriffen werden. PowerShell konvertiert diese Schreibweise in einen Aufruf der parametrisierten Item-Eigenschaft des Objekts.
Wenn Sie die Indexnotation mit Hashtables verwenden, ist der Wert innerhalb der eckigen Klammern der Schlüsselname. Wenn der Schlüssel ein Zeichenfolgenwert ist, schließen Sie den Schlüsselnamen in Anführungszeichen ein. Zum Beispiel:
PS> $hash['three'] 3 PS> $hash[2] two
In diesem Beispiel ist der Schlüsselwert
2
kein Index in der Auflistung von Werten. Es ist der Wert des Schlüssels im Schlüssel-Wert-Paar. Sie können dies nachweisen, indem Sie die Wertesammlung indizieren.PS> ([array]$hash.Values)[2] one
Wenn Sie die Indexnotation mit Wörterbüchern verwenden, wird der Wert innerhalb der Klammern basierend auf seinem Typ interpretiert. Wenn der Wert eine ganze Zahl ist, wird er als Index in der Auflistung von Werten behandelt. Wenn der Wert keine ganze Zahl ist, wird er als Schlüsselname behandelt. Zum Beispiel:
PS> $dictionary[1] two PS> ([array]$dictionary.Values)[1] two PS> $dictionary[[object]1] one PS> $dictionary['three'] 3
In diesem Beispiel ist der Arraywert
[1]
ein Index in der Auflistung von Werten mithilfe derItem(int index)
parametrisierten Eigenschaftsüberladung. Der Arraywert[[object]1]
ist kein Index, sondern ein Schlüsselwert, der dieItem(System.Object key)
Überladung verwendet.Hinweis
Dieses Verhalten kann verwirrend sein, wenn der Schlüsselwert eine ganze Zahl ist. Wenn möglich, sollten Sie die Verwendung ganzzahliger Schlüsselwerte in Wörterbüchern vermeiden.
Behandeln von Eigenschaftennamenskonflikten
Wenn der Schlüsselname mit einem der Eigenschaftennamen des HashTable- Typs kollidiert, können Sie den psbasesysteminternen Member verwenden, um auf diese Eigenschaften zuzugreifen. Wenn der Schlüsselname beispielsweise keys
ist und Sie die Sammlung der HashTable--Schlüssel zurückgeben möchten, verwenden Sie die folgende Syntax:
$hashtable.psbase.Keys
Diese Anforderung gilt für andere Typen, die die System.Collections.IDictionary Schnittstelle implementieren, z OrderedDictionary. B. .
Durchlaufen von Schlüsseln und Werten
Sie können die Schlüssel in einer Hashtabelle iterieren, um die Werte auf verschiedene Weise zu verarbeiten. Jedes der Beispiele in diesem Abschnitt hat eine identische Ausgabe. Sie durchlaufen die $hash
hier definierte Variable:
$hash = [ordered]@{Number = 1; Shape = "Square"; Color = "Blue"}
Hinweis
In diesen Beispielen wird als sortiertes Wörterbuch definiert, um sicherzustellen, $hash
dass die Ausgabe immer in derselben Reihenfolge ist. Diese Beispiele funktionieren für Standardhashtables identisch, aber die Reihenfolge der Ausgabe ist nicht vorhersehbar.
Jedes Beispiel gibt eine Nachricht für jeden Schlüssel und dessen Wert zurück:
The value of 'Number' is: 1
The value of 'Shape' is: Square
The value of 'Color' is: Blue
In diesem Beispiel wird ein foreach
Block verwendet, um die Tasten zu durchlaufen.
foreach ($Key in $hash.Keys) {
"The value of '$Key' is: $($hash[$Key])"
}
In diesem Beispiel werden ForEach-Object
die Tasten durchlaufen.
$hash.Keys | ForEach-Object {
"The value of '$_' is: $($hash[$_])"
}
In diesem Beispiel wird die GetEnumerator()
Methode verwendet, um jedes Schlüssel-Wert-Paar über die Pipeline zu ForEach-Object
senden.
$hash.GetEnumerator() | ForEach-Object {
"The value of '$($_.Key)' is: $($_.Value)"
}
In diesem Beispiel werden die GetEnumerator()
einzelnen Schlüsselwertpaare und ForEach()
Methoden durchlaufen.
$hash.GetEnumerator().ForEach({"The value of '$($_.Key)' is: $($_.Value)"})
Hinzufügen und Entfernen von Schlüsseln und Werten
Wenn Sie in der Regel eine Hashtabelle erstellen, fügen Sie die Schlüsselwertpaare in die Definition ein. Sie können jedoch jederzeit Schlüssel-Wert-Paare aus einer Hashtable hinzufügen und entfernen. Im folgenden Beispiel wird eine leere Hashtabelle erstellt.
$hash = @{}
Sie können Schlüsselwertpaare mithilfe der Arraynotation hinzufügen. Im folgenden Beispiel wird beispielsweise der Hashtabelle ein Time
-Schlüssel mit dem Wert Now
hinzugefügt.
$hash["Time"] = "Now"
Sie können einer Hashtable auch Schlüssel und Werte hinzufügen, indem Sie die Add()
Methode des System.Collections.Hashtable Objekts verwenden. Die Add()
Methode weist die folgende Syntax auf:
Add(Key, Value)
Wenn Sie beispielsweise einen Time
Schlüssel mit dem Wert Now
zur Hashtabelle hinzufügen möchten, verwenden Sie das folgende Anweisungsformat.
$hash.Add("Time", "Now")
Außerdem können Sie einer Hashtable Schlüssel und Werte hinzufügen, indem Sie den Zusatzoperator (+
) verwenden, um einer vorhandenen Hashtable eine Hashtable hinzuzufügen. Mit der folgenden Anweisung wird beispielsweise ein Time
Schlüssel mit einem Wert von Now
der Hashtable in der Variable $hash
hinzugefügt.
$hash = $hash + @{Time="Now"}
Sie können auch Werte hinzufügen, die in Variablen gespeichert sind.
$t = "Today"
$now = (Get-Date)
$hash.Add($t, $now)
Sie können keinen Subtraktionsoperator verwenden, um ein Schlüsselwertpaar aus einer Hashtabelle zu entfernen, aber Sie können die Remove()
Methode des Hashtable-Objekts verwenden. Die Remove
Methode weist die folgende Syntax auf:
$object.Remove(<key>)
Im folgenden Beispiel wird das Time
Schlüssel-Wert-Paar aus $hash
.
$hash.Remove("Time")
Objekttypen in HashTables
Die Schlüssel und Werte in einer Hashtabelle können einen beliebigen .NET-Objekttyp aufweisen, und eine einzelne Hashtabelle kann Schlüssel und Werte mehrerer Typen aufweisen.
Die folgende Anweisung erstellt eine Hashtabelle mit Prozessnamenzeichenfolgen und Prozessobjektwerten und speichert sie in der $p
Variablen.
$p = @{
"PowerShell" = (Get-Process PowerShell)
"Notepad" = (Get-Process notepad)
}
Sie können die Hashtabelle in $p
anzeigen und die Schlüsselnameneigenschaften verwenden, um die Werte anzuzeigen.
PS> $p
Name Value
---- -----
PowerShell System.Diagnostics.Process (PowerShell)
Notepad System.Diagnostics.Process (notepad)
PS> $p.PowerShell
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
441 24 54196 54012 571 5.10 1788 PowerShell
PS> $p.Keys | ForEach-Object {$p.$_.Handles}
441
251
Die Schlüssel in einer Hashtabelle können einen beliebigen .NET-Typ sein. Die folgende Anweisung fügt der Hashtable in der variablen $p
ein Schlüssel-Wert-Paar hinzu. Der Schlüssel ist ein Service -Objekt, das den WinRM-Dienst darstellt, und der Wert ist der aktuelle Status des Diensts.
$p = $p + @{
(Get-Service WinRM) = ((Get-Service WinRM).Status)
}
Sie können das neue Schlüssel-Wert-Paar mit den gleichen Methoden anzeigen und darauf zugreifen, die Sie für andere Paare in der Hashtabelle verwenden.
PS> $p
Name Value
---- -----
PowerShell System.Diagnostics.Process (PowerShell)
Notepad System.Diagnostics.Process (notepad)
System.ServiceProcess.Servi... Running
PS> $p.Keys
PowerShell
Notepad
Status Name DisplayName
------ ---- -----------
Running winrm Windows Remote Management (WS-Manag...
PS> $p.Keys | ForEach-Object {$_.Name}
WinRM
Die Schlüssel und Werte in einer Hashtabelle können auch Hashtable Objekte sein. Die folgende Anweisung fügt der Hashtable in der $p
-Variablen einen Schlüssel-Wert-Paar hinzu, wobei der Schlüssel eine Zeichenfolge ist, Hash2, und der Wert eine Hashtabelle mit drei Schlüssel-Wert-Paaren.
$p = $p + @{
"Hash2"= @{a=1; b=2; c=3}
}
Sie können die neuen Werte mit den gleichen Methoden anzeigen und auf sie zugreifen.
PS> $p
Name Value
---- -----
PowerShell System.Diagnostics.Process (pwsh)
Hash2 {[a, 1], [b, 2], [c, 3]}
Notepad System.Diagnostics.Process (Notepad)
WinRM Running
PS> $p.Hash2
Name Value
---- -----
a 1
b 2
c 3
PS> $p.Hash2.b
2
Sortieren von Schlüsseln und Werten
Die Elemente in einer Hashtabelle sind systemintern ungeordnet. Die Schlüsselwertpaare können bei jeder Anzeige in einer anderen Reihenfolge angezeigt werden.
Obwohl Sie eine Hashtabelle nicht sortieren können, können Sie die GetEnumerator()
-Methode von Hashtables verwenden, um die Schlüssel und Werte aufzulisten, und verwenden Sie dann das Cmdlet Sort-Object
, um die aufgezählten Werte für die Anzeige zu sortieren.
Mit den folgenden Befehlen werden beispielsweise die Schlüssel und Werte in der Hashtabelle in der $p
Variablen aufgelistet und dann die Tasten in alphabetischer Reihenfolge sortiert.
PS> $p.GetEnumerator() | Sort-Object -Property key
Name Value
---- -----
Hash2 {[a, 1], [b, 2], [c, 3]}
Notepad System.Diagnostics.Process (Notepad)
PowerShell System.Diagnostics.Process (pwsh)
WinRM Running
Der folgende Befehl verwendet dieselbe Prozedur, um die Hashwerte in absteigender Reihenfolge zu sortieren.
PS> $p.GetEnumerator() | Sort-Object -Property Value -Descending
Name Value
---- -----
PowerShell System.Diagnostics.Process (pwsh)
Notepad System.Diagnostics.Process (Notepad)
Hash2 {[a, 1], [b, 2], [c, 3]}
WinRM Running
Erstellen von Objekten aus Hashtables
Ab PowerShell 3.0 können Sie ein Objekt aus einer Hashtabelle von Eigenschaften und Eigenschaftswerten erstellen.
Die Syntax lautet wie folgt:
[<class-name>]@{
<property-name>=<property-value>
<property-name>=<property-value>
}
Diese Methode funktioniert nur für Klassen mit einem Konstruktor ohne Parameter. Die Objekteigenschaften müssen öffentlich und festgelegt sein.
Weitere Informationen finden Sie unter about_Object_Creation.
ConvertFrom-StringData
Das cmdlet ConvertFrom-StringData
konvertiert eine Zeichenfolge oder eine here-Zeichenfolge von Schlüsselwertpaaren in eine Hashtabelle. Sie können das ConvertFrom-StringData
Cmdlet sicher im Abschnitt "Daten" eines Skripts verwenden, und Sie können es mit dem Import-LocalizedData
Cmdlet verwenden, um Benutzermeldungen in der Benutzeroberflächenkultur des aktuellen Benutzers anzuzeigen.
Here-Strings sind besonders hilfreich, wenn die Werte in der Hashtabelle Anführungszeichen enthalten. Weitere Informationen zu den hier aufgeführten Zeichenfolgen finden Sie unter about_Quoting_Rules.
Das folgende Beispiel zeigt, wie Sie eine hier-Zeichenfolge der Benutzernachrichten im vorherigen Beispiel erstellen und wie Sie ConvertFrom-StringData
verwenden, um sie aus einer Zeichenfolge in eine Hashtabelle zu konvertieren.
Der folgende Befehl erstellt eine here-Zeichenfolge der Schlüsselwertpaare und speichert sie dann in der $string
Variablen.
$string = @"
Msg1 = Type "Windows".
Msg2 = She said, "Hello, World."
Msg3 = Enter an alias (or "nickname").
"@
Mit diesem Befehl wird das Cmdlet ConvertFrom-StringData
verwendet, um die here-Zeichenfolge in eine Hashtabelle zu konvertieren.
ConvertFrom-StringData $string
Name Value
---- -----
Msg3 Enter an alias (or "nickname").
Msg2 She said, "Hello, World."
Msg1 Type "Windows".
Weitere Informationen zu den hier aufgeführten Zeichenfolgen finden Sie unter about_Quoting_Rules.