about_Hash_Tables
Descrizione breve
Descrive come creare, usare e ordinare tabelle hash in PowerShell.
Descrizione lunga
Un hashtableoggetto , noto anche come dizionario o matrice associativa, è una struttura di dati compatta che archivia una o più coppie chiave-valore. Ad esempio, una tabella hash può contenere una serie di indirizzi IP e nomi di computer, in cui gli indirizzi IP sono le chiavi e i nomi dei computer sono i valori o viceversa.
In PowerShell ogni hashtable oggetto è un [System.Collections.Hashtable]
oggetto . È possibile usare le proprietà e i metodi degli Hashtable oggetti in PowerShell.
A partire da PowerShell 3.0, è possibile usare l'acceleratore [ordered]
di tipi per creare un [System.Collections.Specialized.OrderedDictionary]
oggetto in PowerShell.
I dizionari ordinati differiscono dalle tabelle hash in quanto le chiavi vengono sempre visualizzate nell'ordine in cui vengono elencate. L'ordine delle chiavi in un hashtable non è deterministico.
Le chiavi e il valore nelle tabelle hash sono anche oggetti .NET. Sono più spesso stringhe o numeri interi, ma possono avere qualsiasi tipo di oggetto. È anche possibile creare tabelle hash annidate, in cui il valore di una chiave è un altro hashtable.
Le tabelle hash vengono spesso usate perché sono efficienti per la ricerca e il recupero dei dati. È possibile usare tabelle hash per archiviare elenchi e per creare proprietà calcolate in PowerShell. ConvertFrom-StringData
Il cmdlet converte i dati di stringa strutturati in un oggetto hashtable.
Sintassi
La sintassi di un hashtable è la seguente:
@{ <name> = <value>; [<name> = <value> ] ...}
La sintassi di un dizionario ordinato è la seguente:
[ordered]@{ <name> = <value>; [<name> = <value> ] ...}
L'acceleratore [ordered]
di tipi è stato introdotto in PowerShell 3.0.
Per creare un hashtableoggetto , seguire queste linee guida:
- hashtable Iniziare con un segno
@
(). - Racchiudere tra hashtable parentesi graffe (
{}
). - Immettere una o più coppie chiave-valore per il contenuto di hashtable.
- Usare un segno di uguale (
=
) per separare ogni chiave dal relativo valore. - Usare un punto e virgola (
;
) o un'interruzione di riga per separare le coppie chiave-valore. - Le chiavi contenenti spazi devono essere racchiuse tra virgolette. I valori devono essere espressioni di PowerShell valide. Le stringhe devono essere visualizzate tra virgolette, anche se non includono spazi.
- Per gestire , hashtablesalvarlo in una variabile.
- Quando si assegna un oggetto ordinato hashtable a una variabile, posizionare il
[ordered]
tipo prima del@
simbolo. Se la si posiziona prima del nome della variabile, il comando ha esito negativo.
È possibile usare dizionari ordinati nello stesso modo in cui si usano tabelle hash. Entrambi i tipi possono essere usati come valore di parametri che accettano oggetti hashtable di tipo o dizionario (iDictionary).
Creazione di tabelle hash e dizionari ordinati
Si considerino gli esempi di dizionario ordinati e seguenti hashtable :
$hash = @{
1 = 'one'
2 = 'two'
'three' = 3
}
$hash
Name Value
---- -----
three 3
2 two
1 one
Come si può notare, le coppie chiave-valore in un hashtable non vengono presentate nell'ordine in cui sono state definite.
Il modo più semplice per creare un dizionario ordinato consiste nell'usare l'attributo [ordered]
. Posizionare l'attributo immediatamente prima del @
simbolo.
$dictionary = [ordered]@{
1 = 'one'
2 = 'two'
'three' = 3
}
$dictionary
Name Value
---- -----
1 one
2 two
three 3
A differenza delle tabelle hash, i dizionari ordinati mantengono l'ordine del valore della chiave.
Conversione di tabelle hash e dizionari ordinati
Non è possibile usare l'acceleratore [ordered]
di tipo per convertire o eseguire il cast di un oggetto hashtable.
Se si inserisce l'attributo ordinato prima del nome della variabile, il comando non riesce con il messaggio di errore seguente.
[ordered]$orderedhash = @{}
ParserError:
Line |
1 | [ordered]$orderedhash = @{}
| ~~~~~~~~~~~~~~
| The ordered attribute can be specified only on a hash literal node.
Per correggere l'espressione, spostare l'attributo [ordered].
$orderedhash = [ordered]@{}
È possibile eseguire il cast di un dizionario ordinato in un hashtableoggetto , ma non è possibile garantire l'ordine dei membri.
[hashtable]$newhash = [ordered]@{
Number = 1
Shape = "Square"
Color = "Blue"
}
$newhash
Name Value
---- -----
Color Blue
Shape Square
Number 1
Hashtable Proprietà del dizionario e
Le tabelle hash e i dizionari ordinati condividono diverse proprietà. Si considerino le $hash
variabili e $dictionary
definite negli esempi precedenti.
$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;}
Le proprietà più usate sono Count, Keys, Values e Item.
Proprietà Count che indica il numero di coppie chiave-valore nell'oggetto .
La proprietà Keys è una raccolta di nomi di chiave nel hashtable dizionario o .
PS> $hash.Keys three 2 1 PS> $dictionary.Keys 1 2 three
La proprietà Values è una raccolta di valori nel hashtable dizionario o .
PS> $hash.Values 3 two one PS> $dictionary.Values one two 3
La proprietà Item è una proprietà con parametri che restituisce il valore dell'elemento specificato. Le tabelle hash usano la chiave come parametro per la proprietà con parametri, mentre i dizionari usano l'indice per impostazione predefinita. Questa differenza influisce sul modo in cui si accede ai valori per ogni tipo.
Accesso ai valori
Esistono due modi comuni per accedere ai valori in un hashtable dizionario o: notazione dei membri o notazione dell'indice di matrice.
Notazione membro: è possibile accedere ai valori usando il nome della chiave come proprietà membro dell'oggetto. Ad esempio:
PS> $hash.1 one PS> $dictionary.2 two
Notazione dell'indice di matrice: è possibile accedere ai valori usando la notazione dell'indice. PowerShell converte tale notazione in una chiamata alla proprietà con parametri Item dell'oggetto .
Quando si usa la notazione dell'indice con tabelle hash, il valore all'interno delle parentesi quadre è il nome della chiave. Se la chiave è un valore stringa, racchiudere il nome della chiave tra virgolette. Ad esempio:
PS> $hash['three'] 3 PS> $hash[2] 2
In questo esempio, il valore
2
della chiave non è un indice nella raccolta di valori. È il valore della chiave nella coppia chiave-valore. È possibile dimostrare questa situazione tramite l'indicizzazione nella raccolta di valori.PS> ([array]$hash.Values)[2] one
Quando si usa la notazione di indice con dizionari, il valore all'interno delle parentesi quadre viene interpretato in base al tipo. Se il valore è un numero intero, viene considerato come un indice nella raccolta di valori. Se il valore non è un numero intero, viene considerato come il nome della chiave. Ad esempio:
PS> $dictionary[1] two PS> ([array]$dictionary.Values)[1] two PS> $dictionary[[object]1] one PS> $dictionary['three'] 3
In questo esempio, il valore
[1]
della matrice è un indice nell'insieme di valori usando l'overload dellaItem(int index)
proprietà con parametri. Il valore[[object]1]
della matrice non è un indice, ma un valore chiave usando l'overloadItem(System.Object key)
.Nota
Questo comportamento può generare confusione quando il valore della chiave è un numero intero. Quando possibile, è consigliabile evitare di usare i valori di chiave integer nei dizionari.
Gestione dei conflitti di nomi di proprietà
Se il nome della chiave si scontra con uno dei nomi di proprietà del HashTable tipo, è possibile usare il membro intrinseco psbase per accedere a tali proprietà. Ad esempio, se il nome della chiave è keys
e si vuole restituire la raccolta delle HashTable chiavi, usare questa sintassi:
$hashtable.psbase.Keys
Questo requisito si applica ad altri tipi che implementano l'interfaccia System.Collections.IDictionary , ad esempio OrderedDictionary.
Iterazione su chiavi e valori
È possibile scorrere le chiavi in un hashtable per elaborare i valori in diversi modi. Ognuno degli esempi di questa sezione ha un output identico. Esegue l'iterazione sulla $hash
variabile definita qui:
$hash = [ordered]@{ Number = 1; Shape = "Square"; Color = "Blue"}
Nota
In questi esempi viene $hash
definito come dizionario ordinato per garantire che l'output sia sempre nello stesso ordine. Questi esempi funzionano allo stesso modo per le tabelle hash standard, ma l'ordine dell'output non è prevedibile.
Ogni esempio restituisce un messaggio per ogni chiave e il relativo valore:
The value of 'Number' is: 1
The value of 'Shape' is: Square
The value of 'Color' is: Blue
In questo esempio viene usato un foreach
blocco per scorrere le chiavi.
foreach ($Key in $hash.Keys) {
"The value of '$Key' is: $($hash[$Key])"
}
Questo esempio usa ForEach-Object
per scorrere le chiavi.
$hash.Keys | ForEach-Object {
"The value of '$_' is: $($hash[$_])"
}
In questo esempio viene usato il GetEnumerator()
metodo per inviare ogni coppia chiave-valore tramite la pipeline a ForEach-Object
.
$hash.GetEnumerator() | ForEach-Object {
"The value of '$($_.Key)' is: $($_.Value)"
}
In questo esempio vengono usati i GetEnumerator()
metodi e ForEach()
per scorrere ogni coppia chiave-valore.
$hash.GetEnumerator().ForEach({"The value of '$($_.Key)' is: $($_.Value)"})
Aggiunta e rimozione di chiavi e valori
In genere, quando si crea un oggetto hashtable si includono le coppie chiave-valore nella definizione. Tuttavia, è possibile aggiungere e rimuovere coppie chiave-valore da un oggetto hashtable in qualsiasi momento. Nell'esempio seguente viene creato un oggetto vuoto hashtable.
$hash = @{}
È possibile aggiungere coppie chiave-valore usando la notazione della matrice. Nell'esempio seguente, ad esempio, viene aggiunta una Time
chiave con un valore di Now
a hashtable.
$hash["Time"] = "Now"
È anche possibile aggiungere chiavi e valori a un hashtable utilizzando il Add()
metodo dell'oggetto System.Collections.Hashtable . Il Add()
metodo ha la sintassi seguente:
Add(Key, Value)
Ad esempio, per aggiungere una Time
chiave con un valore di Now
a hashtable, usare il formato di istruzione seguente.
$hash.Add("Time", "Now")
È inoltre possibile aggiungere chiavi e valori a un hashtable oggetto usando l'operatore di addizione (+
) per aggiungere un hashtable oggetto a un oggetto esistente hashtable. Ad esempio, l'istruzione seguente aggiunge una Time
chiave con un valore di Now
a hashtable nella $hash
variabile .
$hash = $hash + @{Time="Now"}
È anche possibile aggiungere valori archiviati nelle variabili.
$t = "Today"
$now = (Get-Date)
$hash.Add($t, $now)
Non è possibile usare un operatore di sottrazione per rimuovere una coppia chiave-valore da una tabella hash, ma è possibile usare il Remove()
metodo dell'oggetto hashtable . Il Remove
metodo ha la sintassi seguente:
$object.Remove(<key>)
Nell'esempio seguente viene rimossa la Time
coppia chiave-valore da $hash
.
$hash.Remove("Time")
Tipi di oggetto nelle tabelle HashTable
Le chiavi e i valori in un hashtable possono avere qualsiasi tipo di oggetto .NET e un singolo hashtable può avere chiavi e valori di più tipi.
L'istruzione seguente crea una hashtable delle stringhe del nome del processo e elabora i valori dell'oggetto $p
e la salva nella variabile .
$p = @{
"PowerShell" = (Get-Process PowerShell)
"Notepad" = (Get-Process notepad)
}
È possibile visualizzare in hashtable $p
e usare le proprietà key-name per visualizzare i valori.
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
Le chiavi in un hashtable possono essere di qualsiasi tipo .NET. L'istruzione seguente aggiunge una coppia chiave-valore a hashtable nella $p
variabile . La chiave è un oggetto Service che rappresenta il servizio WinRM e il valore è lo stato corrente del servizio.
$p = $p + @{
(Get-Service WinRM) = ((Get-Service WinRM).Status)
}
È possibile visualizzare e accedere alla nuova coppia chiave-valore usando gli stessi metodi usati per altre coppie in hashtable.
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
Le chiavi e i valori in un hashtable possono anche essere Hashtable oggetti . L'istruzione seguente aggiunge una coppia chiave-valore alla hashtable nella $p
variabile in cui la chiave è una stringa, Hash2 e il valore è un hashtable oggetto con tre coppie chiave-valore.
$p = $p + @{
"Hash2"= @{a=1; b=2; c=3}
}
È possibile visualizzare e accedere ai nuovi valori usando gli stessi metodi.
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
Ordinamento di chiavi e valori
Gli elementi in un hashtable oggetto sono intrinsecamente non ordinati. Le coppie chiave-valore potrebbero essere visualizzate in un ordine diverso ogni volta che vengono visualizzate.
Sebbene non sia possibile ordinare un hashtableoggetto , è possibile usare il GetEnumerator()
metodo delle tabelle hash per enumerare le chiavi e i valori e quindi usare il Sort-Object
cmdlet per ordinare i valori enumerati per la visualizzazione.
Ad esempio, i comandi seguenti enumerare le chiavi e i valori nella tabella hash nella $p
variabile e quindi ordinare le chiavi in ordine alfabetico.
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
Il comando seguente usa la stessa procedura per ordinare i valori hash in ordine decrescente.
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
Creazione di oggetti da tabelle hash
A partire da PowerShell 3.0, è possibile creare un oggetto da un hashtable oggetto di proprietà e valori di proprietà.
La sintassi è la seguente:
[<class-name>]@{
<property-name>=<property-value>
<property-name>=<property-value>
}
Questo metodo funziona solo per le classi con un costruttore senza parametri. Le proprietà dell'oggetto devono essere pubbliche e impostabili.
Per altre informazioni, vedere about_Object_Creation.
ConvertFrom-StringData
Il ConvertFrom-StringData
cmdlet converte una stringa o una stringa here-value di coppie chiave-valore in un oggetto hashtable. È possibile usare il ConvertFrom-StringData
cmdlet in modo sicuro nella sezione Dati di uno script ed è possibile usarlo con il Import-LocalizedData
cmdlet per visualizzare i messaggi utente nelle impostazioni cultura dell'interfaccia utente dell'utente corrente.
Le stringhe qui sono particolarmente utili quando i valori nelle hashtable virgolette di inclusione. Per altre informazioni sulle stringhe qui, vedere about_Quoting_Rules.
Nell'esempio seguente viene illustrato come creare una stringa here dei messaggi utente nell'esempio precedente e come usarli ConvertFrom-StringData
da una stringa in un oggetto hashtable.
Il comando seguente crea una stringa here delle coppie chiave-valore e quindi la salva nella $string
variabile .
$string = @"
Msg1 = Type "Windows".
Msg2 = She said, "Hello, World."
Msg3 = Enter an alias (or "nickname").
"@
Questo comando usa il ConvertFrom-StringData
cmdlet per convertire la stringa here in un oggetto hashtable.
ConvertFrom-StringData $string
Name Value
---- -----
Msg3 Enter an alias (or "nickname").
Msg2 She said, "Hello, World."
Msg1 Type "Windows".
Per altre informazioni sulle stringhe qui, vedere about_Quoting_Rules.