Tot ce ați vrut să știți despre PSCustomObject

author
9 minutes, 19 seconds Read
  • 10/05/2020
  • 8 minute de citit
    • j
    • .

    • m
    • s
    • j
    • c

PSCustomObjectsunt un instrument excelent de adăugat în centura de instrumente PowerShell. Să începem cu elementele de bazăși să ne îndreptăm spre funcțiile mai avansate. Ideea din spatele utilizării unui PSCustomObject este de aavea o modalitate simplă de a crea date structurate. Aruncați o privire la primul exemplu și veți avea o idee mai bună despre ce înseamnă asta.

Note

Versiunea originală a acestui articol a apărut pe blogul scris de @KevinMarquette. EchipaPowerShell îi mulțumește lui Kevin pentru că a împărtășit acest conținut cu noi. Vă rugăm să consultați blogul său laPowerShellExplained.com.

Crearea unui PSCustomObject

Îmi place să folosesc în PowerShell. Crearea unui obiect utilizabil nu a fost niciodată mai ușoară. din acest motiv, voi trece peste toate celelalte moduri în care puteți crea un obiect, dar trebuie să menționez că majoritatea acestor exemple sunt PowerShell v3.0 și mai noi.

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

Această metodă funcționează bine pentru mine, deoarece folosesc hashtables pentru aproape orice. Dar există momente în care aș dori ca PowerShell să trateze hashtables mai mult ca pe un obiect. Primul loc în care observați diferența este atunci când doriți să folosiți Format-Table sau Export-CSV și vă dați seama că ahashtable este doar o colecție de perechi cheie/valoare.

Apoi puteți accesa și folosi valorile așa cum ați face-o cu un obiect normal.

$myObject.Name

Conversia unui hashtable

Dacă tot sunt pe subiect, știați că puteți face acest lucru:

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

Prefer să creez obiectul de la început, dar există momente în care trebuie să lucrați mai întâi cu ahashtable. Acest exemplu funcționează deoarece constructorul ia un hashtable pentru objectproperties. O notă importantă este că, deși această metodă funcționează, nu este un echivalent exact. Cea mai mare diferență este faptul că ordinea proprietăților nu este păstrată.

Abordare de legitate

Poate ați văzut oameni care folosesc New-Object pentru a crea obiecte personalizate.

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

Acest mod este destul de lent, dar poate fi cea mai bună opțiune pe versiunile timpurii ale PowerShell.

Salvare într-un fișier

Constat că cel mai bun mod de a salva un hashtable într-un fișier este să îl salvați ca JSON. Puteți să o importați înapoi îna

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

Copăr mai multe moduri de a salva obiecte într-un fișier în articolul meu despreCele mai multe moduri de a citi și scrie în fișiere.

Lucrul cu proprietățile

Adăugarea de proprietăți

Puteți adăuga în continuare noi proprietăți la PSCustomObject dvs. cu Add-Member.

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

Îndepărtarea proprietăților

Puteți, de asemenea, îndepărta proprietăți de pe un obiect.

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

psobjecteste o proprietate ascunsă care vă oferă acces la metadatele obiectului de bază.

Enumerarea numelor de proprietăți

Câteodată aveți nevoie de o listă a tuturor numelor de proprietăți ale unui obiect.

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

Puteți obține aceeași listă și din proprietateapsobject.

$myobject.psobject.properties.name

Accesarea dinamică a proprietăților

Am menționat deja că puteți accesa direct valorile proprietăților.

$myObject.Name

Puteți folosi un șir de caractere pentru numele proprietății și tot va funcționa.

$myObject.'Name'

Puteți face încă un pas înainte și folosi o variabilă pentru numele proprietății.

$property = 'Name'$myObject.$property

Știu că pare ciudat, dar funcționează.

Convertiți PSCustomObject într-un hashtable

Pentru a continua de la ultima secțiune, puteți parcurge în mod dinamic proprietățile și crea un hashtable din ele.

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

Testarea proprietăților

Dacă aveți nevoie să știți dacă o proprietate există, puteți verifica dacă acea proprietate are o valoare.

if( $null -ne $myObject.ID )

Dar dacă valoarea ar putea fi $null, puteți verifica dacă există, verificândpsobject.properties pentru aceasta.

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

Adaugarea de metode de obiect

Dacă trebuie să adăugați o metodă de script la un obiect, o puteți face cu Add-Member și aScriptBlock. Trebuie să folosiți referința automată a variabilei this la obiectul curent. Iată ascriptblock pentru a transforma un obiect într-un hashtable. (același cod din ultimul exemplu)

Apoi o adăugăm obiectului nostru ca o proprietate de script.

Apoi putem apela funcția noastră astfel:

$myObject.ToHashtable()

Obiecte vs. tipuri de valori

Obiectele și tipurile de valori nu tratează atribuirile de variabile în același mod. Dacă atribuiți tipuri de valori la fiecare dintre ele, doar valoarea este copiată în noua variabilă.

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

În acest caz, $first este 1 și $second este 2.

Variabilele obiect dețin o referință la obiectul real. Atunci când atribuiți un obiect unei variabile noi, ele fac în continuare referire la același obiect.

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

Pentru că $third și $fourth fac referire la aceeași instanță a unui obiect, atât $third.key cât și$fourth.Key sunt 4.

psobject.copy()

Dacă aveți nevoie de o copie fidelă a unui obiect, îl puteți clona.

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

Clona creează o copie superficială a obiectului. Ele au acum instanțe diferite și $third.key este 3și $fourth.Key este 4 în acest exemplu.

