- 10/05/2020
- 8 minuuttia aikaa lukea
-
- j
- m
- s
- j
- c
PSCustomObject
s on loistava työkalu PowerShell-työkaluvyöhön. Aloitetaan perusasioistaja edetään edistyneempiin ominaisuuksiin. PSCustomObject
:n käytön ideana on yksinkertainen tapa luoda strukturoitua dataa. Tutustu ensimmäiseen esimerkkiin, niin saat paremman käsityksen siitä, mitä se tarkoittaa.
Note
Tämän artikkelin alkuperäinen versio ilmestyi blogissa, jonka kirjoitti @KevinMarquette. PowerShell-tiimi kiittää Keviniä tämän sisällön jakamisesta kanssamme. Tutustu hänen blogiinsa osoitteessaPowerShellExplained.com.
- PSCustomObjectin luominen
- Hashtaulukon muuntaminen
- Legacy-lähestymistapa
- Tallentaminen tiedostoon
- Työskentely ominaisuuksien kanssa
- Ominaisuuksien lisääminen
- Ominaisuuksien poistaminen
- Ominaisuuksien nimien luetteleminen
- Ominaisuuksien dynaaminen käyttäminen
- Muunnetaan PSCustomObject hashtableksi
- Ominaisuuksien testaaminen
- Objektin metodien lisääminen
- Objektit vs. arvotyypit
- psobject.copy()
- PSTypeName mukautettuja objektityyppejä varten
- DefaultPropertySetin käyttäminen (pitkä tapa)
- Update-TypeData with DefaultPropertySet
- Update-TypeData with ScriptProperty
- Funktion parametrit
- Function OutputType
- Loppuajatuksia
PSCustomObjectin luominen
Pidän :n käytöstä PowerShellissä. Käyttökelpoisen objektin luominen ei ole koskaan ollut helpompaa.Tämän vuoksi aion ohittaa kaikki muut tavat, joilla voit luoda objektin, mutta minun täytyy mainita, että useimmat näistä esimerkeistä ovat PowerShell v3.0 ja uudempia.
$myObject = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}
Tämä menetelmä toimii hyvin minulle, koska käytän hashtablesia lähes kaikkeen. Mutta on aikoja, jolloin haluaisin PowerShellin kohtelevan hashtablesia enemmän kuin objektia. Ensimmäisenä eron huomaa, kun haluaa käyttää Format-Table
tai Export-CSV
ja tajuaa, että hashtable on vain kokoelma avain-/arvopareja.
Voit sitten käyttää ja käyttää arvoja kuten tavallista objektia.
$myObject.Name
Hashtaulukon muuntaminen
Tiesitkö aiheesta puheen ollen, että voit tehdä näin:
$myHashtable = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}$myObject = $myHashtable
Luotan kyllä mieluummin objektin alusta alkaen, mutta on tilanteita, joissa joudut ensin työskentelemään ahashtaulukon kanssa. Tämä esimerkki toimii, koska konstruktori ottaa hashtaulukon objektin ominaisuuksille. Yksi tärkeä huomio on, että vaikka tämä menetelmä toimii, se ei ole tarkka vastine. Suurin ero on se, että ominaisuuksien järjestystä ei säilytetä.
Legacy-lähestymistapa
Olet ehkä nähnyt ihmisten käyttävän New-Object
omien objektien luomiseen.
$myHashtable = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}$myObject = New-Object -TypeName PSObject -Property $myHashtable
Tämä tapa on melko paljon hitaampi, mutta se voi olla paras vaihtoehto PowerShellin varhaisissa versioissa.
Tallentaminen tiedostoon
Parhaimmaksi tavaksi tallentaa hashtable tiedostoon on mielestäni tallentaa se JSON-muodossa. Voit tuoda sen takaisin
$myObject | ConvertTo-Json -depth 1 | Set-Content -Path $Path$myObject = Get-Content -Path $Path | ConvertFrom-Json
Käsittelen lisää tapoja tallentaa objekteja tiedostoon artikkelissani The many ways to read and write to files.
Työskentely ominaisuuksien kanssa
Ominaisuuksien lisääminen
Voit edelleen lisätä uusia ominaisuuksia PSCustomObject
-objektiin Add-Member
:lla.
$myObject | Add-Member -MemberType NoteProperty -Name 'ID' -Value 'KevinMarquette'$myObject.ID
Ominaisuuksien poistaminen
Ominaisuuksia voi myös poistaa objekteista.
$myObject.psobject.properties.remove('ID')
psobject
on piilotettu ominaisuus, jonka avulla pääset käsiksi perusobjektin metatietoihin.
Ominaisuuksien nimien luetteleminen
Joskus tarvitset luettelon kaikista objektin ominaisuuksien nimistä.
$myObject | Get-Member -MemberType NoteProperty | Select -ExpandProperty Name
Voidaan saada tämä sama lista myös psobject
-ominaisuudesta.
$myobject.psobject.properties.name
Ominaisuuksien dynaaminen käyttäminen
Mainitsin jo, että ominaisuuksien arvoja voi käyttää suoraan.
$myObject.Name
Ominaisuuden nimenä voi käyttää merkkijonoa ja se toimii silti.
$myObject.'Name'
Voidaan mennä vielä askeleen pidemmälle ja käyttää muuttujaa ominaisuuden nimenä.
$property = 'Name'$myObject.$property
Tiedän, että se näyttää oudolta, mutta se toimii.
Muunnetaan PSCustomObject hashtableksi
Jatkaaksemme edellisestä osiosta, voit dynaamisesti kävellä ominaisuuksissa ja luoda hashtablen niistä.
$hashtable = @{}foreach( $property in $myobject.psobject.properties.name ){ $hashtable = $myObject.$property}
Ominaisuuksien testaaminen
Jos haluat tietää, onko jokin ominaisuus olemassa, voit vain tarkistaa, että kyseisellä ominaisuudella on arvo.
if( $null -ne $myObject.ID )
Mutta jos arvo voisi olla $null
, voit tarkistaa, onko se olemassa tarkistamallapsobject.properties
sen olemassaolon.
if( $myobject.psobject.properties.match('ID').Count )
Objektin metodien lisääminen
Jos sinun täytyy lisätä skriptimetodi objektiin, voit tehdä sen Add-Member
ja aScriptBlock
:n avulla. Sinun on käytettävä this
automaattista muuttujan viittausta nykyiseen objektiin. Tässä on ascriptblock
, jolla voit muuttaa objektin hashtableksi. (sama koodi kuin edellisessä esimerkissä)
Sitten lisäämme sen objektiin skriptiominaisuutena.
Sitten voimme kutsua funktiotamme näin:
$myObject.ToHashtable()
Objektit vs. arvotyypit
Objektit ja arvotyypit eivät käsittele muuttujien osoituksia samalla tavalla. Jos osoitat arvotyyppejä toisilleen, vain arvo kopioidaan uuteen muuttujaan.
$first = 1$second = $first$second = 2
Tässä tapauksessa $first
on 1 ja $second
on 2.
Objektimuuttujat pitävät sisällään viittauksen varsinaiseen objektiin. Kun osoitat yhden objektin newmuuttujalle, ne viittaavat edelleen samaan objektiin.
$third = @{Key=3}$fourth = $third$fourth.Key = 4
Koska $third
ja $fourth
viittaavat samaan objektin instanssiin, sekä $third.key
että $fourth.Key
ovat 4.
psobject.copy()
Jos tarvitset todellisen kopion objektista, voit kloonata sen.
$third = @{Key=3}$fourth = $third.psobject.copy()$fourth.Key = 4
Kloonaus luo objektista pinnallisen kopion. Niillä on nyt eri instanssit ja $third.key
on 3ja $fourth.Key
on 4 tässä esimerkissä.
Kutsun tätä pinnalliseksi kopioksi, koska jos sinulla on sisäkkäisiä objekteja. (joissa ominaisuudet sisältävät muita objekteja). Vain ylimmän tason arvot kopioidaan. Lapsiobjektit viittaavat toisiinsa.
PSTypeName mukautettuja objektityyppejä varten
Nyt kun meillä on objekti, voimme tehdä sillä vielä muutamia asioita, jotka eivät ehkä ole läheskään yhtä ilmeisiä. Ensimmäinen asia, joka meidän on tehtävä, on antaa sille PSTypeName
. Tämä on yleisin tapa, jolla näen ihmisten tekevän sen:
$myObject.PSObject.TypeNames.Insert(0,"My.Object")
Löysin hiljattain toisen tavan tehdä tämä tästä /u/markekrauksen postauksesta. Tein littledigging ja lisää viestejä ideasta Adam Bertramilta ja Mike Shepardilta, jossa he puhuvat tästä lähestymistavasta, jonka avulla voit määritellä sen inline.
$myObject = @{ PSTypeName = 'My.Object' Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}
Ihastun siihen, miten hienosti tämä vain sopii kieleen. Nyt kun meillä on objekti, jolla on oikea typename, voimme tehdä lisää asioita.
Huomautus
Voit myös luoda omia PowerShell-tyyppejä käyttämällä PowerShell-luokkia. Lisätietoja on kohdassaPowerShell-luokkien yleiskatsaus.
DefaultPropertySetin käyttäminen (pitkä tapa)
PowerShell päättää puolestamme, mitkä ominaisuudet näytetään oletuksena. Monilla natiivikomennoilla on.ps1xml
muotoilutiedosto, joka tekee kaiken raskaan työn. Tästä Boe Proxin postauksesta löytyy toinenkin tapa, jolla voimme tehdä tämän mukautetulle objektillemme käyttämällä vain PowerShelliä. Voimme antaa silleMemberSet
sen käytettäväksi.
Nyt kun objektini vain putoaa kuoreen, se näyttää oletusarvoisesti vain nämä ominaisuudet.
Update-TypeData with DefaultPropertySet
Tämä on mukavaa, mutta näin hiljattain paremman tavan katsoessani katsomassaPowerShell unplugged 2016 with Jeffrey Snover & Don Jones. Jeffrey käyttiUpdate-TypeDataa oletusominaisuuksien määrittämiseen.
$TypeData = @{ TypeName = 'My.Object' DefaultDisplayPropertySet = 'Name','Language'}Update-TypeData @TypeData
Tämä on niin yksinkertaista, että voisin melkein muistaa sen, jos minulla ei olisi tätä viestiä pikaviitteenä. Nyt voin helposti luoda objekteja, joilla on paljon ominaisuuksia, ja antaa niille silti kauniin siistin näkymän, kun niitä tarkastellaan komentotulkista. Jos minun on päästävä käsiksi noihin muihin ominaisuuksiin tai nähtävä ne, ne pysyvät siellä.
$myObject | Format-List *
Update-TypeData with ScriptProperty
Muutama muu asia, jonka sain tuosta videosta, oli skriptiominaisuuksien luominen objekteille. Nyt olisi hyvä hetki huomauttaa, että tämä toimii myös olemassa oleville objekteille.
Voit tehdä tämän ennen objektin luomista tai sen jälkeen ja se toimii silti. Tämä tekee tästä erilaisen kuin Add-Member
:n käyttäminen skriptiominaisuuden kanssa. Kun käytät Add-Member
:tä aiemmin mainitsemallasi tavalla, se on olemassa vain kyseisessä objektin instanssissa. Tämä koskee kaikkia objekteja, joilla on tämä TypeName
.
Funktion parametrit
Voit nyt käyttää näitä mukautettuja tyyppejä parametreina funktioissa ja skripteissä. Voit antaa yhden funktion luoda näitä mukautettuja objekteja ja välittää ne sitten muihin funktioihin.
param( $Data )
PowerShell edellyttää, että objekti on määrittämääsi tyyppiä. Se heittää validointivirheen, jos tyyppi ei vastaa automaattisesti, jotta sinun ei tarvitse testata sitä koodissasi. Loistavaesimerkki siitä, että annat PowerShellin tehdä sen, mitä se osaa parhaiten.
Function OutputType
Voit myös määritellä OutputType
edistyneille funktioillesi.
function Get-MyObject{ param ( ...
OutputType-attribuutin arvo on vain dokumentaatiohuomautus. Sitä ei johdeta funktiokoodista eikä sitä verrata varsinaiseen funktion ulostuloon.
Pääsyy siihen, että käytät ulostulotyyppiä, on se, että metatiedot funktiostasi heijastavat aikomuksiasi. Asioita kuten Get-Command
ja Get-Help
, joita kehitysympäristösi voi hyödyntää. Jos haluat lisätietoja, niin vilkaise sen ohjeeseen:about_Functions_OutputTypeAttribute.
Tämän sanottuasi, jos käytät Pesteriä funktioiden yksikkötestaukseen, niin silloin olisi hyvä ideatodentaa, että ulostulo-objektit vastaavat OutputType-tyyppiäsi. Tämä voisi saada kiinni muuttujia, jotka vain putoavat putkeen, kun niiden ei pitäisi.
Loppuajatuksia
Tässä yhteydessä oli kyse :stä, mutta monet näistä tiedoista pätevät objekteihin yleisesti.
Olen nähnyt useimmat näistä ominaisuuksista ohimennen ennenkin, mutta en ole koskaan nähnyt niitä esiteltynä kokoelmana PSCustomObject
:ssa. Juuri viime viikolla törmäsin toiseen ja olin yllättynyt, etten ollut nähnyt sitä aiemmin. Halusin koota kaikki nämä ajatukset yhteen, jotta voit toivottavasti nähdä kokonaiskuvan ja olla tietoinen niistä, kun sinulla on tilaisuus käyttää niitä. Toivottavasti opit jotakin ja löydät keinon sisällyttää nämä käsikirjoituksiisi.