PowerShell自定義對象詳解

什么是對象

在面向?qū)ο缶幊痰念I域有一句話叫:萬事萬物皆為對象。

我們生活中的每一件東西都可以看作是一個對象,包括我們本身都是一個對象。

這是一種抽象的思想,我們將一件事物提取出特征和行為,將特征定義為屬性,將行為封裝成方法

對象在程序開發(fā)中的概念可以說都一樣。

對象通常有自己的屬性和方法,比如一個人,它的屬性有膚色 /身高/ 性別 等,方法有 走路 /躺下 /呼喊/吃飯/睡覺/打豆豆 等。

什么是PowerShell對象

在powershell中提供了對對象的定義方法;使用這樣的方法創(chuàng)建的變量就是powershell對象。

PowerShell是基于面向?qū)ο蠡?,不像傳統(tǒng)的shell那樣基于文本。這其中最主要的原因就是因為Win平臺在管理操作上主要以面向?qū)ο鬄橹?,因此為了符合系統(tǒng)特點和我們的操作習慣,PowerShell也繼承了這一特色。因此,不像傳統(tǒng)的shell,在PowerShell中,我們可以隨意地與對象進行互動。

1.創(chuàng)建

PS C:\Users\Administrator> $aa = New-Object object
PS C:\Users\Administrator> $aa.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object


PS C:\Users\Administrator> $aa | Get-Member *


 TypeName:System.Object

Name        MemberType Definition
----        ---------- ----------
Equals      Method     bool Equals(System.Object obj)
GetHashCode Method     int GetHashCode()
GetType     Method     type GetType()
ToString    Method     string ToString()


PS C:\Users\Administrator>

2.添加屬性:方法1

PS C:\Users\Administrator> $aa | Add-Member -MemberType NoteProperty -Name "Name" -Value "Jack"
PS C:\Users\Administrator> $aa

Name
----
Jack


PS C:\Users\Administrator> $aa | Get-Member *


 TypeName:System.Object

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Name        NoteProperty string Name=Jack


PS C:\Users\Administrator>

3.添加屬性:方法2

PS C:\Users\Administrator> Add-Member -InputObject $aa -MemberType NoteProperty -Name "Language" -Value "Powershell"
PS C:\Users\Administrator> $aa | Get-Member *


 TypeName:System.Object

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Language    NoteProperty string Language=Powershell
Name        NoteProperty string Name=Jack


PS C:\Users\Administrator> $aa

Name Language
---- --------
Jack Powershell


PS C:\Users\Administrator>

4.添加方法

PS C:\Users\Administrator> $aa | Add-Member -MemberType ScriptMethod -Name "sayhello" -Value { write-host "hello" }
PS C:\Users\Administrator> $aa | Get-Member *


 TypeName:System.Object

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Language    NoteProperty string Language=Powershell
Name        NoteProperty string Name=Jack
sayhello    ScriptMethod System.Object sayhello();


PS C:\Users\Administrator> $aa.sayhello()
hello
PS C:\Users\Administrator>
PS C:\Users\Administrator> $S = { $this.Name.ToUpper() }
PS C:\Users\Administrator> $aa | Add-Member -MemberType ScriptMethod -Name "UpperMyName" -Value $S
PS C:\Users\Administrator> $aa

Name Language
---- --------
Jack Powershell


PS C:\Users\Administrator> $aa.UpperMyName()
JACK
PS C:\Users\Administrator>
PS C:\Users\Administrator> $word = "Goodbye!!!"
PS C:\Users\Administrator> $sayword = { Write-Host $word }
PS C:\Users\Administrator> $aa | Add-Member -MemberType ScriptMethod -Name "sayBye" -Value $sayword
PS C:\Users\Administrator> $aa.sayBye()
Goodbye!!!
PS C:\Users\Administrator>

傳參(注意$this和傳入?yún)?shù)的調(diào)用)

$block = {
 param(
 $var
 )
 $result = "{0},{1} I'm {2}" -f $var,"hello world!!",$this.Name
 return $result
}
$aa | Add-Member -MemberType ScriptMethod -Name "sayAnything" -Value $block

PS C:\Users\Administrator> $aa | Add-Member -MemberType ScriptMethod -Name "sayAnything" -Value $block
PS C:\Users\Administrator> $aa.sayAnything("Tom")
Tom,hello world!! I'm Jack
PS C:\Users\Administrator>

若下個驗證代碼塊是否可以正常運行可以使用:

PS C:\Users\Administrator> &$block
,hello world!!
PS C:\Users\Administrator>

或者

PS C:\Users\Administrator> &$block -var "qq"
qq,hello world!!
PS C:\Users\Administrator>

5.移除方法

