Minden, amit tudni akart a PSCustomObjectről

author
9 minutes, 46 seconds Read
  • 10/05/2020
  • 8 perc olvasás
    • j
      • j
    • m
    • s
    • j
    • c

PSCustomObjects egy nagyszerű eszköz, amelyet a PowerShell eszköztárába illeszthet. Kezdjük az alapokkal, és haladjunk tovább a fejlettebb funkciók felé. A PSCustomObject használatának lényege, hogy egyszerű módja legyen a strukturált adatok létrehozásának. Vessen egy pillantást az első példára, és jobban el tudja képzelni, mit jelent ez.

Note

A cikk eredeti változata a @KevinMarquette által írt blogon jelent meg. APowerShell csapata köszöni Kevinnek, hogy megosztotta velünk ezt a tartalmat. Kérjük, látogasson el a blogjára aPowerShellExplained.com címen.

PSCustomObject létrehozása

A PowerShellben szeretem a használatát. Soha nem volt még ilyen egyszerű egy használható objektum létrehozása.Emiatt most átugrom az objektum létrehozásának összes többi módját, de meg kell említenem, hogy a példák többsége a PowerShell v3.0 vagy újabb verziójú.

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

Ez a módszer nekem jól működik, mert szinte mindenhez hashtablet használok. De vannak esetek, amikor szeretném, ha a PowerShell inkább objektumként kezelné a hashtables-t. Az első hely, ahol észreveszed a különbséget, amikor a Format-Table vagy a Export-CSV értéket akarod használni, és rájössz, hogy a hashtable csak egy kulcs/érték párok gyűjteménye.

Az értékeket úgy tudod elérni és használni, mint egy normál objektumot.

$myObject.Name

Egy hashtable átalakítása

Ha már a témánál vagyok, tudtad, hogy ezt is megteheted:

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

Még jobban szeretem, ha az objektumot kezdettől fogva létrehozod, de vannak esetek, amikor először ahashtable-vel kell dolgoznod. Ez a példa azért működik, mert a konstruktor egy hashtable-t vesz az objectpropertieshez. Egy fontos megjegyzés, hogy bár ez a módszer működik, nem pontos ekvivalens. A legnagyobb különbség az, hogy a tulajdonságok sorrendje nem marad meg.

Legacy megközelítés

Láthattad már, hogy az emberek New-Object egyéni objektumok létrehozására használják.

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

Ez a mód eléggé lassabb, de a PowerShell korai verzióinál ez lehet a legjobb megoldás.

Fájlba mentés

A hashtable fájlba mentésének legjobb módját JSON-ként találom. Visszaimportálhatja

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

Az objektumok fájlba mentésének további módjairól aA fájlokba való olvasás és írás számos módja című cikkemben szólok.

A tulajdonságokkal való munka

Tulajdonságok hozzáadása

A Add-Member segítségével továbbra is hozzáadhat új tulajdonságokat a PSCustomObject objektumához.

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

Tulajdonságok eltávolítása

Egy objektumról is eltávolíthat tulajdonságokat.

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

A psobject egy rejtett tulajdonság, amely hozzáférést biztosít az objektum alap metaadataihoz.

A tulajdonságnevek felsorolása

Néha szükségünk van egy objektum összes tulajdonságnevének listájára.

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

A psobject tulajdonságról is megkaphatjuk ugyanezt a listát.

$myobject.psobject.properties.name

A tulajdonságok dinamikus elérése

Azt már említettem, hogy a tulajdonságok értékeit közvetlenül is elérhetjük.

$myObject.Name

Egy karakterláncot használhatunk a tulajdonság nevéhez, és akkor is működni fog.

$myObject.'Name'

Mehetünk még egy lépéssel tovább, és használhatunk egy változót a tulajdonság nevéhez.

$property = 'Name'$myObject.$property

Tudom, hogy furcsán néz ki, de működik.

PSCustomObject átalakítása hashtablevé

Az előző rész folytatásaként dinamikusan bejárhatjuk a tulajdonságokat, és létrehozhatunk belőlük egy hashtablet.

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

Tulajdonságok tesztelése

Ha tudnunk kell, hogy létezik-e egy tulajdonság, akkor egyszerűen ellenőrizhetjük, hogy az adott tulajdonságnak van-e értéke.

if( $null -ne $myObject.ID )

De ha az érték $null lehet, akkor apsobject.properties ellenőrzésével ellenőrizheted, hogy létezik-e.

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

Objektum metódusok hozzáadása

Ha egy szkript metódust kell hozzáadni egy objektumhoz, akkor ezt a Add-Member és aScriptBlock segítségével teheted meg. A this automatikus változóval kell az aktuális objektumra hivatkozni. Itt van az ascriptblock, amellyel egy objektumot hashtabellává alakíthatunk. (ugyanaz a kód az előző példából)

Aztán hozzáadjuk az objektumunkhoz, mint egy script tulajdonságot.

Aztán így hívhatjuk meg a függvényünket:

$myObject.ToHashtable()

Objektek vs. értéktípusok

Az objektumok és az értéktípusok nem ugyanúgy kezelik a változó hozzárendelést. Ha értéktípusokat rendelünk egymáshoz, csak az értéket másolják át az új változóba.

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

Ez esetben $first az 1 és $second a 2.

A tárgyváltozók a tényleges objektumra való hivatkozást tartják. Ha egy objektumot egy newvariable-hez rendelünk, akkor is ugyanarra az objektumra hivatkoznak.

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

Mert mivel $third és $fourth egy objektum ugyanarra a példányára hivatkozik, $third.key és $fourth.Key is 4.

psobject.copy()

Ha egy objektum valódi másolatára van szükségünk, akkor klónozhatjuk azt.

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

