如何在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-Type
或New-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中,一切都变了,我们终于得到了class
和enum
作为定义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