首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Windows PowerShell进阶PSCustomObject

(上一次标题写成25了,改成24重发一遍)

目录

1. 创建PSCustomObject1.1 转化哈希表1.2 传统方法2. 保存到文件3. 添加属性4. 移除属性5. 枚举属性名称5.1 动态访问属性5.1.1 将pscustomboject转换为hashtable6. 测试属性7. 添加对象方法8. 对象与值类型8.1 psobject.copy()9. 自定义对象类型的PSTypeName(类型名称)10. 使用DefaultPropertySet(较长的命令方法)10.1 Update-TypeData with DefaultPropertySet10.2 Update-TypeData with ScriptProperty11. 函数参数12. 函数输出13. 最后的想法

1. 创建PSCustomObject

我喜欢在Powershell中使用[PSCustomObject]。 创建一个可用的对象从未如此简单。 因此,我会跳过所有其他你可能使用的方式创建一个对象,但我需要指出的此文大部分是Powershell v3.0和更新的版本才有的特性。

这对我来说很好,因为我使用哈希表来处理所有事情。 但有时候我会希望Powershell能像对待对象一样处理哈希表而PSCustomObject就可以做到。 您首先注意到不同之处在于,当您想要使用Format-Table或Export-CSV时,您意识到哈希表只是键/值对的集合。(这个我们上一篇已经提到过了)

然后,您可以像访问普通对象一样访问和使用这些值。

1.1 转化哈希表

当我谈论这个话题时,你是否知道你可以这样做:

我更喜欢从一开始就创建对象,但有时候你必须首先使用哈希表。 上面代码能够工作是因为构造器为对象属性提供了一个hastable。 一个重要的注意事项是虽然这有效,但它不是完全相同的(指与上个例子中的$myObject)。最大的区别是属性的顺序不被保留。

1.2 传统方法

您可能已经看到有人使用New-Object来创建自定义对象。

这种方式比较慢,但它可能是PowerShell早期版本的最佳选择。