A klónozás az objektum sekély másolatát hozza létre. Most különböző példányaik vannak, és ebben a példában $third.key 3 és $fourth.Key 4.

Ezt azért nevezem sekély másolatnak, mert ha egymásba ágyazott objektumaink vannak. (ahol a tulajdonságok más objektumokat tartalmaznak). Csak a legfelső szintű értékek kerülnek másolásra. A gyermekobjektumok egymásra hivatkoznak.

PSTypeName az egyéni objektumtípusokhoz

Most, hogy van egy objektumunk, van még néhány dolog, amit tehetünk vele, ami talán nem annyira nyilvánvaló. Az első dolog, amit tennünk kell, hogy adjunk neki egy PSTypeName. Ez a leggyakoribb módja, ahogyan látom, hogy az emberek ezt csinálják:

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

Nemrég fedeztem fel egy másik módot erre a /u/markekraus bejegyzéséből. Csináltam egy kis kutatást és több hozzászólást Adam Bertram és Mike Shepard ötletéről, ahol beszélnek erről a megközelítésről, amely lehetővé teszi, hogy inline definiáld.

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

Imádom, hogy ez milyen szépen illeszkedik a nyelvbe. Most, hogy van egy objektumunk egy megfelelő típusnévvel, több dolgot is tehetünk.

Megjegyzés

Egyéni PowerShell-típusokat is létrehozhatunk a PowerShell-osztályok segítségével. További információért lásd: PowerShell osztályok áttekintése.

A DefaultPropertySet használata (a hosszú út)

A PowerShell eldönti helyettünk, hogy milyen tulajdonságokat jelenítsen meg alapértelmezés szerint. Sok natív parancsnak van egy.ps1xml formázási fájlja, amely elvégzi az összes nehéz munkát. Ebből a Boe Prox által írt bejegyzésből,van egy másik mód arra, hogy ezt az egyéni objektumunkon csak a PowerShell segítségével tegyük meg. Megadhatunk neki egyMemberSet, hogy használja.

Most amikor az objektumom csak a héjra esik, akkor alapértelmezés szerint csak ezeket a tulajdonságokat fogja megmutatni.

Update-TypeData with DefaultPropertySet

Ez szép, de nemrég láttam egy jobb módszert, amikor néztem aPowerShell unplugged 2016 with Jeffrey Snover & Don Jones. Jeffrey azUpdate-TypeData-t használta az alapértelmezett tulajdonságok megadására.

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

Ez elég egyszerű ahhoz, hogy majdnem emlékeznék rá, ha nem lenne ez a bejegyzés gyorsreferenciaként. Most már könnyedén létrehozhatok objektumokat sok tulajdonsággal, és még mindig szép tiszta nézetet adhatok neki, amikor a héjból nézem. Ha szükségem van a többi tulajdonság elérésére vagy megtekintésére, akkor azok még mindig ott vannak.

$myObject | Format-List *

Update-TypeData with ScriptProperty

A videóból még valamit kihoztam: script tulajdonságok létrehozása az objektumokhoz. Ez egy jó alkalom lenne arra rámutatni, hogy ez a meglévő objektumok esetében is működik.

Megteheted ezt az objektum létrehozása előtt vagy után, és akkor is működni fog. Ez az, amiben ez más, mint a Add-Member használata egy szkript tulajdonsággal. Ha a Add-Member-ot a korábban említett módon használod, az csak az objektum adott példányán létezik. Ez az összes objektumra vonatkozik ezzel a TypeName-vel.

Funkció paraméterek

Most már használhatod ezeket az egyéni típusokat a függvények és szkriptek paramétereihez. Az egyik függvény létrehozhatja ezeket az egyéni objektumokat, majd átadhatja őket más függvényeknek.

param( $Data )

A PowerShell megköveteli, hogy az objektum az Ön által megadott típusú legyen. Ha a típus nem felel meg, automatikusan érvényesítési hibát dob, hogy megkímélje Önt a kódban történő tesztelés lépéseitől. Egy nagyszerű példa arra, hogy a PowerShell tegye azt, amihez a legjobban ért.

Function OutputType

Egy OutputType-t is definiálhat a fejlett függvényeihez.

function Get-MyObject{ param ( ...

Az OutputType attribútum értéke csak egy dokumentációs megjegyzés. Nem származik a függvénykódból, és nem hasonlítják össze a tényleges függvénykimenettel.

A fő ok, amiért kimeneti típust használsz, az az, hogy a függvényedre vonatkozó metainformációk tükrözzék a szándékaidat. Olyan dolgok, mint Get-Command és Get-Help, amelyeket a fejlesztőkörnyezeted kihasználhat. Ha több információt szeretne, akkor nézze meg a súgóban:about_Functions_OutputTypeAttribute.

Azzal, hogy azt mondta, ha a Pester-t használja a függvények egységtesztelésére, akkor jó ötlet lennehogy a kimeneti objektumok megfelelnek az OutputType-nak. Ez elkaphatja azokat a változókat, amelyek csak úgy a csőbe esnek, amikor nem kellene.

Záró gondolatok

A kontextusban ez az egész a -ről szólt, de sok információ vonatkozik az objektumokra általában.

A legtöbb ilyen funkciót láttam már futólag, de soha nem láttam, hogy a PSCustomObject-ről szóló információgyűjteményként mutatták volna be őket. Éppen a múlt héten botlottam bele egy másikba, és meglepődtem, hogy még nem láttam korábban. Össze akartam gyűjteni ezeket az ötleteket, hogy remélhetőleg átlásd a nagyobb képet, és tisztában legyél velük, amikor lehetőséged lesz használni őket. Remélem, tanultál valamit, és megtalálod a módját, hogy beépítsd ezeket a szkriptjeidbe.

Similar Posts

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.