Minden, amit tudni akart a PSCustomObject-ről
PSCustomObject
nagyszerű eszköz a PowerShell-eszközövbe való felvételhez. Kezdjük az alapokkal, és vizsgáljuk meg a fejlettebb funkciókat. A strukturált PSCustomObject
adatok létrehozásának egyszerű módja a használatuk. Tekintse meg az első példát, és jobb elképzelése lesz arról, hogy ez mit jelent.
Feljegyzés
A cikk eredeti verziója @KevinMarquette által írt blogon jelent meg. A PowerShell csapata köszönjük Kevinnek, hogy megosztotta velünk ezt a tartalmat. Kérjük, nézze meg a blogját a PowerShellExplained.com.
PSCustomObject létrehozása
Imádom használni [PSCustomObject]
a PowerShellt. A használható objektumok létrehozása még soha nem volt ilyen egyszerű.
Emiatt kihagyom az objektumok létrehozásának összes többi módját, de meg kell említenem, hogy a legtöbb ilyen példa a PowerShell 3.0-s és újabb verziói.
$myObject = [PSCustomObject]@{
Name = 'Kevin'
Language = 'PowerShell'
State = 'Texas'
}
Ez a módszer jól működik számomra, mert kivonatolókat használok nagyjából mindenhez. Vannak azonban olyan esetek, amikor azt szeretném, hogy a PowerShell a kivonatolókat objektumként kezelje. Az első hely, ahol észreveheti a különbséget, amikor használni Format-Table
szeretné, vagy Export-CSV
amikor rájön, hogy a kivonatoló csak kulcs-érték párok gyűjteménye.
Ezután elérheti és használhatja az értékeket, mint egy normál objektumot.
$myObject.Name
Kivonatoló konvertálása
Míg én vagyok a témában, tudtad, hogy ezt megteheti:
$myHashtable = @{
Name = 'Kevin'
Language = 'PowerShell'
State = 'Texas'
}
$myObject = [pscustomobject]$myHashtable
Én inkább a kezdetektől fogva hozza létre az objektumot, de vannak olyan esetek, amikor először egy kivonatolóval kell dolgoznia. Ez a példa azért működik, mert a konstruktor kivonatolót vesz fel az objektum tulajdonságaihoz. Fontos megjegyezni, hogy bár ez a módszer működik, ez nem egy pontos megfelelője. A legnagyobb különbség az, hogy a tulajdonságok sorrendje nem marad meg.
Ha meg szeretné őrizni a sorrendet, olvassa el a Rendezett kivonatolók című témakört.
Örökölt megközelítés
Lehet, hogy látta, hogy a felhasználók egyéni objektumok létrehozására használják New-Object
.
$myHashtable = @{
Name = 'Kevin'
Language = 'PowerShell'
State = 'Texas'
}
$myObject = New-Object -TypeName PSObject -Property $myHashtable
Ez egy kicsit lassabb, de lehet, hogy ez a legjobb megoldás a PowerShell korai verzióiban.
Mentés fájlba
A kivonatoló fájlba mentésének legjobb módja az, ha JSON-ként menti. Vissza is importálhatja egy [PSCustomObject]
$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ódjait is bemutatom a cikkemben, amely a fájlok olvasásának és írásának számos módját ismerteti.
Tulajdonságok használata
Tulajdonságok hozzáadása
Továbbra is hozzáadhat új tulajdonságokat a PSCustomObject
saját fiókjához Add-Member
.
$myObject | Add-Member -MemberType NoteProperty -Name 'ID' -Value 'KevinMarquette'
$myObject.ID
Tulajdonságok eltávolítása
A tulajdonságokat az objektumokról is eltávolíthatja.
$myObject.psobject.properties.remove('ID')
Ez .psobject
egy belső tag, amely hozzáférést biztosít az alapobjektum-metaadatokhoz. További információ a belső tagokról: about_Intrinsic_Members.
Tulajdonságnevek számbavétele
Néha szükség van egy objektum összes tulajdonságnevének listájára.
$myObject | Get-Member -MemberType NoteProperty | Select -ExpandProperty Name
Ugyanezt a listát is lekérhetjük a psobject
tulajdonságról.
$myobject.psobject.properties.name
Feljegyzés
Get-Member
betűrendben adja vissza a tulajdonságokat. A tag-hozzáférés operátor használatával a tulajdonságnevek számbavétele az objektumon definiált sorrendben adja vissza a tulajdonságokat.
Tulajdonságok dinamikus elérése
Már említettem, hogy közvetlenül hozzáférhet a tulajdonságértékekhez.
$myObject.Name
Használhat sztringet a tulajdonságnévhez, és az továbbra is működni fog.
$myObject.'Name'
Ezt még egy lépéssel elvégezhetjük, és használhatunk egy változót a tulajdonságnévhez.
$property = 'Name'
$myObject.$property
Tudom, hogy furcsán néz ki, de működik.
PSCustomObject konvertálása kivonatolóvá
Az utolsó szakasz folytatásához dinamikusan végigvezetheti a tulajdonságokat, és létrehozhat belőlük egy kivonatolót.
$hashtable = @{}
foreach( $property in $myobject.psobject.properties.name )
{
$hashtable[$property] = $myObject.$property
}
Tulajdonságok tesztelése
Ha tudnia kell, hogy létezik-e tulajdonság, egyszerűen ellenőrizze, hogy a tulajdonság rendelkezik-e értékkel.
if( $null -ne $myObject.ID )
De ha az érték lehet $null
, ellenőrizheti, hogy létezik-e a psobject.properties
kereséssel.
if( $myobject.psobject.properties.match('ID').Count )
Objektummetódusok hozzáadása
Ha szkriptmetódust kell hozzáadnia egy objektumhoz, azt Add-Member
ScriptBlock
megteheti egy . Az aktuális objektumra mutató automatikus változót kell használnia this
. Az alábbiakban egy scriptblock
objektumot hashtable-vá alakítunk. (ugyanaz a kód alkotja az utolsó példát)
$ScriptBlock = {
$hashtable = @{}
foreach( $property in $this.psobject.properties.name )
{
$hashtable[$property] = $this.$property
}
return $hashtable
}
Ezután szkripttulajdonságként hozzáadjuk az objektumhoz.
$memberParam = @{
MemberType = "ScriptMethod"
InputObject = $myobject
Name = "ToHashtable"
Value = $scriptBlock
}
Add-Member @memberParam
Ezután így hívhatjuk meg a függvényt:
$myObject.ToHashtable()
Objektumok és értéktípusok
Az objektumok és az értéktípusok nem ugyanúgy kezelik a változó-hozzárendeléseket. Ha értéktípusokat rendel egymáshoz, csak az érték lesz átmásolva az új változóba.
$first = 1
$second = $first
$second = 2
Ebben az esetben $first
1 és $second
2.
Az objektumváltozók a tényleges objektumra mutató hivatkozást tárolnak. Amikor egy objektumot rendel egy új változóhoz, azok továbbra is ugyanarra az objektumra hivatkoznak.
$third = [PSCustomObject]@{Key=3}
$fourth = $third
$fourth.Key = 4
Mivel $third
egy $fourth
objektum ugyanazon példányára hivatkozik, mindkettő $third.key
$fourth.Key
4.
psobject.copy()
Ha egy objektum valódi másolatára van szüksége, klónozhatja.
$third = [PSCustomObject]@{Key=3}
$fourth = $third.psobject.copy()
$fourth.Key = 4
A klón létrehozza az objektum sekély másolatát. Most már különböző példányaik vannak, és $third.key
3, és $fourth.Key
ebben a példában 4.
Ezt azért nevezem sekély másolatnak, mert ha beágyazott objektumokkal rendelkezik (a tulajdonságokkal rendelkező objektumok más objektumokat is tartalmaznak), csak a legfelső szintű értékek lesznek másolva. A gyermekobjektumok hivatkoznak egymásra.
PSTypeName egyéni objektumtípusokhoz
Most, hogy van egy objektum, van még néhány dolog, amit tehetünk vele, hogy közel sem olyan nyilvánvaló. Az első dolog, amit meg kell tennünk, hogy egy PSTypeName
. Ez a leggyakoribb módja annak, ahogy az emberek ezt teszik:
$myObject.PSObject.TypeNames.Insert(0,"My.Object")
Nemrég felfedeztem egy másik módszert, hogy ezt a Redditor u/markekraus
. Erről a megközelítésről beszél, amely lehetővé teszi, hogy beágyazottan definiálja.
$myObject = [PSCustomObject]@{
PSTypeName = 'My.Object'
Name = 'Kevin'
Language = 'PowerShell'
State = 'Texas'
}
Imádom, hogy ez milyen szépen illik a nyelvhez. Most, hogy rendelkezünk egy megfelelő típusnévvel rendelkező objektummal, további műveleteket is elvégezhetünk.
Feljegyzés
Egyéni PowerShell-típusokat PowerShell-osztályok használatával is létrehozhat. További információ: PowerShell-osztály áttekintése.
DefaultPropertySet használata (a hosszú út)
A PowerShell dönti el, hogy milyen tulajdonságok jelenjenek meg alapértelmezés szerint. Sok natív parancs rendelkezik olyan .ps1xml
formázási fájllal , amely elvégzi az összes nehéz emelést. A Boe Prox által közzétett bejegyzésből egy másik módon is elvégezhetjük ezt az egyéni objektumon, csak a PowerShell használatával. Adhatunk neki egy MemberSet
használhatót.
$defaultDisplaySet = 'Name','Language'
$defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',[string[]]$defaultDisplaySet)
$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)
$MyObject | Add-Member MemberSet PSStandardMembers $PSStandardMembers
Most, hogy az objektumom csak a rendszerhéjra esik, alapértelmezés szerint csak ezeket a tulajdonságokat jeleníti meg.
Update-TypeData és DefaultPropertySet
Ez szép, de nemrég láttam jobb módszert az Update-TypeData használatával az alapértelmezett tulajdonságok megadásához.
$TypeData = @{
TypeName = 'My.Object'
DefaultDisplayPropertySet = 'Name','Language'
}
Update-TypeData @TypeData
Ez elég egyszerű, hogy szinte emlékszem rá, ha nem volt ez a post, mint egy gyors referencia. Most már könnyen létrehozhatok objektumokat sok tulajdonságokkal, és még mindig szép tiszta képet adhatok, amikor megtekintem a héjból. Ha hozzá kell férnem vagy meg kell néznem a többi tulajdonságot, még mindig ott vannak.
$myObject | Format-List *
Update-TypeData és ScriptProperty
Valami más, amit ebből a videóból kaptam, az az objektumok szkripttulajdonságainak létrehozása volt. Ez jó alkalom arra, hogy rámutatjon arra, hogy ez a meglévő objektumok esetében is működik.
$TypeData = @{
TypeName = 'My.Object'
MemberType = 'ScriptProperty'
MemberName = 'UpperCaseName'
Value = {$this.Name.toUpper()}
}
Update-TypeData @TypeData
Ezt az objektum létrehozása előtt vagy után is megteheti, és továbbra is működni fog. Ez teszi ezt másként, mint a szkripttulajdonságok használata Add-Member
. Ha a korábban hivatkozott módszert használja Add-Member
, az csak az objektum adott példányán létezik. Ez az ezzel a beállítással rendelkező TypeName
összes objektumra vonatkozik.
Függvényparaméterek
Ezeket az egyéni típusokat mostantól használhatja a függvényekben és szkriptekben lévő paraméterekhez. Egy függvény létrehozhatja ezeket az egyéni objektumokat, majd átadhatja őket más függvényeknek.
param( [PSTypeName('My.Object')]$Data )
A PowerShell megköveteli, hogy az objektum a megadott típus legyen. Érvényesítési hibát jelez, ha a típus nem egyezik meg automatikusan, hogy mentse a tesztelési lépést a kódban. Nagyszerű példa arra, hogy a PowerShell azt teszi, amit a legjobban csinál.
Függvény kimenettípusa
Speciális függvényeket is definiálhat OutputType
.
function Get-MyObject
{
[OutputType('My.Object')]
[CmdletBinding()]
param
(
...
Az OutputType attribútum értéke csak dokumentációs megjegyzés. Nem a függvénykódból származik, és nem hasonlítja össze a tényleges függvénykimenettel.
A kimeneti típus fő oka az, hogy a függvény metaadatai tükrözik a szándékait. Ilyen és ehhez hasonló Get-Command
dolgok, amelyeket Get-Help
a fejlesztői környezet kihasználhat. Ha további információra van szüksége, tekintse meg a súgót: about_Functions_OutputTypeAttribute.
Ezzel együtt, ha a Pestert használja a függvények egységtesztelésére, akkor érdemes ellenőrizni, hogy a kimeneti objektumok megfelelnek-e az OutputType-nak. Ez elkaphatja a változókat, amelyek csak akkor esnek a csőre, amikor nem kellene.
Záró gondolatok
Ennek kontextusa az egészről szólt [PSCustomObject]
, de ezek az információk nagy része általában az objektumokra vonatkozik.
Láttam a legtöbb ilyen funkciók átadása előtt, de soha nem láttam őket bemutatott, mint egy információgyűjtemény.PSCustomObject
Csak ezen a héten megbotlottam egy másikra, és meglepődtem, hogy még nem láttam korábban. Össze akartam húzni ezeket az ötleteket, hogy remélhetőleg láthassa a nagyobb képet, és tisztában legyen velük, amikor lehetősége van használni őket. Remélem, tanult valamit, és megtalálja a módját, hogy ezt a szkriptek.