Vše, co jste chtěli vědět o PSCustomObject

author
9 minutes, 4 seconds Read
  • 10/05/2020
  • 8 minut čtení
    • j
    • m
    • s
    • j
    • c

PSCustomObjects jsou skvělým nástrojem, který můžete přidat do svého opasku nástrojů PowerShell. Začněme se základya propracujme se k pokročilejším funkcím. Myšlenkou použití PSCustomObject je mít jednoduchý způsob vytváření strukturovaných dat. Podívejte se na první příklad a budete mít lepší představu o tom, co to znamená.

Poznámka

Původní verze tohoto článku se objevila na blogu, jehož autorem je @KevinMarquette. TýmPowerShell děkuje Kevinovi za sdílení tohoto obsahu s námi. Podívejte se prosím na jeho blog na adresePowerShellExplained.com.

Vytvoření objektu PSCustomObject

Mám rád používání v prostředí PowerShell. Vytvoření použitelného objektu nebylo nikdy jednodušší. z tohoto důvodu přeskočím všechny ostatní způsoby, jak můžete objekt vytvořit, ale musím zmínit, že většina těchto příkladů je pro PowerShell v3.0 a novější.

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

Tento způsob mi vyhovuje, protože hashtables používám téměř na všechno. Ale jsou chvíle, kdy bych chtěl, aby PowerShell zacházel s hashtables více jako s objektem. Prvním místem, kde si všimnete rozdílu, je, když chcete použít Format-Table nebo Export-CSV a uvědomíte si, že hashtable je jen kolekce dvojic klíč/hodnota.

K hodnotám pak můžete přistupovat a používat je jako u běžného objektu.

$myObject.Name

Konverze hashtable

Když už jsem u toho, věděli jste, že můžete udělat toto:

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

Přednostně vytvářím objekt od začátku, ale jsou chvíle, kdy je třeba s ahashtable nejprve pracovat. Tento příklad funguje, protože konstruktor přebírá hashtable pro objektvlastnosti. Důležitá poznámka je, že tato metoda sice funguje, ale není přesným ekvivalentem. Největší rozdíl je v tom, že není zachováno pořadí vlastností.

Přístup podle legendy

Možná jste viděli, že lidé používají New-Object k vytváření vlastních objektů.

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

Tento způsob je o dost pomalejší, ale v raných verzích prostředí PowerShell to může být nejlepší volba.

Uložení do souboru

Zjistil jsem, že nejlepší způsob, jak uložit hashtable do souboru, je uložit jej jako JSON. Můžete jej importovat zpět do

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

Dalším způsobům ukládání objektů do souboru se věnuji v článku Mnoho způsobů čtení a zápisu do souborů.

Práce s vlastnostmi

Přidávání vlastností

Stále můžete přidávat nové vlastnosti do svého PSCustomObject pomocí Add-Member.

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

Odstraňování vlastností

Můžete také odebrat vlastnosti z objektu.

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

Vlastnost psobject je skrytá vlastnost, která vám umožňuje přístup k metadatům základního objektu.

Vyčíslení názvů vlastností

Někdy potřebujete seznam všech názvů vlastností objektu.

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

Tentýž seznam můžeme získat i z vlastnosti psobject.

$myobject.psobject.properties.name

Dynamický přístup k vlastnostem

Již jsem se zmínil, že k hodnotám vlastností můžete přistupovat přímo.

$myObject.Name

Můžete pro název vlastnosti použít řetězec a bude to stále fungovat.

$myObject.'Name'

Můžeme udělat ještě jeden krok a pro název vlastnosti použít proměnnou.

$property = 'Name'$myObject.$property

Vím, že to vypadá divně, ale funguje to.

Převedení PSCustomObject na hashtable

Pokračovat z minulé části můžete dynamicky procházet vlastnosti a vytvořit z nich hashtable.

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

Testování vlastností

Pokud potřebujete zjistit, zda nějaká vlastnost existuje, můžete prostě zkontrolovat, zda má daná vlastnost hodnotu.

if( $null -ne $myObject.ID )

Pokud by ale hodnota mohla být $null, můžete zkontrolovat, zda existuje, tak, že pro ni zkontrolujetepsobject.properties.

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

Přidání metod objektu

Pokud potřebujete přidat metodu skriptu k objektu, můžete to udělat pomocí Add-Member aScriptBlock. Musíte použít automatickou proměnnou this odkaz na aktuální objekt. Zde je ascriptblock pro přeměnu objektu na hashtable. (stejný kód jako v minulém příkladu)

Poté ji přidáme do našeho objektu jako vlastnost skriptu.

Poté můžeme zavolat naši funkci takto:

$myObject.ToHashtable()

Objekty vs hodnotové typy

Objekty a hodnotové typy nezpracovávají přiřazení proměnných stejným způsobem. Při přiřazení hodnotových typů se do nové proměnné zkopíruje pouze hodnota.

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

V tomto případě je $first 1 a $second 2.

Objektové proměnné uchovávají odkaz na skutečný objekt. Když přiřadíte jeden objekt nové proměnné, stále odkazují na stejný objekt.

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

Protože $third a $fourth odkazují na stejnou instanci objektu, jsou $third.key i$fourth.Key 4.

psobject.copy()

Potřebujete-li skutečnou kopii objektu, můžete jej klonovat.

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

