Tutto quello che volevi sapere su PSCustomObject

author
7 minutes, 35 seconds Read
  • 10/05/2020
  • 8 minuti per leggere
    • j
    • m
    • s
    • j
    • c

PSCustomObjectsono un ottimo strumento da aggiungere alla tua cintura di strumenti PowerShell. Iniziamo con le basi e ci facciamo strada verso le funzioni più avanzate. L’idea dietro l’uso di un PSCustomObject è di avere un modo semplice per creare dati strutturati. Dai un’occhiata al primo esempio e avrai un’idea più chiara di cosa significa.

Note

La versione originale di questo articolo è apparsa sul blog scritto da @KevinMarquette. Il team di PowerShell ringrazia Kevin per aver condiviso questo contenuto con noi. Controlla il suo blog su PowerShellExplained.com.

Creazione di un PSCustomObject

Adoro usare in PowerShell. Per questo motivo, salterò tutti gli altri modi in cui potete creare un oggetto, ma devo menzionare che la maggior parte di questi esempi sono PowerShell v3.0 e più recenti.

$myObject = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}

Questo metodo funziona bene per me perché uso hashtables per quasi tutto. Ma ci sono momenti in cui vorrei che PowerShell trattasse gli hashtables più come un oggetto. Il primo posto in cui si nota la differenza è quando si vuole usare Format-Table o Export-CSV e ci si rende conto che una hashtable è solo una collezione di coppie chiave/valore.

Si può quindi accedere e usare i valori come si farebbe con un oggetto normale.

$myObject.Name

Convertire una hashtable

Mentre sono sull’argomento, sapevate che potete fare questo:

$myHashtable = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}$myObject = $myHashtable

Preferisco creare l’oggetto dall’inizio ma ci sono volte in cui dovete lavorare prima con ahashtable. Questo esempio funziona perché il costruttore prende una hashtable per le proprietà dell’oggetto. Una nota importante è che mentre questo metodo funziona, non è un equivalente esatto. La più grande differenza è che l’ordine delle proprietà non è conservato.

Approccio legacy

Potreste aver visto persone usare New-Objectper creare oggetti personalizzati.

$myHashtable = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}$myObject = New-Object -TypeName PSObject -Property $myHashtable

Questo modo è un po’ più lento, ma può essere la vostra migliore opzione nelle prime versioni di PowerShell.

Salvare in un file

Ho trovato il modo migliore per salvare una hashtable in un file è salvarla come JSON. Puoi importarla di nuovo in un

$myObject | ConvertTo-Json -depth 1 | Set-Content -Path $Path$myObject = Get-Content -Path $Path | ConvertFrom-Json

Copro altri modi per salvare oggetti in un file nel mio articolo su I molti modi di leggere e scrivere su file.

Lavorare con le proprietà

Aggiungere proprietà

Puoi ancora aggiungere nuove proprietà al tuo PSCustomObject con Add-Member.

$myObject | Add-Member -MemberType NoteProperty -Name 'ID' -Value 'KevinMarquette'$myObject.ID

Rimuovere proprietà

Puoi anche rimuovere proprietà da un oggetto.

$myObject.psobject.properties.remove('ID')

Il psobject è una proprietà nascosta che vi dà accesso ai metadati dell’oggetto base.

Enumerare i nomi delle proprietà

A volte avete bisogno di una lista di tutti i nomi delle proprietà di un oggetto.

$myObject | Get-Member -MemberType NoteProperty | Select -ExpandProperty Name

Possiamo ottenere questa stessa lista anche dalla proprietà psobject.

$myobject.psobject.properties.name

Accedere dinamicamente alle proprietà

Ho già detto che si può accedere direttamente ai valori delle proprietà.

$myObject.Name

Puoi usare una stringa per il nome della proprietà e funzionerà lo stesso.

$myObject.'Name'

Possiamo fare un altro passo e usare una variabile per il nome della proprietà.

$property = 'Name'$myObject.$property

Lo so che sembra strano, ma funziona.

Convertire PSCustomObject in un hashtable

Per continuare dall’ultima sezione, potete camminare dinamicamente sulle proprietà e creare un hashtable da esse.

$hashtable = @{}foreach( $property in $myobject.psobject.properties.name ){ $hashtable = $myObject.$property}

Testare le proprietà

Se avete bisogno di sapere se una proprietà esiste, potete semplicemente controllare che quella proprietà abbia un valore.

if( $null -ne $myObject.ID )

Ma se il valore potrebbe essere $null potete verificare se esiste controllando ilpsobject.properties per esso.

if( $myobject.psobject.properties.match('ID').Count )

Aggiungimento di metodi di oggetti

Se avete bisogno di aggiungere un metodo di script ad un oggetto, potete farlo con Add-Member e unScriptBlock. Devi usare la variabile automatica this di riferimento all’oggetto corrente. Ecco ascriptblock per trasformare un oggetto in un hashtable. (stesso codice dell’ultimo esempio)

Poi lo aggiungiamo al nostro oggetto come una proprietà dello script.

Poi possiamo chiamare la nostra funzione in questo modo:

$myObject.ToHashtable()

Oggetti vs tipi di valore

Gli oggetti e i tipi di valore non gestiscono le assegnazioni delle variabili allo stesso modo. Se si assegnano tipi di valore l’uno all’altro, solo il valore viene copiato nella nuova variabile.

$first = 1$second = $first$second = 2

In questo caso, $first è 1 e $second è 2.

Le variabili oggetto contengono un riferimento all’oggetto stesso. Quando assegnate un oggetto a una nuova variabile, fanno ancora riferimento allo stesso oggetto.

