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 della Item(int index) proprietà con parametri. Il valore [[object]1] della matrice non è un indice, ma un valore chiave usando l'overload Item(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)
WinRM                          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 (powershell)
Notepad                        System.Diagnostics.Process (Notepad)
WinRM                          Running
Hash2                          {c, b, a}

PS> $p.Hash2

Name                           Value
----                           -----
c                              3
b                              2
a                              1

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                          {c, b, a}
Notepad                        System.Diagnostics.Process (Notepad)
PowerShell                     System.Diagnostics.Process (powershell)
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 (powershell)
Notepad                        System.Diagnostics.Process (Notepad)
Hash2                          {c, b, a}
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.

Vedi anche