about_Object_Creation

简短说明

介绍了如何在 PowerShell 中创建对象。

长说明

你可以在 PowerShell 中创建对象,并在命令和脚本中使用你创建的对象。

创建对象的方法有很多,此列表不是最终完整的:

  • New-Object:创建 .NET Framework 对象或 COM 对象的实例。
  • Import-Csv / ConvertFrom-CSV:基于定义为字符分隔值的项创建自定义对象 (PSCustomObject)
  • ConvertFrom-Json:创建以 JavaScript 对象表示法 (JSON) 定义的自定义对象。
  • ConvertFrom-String:在 FlashExtract 的基础上构建,ConvertFrom-String 基于结构化的字符串数据创建自定义对象。 本主题会演示和讨论所有这些方法。
  • ConvertFrom-StringData:创建以键值对形式定义的自定义对象。
  • Add-Type:允许在 PowerShell 会话中定义可以使用 New-Object 实例化的类。
  • New-Module:AsCustomObject 参数创建你使用脚本块定义的自定义对象
  • Add-Member:向现有对象添加属性。 可以使用 Add-Member 从简单类型创建自定义对象,如 [System.Int32]
  • Select-Object:选择对象的属性。 可以使用 Select-Object 在已实例化对象上创建自定义和计算属性。

本文介绍了以下其他方法:

  • 通过使用静态 new() 方法调用类型的构造函数
  • 通过对属性名称和属性值的哈希表进行类型转换

静态 new() 方法

所有 .NET 类型都有一个 new() 方法,可用于更轻松地构造实例。 还可以查看给定类型的所有可用构造函数。

若要查看类型的构造函数,请在类型名称后面指定 new 方法名称,然后按 <ENTER>

[System.Uri]::new
OverloadDefinitions
-------------------
uri new(string uriString)
uri new(string uriString, bool dontEscape)
uri new(uri baseUri, string relativeUri, bool dontEscape)
uri new(string uriString, System.UriKind uriKind)
uri new(uri baseUri, string relativeUri)
uri new(uri baseUri, uri relativeUri)

现在,可以通过指定相应的构造函数来创建 System.Uri

[System.Uri]::new("https://www.bing.com")
AbsolutePath   : /
AbsoluteUri    : https://www.bing.com/
LocalPath      : /
Authority      : www.bing.com
...

可以使用以下示例来确定当前加载了哪些 .NET 类型以供实例化。

[AppDomain]::CurrentDomain.GetAssemblies() |
  ForEach-Object {
    $_.GetExportedTypes() |
      ForEach-Object { $_.FullName }
  }

使用 new() 方法创建的对象可能与由 PowerShell cmdlet 创建的相同类型的对象具有相同的属性。 PowerShell cmdlet、提供程序和扩展类型系统可以向实例添加额外的属性。

例如,PowerShell 中的 FileSystem 提供程序向 Get-Item 返回的 DirectoryInfo 对象添加六个 NoteProperty 值

$PSDirInfo = Get-Item /
$PSDirInfo | Get-Member | Group-Object MemberType | Select-Object Count, Name
Count Name
----- ----
    4 CodeProperty
   13 Property
    6 NoteProperty
    1 ScriptProperty
   18 Method

直接创建 DirectoryInfo 对象时,它没有这六个 NoteProperty 值

$NewDirInfo = [System.IO.DirectoryInfo]::new('/')
$NewDirInfo | Get-Member | Group-Object MemberType | Select-Object Count, Name
Count Name
----- ----
    4 CodeProperty
   13 Property
    1 ScriptProperty
   18 Method

有关扩展类型系统的详细信息,请参阅 about_Types.ps1xml

此功能是在 PowerShell 5.0 中添加的

基于哈希表创建对象

可以通过属性和属性值的哈希表创建对象。

语法如下:

[<class-name>]@{
  <property-name>=<property-value>
  <property-name>=<property-value>
}

此方法仅适用于具有无参数构造函数的类。 对象属性必须是公共且可设置的。

此功能是在 PowerShell 版本 3.0 中添加的

基于哈希表创建自定义对象

自定义对象非常有用,并且很容易使用哈希表方法创建。 PSCustomObject 类是专门为此目的而设计的

