如何在PowerShell中为脚本创build自定义types?

我希望能够在我的一些PowerShell脚本中定义和使用自定义types。 例如,假设我需要一个具有以下结构的对象:

Contact { string First string Last string Phone } 

我将如何去创build这个,以便我可以像下面这样使用它:

 function PrintContact { param( [Contact]$contact ) "Customer Name is " + $contact.First + " " + $contact.Last "Customer Phone is " + $contact.Phone } 

是这样的可能,甚至build议在PowerShell?

创build自定义types可以在PowerShell中完成。
Kirk Munro实际上有两个伟大的职位,彻底详细的过程。

  • 命名自定义对象
  • 定义自定义对象的默认属性

Manning的“ Windows PowerShell In Action ”一书还有一个代码示例,用于创build特定于域的语言来创build自定义types。 这本书很好,所以我真的推荐它。

如果你正在寻找一个快速的方法来做到这一点,你可以创build一个函数来创build自定义对象

 function New-Person() { param ($FirstName, $LastName, $Phone) $person = new-object PSObject $person | add-member -type NoteProperty -Name First -Value $FirstName $person | add-member -type NoteProperty -Name Last -Value $LastName $person | add-member -type NoteProperty -Name Phone -Value $Phone return $person } 

在PowerShell 3之前

PowerShell的可扩展types系统最初并没有让你创build具体的types,你可以用你在参数中做的方式来testing。 如果你不需要这个testing,你可以使用上面提到的其他方法。

如果你想要一个实际的types,你可以强制转换或者types检查,就像在你的脚本中一样……如果不在 C#或VB.net中编写,编译就不能完成。 在PowerShell 2中,你可以使用“Add-Type”命令来做到这一点:

 add-type @" public struct contact { public string First; public string Last; public string Phone; } "@ 

历史注意事项 :在PowerShell 1中,它更难。 你必须手动使用CodeDom,PoshCode.org上有一个非常旧的函数new-struct脚本,这将有所帮助。 你的例子变成:

 New-Struct Contact @{ First=[string]; Last=[string]; Phone=[string]; } 

使用Add-TypeNew-Struct可以让你实际testing你的param([Contact]$contact)并使用$contact = new-object Contact来创build新类,等等。

在PowerShell 3中

如果你不需要一个“真实”的类,你可以使用添加成员的方式, 史蒂文和其他人已经在上面演示 。

由于PowerShell 2,您可以使用New-Object的-Property参数:

 $Contact = New-Object PSObject -Property @{ First=""; Last=""; Phone="" } 

在PowerShell 3中,我们有能力使用PSCustomObject加速器来添加一个TypeName:

 [PSCustomObject]@{ PSTypeName = "Contact" First = $First Last = $Last Phone = $Phone } 

你仍然只是得到一个单一的对象,所以你应该做一个New-Contact函数,以确保每个对象出来,但你现在可以轻松地validation参数“是”之一,通过装饰参数PSTypeName属性:

 function PrintContact { param( [PSTypeName("Contact")]$contact ) "Customer Name is " + $contact.First + " " + $contact.Last "Customer Phone is " + $contact.Phone } 

在PowerShell 5中

在PowerShell 5中,一切都变了,我们终于得到了classenum作为定义types的语言关键字(没有struct但没关系):

 class Contact { # Optionally, add attributes to prevent invalid values [ValidateNotNullOrEmpty()][string]$First [ValidateNotNullOrEmpty()][string]$Last [ValidateNotNullOrEmpty()][string]$Phone # optionally, have a constructor to # force properties to be set: Contact($First, $Last, $Phone) { $this.First = $First $this.Last = $Last $this.Phone = $Phone } } 

我们也有一种不使用New-Object来创build对象的新方法: [Contact]::new() – 事实上,如果你保持你的类简单而不定义一个构造函数,你可以通过build立一个hashtable (虽然没有构造函数,但是没有办法强制所有的属性必须被设置):

 class Contact { # Optionally, add attributes to prevent invalid values [ValidateNotNullOrEmpty()][string]$First [ValidateNotNullOrEmpty()][string]$Last [ValidateNotNullOrEmpty()][string]$Phone } $C = [Contact]@{ First = "Joel" Last = "Bennett" } 

这是捷径:

 $myPerson = "" | Select-Object First,Last,Phone 

史蒂文Murawski的答案是伟大的,但我喜欢较短的(或者只是整洁的select对象,而不是使用添加成员的语法):

 function New-Person() { param ($FirstName, $LastName, $Phone) $person = new-object PSObject | select-object First, Last, Phone $person.First = $FirstName $person.Last = $LastName $person.Phone = $Phone return $person } 

有可用的PSObject和Add-Member的概念。

 $contact = New-Object PSObject $contact | Add-Member -memberType NoteProperty -name "First" -value "John" $contact | Add-Member -memberType NoteProperty -name "Last" -value "Doe" $contact | Add-Member -memberType NoteProperty -name "Phone" -value "123-4567" 

这个输出如下:

 [8] » $contact First Last Phone ----- ---- ----- John Doe 123-4567 

另一种方法(我知道)是在C#/ VB.NET中定义一个types,并将该程序集加载到PowerShell中直接使用。

这种行为是绝对鼓励的,因为它允许脚本的其他脚本或部分与实际对象一起工作。

惊讶没有人提到这个简单的选项(vs 3或更高版本)创build自定义对象:

 [PSCustomObject]@{ First = $First Last = $Last Phone = $Phone } 

types将是PSCustomObject,但不是实际的自定义types。 但是这可能是创build自定义对象最简单的方法。

这是创build自定义types并将其存储在集合中的硬path。

 $Collection = @() $Object = New-Object -TypeName PSObject $Object.PsObject.TypeNames.Add('MyCustomType.Contact.Detail') Add-Member -InputObject $Object -memberType NoteProperty -name "First" -value "John" Add-Member -InputObject $Object -memberType NoteProperty -name "Last" -value "Doe" Add-Member -InputObject $Object -memberType NoteProperty -name "Phone" -value "123-4567" $Collection += $Object $Object = New-Object -TypeName PSObject $Object.PsObject.TypeNames.Add('MyCustomType.Contact.Detail') Add-Member -InputObject $Object -memberType NoteProperty -name "First" -value "Jeanne" Add-Member -InputObject $Object -memberType NoteProperty -name "Last" -value "Doe" Add-Member -InputObject $Object -memberType NoteProperty -name "Phone" -value "765-4321" $Collection += $Object Write-Ouput -InputObject $Collection