Klonování vytvoří mělkou kopii objektu. Nyní mají různé instance a $third.key je 3a $fourth.Key je 4 v tomto příkladu.

Říkám tomu mělká kopie, protože pokud máte vnořené objekty. (kde vlastnosti obsahují jinéobjekty). Kopírují se pouze hodnoty nejvyšší úrovně. Podřízené objekty budou odkazovat jeden na druhý.

PSTypeName pro vlastní typy objektů

Teď, když máme objekt, můžeme s ním dělat ještě několik věcí, které nemusí být zdaleka tak zřejmé. První věc, kterou musíme udělat, je dát mu PSTypeName. Tohle je nejčastější způsob, který vídám, jak to lidé dělají:

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

Nedávno jsem objevil další způsob, jak to udělat z tohoto příspěvku od /u/markekraus. Trochu jsem zapátral a našel jsem další příspěvky o nápadu od Adama Bertrama a Mikea Sheparda, kde se mluví o tomto přístupu, který umožňuje definovat to inline.

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

Líbí se mi, jak pěkně to prostě zapadá do jazyka. Nyní, když máme objekt se správným typename, můžeme dělat další věci.

Poznámka

Vlastní typy prostředí PowerShell můžete vytvářet také pomocí tříd prostředí PowerShell. Další informace naleznete v částiPřehled tříd prostředí PowerShell.

Použití sady DefaultPropertySet (delší cesta)

PowerShell za nás rozhodne, jaké vlastnosti se mají zobrazit ve výchozím nastavení. Mnoho nativních příkazů má .ps1xmlformátovací soubor, který dělá všechnu těžkou práci. Z tohoto příspěvku od Boe Prox,existuje další způsob, jak to můžeme udělat na našem vlastním objektu pouze pomocí PowerShellu. Můžeme mu zadatMemberSet, aby se použil.

Nyní, když můj objekt prostě spadne do shellu, bude ve výchozím nastavení zobrazovat jen tyto vlastnosti.

Update-TypeData s DefaultPropertySet

To je pěkné, ale nedávno jsem viděl lepší způsob, když jsem sledovalPowerShell unplugged 2016 s Jeffrey Snoverem & Donem Jonesem. Jeffrey používalUpdate-TypeData pro zadání výchozích vlastností.

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

To je natolik jednoduché, že bych si to skoro pamatoval, kdybych neměl tento příspěvek jako rychlý odkaz. Nyní mohu snadno vytvářet objekty se spoustou vlastností a přitom jim dát při pohledu ze shellu pěkně čistý vzhled. Pokud potřebuji přistupovat k těmto dalším vlastnostem nebo je vidět, jsou tam stále.

$myObject | Format-List *

Update-TypeData with ScriptProperty

Něco dalšího, co jsem si z tohoto videa odnesl, bylo vytváření skriptových vlastností pro vaše objekty. Tentokrát by bylo dobré upozornit, že to funguje i pro existující objekty.

Můžete to udělat před vytvořením objektu nebo po něm a bude to stále fungovat. Tím se to liší od použití Add-Member s vlastností skriptu. Když použijete Add-Member dříve uvedeným způsobem, existuje pouze na této konkrétní instanci objektu. Tato se vztahuje na všechnyobjekty s touto TypeName.

Parametry funkcí

Tyto vlastní typy můžete nyní používat pro parametry ve svých funkcích a skriptech. Můžete nechat jednu funkci vytvořit tyto vlastní objekty a pak je předávat do dalších funkcí.

param( $Data )

PowerShell vyžaduje, aby objekt byl zadaného typu. Pokud typ neodpovídá, automaticky vyhodí chybu ověření, aby vám ušetřil krok testování tohoto typu v kódu. Skvělýpříklad toho, jak nechat PowerShell dělat to, co umí nejlépe.

Funkce OutputType

Můžete také definovat OutputType pro své pokročilé funkce.

function Get-MyObject{ param ( ...

Hodnota atributu OutputType je pouze dokumentační poznámka. Není odvozena z kódu funkce ani není porovnávána se skutečným výstupem funkce.

Hlavním důvodem, proč byste měli použít typ výstupu, je, aby metainformace o vaší funkciodrážely vaše záměry. Věci jako Get-Command a Get-Help, které vaše vývojové prostředímůže využít. Pokud chcete více informací, pak se podívejte do nápovědy k němu:about_Functions_OutputTypeAttribute.

Pokud používáte Pester k unit testování svých funkcí, pak by bylo dobré ověřit, zda výstupní objekty odpovídají vašemu OutputType. To by mohlo zachytit proměnné, které prostě spadnou do roury, i když by neměly.

Závěrečné myšlenky

Kontext tohoto článku se týkal , ale mnoho z těchto informací platí pro objekty obecně.

Většinu těchto funkcí jsem již dříve letmo viděl, ale nikdy jsem je neviděl prezentované jako souborinformací o PSCustomObject. Zrovna minulý týden jsem narazil na další a byl jsem překvapen,že jsem ji předtím neviděl. Chtěl jsem všechny tyto myšlenky shromáždit, abyste snad viděli širší souvislosti a uvědomili si je, až budete mít příležitost je použít. Doufám, že se něco naučíte a najdete způsob, jak je zapracovat do svých skriptů.

Similar Posts

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.