当前位置:  开发笔记 > 编程语言 > 正文

如何在PowerShell中创建自定义类型以供我的脚本使用?

如何解决《如何在PowerShell中创建自定义类型以供我的脚本使用?》经验,为你挑选了5个好方法。

我希望能够在我的一些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中推荐?



1> Jaykul..:

在PowerShell 3之前

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-TypeNew-Struct将让你实际测试你的课程param([Contact]$contact)并使用$contact = new-object Contact等等制作新课程......

在PowerShell 3中

如果您不需要可以强制转换的"真实"类,则不必使用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一切都改变了,我们终于得到了classenum作为语言关键字定义类型(有没有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 5版本中,您无法将New-Object与使用类语法创建的类一起使用,但您现在可以使用.但是,如果您使用的是class关键字,那么您的脚本无论如何都只限于PS5,所以如果对象有一个带参数的构造函数,我仍然会建议使用:: new语法(它比新的快**) - 对象)或其他方式,这是更清晰的语法和更快.

2> Steven Muraw..:

可以在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
}



3> EBGreen..:

这是快捷方式:

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


基本上,如果对象尚未具有该属性,则Select-Object cmdlet会向对象添加属性.在这种情况下,您将空白String对象移交给Select-Object cmdlet.它添加属性并沿管道传递对象.或者,如果它是管道中的最后一个命令,则输出该对象.我应该指出,如果我在提示符下工作,我只会使用此方法.对于脚本,我总是使用更明确的Add-Member或New-Object cmdlet.

4> Nick Meldrum..:

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
}


我明白了这一点.仍然,`int`方式有明显的优点:1)它工作得更快,不多,但对于这个特殊功能`New-Person`,差异是20%; 2)打字显然更容易.同时,基本上到处都使用这种方法,我从未见过任何缺点.但我同意:当PSCustomObject更好时,可能会出现一些罕见的情况.

5> Benjamin Hub..:

没有人惊讶地提到创建自定义对象的简单方法(相对于3或更高版本):

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

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


@superjos,谢谢您的提示。我找不到帖子的新位置。至少该帖子由[存档](https://web-beta.archive.org/web/20151215173303/http://powershell.org:80/wp/kb/new-object-psobject-vs备份-pscustomobject /)。
显然,这似乎变成了一本Git书[here](https://devopscollective.gitbooks.io/the-big-book-of-powershell-gotchas/content/manuscript/new-object_psobject_vs_pscustomobject.html):)
推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有