(编者注:[pscustomobject]是从powershell V3.0之后引入的,早期版本只能用New-Object来达到此效果,具体使用和区别见:https://blogs.technet.microsoft.com/heyscriptingguy/2013/11/07/a-powershell-object-lesson-part-3/)

2. 保存到文件

我发现将一个哈希表保存为一个文件的最好方法是将其另存为JSON。 您可以将其导回到[PSCusomObject]。我在文章中介绍了更多将对象保存到文件的方法:https://kevinmarquette.github.io/2017-03-18-Powershell-reading-and-saving-data-to-files/?utm_source=blog&utm_medium=blog&utm_content=pscustomobject

(编者注:这个大家自己根据实际情况决定,我一般还是喜欢保存为csv格式的)

3. 添加属性

您仍然可以使用Add-Member将新属性添加到PSCustomObject

4. 移除属性

您也可以从对象中移除属性。

psobject是一个隐藏属性,可让您访问基础对象元数据。(编者注:这个后面专门会讲)

5. 枚举属性名称

有时你需要一个对象上所有属性名称的列表。

我们也可以从psobject属性中获得同样的列表。

5.1 动态访问属性

我已经提到你直接访问属性值。

您可以使用字符串作为属性名称,它仍然可以工作。(编者注:针对属性名字中含有空格或者特殊字符)

我们可以据此近一步使用变量作为属性名称。

我知道这看起来很奇怪,但它确实可以生效。

5.1.1 将pscustomboject转换为hashtable

接着上一节所说,您可以动态地遍历pscustomboject属性并从中创建一个哈希表。

6. 测试属性

如果你需要知道一个属性是否存在,你可以检查该属性是否为null。

但是,如果属性值可能为$null,并且您仍然需要检查它,则可以检查psobject.properties。

7. 添加对象方法

如果需要将脚本方法添加到对象,可以使用Add-MemberScriptBlock来完成。 你必须使用this自动变量引用当前对象。 这是一个将对象转换为哈希表的脚本块。(最后5.1.1例子的代码相同)

然后我们将它作为脚本属性添加到我们的对象中。

然后我们可以像这样调用我们的函数:

8. 对象与值类型

对象和值类型不以相同的方式处理变量赋值。 如果将值类型分配给彼此,则只有值被复制到新变量。

在这种情况下,$first是1,$second是2。

对象变量持有对实际对象的引用。 当您将一个对象分配给一个新变量时,它们仍然引用相同的对象。

因为$third$fourth引用同一个对象实例,所以$third.key$fourth.Key都是4。

8.1 psobject.copy()

如果你需要一个对象的真实副本,你可以克隆它。

克隆创建对象的浅表副本。 他们现在有不同的实例,在这个例子中$third.key是3,$fourth.Key是4。

我称之为浅拷贝是因为如果你有嵌套的对象(这些属性包含其他对象)。只有顶级值被复制。子对象依然相互引用。

(编者注:这一节大家多留个心,后面讲多线程的时候会用到这个知识点)

9. 自定义对象类型的PSTypeName(类型名称)

现在我们有了一个对象,我们可以用它做更多的事情,这可能不是那么明显。 首先我们需要做的是给它一个PSTypeName。 这是我看到人们最常见的方式:

我最近从https://www.reddit.com/r/PowerShell/comments/590awc/is_it_possible_to_initialize_a_pscustoobject_with/这篇文章中发现了另一种方法。 我做了一点挖掘,并从http://www.adamtheautomator.com/building-custom-object-types-powershell-pstypename/https://powershellstation.com/2016/05/22/custom-objects-and-pstypename/那里了解更多关于这个想法的帖子,他们在这里谈论了这种方法,可以让你对它进行内联定义。

我热爱这种恰到好处的语言使用技巧。 既然我们有一个适当类型名称的对象,我们可以做更多的事情。

10. 使用DefaultPropertySet(较长的命令方法)

Powershell为我们决定默认显示哪些属性。 许多本机命令都有一个.ps1xml格式化文件,可以完成所有繁重的工作。 从Boe Prox的这篇文章中(https://learn-powershell.net/2013/08/03/quick-hits-set-the-default-property-display-in-powershell-on-custom-objects/),我们有另一种方法可以使用Powershell在我们的自定义对象上执行此操作。 我们可以给它一个MemberSet供它使用。

现在,当我的对象落到了shell中时,它只会默认显示这些属性。

10.1 Update-TypeData with DefaultPropertySet

上面使用方法真的很不错,但是最近我看到PowerShell unplugged 2016 with Jeffrey Snover & Don Jones(https://www.youtube.com/watch?v=Ab46gHXNm8Q),他使用Update-TypeData来指定默认属性。(编者注:V3.0 之后才有的cmdlets)

这很简单,如果我没有这篇文章作为快速参考,我几乎可以记住它。 现在我可以轻松地创建具有许多属性的对象,并且在从shell查看时仍然可以给它一个很好的清晰视图。 如果我需要访问或查看其他属性,它们仍然存在。

10.2 Update-TypeData with ScriptProperty

我从视频中获得的其他内容是为对象创建脚本属性。 这将是一个很好的时机,指出这也适用于已存在的对象。

你可以在你的对象被创建或之后做到这一点,它仍然会工作。 这使得其与Add-Member是2种不同的方式。 按照我之前提到的方式使用Add-Member时,它只存在于该对象的特定实例上。 这个适用于所有具有此TypeName的对象。

11. 函数参数

您现在可以在您的函数和脚本中使用这些自定义类型的参数。 你可以有一个函数创建这些自定义对象,然后将它们传递给其他函数。

然后Powershell将要求该对象是您指定的类型。 如果类型不自动匹配,它会引发验证错误,以便为您节省在代码中对其进行测试的步骤。 一个很好说明让Powershell做到最好的例子。

12. 函数输出

您也可以为您的高级功能定义一个OutputType

OutputType(https://technet.microsoft.com/en-us/library/hh847785.aspx)属性值只是文档说明。 它不是从功能代码派生出来的,或者是与实际功能输出相比较的。

您将使用输出类型的主要原因是,有关您的函数的元信息反映了您的意图。 像Get-CommandGet-Help和你的开发环境可以利用它。 如果您想了解更多信息,请查看帮助信息:about_Functions_OutputTypeAttribute

这就是说,如果您正在使用Pester来测试您的函数,那么验证输出对象与您的OutputType匹配将是一个好主意。 当它们不应该的时候,这可以捕获刚落入管道的变量。

13. 最后的想法

这是关于[PSCustomObject]的全部内容,但很多这些信息适用于一般对象。

过去我已经看到了大部分这些功能,但从来没有看到它们作为PSCustomObject信息的集合呈现。 就在上个星期,我偶然发现了另一个,我很惊讶我之前没有看到它。 我想将所有这些想法集中在一起,以便您有望看到更大的图景,并在有机会使用它们时注意它们。 我希望你学到了一些东西,并且可以找到一种方法将它应用到脚本中。

上面就是原文的内容, 下一篇讲compare 2 csv contents。放几张衢山岛游玩的照片(*^▽^*):

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180512G0ME8600?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券