$third = @{Key=3}$fourth = $third$fourth.Key = 4

Perché $third e $fourth fanno riferimento alla stessa istanza di un oggetto, sia $third.key che$fourth.Key sono 4.

psobject.copy()

Se avete bisogno di una vera copia di un oggetto, potete clonarlo.

$third = @{Key=3}$fourth = $third.psobject.copy()$fourth.Key = 4

Clone crea una copia superficiale dell’oggetto. Ora hanno istanze diverse e $third.key è 3 e $fourth.Key è 4 in questo esempio.

Lo chiamo una copia superficiale perché se avete oggetti annidati. (dove le proprietà contengono altri oggetti). Solo i valori di primo livello vengono copiati. Gli oggetti figli faranno riferimento l’uno all’altro.

PSTypeName per tipi di oggetti personalizzati

Ora che abbiamo un oggetto, ci sono alcune altre cose che possiamo fare con esso che potrebbero non essere così ovvie. La prima cosa che dobbiamo fare è dargli un PSTypeName. Questo è il modo più comune in cui vedo la gente farlo:

$myObject.PSObject.TypeNames.Insert(0,"My.Object")

Ho recentemente scoperto un altro modo per farlo da questo post di /u/markekraus. Ho fatto un littledigging e altri post sull’idea di Adam Bertram e Mike Shepard dove parlano di questo approccio che ti permette di definirlo inline.

$myObject = @{ PSTypeName = 'My.Object' Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}

Mi piace come questo si adatta bene al linguaggio. Ora che abbiamo un oggetto con un typename appropriato, possiamo fare altre cose.

Nota

Puoi anche creare tipi PowerShell personalizzati usando classi PowerShell. Per maggiori informazioni, vediPowerShell Class Overview.

Usare DefaultPropertySet (la strada lunga)

PowerShell decide per noi quali proprietà visualizzare per default. Molti dei comandi nativi hanno un.ps1xml file di formattazione che fa tutto il lavoro pesante. Da questo post di Boe Prox, c’è un altro modo per noi di fare questo sul nostro oggetto personalizzato usando solo PowerShell. Possiamo dargli unMemberSet da usare.

Ora quando il mio oggetto cade solo nella shell, mostrerà solo quelle proprietà per impostazione predefinita.

Update-TypeData con DefaultPropertySet

Questo è bello ma recentemente ho visto un modo migliore guardandoPowerShell unplugged 2016 con Jeffrey Snover & Don Jones. Jeffrey stava usandoUpdate-TypeData per specificare le proprietà predefinite.

$TypeData = @{ TypeName = 'My.Object' DefaultDisplayPropertySet = 'Name','Language'}Update-TypeData @TypeData

Questo è abbastanza semplice che potrei quasi ricordarlo se non avessi questo post come riferimento rapido. Ora posso facilmente creare oggetti con molte proprietà e dargli ancora una bella visione pulita quando li guardo dalla shell. Se ho bisogno di accedere o vedere quelle altre proprietà, sono ancora lì.

$myObject | Format-List *

Update-TypeData con ScriptProperty

Un’altra cosa che ho capito da quel video è la creazione di proprietà di script per i vostri oggetti. Questo sarebbe un buon momento per sottolineare che questo funziona anche per gli oggetti esistenti.

Puoi farlo prima che il tuo oggetto sia creato o dopo e funzionerà ancora. Questo è ciò che rende questo diverso dall’uso di Add-Member con una proprietà di script. Quando usate Add-Member nel modo Ireferito prima, esiste solo su quella specifica istanza dell’oggetto. Questo si applica a tutti gli oggetti con questo TypeName.

Parametri di funzione

Ora potete usare questi tipi personalizzati per i parametri nelle vostre funzioni e script. Potete avere una funzione che crea questi oggetti personalizzati e poi passarli in altre funzioni.

param( $Data )

PowerShell richiede che l’oggetto sia del tipo che avete specificato. Lancia un errore di convalida se il tipo non corrisponde automaticamente per risparmiarvi il passo di testarlo nel vostro codice. Un grande esempio di lasciare che PowerShell faccia ciò che sa fare meglio.

Function OutputType

Puoi anche definire un OutputType per le tue funzioni avanzate.

function Get-MyObject{ param ( ...

Il valore dell’attributo OutputType è solo una nota di documentazione. Non è derivato dal codice della funzione o paragonato all’effettivo output della funzione.

La ragione principale per cui usereste un tipo di output è che le meta informazioni sulla vostra funzione riflettano le vostre intenzioni. Cose come Get-Command e Get-Help che il vostro ambiente di sviluppo può sfruttare. Se volete maggiori informazioni, date un’occhiata all’aiuto per esso:about_Functions_OutputTypeAttribute.

Detto questo, se state usando Pester per testare le vostre funzioni, allora sarebbe una buona idea validare gli oggetti di output che corrispondono al vostro OutputType. Questo potrebbe catturare le variabili che cadono nel tubo quando non dovrebbero.

Pensieri conclusivi

Il contesto di questo era tutto su , ma molte di queste informazioni si applicano agli oggetti in generale.

Ho visto molte di queste caratteristiche di sfuggita prima, ma non le ho mai viste presentate come una raccolta di informazioni su PSCustomObject. Proprio la settimana scorsa mi sono imbattuto in un’altra e sono rimasto sorpreso di non averla vista prima. Ho voluto mettere insieme tutte queste idee in modo che possiate vedere il quadro generale ed esserne consapevoli quando avrete l’opportunità di usarle. Spero che abbiate imparato qualcosa e possiate trovare un modo per lavorare a questo nei vostri script.

Similar Posts

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.