如何在PowerShell中创建一个`PSObject`

3
当我在MSDN上听说PSObject的酷炫属性和方法时,我觉得尝试一下会很酷。

这就是我所做的:

首先,我创建了一个PSObject类型的新实例。

然后,我使用Get-Member查找所有这些酷炫成员(但它们并不存在):

PS .> $plainObj = New-Object PSObject

PS .> $plainObj | Get-Member


   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType Definition
----        ---------- ----------
Equals      Method     bool Equals(System.Object obj)
GetHashCode Method     int GetHashCode()
GetType     Method     type GetType()
ToString    Method     string ToString()

问题:

没有BaseObject属性,也没有AsPSObject()方法。所有很酷的成员都不在那里。但是为什么呢?

Get-Member告诉我,我的对象的种类(TypeName)是PSCustomObject,而不是PSObject。而PSCustomObject并没有所有这些很酷的成员。

但我不想$plainObj成为PSCustomObject的一个种类 - 我希望它成为PSObject的一种类型。

我的问题:

  • 为什么$plainObjPSCustomObject的一种类型,尽管我明确地使用-TypeName$plainObj New-Object PSObject中使用了PSObject?有什么想法吗?

  • 如何让$plainObj成为PSObject的一种类型,而不是PSCustomObject的一种类型?


@RussC Even if I use your script - that's the result:

PS .> $plainObj = New-Object PSObject -property @{ title = 'fridojet' };
$plainObj | Add-Member -MemberType NoteProperty -Name Colour -Value Blue

PS .> $plainobj | Get-Member


   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Colour      NoteProperty System.String Colour=Blue
title       NoteProperty System.String title=fridojet

@RussC Now I managed to create an object which is not kind of PSCustomObject:

PS .> New-Object Object

But even then, I'm not able to create a PSObject (with a BaseObject property and so on):

PS .> [PSObject]::AsPSObject((New-Object Object)) | Get-Member


   TypeName: System.Object

Name        MemberType Definition
----        ---------- ----------
Equals      Method     bool Equals(System.Object obj)
GetHashCode Method     int GetHashCode()
GetType     Method     type GetType()
ToString    Method     string ToString()

你能告诉我们你实际上正在尝试使用哪种方法吗? - Russ Clarke
@RussC 你是什么意思? - fridojet
你的问题提到了你“听说过一些很酷的属性和方法”,我想知道你是否有任何特定的想要测试的? - Russ Clarke
你的意思是:“我应该使用-property还是Add-Member来向我的对象添加属性?” - 那么我的答案是:我两个都用 - 首先我使用-property添加title属性,然后我使用Add-Member添加Colour属性。我只是采用了你回答中的代码。 - fridojet
哦,现在我知道你的意思了。- 不,没有一个具体的,但我认为AsPSObject()方法和BaseObject属性是最有趣的。 - fridojet
我已经为您更新了我的原始答案,并添加了一些详细信息。 - Russ Clarke
1个回答

2

我认为它没有任何内容可报告,因为它没有包装任何东西。

如果您创建一个新的PSObject,而不包装另一个对象或提供任何默认成员,则会创建一个PSCustomObject

如MSDN所述,对于PSCustomObject:“在使用没有参数的PSObject构造函数时用作占位符对象。”

例如,如果您这样做:

$plainObj = New-Object PSObject -property @{ title = 'fridojet' }
$plainObj | Add-Member -MemberType NoteProperty -Name Colour -Value Blue

那么$plainObj应该是一个PSObject。

由于PSObject是一个静态转换调用,

$date = Get-Date
$pso = PSObject.AsPSObject($date)

或者

$obj = New-Object object -property @{ title = "fridojet" }
$pso = PSObject.AsPSObject($obj)

另一方面,BaseObject返回PSObject的基类。

使用上面的第二个示例:

$obj = New-Object object -property @{ title = "fridojet" }
$pso = PSObject.AsPSObject($obj)
$end = $pso.BaseObject

在这种情况下,$end应该是一个对象;如果您使用Get-Date,$end应该是DateTime类型。
我希望使用这种方法会返回PSObject类型,而不是PSCustomObject类型。
然而,这些属性和方法的优点是值得怀疑的。使用PSObject包装器的主要原因是当您在许多.NET类之间传递对象时。
如果您只是进行实验,则不会提供任何您不知道的内容。
此博客文章显示了一些使用PSObject的原因,特别是在通过.NET类迭代许多对象的情况下:Custom object gotchas

谢谢你的回答。我已经尝试过类似的方法,但它仍然是一个“PSCustomObject”。还有其他想法吗? - fridojet
我已经测试了你的脚本,并在我的回答末尾发布了一些关于你的脚本结果的细节。 - fridojet
$obj = New-Object object -property @{ (...) } 中,object 是什么意思?它有特殊的含义还是只是一个 TypeName 的占位符? - fridojet
我可以这样使用 AsPSObject()$pso = [PSObject]::AsPSObject($plainobj)。但是即使我明确地使用 AsPSObject() 强制转换方法以获得一个 PSObjectAsPSObject() 的结果也是一个 PSCustomObject!天哪?! - fridojet
我在问题文本底部添加了一些相关信息:虽然现在我能够创建一个不是PSCustomObject类型的对象,但我无法创建一个PSObject - fridojet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接