什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

PowerShell解釋器視窗中命令的文字輸出只是一種以適合人類感知的形式顯示資訊的方式。 其實星期三 導向的 使用物件:cmdlet 和函數接收它們作為輸入並 在出口處返回,並且互動式和腳本中可用的變數類型是基於 .NET 類別。 在本系列的第四篇文章中,我們將更詳細地研究如何使用物件。

目錄:

PowerShell 中的對象
查看物件的結構
篩選對象
對物件進行排序
選擇物件及其部分
ForEach-對象、組-對象與測量-對象
建立 .NET 和 COM 物件(新物件)
呼叫靜態方法
類型 PSCustomObject
創建您自己的課程

PowerShell 中的對象

讓我們回想一下,物件是資料欄位(屬性、事件等)和處理它們的方法(方法)的集合。 它的結構由類型指定,該類型通常基於統一.NET Core平台中使用的類別。 也可以使用 COM、CIM (WMI) 和 ADSI 物件。 對資料執行各種操作需要屬性和方法;此外,在PowerShell中,物件可以作為參數傳遞給函數和cmdlet,將它們的值賦給變量,還有 命令組合機制 (輸送機或管道)。 管道中的每個命令將其輸出依次逐個物件傳遞到下一個命令。 對於處理,您可以使用編譯的 cmdlet 或建立自己的 進階功能對管道中的物件執行各種操作:過濾、排序、分組,甚至更改其結構。 以這種形式傳輸資料具有很大的優勢:接收團隊不需要解析位元組流(文字),透過呼叫適當的屬性和方法可以輕鬆檢索所有必要的資訊。

查看物件的結構

例如,讓我們運行 Get-Process cmdlet,它允許您獲取有關係統中運行的進程的資訊:

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

它將顯示一些格式化的文字數據,這些數據不提供有關傳回物件及其方法的屬性的任何資訊。 為了微調輸出,我們需要學習如何檢查物件的結構,Get-Member cmdlet 將幫助我們完成此任務:

Get-Process | Get-Member

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

在這裡,我們已經看到了類型和結構,並且在附加參數的幫助下,我們可以只顯示輸入中包含的物件的屬性:

Get-Process | Get-Member -MemberType Property

以互動方式解決管理問題或編寫自己的腳本將需要這些知識:例如,使用 Responding 屬性來取得掛起進程的資訊。

篩選對象

PowerShell允許滿足特定條件的物件透過管道傳遞:

Where-Object { блок сценария }

執行括號內的腳本區塊的結果必須是布林值。 如果為 true ($true),則輸入到Where-Object cmdlet 的物件將沿著管道傳遞,否則($false) 將被刪除。 例如,讓我們顯示已停止的 Windows Server 服務的列表,即Status 屬性設定為「Stopped」的那些:

Get-Service | Where-Object {$_.Status -eq "Stopped"}

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

這裡我們再次看到了文字表示,但是如果你想了解透過管道傳遞的物件的類型和內部結構並不困難:

Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

對物件進行排序

當管道處理物件時,經常需要對它們進行排序。 Sort-Object cmdlet 傳遞屬性名稱(排序鍵)並傳回依其值排序的物件。 透過花費的 CPU 時間(cpu 屬性)對正在運行的進程的輸出進行排序很容易:

Get-Process | Sort-Object –Property cpu

當呼叫 Sort-Object cmdlet 時可以省略 -Property 參數;預設使用此參數。 對於反向排序,請使用 -Descending 參數:

Get-Process | Sort-Object cpu -Descending

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

選擇物件及其部分

Select-Object cmdlet 可讓您使用 -First 或 -Last 參數在管道的開頭或結尾選擇特定數量的物件。 在它的幫助下,您可以選擇單一物件或某些屬性,也可以基於它們建立新物件。 讓我們透過簡單的範例來了解 cmdlet 的工作原理。

以下命令顯示有關消耗最大 RAM 量(WS 屬性)的 10 個進程的資訊:

Get-Process | Sort-Object WS -Descending | Select-Object -First 10

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

您可以僅選擇通過管道的物件的某些屬性,並基於它們建立新的屬性:

Get-Process | Select-Object ProcessName, Id -First 1

作為管道操作的結果,我們將收到一個新對象,其結構將與 Get-Process cmdlet 傳回的結構不同。 讓我們使用 Get-Member 來驗證這一點:

Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