Aceasta o numesc copie superficială pentru că dacă aveți obiecte imbricate. (în care proprietățile conțin alte obiecte). Sunt copiate doar valorile de nivel superior. Obiectele copil se vor referi unele la altele.

PSTypeName pentru tipurile de obiecte personalizate

Acum că avem un obiect, mai sunt câteva lucruri pe care le putem face cu el și care s-ar putea să nu fie la fel de evidente. Primul lucru pe care trebuie să-l facem este să-i dăm un PSTypeName. Acesta este cel mai comun mod în care văd că o fac oamenii:

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

Am descoperit recent un alt mod de a face acest lucru din această postare de către /u/markekraus. Am făcut puțină cercetare și mai multe postări despre ideea de la Adam Bertram și Mike Shepard în care vorbesc despre această abordare care vă permite să o definiți inline.

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

Îmi place cât de bine se potrivește acest lucru pur și simplu în limbaj. Acum că avem un obiect cu un typename corespunzător, putem face mai multe lucruri.

Nota

Puteți crea, de asemenea, tipuri PowerShell personalizate folosind clase PowerShell. Pentru mai multe informații, consultațiPowerShell Class Overview.

Utilizarea DefaultPropertySet (the long way)

PowerShell decide pentru noi ce proprietăți să afișeze în mod implicit. O mulțime de comenzi native au un fișier de formatare.ps1xml care face toată treaba grea. Din această postare a lui Boe Prox,există o altă modalitate prin care putem face acest lucru pe obiectul nostru personalizat folosind doar PowerShell. Îi putem da unMemberSet pentru ca acesta să îl folosească.

Acum, când obiectul meu doar cade în shell, va arăta doar acele proprietăți în mod implicit.

Update-TypeData with DefaultPropertySet

Este frumos, dar am văzut recent o modalitate mai bună când am urmăritPowerShell unplugged 2016 cu Jeffrey Snover & Don Jones. Jeffrey foloseaUpdate-TypeData pentru a specifica proprietățile implicite.

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

Este suficient de simplu încât aproape că aș putea să mi-l amintesc dacă nu aș avea această postare ca referință rapidă. Acum pot să creez cu ușurință obiecte cu o mulțime de proprietăți și totuși să le dau o vedere frumoasă și curată atunci când le privesc din shell. Dacă am nevoie să accesez sau să văd acele alte proprietăți, ele rămân acolo.

$myObject | Format-List *

Update-TypeData with ScriptProperty

Altul pe care l-am mai reținut din acel videoclip a fost crearea de proprietăți de script pentru obiectele dumneavoastră. Acesta ar fi un moment bun pentru a sublinia faptul că acest lucru funcționează și pentru obiectele existente.

Puteți face acest lucru înainte ca obiectul dvs. să fie creat sau după și va funcționa în continuare. Aceasta este ceea ce face ca acest lucru să fie diferit de utilizarea Add-Member cu o proprietate de script. Când folosiți Add-Member în modul în care Ireferențiat mai devreme, acesta există doar pe acea instanță specifică a obiectului. Aceasta se aplică la toate obiectele cu acest TypeName.

Parametrii funcțiilor

Acum puteți folosi aceste tipuri personalizate pentru parametrii din funcțiile și scripturile dumneavoastră. Puteți face ca o singurăfuncție să creeze aceste obiecte personalizate și apoi să le treacă în alte funcții.

param( $Data )

PowerShell cere ca obiectul să fie de tipul pe care l-ați specificat. Aruncă o eroare de validare dacă tipul nu se potrivește în mod automat pentru a vă scuti de pasul de a testa acest lucru în codul dumneavoastră. Un exemplu excelent de a lăsa PowerShell să facă ceea ce știe să facă cel mai bine.

Function OutputType

De asemenea, puteți defini un OutputType pentru funcțiile dvs. avansate.

function Get-MyObject{ param ( ...

Valoarea atributului OutputType este doar o notă de documentare. Nu este derivată din codul funcției și nici nu este comparată cu ieșirea reală a funcției.

Motivul principal pentru care ați folosi un tip de ieșire este pentru ca informațiile meta despre funcția dvs. să reflecte intențiile dvs. Lucruri precum Get-Command și Get-Help de care mediul dvs. de dezvoltare poate profita. Dacă doriți mai multe informații, atunci aruncați o privire la ajutorul pentru acesta:about_Functions_OutputTypeAttribute.

După aceasta, dacă folosiți Pester pentru a vă testa unitar funcțiile, atunci ar fi o idee bună să validați că obiectele de ieșire se potrivesc cu OutputType-ul dumneavoastră. Acest lucru ar putea prinde variabilele care pur și simplu cad în țeavă atunci când nu ar trebui.

Gânduri de încheiere

Contextul a fost tot despre , dar multe dintre aceste informații se aplică obiectelor în general.

Am mai văzut cele mai multe dintre aceste caracteristici în trecere, dar nu le-am văzut niciodată prezentate ca o colecție de informații pe PSCustomObject. Chiar săptămâna trecută am dat peste o alta și am fost surprinscă nu o mai văzusem înainte. Am vrut să reunesc toate aceste idei, astfel încât să sperăm că puteți vedea imaginea de ansamblu și să fiți conștienți de ele atunci când veți avea ocazia să le folosiți. Sper că ați învățat ceva și că puteți găsi o modalitate de a lucra cu acestea în scripturile dumneavoastră.

.

Similar Posts

Lasă un răspuns

Adresa ta de email nu va fi publicată.