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-MemberScriptBlockmegteheti 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 post /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 .ps1xmlformá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.