PS C:\Users\Administrator> $aa | Get-Member


 TypeName:System.Object

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Language    NoteProperty string Language=Powershell
Name        NoteProperty string Name=Jack
sayAnything ScriptMethod System.Object sayAnything();
sayBye      ScriptMethod System.Object sayBye();
sayhello    ScriptMethod System.Object sayhello();
UpperMyName ScriptMethod System.Object UpperMyName();


PS C:\Users\Administrator> $aa.PsObject.Members.Remove("sayAnything")
PS C:\Users\Administrator> $aa | Get-Member


 TypeName:System.Object

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Language    NoteProperty string Language=Powershell
Name        NoteProperty string Name=Jack
sayBye      ScriptMethod System.Object sayBye();
sayhello    ScriptMethod System.Object sayhello();
UpperMyName ScriptMethod System.Object UpperMyName();


PS C:\Users\Administrator>

什么是PowerShell自定義對象

自定義對象可以完全根據(jù)自己的設計,定義對象的屬性和方法。

PowerShell自定義對象有什么作用

自定義對象可以更符合使用者的要求,因為他的屬性和方法完全由使用者自己定義設定;比默認的對象更加靈活。自己創(chuàng)建的自定義對象完完全全根據(jù)自己的意愿賦予屬性和方法,可以完全做到獨一無二。

PowerShell自定義對象的常見用法

1.創(chuàng)建自定義對象

tips:需要powershell 3.0及以上版本

$myObject = [PSCustomObject]@{
 Name = 'Kevin'
 Language = 'PowerShell'
 State    = 'Texas'
}
##創(chuàng)建
PS C:\WINDOWS\System32> $myObject = [PSCustomObject]@{
>> Name = 'Kevin'
>> Language = 'PowerShell'
>> State    = 'Texas'
>> }
PS C:\WINDOWS\System32>

##查看
PS C:\WINDOWS\System32> $myObject

Name  Language   State
----  --------   -----
Kevin PowerShell Texas

##查看屬性
PS C:\WINDOWS\System32> $myObject.name
Kevin
PS C:\WINDOWS\System32>

上面這些利用hashtable也能實現(xiàn)基本一樣的效果,那我們來做下對比:

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

##創(chuàng)建
PS C:\WINDOWS\System32> $myHashtable = @{
>> Name = 'Kevin'
>> Language = 'PowerShell'
>> State    = 'Texas'
>> }
PS C:\WINDOWS\System32>
#查看
PS C:\WINDOWS\System32> $myHashtable

Name                           Value
----                           -----
Name                           Kevin
Language                       PowerShell
State                          Texas


##查看屬性
PS C:\WINDOWS\System32> $myHashtable.Name
Kevin
PS C:\WINDOWS\System32>

2.自定義對象 vs. HashTable

類型不同

PS C:\WINDOWS\System32> $myObject.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object


PS C:\WINDOWS\System32>
PS C:\WINDOWS\System32> $myHashtable.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Hashtable                                System.Object


PS C:\WINDOWS\System32>

可用的方法不同

PS C:\WINDOWS\System32> $myHashtable.Count
3
PS C:\WINDOWS\System32> $myObject.Count
PS C:\WINDOWS\System32>

Member大大不同

##查看Member
PS C:\WINDOWS\System32> $myObject | Get-Member


 TypeName:System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Language    NoteProperty string Language=PowerShell
Name        NoteProperty string Name=Kevin
State       NoteProperty string State=Texas

##利用select
PS C:\WINDOWS\System32> $myObject | select name

Name
----
Kevin


PS C:\WINDOWS\System32>



##查看Member
PS C:\WINDOWS\System32> $myHashtable | Get-Member


 TypeName:System.Collections.Hashtable

Name              MemberType            Definition
----              ----------            ----------
Add               Method                void Add(System.Object key, System.Object value), void IDictionary.Add(System.Object key, System.Object value)
Clear             Method                void Clear(), void IDictionary.Clear()
Clone             Method                System.Object Clone(), System.Object ICloneable.Clone()
Contains          Method                bool Contains(System.Object key), bool IDictionary.Contains(System.Object key)
ContainsKey       Method                bool ContainsKey(System.Object key)
ContainsValue     Method                bool ContainsValue(System.Object value)
CopyTo            Method                void CopyTo(array array, int arrayIndex), void ICollection.CopyTo(array array, int index)
Equals            Method                bool Equals(System.Object obj)
GetEnumerator     Method                System.Collections.IDictionaryEnumerator GetEnumerator(), System.Collections.IDictionaryEnumerator IDictionary.GetEnumerator(), System.Collections.IEnume...
GetHashCode       Method                int GetHashCode()
GetObjectData     Method                void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context), void ISerializable.GetObj...
GetType           Method                type GetType()
OnDeserialization Method                void OnDeserialization(System.Object sender), void IDeserializationCallback.OnDeserialization(System.Object sender)
Remove            Method                void Remove(System.Object key), void IDictionary.Remove(System.Object key)
ToString          Method                string ToString()
Item              ParameterizedProperty System.Object Item(System.Object key) {get;set;}
Count             Property              int Count {get;}
IsFixedSize       Property              bool IsFixedSize {get;}
IsReadOnly        Property              bool IsReadOnly {get;}
IsSynchronized    Property              bool IsSynchronized {get;}
Keys              Property              System.Collections.ICollection Keys {get;}
SyncRoot          Property              System.Object SyncRoot {get;}
Values            Property              System.Collections.ICollection Values {get;}

