Aracılığıyla paylaş


PSCustomObject hakkında bilmek istediğiniz her şey

PSCustomObject PowerShell araç kemerinize eklemek için harika bir araçtır. Temel bilgilerle başlayalım ve daha gelişmiş özelliklere doğru ilerleyelim. kullanmanın PSCustomObject ardındaki fikir, yapılandırılmış veri oluşturmak için basit bir yönteme sahip olmaktır. İlk örneğe göz atarak bunun ne anlama geldiğini daha iyi anlamış olursunuz.

Not

Bu makalenin özgün sürümü, @KevinMarquette tarafından yazılan blogda yer almıştır. PowerShell ekibi, bu içeriği bizimle paylaştığı için Kevin'e teşekkür ederiz. Lütfen PowerShellExplained.com'daki blogunu inceleyin.

PSCustomObject Oluşturma

PowerShell'de kullanmayı [PSCustomObject] seviyorum. Kullanılabilir nesne oluşturmak hiç bu kadar kolay olmamıştı. Bu nedenle, nesne oluşturmanın diğer yollarını atlayacağım ama bu örneklerin çoğunun PowerShell v3.0 ve daha yeni olduğunu belirtmem gerekiyor.

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

Hemen hemen her şey için karma tablo kullandığım için bu yöntem benim için iyi çalışıyor. Ancak Bazen PowerShell'in karma tablolara daha çok nesne gibi davranmasını istiyorum. Farkı ilk fark ettiğiniz yer, Export-CSV veya kullanmak Format-Table istediğiniz ve karma tablonun yalnızca anahtar/değer çiftleri koleksiyonu olduğunu fark ettiğiniz yerdir.

Ardından normal bir nesne gibi değerlere erişebilir ve bunları kullanabilirsiniz.

$myObject.Name

Karma tablo dönüştürme

Ben konu başlığı altındayken, bunu yapabileceğinizi biliyor muydunuz:

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

Nesneyi baştan oluşturmayı tercih ediyorum ama önce bir karma tabloyla çalışmanız gereken zamanlar oluyor. Oluşturucu nesne özellikleri için bir karma tablo aldığından bu örnek çalışır. Önemli bir not, bu yöntem çalışırken tam olarak eşdeğer olmadığıdır. En büyük fark, özelliklerin sırasının korunmamasıdır.

Sırayı korumak istiyorsanız bkz. Sıralı karma tablo.

Eski yaklaşım

Özel nesneler oluşturmak için kullanan New-Object kişiler görmüş olabilirsiniz.

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

$myObject = New-Object -TypeName PSObject -Property $myHashtable

Bu yol biraz daha yavaştır, ancak PowerShell'in ilk sürümlerinde en iyi seçeneğiniz olabilir.

Dosyaya kaydetme

Hashtable'ı bir dosyaya kaydetmenin en iyi yolunuN bunu JSON olarak kaydetmek olduğunu düşünüyorum. Bunu bir [PSCustomObject]

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

Dosyaları okumanın ve dosyaya yazmanın birçok yolu başlıklı makalemde nesneleri bir dosyaya kaydetmenin diğer yollarını ele alıyorum.

Özelliklerle çalışma

Özellik ekleme

ile Add-Membercihazınıza PSCustomObject yeni özellikler ekleyebilirsiniz.

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

$myObject.ID

Özellikleri kaldırma

Ayrıca bir nesnenin özelliklerini kaldırabilirsiniz.

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

.psobject, temel nesne meta verilerine erişmenizi sağlayan bir iç üyedir. İç üyeler hakkında daha fazla bilgi için bkz . about_Intrinsic_Members.

Özellik adlarını numaralandırma

Bazen bir nesnedeki tüm özellik adlarının listesi gerekir.

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

Bu listeyi özelliğinden psobject de alacağız.

$myobject.psobject.properties.name

Not

Get-Member özellikleri alfabetik sırada döndürür. Özellik adlarını numaralandırmak için üye erişim işlecini kullanmak, özellikleri nesnede tanımlanma sıralarına göre döndürür.

Özelliklere dinamik olarak erişme

Özellik değerlerine doğrudan erişebildiğinizden bahsetmiştim.

$myObject.Name

Özellik adı için bir dize kullanabilirsiniz ve bu dize çalışmaya devam eder.

$myObject.'Name'