自定义对象是从函数或脚本返回自定义输出的好方法。 这比返回无法重格式化或无法通过管道传递给其他命令的格式化输出更有用。

Test-Object function 中的命令会设置一些变量值,然后使用这些值创建自定义对象。 可以在 Update-Help cmdlet 帮助主题的示例部分中查看如何使用此对象。

function Test-Object {
  $ModuleName = "PSScheduledJob"
  $HelpCulture = "en-us"
  $HelpVersion = "3.1.0.0"
  [PSCustomObject]@{
    "ModuleName"=$ModuleName
    "UICulture"=$HelpCulture
    "Version"=$HelpVersion
  }
  $ModuleName = "PSWorkflow"
  $HelpCulture = "en-us"
  $HelpVersion = "3.0.0.0"
  [PSCustomObject]@{
    "ModuleName"=$ModuleName
    "UICulture"=$HelpCulture
    "Version"=$HelpVersion
  }
}
Test-Object

此函数的输出在默认情况下是格式化为表的自定义对象集合。

ModuleName        UICulture      Version
---------         ---------      -------
PSScheduledJob    en-us          3.1.0.0
PSWorkflow        en-us          3.0.0.0

用户可以如同标准对象一样管理自定义对象的属性。

(Test-Object).ModuleName
 PSScheduledJob
 PSWorkflow

PSObject 类型对象按照成员添加到对象的顺序维护其成员列表。 尽管哈希表对象不能保证键值对的顺序,但将文本哈希表强制转换为 [pscustomobject] 可保持该顺序。

哈希表必须是文本。 如果将哈希表括在括号中,或者强制转换包含哈希表的变量,则不能保证顺序被保留。

$hash = @{
    Name      = "Server30"
    System    = "Server Core"
    PSVersion = "4.0"
}
$Asset = [pscustomobject]$hash
$Asset
PSVersion Name     System
--------- ----     ------
4.0       Server30 Server Core

基于哈希表创建非自定义对象

还可以使用哈希表为非自定义类创建对象。 尽管可以省略任何初始系统命名空间组件,但为非自定义类创建对象时,需要使用命名空间限定的类型名称

例如,以下命令会创建一个会话选项对象。

[System.Management.Automation.Remoting.PSSessionOption]@{
  IdleTimeout=43200000
  SkipCnCheck=$True
}

哈希表功能的要求(尤其是无参数构造函数这个要求)淘汰了许多现有类。 但是,大多数 PowerShell 选项类以及其他非常有用的类(例如 ProcessStartInfo 类)都设计为可以与此功能配合使用。

[System.Diagnostics.ProcessStartInfo]@{
  CreateNoWindow="$true"
  Verb="run as"
}
Arguments               :
ArgumentList            : {}
CreateNoWindow          : True
EnvironmentVariables    : {OneDriveConsumer, PROCESSOR_ARCHITECTURE,
                           CommonProgramFiles(x86), APPDATA...}
Environment             : {[OneDriveConsumer, C:\Users\user1\OneDrive],
                           [PROCESSOR_ARCHITECTURE, AMD64],
                           [CommonProgramFiles(x86),
                           C:\Program Files (x86)\Common Files],
                           [APPDATA, C:\Users\user1\AppData\Roaming]...}
RedirectStandardInput   : False
RedirectStandardOutput  : False
RedirectStandardError   : False
...

设置参数值时,也可以使用哈希表功能。 例如,New-PSSession 的 SessionOption 参数的值。 cmdlet 可以是哈希表。

New-PSSession -ComputerName Server01 -SessionOption @{
  IdleTimeout=43200000
  SkipCnCheck=$True
}
Register-ScheduledJob Name Test -FilePath .\Get-Inventory.ps1 -Trigger @{
  Frequency="Daily"
  At="15:00"
}

泛型对象

还可在 PowerShell 中创建泛型对象。 泛型是为所存储或使用的一个或多个类型具有占位符(类型形参)的类、结构、接口和方法。

以下示例创建一个 Dictionary 对象

$dict = New-Object 'System.Collections.Generic.Dictionary[String,Int]'
$dict.Add("One", 1)
$dict
Key Value
--- -----
One     1

有关泛型的详细信息,请参阅 .NET 中的泛型

另请参阅