##利用select
PS C:\WINDOWS\System32>
PS C:\WINDOWS\System32> $myHashtable | select Name

Name
----



PS C:\WINDOWS\System32>

注意:對于hashtable而言,我們的例子中演示的結(jié)果雖然也能通過$myHashtable.Name顯示出與$myObject.Name一樣的結(jié)果;但是,$myHashtable.Name真正的寫法應該是$myHashtable.Item("Name")

因為hashtable僅僅是鍵值對,所以無法通過使用Format-TableExport-CSVSelect的方法對數(shù)據(jù)進行處理。

3.HashTable轉(zhuǎn)換成PSCustomObject

PS C:\WINDOWS\System32> $myHashtable = @{
>>     Name     = 'Kevin'
>>     Language = 'PowerShell'
>>     State    = 'Texas'
>> }
>> $myObject = [pscustomobject]$myHashtable
PS C:\WINDOWS\System32> $myObject

Name  Language   State
----  --------   -----
Kevin PowerShell Texas


PS C:\WINDOWS\System32>

注意:強烈建議如果在需要使用自定義對象的情況時從一開始使用;因為像這種從hashtable轉(zhuǎn)換的PSCustomObject,實際上肯惡搞并不完全保障對象屬性的順序。

當然,這種情況目前可以通過[ordered]@()來解決,但這不時本片文章的討論重點。

將哈希表保存到文件的最佳方法是將其保存為 JSON。 可以將其導入回 [PSCustomObject]

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

4.歷史遺留問題

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

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

老版本的powershell使用上述方法創(chuàng)建自定義對象;但這種方法創(chuàng)建的速度比較慢,而且時公認要逐步廢棄的方法;除非你是老版本,否則請務必精良使用新的方法創(chuàng)建。

5.自定義對象的屬性

5.1添加屬性

PS C:\WINDOWS\System32> $myObject

Name  Language   State
----  --------   -----
Kevin PowerShell Texas


PS C:\WINDOWS\System32>
PS C:\WINDOWS\System32>
PS C:\WINDOWS\System32> $myObject | Add-Member -MemberType NoteProperty -Name 'ID' -Value 'KevinMarquette'
PS C:\WINDOWS\System32>
PS C:\WINDOWS\System32> $myObject

Name  Language   State ID
----  --------   ----- --
Kevin PowerShell Texas KevinMarquette


PS C:\WINDOWS\System32>
PS C:\WINDOWS\System32> $myObject.ID
KevinMarquette
PS C:\WINDOWS\System32>

5.2移除屬性

PS C:\WINDOWS\System32> $myObject.psobject.properties.remove('ID')
PS C:\WINDOWS\System32> $myObject

Name  Language   State
----  --------   -----
Kevin PowerShell Texas


PS C:\WINDOWS\System32>

.psobject 是內(nèi)部成員,它使你能夠訪問基對象元數(shù)據(jù)。

5.3列出屬性名稱

PS C:\WINDOWS\System32> $myObject | Get-Member -MemberType NoteProperty | Select -ExpandProperty Name
Language
Name
State

PS C:\WINDOWS\System32> $myObject | Get-Member


 TypeName:System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Language    NoteProperty string Language=PowerShell
Name        NoteProperty string Name=Kevin
State       NoteProperty string State=Texas


PS C:\WINDOWS\System32>

或者

PS C:\WINDOWS\System32> $myobject.psobject.properties.name
Name
Language
State
PS C:\WINDOWS\System32>

5.4動態(tài)訪問屬性

$myObject.Name
or
$myObject.'Name'

都是允許的方法

PS C:\WINDOWS\System32> $myObject.Name
Kevin
PS C:\WINDOWS\System32> $myObject.'Name'
Kevin
PS C:\WINDOWS\System32>


因此我們可以利用第二種方式并定義變量的形式實現(xiàn)動態(tài)訪問自定義對象的屬性

$property = 'Name'
$myObject.$property

PS C:\WINDOWS\System32> $property = 'Name'
PS C:\WINDOWS\System32> $myObject.$property
Kevin
PS C:\WINDOWS\System32>