Bu bir adım daha atabilir ve özellik adı için bir değişken kullanabiliriz.

$property = 'Name'
$myObject.$property

Garip göründüğünü biliyorum ama işe yarıyor.

PSCustomObject'i karma tabloya dönüştürme

Son bölümden devam etmek için özellikleri dinamik olarak izleyebilir ve bunlardan bir karma tablo oluşturabilirsiniz.

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

Özellikler için test etme

Bir özelliğin mevcut olup olmadığını bilmeniz gerekiyorsa, bu özelliğin bir değere sahip olup olmadığını de denetlemeniz yeterlidir.

if( $null -ne $myObject.ID )

Ancak değer olabilirse $null değerini denetleyerek psobject.properties var olup olmadığını kontrol edebilirsiniz.

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

Nesne yöntemleri ekleme

Bir nesneye bir betik yöntemi eklemeniz gerekiyorsa, bunu ve ScriptBlockile Add-Member yapabilirsiniz. Geçerli nesneye başvuruda bulunan this otomatik değişkeni kullanmanız gerekir. Burada, scriptblock bir nesneyi karma tabloya dönüştürmek için bir bulunur. (son örnekle aynı kod formu)

$ScriptBlock = {
    $hashtable = @{}
    foreach( $property in $this.psobject.properties.name )
    {
        $hashtable[$property] = $this.$property
    }
    return $hashtable
}

Ardından bunu nesnemize betik özelliği olarak ekleriz.

$memberParam = @{
    MemberType = "ScriptMethod"
    InputObject = $myobject
    Name = "ToHashtable"
    Value = $scriptBlock
}
Add-Member @memberParam

Ardından işlevimizi şu şekilde çağırabiliriz:

$myObject.ToHashtable()

Nesneler ve Değer türleri karşılaştırması

Nesneler ve değer türleri değişken atamalarını aynı şekilde işlemez. Değer türlerini birbirine atarsanız, yalnızca değer yeni değişkene kopyalanır.

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

Bu durumda, $first 1 ve $second 2'dir.

Nesne değişkenleri, gerçek nesneye bir başvuru içerir. Yeni bir değişkene bir nesne atadığınızda, bunlar yine de aynı nesneye başvurur.

$third = [PSCustomObject]@{Key=3}
$fourth = $third
$fourth.Key = 4

Çünkü $third ve $fourth bir nesnenin aynı örneğine başvuruda bulunur, hem hem $fourth.Key de $third.key 4'tür.

psobject.copy()

Bir nesnenin gerçek bir kopyasına ihtiyacınız varsa, nesneyi kopyalayabilirsiniz.

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

Clone, nesnenin sığ bir kopyasını oluşturur. Şimdi farklı örnekleri vardır ve $third.key bu örnekte 3 ve $fourth.Key 4'dür.

İç içe nesnelere sahipseniz (özelliklere sahip nesneler başka nesneler içerir) yalnızca en üst düzey değerler kopyalandığından buna sığ bir kopya diyorum. Alt nesneler birbirine başvurur.

Özel nesne türleri için PSTypeName

Artık bir nesnemiz olduğuna göre, bu nesneyle yapabileceğimiz birkaç şey daha var. yapmamız gereken ilk şey bir vermektir PSTypeName. İnsanların bunu en yaygın şekilde yapabileceğini görüyorum:

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

Yakın zamanda Redditor'dan u/markekrausbunu yapmak için başka bir yol keşfettim. Satır içinde tanımlamanızı sağlayan bu yaklaşımdan bahsediyor.

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

Bunun dile sığma şekline bayılıyorum. Artık uygun tür adına sahip bir nesnemiz olduğuna göre, bazı daha fazla işlem yapabiliriz.

Not

Ayrıca, PowerShell sınıflarını kullanarak özel PowerShell türleri de oluşturabilirsiniz. Daha fazla bilgi için bkz . PowerShell Sınıfına Genel Bakış.

DefaultPropertySet kullanma (uzun yol)

PowerShell, varsayılan olarak hangi özelliklerin görüntüleneceğine karar verir. Yerel komutların çoğu, tüm ağır kaldırma işlemini gerçekleştiren bir .ps1xml biçimlendirme dosyasına sahiptir. Boe Prox'un bu gönderisinden, yalnızca PowerShell kullanarak özel nesnemizde bunu yapmamızın başka bir yolu vardır. Kullanması için bir MemberSet verebiliriz.

