簡短描述
說明如何使用 Types.ps1xml 檔案來擴充 PowerShell 中使用的物件類型。
完整描述
擴充類型數據會定義PowerShell中物件類型的其他屬性和方法(“members”)。 將擴充類型數據新增至PowerShell工作階段有兩種技術。
-
Types.ps1xml檔案:定義擴充型別數據的 XML 檔案。 -
Update-TypeData:用於重載Types.ps1xml檔案,並在目前會話中為型別定義擴展資料的 Cmdlet。
本主題描述 Types.ps1xml 檔案。 如需使用 Update-TypeData Cmdlet 將動態擴充類型數據新增至目前工作階段的詳細資訊,請參閱 Update-TypeData。
關於延伸類型資料
擴充類型數據會定義PowerShell中物件類型的其他屬性和方法(“members”)。 您可以擴充 PowerShell 所支援的任何類型,並使用新增的屬性和方法,就像使用物件類型上定義的屬性一樣。
例如,PowerShell 會將 DateTime 屬性新增至所有 System.DateTime 物件,例如 Get-Date Cmdlet 傳回的物件。
(Get-Date).DateTime
Sunday, January 29, 2012 9:43:57 AM
你在 System.DateTime 結構的描述中找不到 DateTime 屬性,因為這個屬性是由 PowerShell 添加的,且僅在 PowerShell 中可見。
PowerShell 會在內部定義一組預設的擴充類型。 此類型資訊會在啟動時在每個 PowerShell 工作階段中載入。
DateTime 屬性是這個預設集合的一部分。 在 PowerShell 6 之前,類型定義會儲存在 PowerShell 安裝目錄中 Types.ps1xml 檔案($PSHOME)。
將擴充類型資料新增至 PowerShell
PowerShell 會話中有三個擴充類型數據的來源。
擴充類型數據是由 PowerShell 定義,並自動載入至每個 PowerShell 會話。 從 PowerShell 6 開始,這項資訊會編譯成 PowerShell,不再隨附於
Types.ps1xml檔案中。當模組匯入目前會話時,會載入模組導出的
Types.ps1xml檔案。使用
Update-TypeDataCmdlet 所定義的擴充型別數據只會新增至目前的會話。 它不會儲存在檔案中。
在會話中,來自三個來源的擴充型別數據會以相同方式套用至物件,而且可在指定型別的所有物件上使用。
TypeData Cmdlet
下列 Cmdlet 包含在 PowerShell 3.0 和更新版本中的 Microsoft.PowerShell.Utility 模組中。
-
Get-TypeData:取得目前會話中的擴展類型的資料。 -
Update-TypeData:重載Types.ps1xml檔案。 將擴充類型數據加入至目前的會話。 -
Remove-TypeData:從目前的會話移除延伸類型資料。
如需這些 Cmdlet 的詳細資訊,請參閱每個 Cmdlet 的說明主題。
內建 Types.ps1xml 檔案
Types.ps1xml 目錄中的 $PSHOME 檔案會自動新增至每個會話。
PowerShell 安裝目錄 (Types.ps1xml) 中的 $PSHOME 檔案是以 XML 為基礎的文字檔,可讓您將屬性和方法新增至 PowerShell 中使用的物件。 PowerShell 有內建 Types.ps1xml 檔案,可將數個元素新增至 .NET 類型,但您可以建立其他 Types.ps1xml 檔案來進一步擴充類型。
例如,根據預設,陣列物件 (System.Array) 具有 Length 屬性,可列出陣列中的物件數目。 不過,因為名稱 Length 並未清楚描述屬性,因此 PowerShell 會新增名為 Count 的別名屬性,以顯示相同的值。 下列 XML 會將 Count 屬性新增至 System.Array 類型。
<Type>
<Name>System.Array</Name>
<Members>
<AliasProperty>
<Name>Count</Name>
<ReferencedMemberName>
Length
</ReferencedMemberName>
</AliasProperty>
</Members>
</Type>
若要取得新的 AliasProperty,請在任何陣列上使用 Get-Member 命令,如下列範例所示。
Get-Member -InputObject (1,2,3,4)
此命令會傳回下列結果。
Name MemberType Definition
---- ---------- ----------
Count AliasProperty Count = Length
Address Method System.Object& Address(Int32)
Clone Method System.Object Clone()
CopyTo Method System.Void CopyTo(Array array, Int32 index):
Equals Method System.Boolean Equals(Object obj)
Get Method System.Object Get(Int32)
# ...
因此,您可以使用 PowerShell 中陣列的 Count 屬性或陣列的 Length 屬性。 例如:
(1, 2, 3, 4).Count
4
(1, 2, 3, 4).Length
4
建立新的 Types.ps1xml 檔案
使用 PowerShell 安裝的 .ps1xml 檔案會經過數位簽章,以防止被竄改,因為格式可能包含腳本區塊。 因此,若要將屬性或方法新增至 .NET 類型,請建立自己的 Types.ps1xml 檔案,然後將它們新增至 PowerShell 會話。
若要建立新的檔案,請從複製現有的 Types.ps1xml 檔案開始。 新檔案可以有任何名稱,但它必須具有 .ps1xml 擴展名。 您可以將新檔案放在 PowerShell 可存取的任何目錄中,但將檔案放在 PowerShell 安裝目錄 ($PSHOME) 或安裝目錄的子目錄中很有用。
當您儲存新檔案時,請使用 Update-TypeData Cmdlet 將新檔案新增至 PowerShell 會話。 如果您想要讓類型優先於定義的內建類型,請使用 Cmdlet 的 Update-TypeData 參數。
Update-TypeData 只會影響目前的會話。 若要變更所有未來的會話,請導出主控台,或將 Update-TypeData 命令新增至 PowerShell 配置檔。
Types.ps1xml 和 Add-Member
Types.ps1xml 檔案會將屬性和方法新增至受影響 PowerShell 工作階段中指定 .NET 類型之物件的所有實例。 不過,如果您只需要將屬性或方法新增至物件的一個實例,請使用 Add-Member Cmdlet。 如需詳細資訊,請參閱 Add-Member。
範例:將 Age 成員新增至 FileInfo 物件
此範例示範如何將 Age 屬性新增至 system.IO.FileInfo 物件。 檔案的存留期是其建立時間和目前天數之間的差異。
因為 Age 屬性是用 scriptblock 計算的,請找一個 <ScriptProperty> 標籤作為新 Age 屬性的模型。
將下列 XML 程式代碼儲存至檔案 $PSHOME\MyTypes.ps1xml。
<?xml version="1.0" encoding="utf-8" ?>
<Types>
<Type>
<Name>System.IO.FileInfo</Name>
<Members>
<ScriptProperty>
<Name>Age</Name>
<GetScriptBlock>
((Get-Date) - ($this.CreationTime)).Days
</GetScriptBlock>
</ScriptProperty>
</Members>
</Type>
</Types>
執行 Update-TypeData,將新的 Types.ps1xml 檔案新增至目前的會話。 此命令會使用 prependData 參數,將新檔案置於高於原始定義的優先順序。 如需 Update-TypeData的詳細資訊,請參閱 Update-TypeData。
Update-TypeData -PrependPath $PSHOME\MyTypes.ps1xml
若要測試變更,請執行 Get-ChildItem 命令以取得 powershell.exe 目錄中的 $PSHOME 檔案,然後將檔案傳送至 Format-List Cmdlet,以列出檔案的所有屬性。 由於變更,Age 屬性會出現在清單中。
Get-ChildItem $PSHOME\pwsh.exe | Select-Object Age
142
Types.ps1xml 檔案中的 XML
您可以在 GitHub 上 PowerShell 原始程式碼存放庫中的 Types.xsd 中找到完整的架構定義。
<Types> 標記會括住檔案中定義的所有類型。 應該只有一個 <Types> 標記。
檔案中提及的每個 .NET 類型都應該以 <Type> 標記來表示。
類型標籤必須包含下列標籤:
<Name>:括住受影響 .NET 類型的名稱。
<Members>:括住為 .NET 類型定義之新屬性和方法的標記。
以下任一成員標籤都可以放置在 <Members> 標籤內。
AliasProperty
定義現有屬性的新名稱。
<AliasProperty> 標籤必須具有 <Name> 標記,指定新屬性的名稱,以及指定現有屬性的 <ReferencedMemberName> 標記。
例如,Count alias 屬性是陣列物件的 Length 屬性的別名。
<Type>
<Name>System.Array</Name>
<Members>
<AliasProperty>
<Name>Count</Name>
<ReferencedMemberName>Length</ReferencedMemberName>
</AliasProperty>
</Members>
</Type>
CodeMethod
參考 .NET 類別的靜態方法。
<CodeMethod> 標記必須具有指定新方法名稱的 <Name> 標記,以及指定方法定義程式代碼的 <CodeReference> 標記。
例如,ToString 方法是 Microsoft.PowerShell.ToStringCodeMethods 程式代碼定義的名稱。
<Type>
<Name>System.Xml.XmlNode</Name>
<Members>
<CodeMethod>
<Name>ToString</Name>
<CodeReference>
<TypeName>Microsoft.PowerShell.ToStringCodeMethods</TypeName>
<MethodName>XmlNode</MethodName>
</CodeReference>
</CodeMethod>
</Members>
</Type>
程式屬性
參考 .NET 類別的靜態方法。
<CodeProperty> 標記必須具有 <Name> 標記,指定新屬性的名稱,以及指定定義屬性之程式代碼的 <GetCodeReference> 標記。
例如, 物件的 System.IO.DirectoryInfo 屬性是在 PowerShell FileSystem 提供者中定義的程式代碼屬性。
<Type>
<Name>System.IO.DirectoryInfo</Name>
<Members>
<CodeProperty>
<Name>Mode</Name>
<GetCodeReference>
<TypeName>
Microsoft.PowerShell.Commands.FileSystemProvider
</TypeName>
<MethodName>Mode</MethodName>
</GetCodeReference>
</CodeProperty>
</Members>
</Type>
MemberSet
定義成員集合(屬性和方法)。
<MemberSet> 標籤會出現在主要 <Members> 標籤內。 標記必須括住圍繞成員集名稱的 <Name> 標記,以及圍繞集合中成員(屬性和方法)的次要 <Members> 標記。 建立屬性的任何標記(例如 <NoteProperty> 或 <ScriptProperty>)或方法(例如 <Method> 或 <ScriptMethod>)都可以是集合的成員。
在 Types.ps1xml 檔案中,會使用 <MemberSet> 標記在PowerShell中定義 .NET 對象的默認檢視。 在此情況下,成員集的名稱(<Name> 卷標內的值)一律 PsStandardMembers,而屬性的名稱(<Name> 標記的值)如下:
DefaultDisplayProperty:物件的單一屬性。DefaultDisplayPropertySet:物件的一或多個屬性。DefaultKeyPropertySet:一或多個物件的關鍵屬性。 關鍵屬性識別屬性值的實例,例如會話記錄中的專案的識別碼。
例如,下列 XML 會定義由 System.ServiceProcess.ServiceController Cmdlet 傳回的服務 (Get-Service 物件) 的預設顯示。 它會定義名為 PsStandardMembers 的成員集,其中包含預設屬性集和預設顯示屬性。 它會將預設屬性設定為 Status、Name和 DisplayName 屬性。 它會將預設顯示屬性定義為 Name。
<Type>
<Name>System.ServiceProcess.ServiceController</Name>
<Members>
<MemberSet>
<Name>PSStandardMembers</Name>
<Members>
<PropertySet>
<Name>DefaultDisplayPropertySet</Name>
<ReferencedProperties>
<Name>Status</Name>
<Name>Name</Name>
<Name>DisplayName</Name>
</ReferencedProperties>
</PropertySet>
<NoteProperty>
<Name>DefaultDisplayProperty</Name>
<Value>Name</Value>
</NoteProperty>
</Members>
</MemberSet>
</Members>
</Type>
<Method>:參考基礎物件的原生方法。
<Methods>:物件的方法集合。
NoteProperty
定義具有靜態值的屬性。
<NoteProperty> 標記必須具有指定新屬性名稱的 <Name> 標記,以及指定屬性值的 <Value> 標記。
例如,下列 XML 會建立 System.IO.DirectoryInfo 物件的 Status 屬性。 Status 屬性的值始終為 Success。
<Type>
<Name>System.IO.DirectoryInfo</Name>
<Members>
<NoteProperty>
<Name>Status</Name>
<Value>Success</Value>
</NoteProperty>
</Members>
</Type>
PropertySet
接受自變數並傳回值的屬性。
<Properties>:對象的屬性集合。
<Property>:基底對象的 屬性。
<PropertySet>:定義 物件的屬性集合。
<PropertySet> 標記必須具有指定屬性集名稱的 <Name> 標記,且指定屬性的 <ReferencedProperty> 標記。 屬性的名稱以 <Name> 標籤括住。
在 Types.ps1xml中,<PropertySet> 標記可用來定義物件默認顯示的屬性集。 您可以透過在 標籤的 <Name> 標籤中找到值 <MemberSet> 來識別預設顯示。
例如,下列 XML 會建立名為 DefaultDisplayPropertySet 的 PropertySet,其中包含三個 ReferencedProperties。
<Type>
<Name>System.ServiceProcess.ServiceController</Name>
<Members>
<MemberSet>
<Name>PSStandardMembers</Name>
<Members>
<PropertySet>
<Name>DefaultDisplayPropertySet</Name>
<ReferencedProperties>
<Name>Status</Name>
<Name>Name</Name>
<Name>DisplayName</Name>
</ReferencedProperties>
</PropertySet>
</Members>
</MemberSet>
</Members>
</Type>
ScriptMethod
定義方法,其值是腳本的輸出。
標籤 <ScriptMethod> 必須包含 <Name> 一個指定新方法名稱的標籤,以及 <Script> 一個包含回傳方法結果的腳本區塊的標籤。
例如,管理物件的 ConvertToDateTime 和 ConvertFromDateTime 方法(System.System.Management.ManagementObject)是使用 ToDateTime 類別 ToDmtfDateTime 和 System.Management.ManagementDateTimeConverter 靜態方法的腳本方法。
<Type>
<Name>System.Management.ManagementObject</Name>
<Members>
<ScriptMethod>
<Name>ConvertToDateTime</Name>
<Script>
[System.Management.ManagementDateTimeConverter]::ToDateTime($args[0])
</Script>
</ScriptMethod>
<ScriptMethod>
<Name>ConvertFromDateTime</Name>
<Script>
[System.Management.ManagementDateTimeConverter]::ToDmtfDateTime($args[0])
</Script>
</ScriptMethod>
</Members>
</Type>
ScriptProperty
定義屬性,其值是腳本的輸出。
標籤 <ScriptProperty> 必須包含 <Name> 一個指定新屬性名稱的標籤,以及 <GetScriptBlock> 一個包含回傳屬性值的 scriptblock 的標籤。
例如,System.IO.FileInfo 物件的 VersionInfo 屬性是腳本屬性,該屬性是使用 System.Diagnostics.FileVersionInfo 物件的 GetVersionInfo 靜態方法中的 FullName 屬性所產生。
<Type>
<Name>System.IO.FileInfo</Name>
<Members>
<ScriptProperty>
<Name>VersionInfo</Name>
<GetScriptBlock>
[System.Diagnostics.FileVersionInfo]::GetVersionInfo($this.FullName)
</GetScriptBlock>
</ScriptProperty>
</Members>
</Type>
如需詳細資訊,請參閱 Windows PowerShell 軟體開發工具套件 (SDK)。
Update-TypeData
若要將 Types.ps1xml 檔案載入 PowerShell 會話,請執行 Update-TypeData Cmdlet。 如果您想要檔案中的類型優先於內建 Types.ps1xml 檔案中的類型,請新增 的 Update-TypeData 參數。
Update-TypeData 只會影響目前的會話。 若要變更所有未來的會話,請導出會話,或將 Update-TypeData 命令新增至 PowerShell 配置檔。
在屬性中發生的例外,或將屬性新增至 Update-TypeData 命令時,不會將錯誤回報給 StdErr。 這是在格式化和輸出期間,隱藏許多常見類型的例外狀況。 如果您要取得 .NET 屬性,可以改用方法語法來繞過例外狀況的抑制,如以下範例所示:
"hello".get_Length()
請注意,方法語法只能與 .NET 屬性搭配使用。 執行 Update-TypeData Cmdlet 新增的屬性無法使用方法語法。
簽署 Types.ps1xml 檔案
若要保護 Types.ps1xml 檔案的使用者,您可以使用數位簽名簽署檔案。 如需詳細資訊,請參閱 about_Signing。