6.PSCustomObject轉(zhuǎn)換為HshTable

PS C:\WINDOWS\System32> $hashtable = @{}
PS C:\WINDOWS\System32> foreach( $property in $myobject.psobject.properties.name )
>> {
>>     $hashtable[$property] = $myObject.$property
>> }
PS C:\WINDOWS\System32>
PS C:\WINDOWS\System32> $hashtable

Name                           Value
----                           -----
Name                           Kevin
Language                       PowerShell
State                          Texas


PS C:\WINDOWS\System32>

7.自定義對象的方法(Method)

如果需要將腳本方法添加到對象,則可以使用 Add-MemberScriptBlock 執(zhí)行此操作。 必須使用 this 自動變量引用當前對象。 下面是將對象轉(zhuǎn)換為哈希表的 scriptblock。

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

然后

PS C:\WINDOWS\System32> $memberParam = @{
>>     MemberType = "ScriptMethod"
>>     InputObject = $myobject
>>     Name = "ToHashtable"
>>     Value = $scriptBlock
>> }
PS C:\WINDOWS\System32> Add-Member @memberParam
PS C:\WINDOWS\System32>
PS C:\WINDOWS\System32> $myObject

Name  Language   State
----  --------   -----
Kevin PowerShell Texas


PS C:\WINDOWS\System32> $myObject | Get-Member


 TypeName:System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Language    NoteProperty string Language=PowerShell
Name        NoteProperty string Name=Kevin
State       NoteProperty string State=Texas
ToHashtable ScriptMethod System.Object ToHashtable();


PS C:\WINDOWS\System32>

使用自定義的Method

PS C:\WINDOWS\System32> $myObject.ToHashtable()

Name                           Value
----                           -----
Name                           Kevin
Language                       PowerShell
State                          Texas


PS C:\WINDOWS\System32>

8.自定義對象類型的 PSTypeName

既然我們有了一個對象,我們還可以用它做一些可能不那么顯而易見的事情。 第一件事就是為它指定 PSTypeName。 以下是我看到的最常用的方法:

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


PS C:\Users\Administrator> $myObject.PSObject.TypeNames
My.Object
System.Management.Automation.PSCustomObject
System.Object
PS C:\Users\Administrator>

或者

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

PS C:\Users\Administrator> $myObject.PSObject.TypeNames
My.Object
System.Management.Automation.PSCustomObject
System.Object
PS C:\Users\Administrator>
##我本人更新?lián)Q這種方式

9.自定義對象結(jié)合array使用的例子(一般寫腳本收集數(shù)據(jù)時比較常用)

$myObject1 = [PSCustomObject]@{
 Name     = 'Arthur'
 Language = 'PowerShell'
 State    = 'Texas'
}


$myObject2 = [PSCustomObject]@{
 Name     = 'Bill'
 Language = 'Python'
 State    = 'Texas'
}
$a = @()

$a += $myObject1
$a += $myObject2

PS C:\Users\Administrator> $a

Name     Language   State
----     --------   -----
Arthur   PowerShell Texas
Bill     Python     Texas


PS C:\Users\Administrator>
PS C:\Users\Administrator> $a | select Name

Name
----
Arthur
Bill

PS C:\Users\Administrator>

Powershell自定義變量進階篇

1.Update-TypeData

PowerShell 為我們決定默認情況下顯示哪些屬性。 很多本機命令都有一個可以完成所有繁重工作的 .ps1xml格式化文件

1.1帶有 DefaultPropertySet 的 Update-TypeData

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

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

PS C:\Users\Administrator> $myObject | Format-List
Name     : Kevin
Language : PowerShell

PS C:\Users\Administrator> $myObject | Format-List *
Name     : Kevin
Language : PowerShell
State    : Texas

PS C:\Users\Administrator>

現(xiàn)在,我可以輕松地創(chuàng)建具有很多屬性的對象,并在從 shell 中查看時,為其提供一個經(jīng)過定制的干凈清爽的視圖。

1.2帶有 ScriptProperty 的 Update-TypeData

如何為你的對象創(chuàng)建腳本屬性呢?

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

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


PS C:\Users\Administrator> $myObject | Format-List *


Name          : Kevin
Language      : PowerShell
State         : Texas
UpperCaseName : KEVIN



PS C:\Users\Administrator>

你可以在創(chuàng)建對象之前或之后執(zhí)行此操作,它仍可正常工作。 這就是將 Add-Member 與腳本屬性一起使用帶來的不同之處。 當你通過我前面提及的方式使用 Add-Member 時,它只存在于對象的特定實例上。 此方法適用于具有此 TypeName 的所有對象。

本文如有考慮步驟出現(xiàn)任何紕漏,歡迎大家不吝指正。
——夏明亮

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容