我希望能够在我的一些PowerShell脚本中定义和使用自定义类型.例如,让我假装我需要一个具有以下结构的对象:
Contact { string First string Last string Phone }
我将如何创建它,以便我可以在以下功能中使用它:
function PrintContact { param( [Contact]$contact ) "Customer Name is " + $contact.First + " " + $contact.Last "Customer Phone is " + $contact.Phone }
这样的事情是可能的,甚至在PowerShell中推荐?
PowerShell的可扩展类型系统最初并不允许您创建具体类型,您可以根据参数的方式进行测试.如果您不需要该测试,那么您可以使用上述任何其他方法.
如果你想要一个你可以强制转换的类型或类型检查的实际类型,就像在你的示例脚本中那样......如果不在 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
将让你实际测试你的课程param([Contact]$contact)
并使用$contact = new-object Contact
等等制作新课程......
如果您不需要可以强制转换的"真实"类,则不必使用Steven和其他人在上面演示过的Add-Member方法.
从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
函数来确保每个对象都是相同的,但你现在可以通过使用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
作为语言关键字定义类型(有没有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
:[Contact]::new()
- 实际上,如果你保持你的类简单并且没有定义构造函数,你可以通过转换哈希表来创建对象(虽然没有构造函数,但是没有办法强制必须设置所有属性):
class Contact { # Optionally, add attributes to prevent invalid values [ValidateNotNullOrEmpty()][string]$First [ValidateNotNullOrEmpty()][string]$Last [ValidateNotNullOrEmpty()][string]$Phone } $C = [Contact]@{ First = "Joel" Last = "Bennett" }
可以在PowerShell中创建自定义类型.
Kirk Munro实际上有两个很好的帖子,详细介绍了这个过程.
命名自定义对象
定义自定义对象的默认属性
Manning的Windows PowerShell In Action一书还提供了一个代码示例,用于创建特定于域的语言来创建自定义类型.这本书很好,所以我真的推荐它.
如果您只是想快速完成上述操作,可以创建一个函数来创建自定义对象
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 }
这是快捷方式:
$myPerson = "" | Select-Object First,Last,Phone
Steven Murawski的答案很棒,但我喜欢较短的(或者更简单的是更简洁的select-object而不是使用add-member语法):
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 }
没有人惊讶地提到创建自定义对象的简单方法(相对于3或更高版本):
[PSCustomObject]@{ First = $First Last = $Last Phone = $Phone }
该类型将是PSCustomObject,但不是实际的自定义类型。但这可能是创建自定义对象的最简单方法。