Wszystko co chciałeś wiedzieć o PSCustomObject

author
8 minutes, 33 seconds Read
  • 10/05/2020
  • 8 minut na przeczytanie
    • j
    • .

    • m
    • s
    • j
    • c

PSCustomObjects są świetnym narzędziem, które można dodać do swojego paska narzędzi PowerShell. Zacznijmy od podstaw i przejdźmy do bardziej zaawansowanych funkcji. Ideą używania PSCustomObject jest posiadanie prostego sposobu na tworzenie danych strukturalnych. Spójrz na pierwszy przykład, a będziesz miał lepsze pojęcie, co to oznacza.

Note

Oryginalna wersja tego artykułu pojawiła się na blogu napisanym przez @KevinMarquette. Zespół ThePowerShell dziękuje Kevinowi za podzielenie się z nami tą treścią. Proszę sprawdzić jego blog naPowerShellExplained.com.

Tworzenie PSCustomObject

Uwielbiam używać w PowerShell. Z tego powodu pominę wszystkie inne sposoby tworzenia obiektów, ale muszę wspomnieć, że większość z tych przykładów to PowerShell v3.0 i nowsze.

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

Ta metoda działa dobrze dla mnie, ponieważ używam hashtables do wszystkiego. Ale są chwile, kiedy chciałbym, aby PowerShell traktował hashtables bardziej jak obiekty. Pierwszym miejscem, w którym zauważysz różnicę jest kiedy chcesz użyć Format-Table lub Export-CSV i zdasz sobie sprawę, że tablica hashtabli jest po prostu kolekcją par klucz/wartość.

Możesz wtedy uzyskać dostęp i używać wartości jak normalnego obiektu.

$myObject.Name

Konwersja hashtable

Podczas gdy jestem w temacie, czy wiedziałeś, że możesz zrobić to:

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

Wolę tworzyć obiekt od początku, ale są chwile, kiedy musisz najpierw pracować z ahashtable. Ten przykład działa, ponieważ konstruktor pobiera tablicę hashtable dla właściwości obiektu. Jedną z ważnych uwag jest to, że podczas gdy ta metoda działa, nie jest ona dokładnym odpowiednikiem. Największą różnicą jest to, że kolejność właściwości nie jest zachowana.

Podejście legendarne

Może widziałeś, jak ludzie używają New-Object do tworzenia niestandardowych obiektów.

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

Ten sposób jest nieco wolniejszy, ale może być najlepszą opcją na wczesnych wersjach PowerShell.

Zapisywanie do pliku

Odkryłem, że najlepszym sposobem na zapisanie hashtable do pliku jest zapisanie go jako JSON. Możesz zaimportować go z powrotem do

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

Obejmuję więcej sposobów zapisywania obiektów do pliku w moim artykule na tematWiele sposobów odczytu i zapisu do plików.

Praca z właściwościami

Dodawanie właściwości

Możesz nadal dodawać nowe właściwości do swojego PSCustomObject za pomocą Add-Member.

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

Usuwanie właściwości

Możesz również usuwać właściwości z obiektu.

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

Właściwość psobject jest właściwością ukrytą, która daje dostęp do metadanych obiektu bazowego.

Wyliczanie nazw właściwości

Czasami potrzebujesz listy wszystkich nazw właściwości obiektu.

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

Możemy uzyskać tę samą listę również z właściwości psobject.

$myobject.psobject.properties.name

Dynamiczny dostęp do właściwości

Wspomniałem już, że można uzyskać bezpośredni dostęp do wartości właściwości.

$myObject.Name

Możesz użyć łańcucha dla nazwy właściwości i to nadal będzie działać.

$myObject.'Name'

Możemy zrobić ten jeden krok więcej i użyć zmiennej dla nazwy właściwości.

$property = 'Name'$myObject.$property

Wiem, że to wygląda dziwnie, ale działa.

Konwersja PSCustomObject do hashtable

Aby kontynuować z ostatniej sekcji, możesz dynamicznie chodzić po właściwościach i tworzyć z nich hashtable.

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

Testowanie właściwości

Jeśli musisz wiedzieć, czy dana właściwość istnieje, możesz po prostu sprawdzić, czy ta właściwość ma wartość.

if( $null -ne $myObject.ID )

Ale jeśli wartość mogłaby być $null, możesz sprawdzić, czy istnieje, sprawdzającpsobject.properties dla niej.

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

Dodawanie metod obiektów

Jeśli potrzebujesz dodać metodę skryptu do obiektu, możesz to zrobić za pomocą Add-Member i aScriptBlock. Musisz użyć this automatycznej zmiennej odwołującej się do bieżącego obiektu. Tutaj jest ascriptblock aby zamienić obiekt w tablicę hashtable. (ten sam kod z ostatniego przykładu)

Wtedy dodamy go do naszego obiektu jako właściwość skryptu.

Wtedy możemy wywołać naszą funkcję w ten sposób:

$myObject.ToHashtable()

Objects vs Value types

Objects i typy wartości nie obsługują przypisania zmiennych w ten sam sposób. Jeśli przypiszesz typy wartości do siebie nawzajem, tylko wartość zostanie skopiowana do nowej zmiennej.

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

W tym przypadku, $first jest 1 i $second jest 2.

Zmienne obiektowe przechowują odniesienie do rzeczywistego obiektu. Kiedy przypisujesz jeden obiekt do nowej zmiennej, wciąż odwołują się one do tego samego obiektu.

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

Ponieważ $third i $fourth odwołują się do tej samej instancji obiektu, zarówno $third.key jak i$fourth.Key mają wartość 4.

psobject.copy()