請注意,Select-Object 傳回單一物件 (-First 1),該物件僅包含我們指定的兩個欄位:它們的值是從 Get-Process cmdlet 傳遞到管道的第一個物件中複製的。 在 PowerShell 腳本中建立物件的方法之一是基於使用 Select-Object:

$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType()

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

使用 Select-Object,您可以將計算屬性新增至需要表示為的對象 哈希表。 在這種情況下,其第一個鍵的值對應於屬性名稱,第二個鍵的值對應於目前管道元素的屬性值:

Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}}

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

我們來看看通過傳送帶的物體的結構:

Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

ForEach-對象、組-對象與測量-對象

還有其他用於處理物件的 cmdlet。 作為例子,我們來談談三個最有用的:

每個對象 允許您為管道中的每個物件執行 PowerShell 程式碼:

ForEach-Object { блок сценария }

群組對象 按屬性值對物件進行分組:

Group-Object PropertyName

如果使用 -NoElement 參數執行它,您可以找出群組中的元素數量。

測量對象 以管道中的物件欄位值聚合各種總和參數(計算總和,同時也求最小值、最大值或平均值):

Measure-Object -Property PropertyName -Minimum -Maximum -Average -Sum

通常,所討論的 cmdlet 是互動式使用的,並且通常是在腳本中建立的。 功能 包含 Begin、Process 和 End 區塊。

建立 .NET 和 COM 物件(新物件)

有許多具有 .NET Core 和 COM 介面的軟體元件對系統管理員很有用。 使用 System.Diagnostics.EventLog 類別,您可以直接從 Windows PowerShell 管理系統日誌。 讓我們來看看使用帶有 -TypeName 參數的 New-Object cmdlet 來建立此類實例的範例:

New-Object -TypeName System.Diagnostics.EventLog

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

由於我們沒有指定特定的事件日誌,因此產生的類別實例不包含資料。 若要變更此設置,您需要在建立過程中使用 -ArgumentList 參數呼叫特殊的建構子方法。 如果我們想存取應用程式日誌,我們應該將字串“Application”作為參數傳遞給建構子:

$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

請注意,我們將命令的輸出保存在 $AppLog 變數中。 儘管管道通常用於互動模式,但編寫腳本通常需要維護對物件的參考。 此外,核心 .NET Core 類別包含在 System 命名空間中:PowerShell 預設會尋找其中的指定類型,因此編寫 Diagnostics.EventLog 而不是 System.Diagnostics.EventLog 是非常正確的。

要使用日誌,您可以使用適當的方法:

$AppLog | Get-Member -MemberType Method

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

假設如果有存取權限,則由 Clear() 方法清除:

$AppLog.Clear()

New-Object cmdlet 也用於處理 COM 元件。 其中有很多 - 從 Windows 腳本伺服器提供的庫到 ActiveX 應用程序,例如 Internet Explorer。 若要建立 COM 對象,您需要使用所需類別的程式設計 ProgId 設定 -ComObject 參數:

New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject

要創建具有任意結構的自己的對象,使用 New-Object 似乎過於陳舊和麻煩;此 cmdlet 用於與 PowerShell 外部的軟體組件配合使用。 在以後的文章中,我們將更詳細地討論這個問題。 除了.NET 和COM 物件之外,我們還將探索CIM (WMI) 和ADSI 物件。

呼叫靜態方法

某些 .NET Core 類別無法實例化,包括 System.Environment 和 System.Math。 他們是 靜態的 並且僅包含靜態屬性和方法。 這些本質上是在不創建物件的情況下使用的參考庫。 您可以將類型名稱括在方括號中來透過文字引用靜態類別。 但是,如果我們使用 Get-Member 查看物件的結構,我們將看到類型 System.RuntimeType 而不是 System.Environment:

[System.Environment] | Get-Member

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

若要僅查看靜態成員,請使用 -Static 參數呼叫 Get-Member(注意物件類型):

[System.Environment] | Get-Member -Static

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

若要存取靜態屬性和方法,請在文字後面使用兩個連續的冒號而不是句點:

[System.Environment]::OSVersion

$test=[System.Math]::Sqrt(25) 
$test
$test.GetType()

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

類型 PSCustomObject

在 PowerShell 中可用的眾多資料類型中,值得一提的是 PSCustomObject,它是為儲存具有任意結構的物件而設計。 使用 New-Object cmdlet 創建這樣的物件被認為是一種經典但麻煩且過時的方法:

$object = New-Object  –TypeName PSCustomObject -Property @{Name = 'Ivan Danko'; 
                                          City = 'Moscow';
                                          Country = 'Russia'}

我們來看一下對象的結構:

$object | Get-Member

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

從 PowerShell 3.0 開始,可以使用另一種語法:

$object = [PSCustomObject]@{Name = 'Ivan Danko'; 
                                          City = 'Moscow';
                                          Country = 'Russia'
}

您可以透過等效方式之一存取資料:

$object.Name

$object.'Name'

$value = 'Name'
$object.$value

以下是將現有哈希表轉換為物件的範例:

$hash = @{'Name'='Ivan Danko'; 'City'='Moscow'; 'Country'='Russia'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

這種類型的物件的缺點之一是它們的屬性順序可以改變。 為了避免這種情況,您必須使用 [ordered] 屬性:

$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko'; 
                                          City = 'Moscow';
                                          Country = 'Russia'
}

還有其他用於建立物件的選項:上面我們查看了使用 cmdlet 選擇對象。 剩下的就是弄清楚新增和刪除元素。 對上一個範例中的物件執行此操作非常簡單:

$object | Add-Member –MemberType NoteProperty –Name Age  –Value 33
$object | Get-Member

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

Add-Member cmdlet 不僅允許您使用「-MemberType ScriptMethod」構造為先前建立的 $object 新增屬性,還可以新增方法:

$ScriptBlock = {
    # код 
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member

請注意,我們使用 ScriptBlock 類型的 $ScriptBlock 變數來儲存新方法的程式碼。

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

若要刪除屬性,請使用對應的方法:

$object.psobject.properties.remove('Name')

創建您自己的課程

PowerShell 5.0 引入了定義的能力 使用物件導向程式語言的語法特徵。 服務詞 Class 就是用於此目的,之後您應該指定類別的名稱並在運算子括號中描述其主體:

class MyClass
{
    # тело класса
}

這是真正的 .NET Core 類型,其主體描述了其屬性、方法和其他元素。 讓我們來看一個定義最簡單的類別的範例:

class MyClass 
{
     [string]$Name
     [string]$City
     [string]$Country
}

若要建立物件(類別實例),請使用 cmdlet 新物件,或 [MyClass] 類型的文字並且 偽靜力法 新(預設建構函數):

$object = New-Object -TypeName MyClass

$object = [MyClass]::new()

讓我們來分析一下對象的結構:

$object | Get-Member

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

不要忘記範圍:您不能將類型名稱作為字串引用,也不能在定義該類別的腳本或模組之外使用類型文字。 在這種情況下,函數可以傳回可在模組或腳本外部存取的類別實例(物件)。

建立物件後,填寫其屬性:

$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

請注意,類別描述不僅指定屬性類型,還指定它們的預設值:

class Example
{
     [string]$Name = 'John Doe'
}

類別方法的描述類似於函數的描述,但不使用函數詞。 與在函數中一樣,如有必要,參數會傳遞給方法:

class MyClass 
{
     [string]$Name
     [string]$City
     [string]$Country
     
     #описание метода
     Smile([bool]$param1)
     {
         If($param1) {
            Write-Host ':)'
         }
     }
}

現在我們班代表可以笑了:

$object = [MyClass]::new()
$object.Smile($true)

方法可以重載;此外,類別還具有 靜態屬性和方法,以及名稱與類別本身名稱一致的建構子。 腳本或 PowerShell 模組中定義的類別可以作為另一個類別的基礎 - 這就是繼承的實作方式。 在這種情況下,允許使用現有的 .NET 類別作為基底類別:

class MyClass2 : MyClass
{
      #тело нового класса, базовым для которого является MyClass
}
[MyClass2]::new().Smile($true)

我們對在 PowerShell 中使用物件的描述並不詳盡。 在接下來的出版物中,我們將嘗試透過實際範例來加深它:該系列的第五篇文章將專門討論 PowerShell 與第三方軟體元件的整合問題。 過去的部分可以在下面的連結中找到。

第 1 部分:基本 Windows PowerShell 功能
第 2 部分:Windows PowerShell 程式語言簡介
第 3 部分:將參數傳遞給腳本和函數,建立 cmdlet

什麼是 Windows PowerShell 以及它的用途是什麼? 第 4 部分:使用物件、自己的類

來源: www.habr.com

添加評論