about_Types.ps1xml

简短说明

介绍如何使用 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 安装目录 ($PSHOME) 中的 Types.ps1xml 文件中。

向 PowerShell 添加扩展类型数据

PowerShell 会话中有三个扩展类型数据源。

  • 扩展类型数据由 PowerShell 定义,并自动加载到每个 PowerShell 会话中。 从 PowerShell 6 开始,此信息被编译到 PowerShell 中,并且不再在 Types.ps1xml 文件中提供。

  • 当模块导入当前会话时,会加载模块导出的 Types.ps1xml 文件。

  • 使用 Update-TypeData cmdlet 定义的扩展类型数据仅添加到当前会话。 它不会保存在文件中。

在会话中,来自三个源的扩展类型数据以相同的方式应用于对象,并且可用于指定类型的所有对象。

TypeData cmdlet

以下 cmdlet 包含在 PowerShell 3.0 及更高版本的 Microsoft.PowerShell.Utility 模块中。

  • Get-TypeData:获取当前会话中的扩展类型数据。
  • Update-TypeData:重新加载 Types.ps1xml 文件。 将扩展类型数据添加到当前会话。
  • Remove-TypeData:从当前会话中删除扩展类型数据。

有关这些 cmdlet 的详细信息,请参阅每个 cmdlet 的帮助主题。

内置 Types.ps1xml 文件

$PSHOME 目录中的 Types.ps1xml 文件会自动添加到每个会话。

PowerShell 安装目录 ($PSHOME) 中的 Types.ps1xml 文件是一个基于 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 会话。 如果希望类型优先于定义的内置类型,请使用 Update-TypeDatacmdlet 的 PrependData 参数。 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 属性是使用脚本块计算的,因此请查找用作新 Age 属性模型的 <ScriptProperty> 标记。

将以下 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 命令以获取 $PSHOME 目录中的 PowerShell.exe 文件,然后将该文件通过管道传递给 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 别名属性是数组对象的 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>

CodeProperty

引用 .NET 类的静态方法。

<CodeProperty> 标记必须具有指定新属性名称的 <Name> 标记和指定定义该属性的代码的 <GetCodeReference> 标记。

例如,System.IO.DirectoryInfo 对象的 Mode 属性是 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:对象的一个或多个键属性。 键属性标识属性值的实例,例如会话历史记录中的项的 ID 号。

例如,以下 XML 定义由 Get-Service cmdlet 返回的服务(System.ServiceProcess.ServiceController 对象)的默认显示。 它定义了一个名为 PsStandardMembers 的成员集,该成员集由具有 StatusNameDisplayName 属性的默认属性集组成。

<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>

<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> 标记用于定义对象默认显示的属性集。 可以通过 <MemberSet> 标记 的 <Name> 标记中的 PsStandardMembers 值来标识默认显示。

例如,以下 XML 创建一个名为 DefaultDisplayPropertySetPropertySet,其中包含三个 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> 标记。

例如,管理对象的 ConvertToDateTimeConvertFromDateTime 方法 (System.System.Management.ManagementObject) 是使用 System.Management.ManagementDateTimeConverter 类的 ToDateTimeToDmtfDateTime 静态方法的脚本方法。

<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> 标记。

例如,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-TypeDataPrependData 参数。 Update-TypeData 仅影响当前会话。 若要更改所有将来的会话,请导出会话,或将 Update-TypeData 命令添加到 PowerShell 配置文件。

在属性中出现的异常,或在将属性添加到 Update-TypeData 命令的过程中出现的异常不会向 StdErr 报告错误。 这是为了取消显示在格式设置和输出期间在许多常见类型中发生的异常。 如果你要获得 .NET 属性,可以通过改用方法语法来处理取消显示异常问题,如下面的示例所示:

"hello".get_Length()

请注意,方法语法仅可用于 .NET 属性。 通过运行 Update-TypeData cmdlet 添加的属性不能使用方法语法。

为 Types.ps1xml 文件签名

若要保护 Types.ps1xml 文件的用户,可以使用数字签名对文件进行签名。 有关详细信息,请参阅 about_Signing

另请参阅