Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
PSCustomObject
adalah alat yang bagus untuk ditambahkan ke sabuk alat PowerShell Anda. Mari kita mulai dengan dasar-dasar dan melanjutkan ke fitur yang lebih canggih. Ide di balik penggunaan PSCustomObject
adalah memiliki cara sederhana untuk membuat data terstruktur. Lihat contoh pertama dan Anda akan memiliki gambaran yang lebih baik tentang apa artinya itu.
Nota
Versi asli artikel ini muncul di blog yang ditulis oleh @KevinMarquette. Tim PowerShell berterima kasih kepada Kevin karena telah membagikan konten ini kepada kami. Silakan lihat blognya di PowerShellExplained.com.
Membuat PSCustomObject
Saya suka menggunakan [pscustomobject]
di PowerShell. Membuat objek yang dapat digunakan tidak pernah lebih mudah.
Karena itu, saya akan melewati semua cara lain yang dapat Anda buat objek tetapi saya perlu menyebutkan bahwa sebagian besar contoh ini adalah PowerShell v3.0 dan yang lebih baru.
$myObject = [pscustomobject]@{
Name = 'Kevin'
Language = 'PowerShell'
State = 'Texas'
}
Metode ini bekerja dengan baik untuk saya karena saya menggunakan hashtable untuk hampir semuanya. Ada kalanya saya ingin PowerShell memperlakukan hashtabel lebih seperti objek. Tempat pertama yang Anda perhatikan perbedaannya adalah ketika Anda ingin menggunakan Format-Table
atau Export-Csv
dan Anda menyadari bahwa hashtable hanyalah kumpulan pasangan kunci/nilai.
Anda kemudian dapat mengakses dan menggunakan nilai seperti objek normal.
$myObject.Name
Mengonversi sebuah tabel hash
Sementara saya sedang dalam topik, tahukah Anda bahwa Anda bisa melakukan ini:
$myHashtable = @{
Name = 'Kevin'
Language = 'PowerShell'
State = 'Texas'
}
$myObject = [pscustomobject]$myHashtable
Saya lebih suka membuat objek dari awal, tetapi ada kalanya Anda harus bekerja dengan sebuah hashtable terlebih dahulu. Contoh ini berfungsi karena konstruktor (fungsi pembangun) menggunakan hashtable untuk properti objek. Salah satu catatan penting adalah bahwa meskipun metode ini berfungsi, metode ini tidak sama persis. Perbedaan terbesar adalah urutan properti tidak dipertahankan.
Jika Anda ingin mempertahankan urutan, lihat tabel hash yang diurutkan .
Pendekatan warisan
Anda mungkin telah melihat orang menggunakan New-Object
untuk membuat objek kustom.
$myHashtable = @{
Name = 'Kevin'
Language = 'PowerShell'
State = 'Texas'
}
$myObject = New-Object -TypeName psobject -Property $myHashtable
Cara ini cukup lambat tetapi mungkin merupakan opsi terbaik Anda pada versi awal PowerShell.
Menyimpan ke file
Saya menemukan cara terbaik untuk menyimpan hashtable ke file adalah dengan menyimpannya sebagai JSON. Anda dapat mengimpornya kembali ke [pscustomobject]
$myObject | ConvertTo-Json -Depth 1 | Set-Content -Path $Path
$myObject = Get-Content -Path $Path | ConvertFrom-Json
Saya membahas lebih banyak cara untuk menyimpan objek ke file di artikel saya di Banyak cara untuk membaca dan menulis ke file.
Bekerja dengan properti
Menambahkan properti
Anda masih dapat menambahkan properti baru ke PSCustomObject
Anda dengan Add-Member
.
$myObject | Add-Member -MemberType NoteProperty -Name 'ID' -Value 'KevinMarquette'
$myObject.ID
Hapus properti
Anda juga dapat menghapus properti dari objek.
$myObject.psobject.Properties.Remove('ID')
.psobject
adalah anggota intrinsik yang memberi Anda akses ke metadata objek dasar. Untuk informasi selengkapnya tentang anggota intrinsik, lihat about_Intrinsic_Members.
Menghitung nama properti
Terkadang Anda memerlukan daftar semua nama properti pada objek.
$myObject | Get-Member -MemberType NoteProperty | select -ExpandProperty Name
Kita bisa mendapatkan daftar yang sama ini dari properti psobject
juga.
$myobject.psobject.Properties.Name
Nota
Get-Member
mengembalikan properti dalam urutan alfabet. Menggunakan operator akses anggota untuk menghitung nama properti mengembalikan properti dalam urutan yang ditentukan pada objek.
Mengakses properti secara dinamis
Saya sudah menyebutkan bahwa Anda dapat mengakses nilai properti secara langsung.
$myObject.Name
Anda dapat menggunakan string sebagai nama properti, dan tetap akan berfungsi.
$myObject.'Name'
Kita dapat mengambil satu langkah lagi ini dan menggunakan variabel untuk nama properti.
$property = 'Name'
$myObject.$property
Aku tahu itu terlihat aneh, tapi berhasil.
Mengonversi PSCustomObject menjadi hashtable
Untuk melanjutkan dari bagian terakhir, Anda dapat secara dinamis menelusuri properti dan membuat hashtable dari properti tersebut.
$hashtable = @{}
foreach( $property in $myobject.psobject.Properties.Name )
{
$hashtable[$property] = $myObject.$property
}
Pengujian sifat-sifat
Jika Anda perlu tahu apakah properti ada, Anda bisa memeriksa apakah properti tersebut memiliki nilai.
if( $null -ne $myObject.ID )
Tetapi jika nilainya bisa $null
Anda dapat memeriksa apakah nilai tersebut ada dengan memeriksa psobject.Properties
untuk nilai tersebut.
if( $myobject.psobject.Properties.Match('ID').Count )
Menambahkan metode objek
Jika Anda perlu menambahkan metode skrip ke objek, Anda dapat melakukannya dengan Add-Member
dan ScriptBlock
. Anda harus menggunakan variabel otomatis this
mereferensikan objek saat ini. Berikut adalah scriptblock
untuk mengubah objek menjadi tabel hash. (kode yang sama membentuk contoh terakhir)
$ScriptBlock = {
$hashtable = @{}
foreach( $property in $this.psobject.Properties.Name )
{
$hashtable[$property] = $this.$property
}
return $hashtable
}
Kemudian kita menambahkannya ke objek kita sebagai properti skrip.
$memberParam = @{
MemberType = "ScriptMethod"
InputObject = $myobject
Name = "ToHashtable"
Value = $scriptBlock
}
Add-Member @memberParam
Kemudian kita dapat memanggil fungsi kita seperti ini:
$myObject.ToHashtable()
Jenis objek vs Nilai
Objek dan jenis nilai tidak menangani penetapan variabel dengan cara yang sama. Jika Anda menetapkan jenis nilai satu sama lain, hanya nilainya yang akan disalin ke variabel baru.
$first = 1
$second = $first
$second = 2
Dalam hal ini, $first
adalah 1 dan $second
adalah 2.
Variabel objek menyimpan referensi ke objek aktual. Saat Anda menetapkan satu objek ke variabel baru, objek tersebut masih mereferensikan objek yang sama.
$third = [pscustomobject]@{Key=3}
$fourth = $third
$fourth.Key = 4
Karena $third
dan $fourth
mereferensikan instans objek yang sama, baik $third.key
maupun $fourth.Key
adalah 4.
psobject. Copy()
Jika Anda memerlukan salinan objek yang benar, Anda dapat mengkloningnya.
$third = [pscustomobject]@{Key=3}
$fourth = $third.psobject.Copy()
$fourth.Key = 4
Mengklon membuat salinan dangkal dari objek. Sekarang, mereka memiliki contoh kejadian yang berbeda dan $third.key
adalah 3 dan $fourth.Key
adalah 4 dalam contoh ini.
Saya menyebutnya salinan dangkal karena jika Anda memiliki objek berlapis (objek dengan properti berisi objek lain), hanya nilai tingkat atas yang disalin. Objek anak akan merujuk satu sama lain.
PSTypeName untuk jenis objek kustom
Sekarang setelah kita memiliki objek, ada beberapa hal lagi yang dapat kita lakukan dengannya yang mungkin tidak begitu jelas. Langkah pertama yang perlu kita lakukan adalah memberikan PSTypeName
padanya. Ini adalah cara paling umum saya melihat orang melakukannya:
$myObject.psobject.TypeNames.Insert(0,"My.Object")
Saya baru-baru ini menemukan cara lain untuk melakukan ini dari Redditor u/markekraus
. Dia berbicara tentang pendekatan ini yang memungkinkan Anda menentukannya secara langsung.
$myObject = [pscustomobject]@{
PSTypeName = 'My.Object'
Name = 'Kevin'
Language = 'PowerShell'
State = 'Texas'
}
Saya suka betapa cocoknya ini dengan bahasa. Sekarang kita memiliki objek dengan nama jenis yang tepat, kita dapat melakukan beberapa hal lagi.
Nota
Anda juga dapat membuat jenis PowerShell kustom menggunakan kelas PowerShell. Untuk informasi selengkapnya, lihat Ikhtisar Kelas PowerShell.
Menggunakan DefaultPropertySet (jalan panjang)
PowerShell memutuskan properti apa yang akan ditampilkan secara default. Banyak perintah asli memiliki file pemformatan .ps1xml
yang menangani semua tugas rumit. Dari posting ini oleh Boe Prox, ada cara lain bagi kita untuk melakukan ini pada objek kustom kita dengan hanya menggunakan PowerShell. Kita bisa mengatur MemberSet
untuk digunakan.
$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
Sekarang ketika objek saya jatuh pada antarmuka shell, itu hanya akan menampilkan properti-properti tersebut secara default.
Update-TypeData dengan DefaultPropertySet
Ini bagus tetapi baru-baru ini saya melihat cara yang lebih baik menggunakan Update-TypeData untuk menentukan properti default.
$TypeData = @{
TypeName = 'My.Object'
DefaultDisplayPropertySet = 'Name','Language'
}
Update-TypeData @TypeData
Itu cukup sederhana sehingga saya hampir bisa mengingatnya jika saya tidak memiliki posting ini sebagai referensi cepat. Sekarang saya dapat dengan mudah membuat objek dengan banyak properti dan tetap memberikan tampilan bersih yang bagus saat melihatnya dari shell. Jika saya perlu mengakses atau melihat properti lain tersebut, properti tersebut masih ada.
$myObject | Format-List *
Update-TypeData dengan ScriptProperty
Sesuatu yang saya pelajari dari video itu adalah cara membuat properti skrip untuk objek Anda. Ini akan menjadi waktu yang tepat untuk menunjukkan bahwa ini juga berfungsi untuk objek yang ada.
$TypeData = @{
TypeName = 'My.Object'
MemberType = 'ScriptProperty'
MemberName = 'UpperCaseName'
Value = {$this.Name.ToUpper()}
}
Update-TypeData @TypeData
Anda dapat melakukan ini sebelum objek Anda dibuat atau setelahnya dan itu akan tetap berfungsi. Inilah yang membuat ini berbeda dari menggunakan Add-Member
dengan properti skrip. Ketika Anda menggunakan Add-Member
dengan cara yang telah saya sebutkan sebelumnya, hanya ada pada contoh objek tersebut. Yang satu ini berlaku untuk semua objek dengan TypeName
ini.
Parameter fungsi
Anda sekarang dapat menggunakan jenis kustom ini untuk parameter dalam fungsi dan skrip Anda. Anda dapat memiliki satu fungsi membuat objek kustom ini lalu meneruskannya ke fungsi lain.
param( [PSTypeName('My.Object')]$Data )
PowerShell mengharuskan objek adalah jenis yang Anda tentukan. Ini menghasilkan kesalahan validasi jika jenisnya tidak cocok secara otomatis, sehingga Anda tidak perlu melakukan pengujian dalam kode Anda. Contoh yang bagus untuk membiarkan PowerShell melakukan apa yang terbaik.
Fungsi OutputType
Anda juga dapat menentukan OutputType
untuk fungsi lanjutan Anda.
function Get-MyObject
{
[OutputType('My.Object')]
[CmdletBinding()]
param
(
...
Nilai atribut OutputType hanyalah catatan dokumentasi. Ini tidak berasal dari kode fungsi atau dibandingkan dengan output fungsi aktual.
Alasan utama Anda akan menggunakan jenis output adalah agar informasi meta tentang fungsi Anda mencerminkan niat Anda. Hal-hal seperti Get-Command
dan Get-Help
yang dapat dimanfaatkan oleh lingkungan pengembangan Anda. Jika Anda ingin informasi lebih lanjut, lihat bantuan untuk itu: about_Functions_OutputTypeAttribute.
Dengan demikian, jika Anda menggunakan Pester untuk menyatukan pengujian fungsi Anda maka akan menjadi ide yang baik untuk memvalidasi objek output yang cocok dengan OutputType Anda. Ini bisa menangkap variabel yang tanpa sengaja masuk ke dalam pipa saat seharusnya tidak boleh.
Pemikiran Akhir
Konteksnya adalah tentang [pscustomobject]
, tetapi banyak informasi ini berlaku untuk objek secara umum.
Saya telah melihat sebagian besar fitur ini hanya sekilas sebelumnya tetapi tidak pernah melihatnya disajikan sebagai kumpulan informasi tentang PSCustomObject
. Minggu lalu aku tersandung satu lagi dan terkejut bahwa aku belum pernah melihatnya sebelumnya. Saya ingin menarik semua ide-ide ini bersama-sama sehingga Anda mudah-mudahan dapat melihat gambaran yang lebih besar dan menyadarinya ketika Anda memiliki kesempatan untuk menggunakannya. Saya harap Anda belajar sesuatu dan dapat menemukan cara untuk menerapkannya ke dalam skrip Anda.