- 10/05/2020
- 8 perc olvasás
-
- j
-
- j
- m
- s
- j
- c
PSCustomObject
s 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
- Egy hashtable átalakítása
- Legacy megközelítés
- Fájlba mentés
- A tulajdonságokkal való munka
- Tulajdonságok hozzáadása
- Tulajdonságok eltávolítása
- A tulajdonságnevek felsorolása
- A tulajdonságok dinamikus elérése
- PSCustomObject átalakítása hashtablevé
- Tulajdonságok tesztelése
- Objektum metódusok hozzáadása
- Objektek vs. értéktípusok
- psobject.copy()
- PSTypeName az egyéni objektumtípusokhoz
- A DefaultPropertySet használata (a hosszú út)
- Update-TypeData with DefaultPropertySet
- Update-TypeData with ScriptProperty
- Funkció paraméterek
- Function OutputType
- Záró gondolatok
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.