Jeśli potrzebujesz prawdziwej kopii obiektu, możesz go sklonować.

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

Clone tworzy płytką kopię obiektu. Mają one teraz różne instancje i $third.key jest 3, a $fourth.Key jest 4 w tym przykładzie.

Nazywam to płytką kopią, ponieważ jeśli masz zagnieżdżone obiekty. (gdzie właściwości zawierają inne obiekty). Kopiowane są tylko wartości najwyższego poziomu. Obiekty potomne będą odwoływać się do siebie nawzajem.

PSTypeName dla niestandardowych typów obiektów

Teraz, gdy mamy obiekt, jest jeszcze kilka rzeczy, które możemy z nim zrobić, a które mogą nie być tak oczywiste. Pierwszą rzeczą, którą musimy zrobić, to nadać mu PSTypeName. Jest to najczęstszy sposób, w jaki ludzie to robią:

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

Ostatnio odkryłem inny sposób na zrobienie tego z tego postu autorstwa /u/markekraus. I did a littledigging and more posts about the idea from Adam Bertram and Mike Shepard where they talkabout this approach that allows you to define it inline.

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

I love how niceely this just fits into the language. Teraz, gdy mamy obiekt z odpowiednią nazwą typu, możemy zrobić jeszcze kilka rzeczy.

Uwaga

Możesz również tworzyć niestandardowe typy PowerShell używając klas PowerShell. Aby uzyskać więcej informacji, zobaczPowerShell Class Overview.

Używanie DefaultPropertySet (długa droga)

PowerShell decyduje za nas, jakie właściwości mają być domyślnie wyświetlane. Wiele z natywnych poleceń ma plik formatujący.ps1xml, który wykonuje całą ciężką pracę. Z tego postu przez Boe Prox, jest inny sposób na zrobienie tego na naszym niestandardowym obiekcie używając tylko PowerShell. Możemy dać muMemberSet do użycia.

Teraz, gdy mój obiekt po prostu spadnie do powłoki, domyślnie pokaże tylko te właściwości.

Update-TypeData with DefaultPropertySet

To jest fajne, ale ostatnio widziałem lepszy sposób podczas oglądaniaPowerShell unplugged 2016 z Jeffreyem Snoverem & Don Jones. Jeffrey używałUpdate-TypeData do określenia domyślnych właściwości.

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

To jest na tyle proste, że prawie mógłbym to zapamiętać, gdybym nie miał tego postu jako quickreference. Teraz mogę łatwo tworzyć obiekty z wieloma właściwościami i nadal nadawać im ładny, czysty wygląd, gdy patrzę na nie z poziomu powłoki. Jeśli potrzebuję uzyskać dostęp lub zobaczyć te inne właściwości, one tam pozostaną.

$myObject | Format-List *

Update-TypeData with ScriptProperty

Coś jeszcze wyniosłem z tego wideo to tworzenie właściwości skryptu dla twoich obiektów. To byłby dobry moment, aby zaznaczyć, że to działa również dla istniejących obiektów.

Możesz to zrobić przed utworzeniem obiektu lub po i nadal będzie działać. To jest to, co czyni to innym niż użycie Add-Member z właściwością skryptu. Kiedy używasz Add-Member w sposób opisany wcześniej, istnieje ona tylko na tej konkretnej instancji obiektu. Ten odnosi się do wszystkich obiektów z tym TypeName.

Parametry funkcji

Możesz teraz użyć tych niestandardowych typów dla parametrów w twoich funkcjach i skryptach. Możesz mieć jedną funkcję, która tworzy te niestandardowe obiekty, a następnie przekazuje je do innych funkcji.

param( $Data )

PowerShell wymaga, aby obiekt był typu określonego przez użytkownika. Jeśli typ nie jest zgodny automatycznie wyrzuca błąd walidacji, aby oszczędzić Ci testowania go w kodzie. Wspaniały przykład pozwalania PowerShell na robienie tego, co robi najlepiej.

Function OutputType

Możesz również zdefiniować OutputType dla swoich zaawansowanych funkcji.

function Get-MyObject{ param ( ...

Wartość atrybutu OutputType jest tylko uwagą do dokumentacji. Nie jest on wyprowadzany z kodu funkcji ani porównywany z rzeczywistym wyjściem funkcji.

Głównym powodem, dla którego używałbyś typu wyjścia, jest to, że meta informacje o twojej funkcji odzwierciedlają twoje intencje. Rzeczy takie jak Get-Command i Get-Help, z których może skorzystać twoje środowisko programistyczne. Jeśli chcesz uzyskać więcej informacji, to spójrz na pomoc dla niego:about_Functions_OutputTypeAttribute.

Pamiętając o tym, jeśli używasz Pestera do testowania jednostkowego swoich funkcji, to dobrym pomysłem byłoby sprawdzenie czy obiekty wyjściowe pasują do twojego OutputType. To mogłoby złapać zmienne, które po prostu wpadają do rury, kiedy nie powinny.

Myślenia końcowe

Kontekst tego był o , ale wiele z tych informacji odnosi się do obiektów w ogóle.

Widziałem większość z tych funkcji w przelocie wcześniej, ale nigdy nie widziałem ich przedstawionych jako zbiór informacji na PSCustomObject. Właśnie w tym ostatnim tygodniu natknąłem się na kolejny i byłem zaskoczony, że nie widziałem go wcześniej. Chciałem zebrać wszystkie te pomysły razem, abyś mógł, mam nadzieję, zobaczyć większy obraz i być świadomy ich, gdy masz okazję ich używać. Mam nadzieję, że nauczyłeś się czegoś i możesz znaleźć sposób na wykorzystanie tego w swoich skryptach.

Similar Posts

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.