$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

Artık nesnem yalnızca kabuğa düştüğünde, varsayılan olarak yalnızca bu özellikleri gösterir.

DefaultPropertySet ile Update-TypeData

Bu güzel ama yakın zamanda varsayılan özellikleri belirtmek için Update-TypeData'yı kullanmanın daha iyi bir yolunu gördüm.

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

Bu, hızlı bir başvuru olarak bu gönderiyi almadıysam neredeyse hatırlayabildiğim kadar basit. Artık birçok özelliğe sahip nesneleri kolayca oluşturabilir ve yine de kabuktan bakarken güzel bir temiz görünüm verebilirim. Diğer özelliklere erişmem veya bunları görmem gerekirse, hala oradalar.

$myObject | Format-List *

ScriptProperty ile Update-TypeData

Bu videodan aldığım başka bir şey de nesneleriniz için betik özellikleri oluşturmaktı. Bunun mevcut nesneler için de işe yaradığını belirtmek için iyi bir zaman olabilir.

$TypeData = @{
    TypeName = 'My.Object'
    MemberType = 'ScriptProperty'
    MemberName = 'UpperCaseName'
    Value = {$this.Name.toUpper()}
}
Update-TypeData @TypeData

Bunu, nesneniz oluşturulmadan önce veya sonra da yapabilirsiniz ve çalışmaya devam eder. Bunu betik özelliğiyle kullanmaktan Add-Member farklı kılan budur. Daha önce başvurdığım şekilde kullandığınızda Add-Member , yalnızca nesnenin belirli bir örneğinde var olur. Bu, ile tüm TypeNamenesneler için geçerlidir.

İşlev parametreleri

Artık işlevlerinizdeki ve betiklerinizdeki parametreler için bu özel türleri kullanabilirsiniz. Bir işlevin bu özel nesneleri oluşturmasını ve sonra bunları diğer işlevlere geçirmesini sağlayabilirsiniz.

param( [PSTypeName('My.Object')]$Data )

PowerShell, nesnenin belirttiğiniz tür olmasını gerektirir. Türün kodunuzda test etme adımını kaydetmeniz için otomatik olarak eşleşmemesi durumunda bir doğrulama hatası oluşturur. PowerShell'in en iyi yaptığı işi yapmasına izin vermenin harika bir örneği.

İşlev Çıktı Türü

Gelişmiş işlevleriniz için de bir OutputType tanımlayabilirsiniz.

function Get-MyObject
{
    [OutputType('My.Object')]
    [CmdletBinding()]
        param
        (
            ...

OutputType öznitelik değeri yalnızca bir belge notudur. İşlev kodundan türetilmiş değildir veya gerçek işlev çıkışıyla karşılaştırılamaz.

Çıkış türünü kullanmanızın temel nedeni, işlevinizle ilgili meta bilgilerin amacınızı yansıtmasıdır. Geliştirme ortamınızın yararlanabileceği ve Get-Help gibi Get-Command şeyler. Daha fazla bilgi edinmek istiyorsanız yardım bölümüne göz atın: about_Functions_OutputTypeAttribute.

Bununla birlikte, işlevlerinizi birim testi için Pester kullanıyorsanız çıkış nesnelerinin OutputType'ınızla eşleşeceğini doğrulamak iyi bir fikir olacaktır. Bu, boruya düşmemesi gereken değişkenleri yakalayabilir.

Kapanış düşünceleri

Bunun bağlamı tamamen ile ilgiliydi [PSCustomObject], ancak bu bilgilerin çoğu genel olarak nesneler için geçerlidir.

Bu özelliklerin çoğunu daha önce geçirirken gördüm ama hakkında bilgi PSCustomObjectkoleksiyonu olarak sunulduğunu hiç görmedim. Sadece geçen hafta başka bir taneyle karşılaştım ve daha önce görmediğim için şaşırdım. Tüm bu fikirleri bir araya getirmek istedim, böylece daha büyük bir resmi görebilmeniz ve bunları kullanma fırsatınız olduğunda bunları fark edebilmeniz için. Umarım bir şeyler öğrenmişsinizdir ve bunu senaryolarınızda çalıştırmanın bir yolunu bulursunuz.