Object 数组与自定义数组比较 Headers

Object Array Comparison with Custom Headers

我有一个 object 角色数组,我从两个 vcenter 中提取了这些角色。

我正在尝试制作一个具有 3 列的格式化 table:角色、主人、奴隶

后两栏会有"exists"或"missing"

我认为发生的问题是当它发现角色存在于 master 中时,它以某种方式将 slave 列标记为 "missing",即使我知道它在那里。

我才接触 Powershell 几个月,有人能看出我的逻辑有什么问题吗?

编辑:RoleTable.AllRoles、RoleTable.MasterRoles 和 RoleTable.SlaveRoles 都是 object 数组

    $RoleTable.AllRoles | Select-Object Name, 
    @{Name = "Master Server"; Expression = {if ($RoleTable.MasterRoles -contains $_) {"EXISTS"} else {"MISSING"}}}, 
    @{Name = "Slave Server"; Expression = {if ($RoleTable.SlaveRoles -contains $_) {"EXISTS"} else {"MISSING"}}}

Roletable.Allrolesobject的例子:

$RoleTable.AllRoles[1] | Select-Object *


Description   : Not logged-in user (cannot be granted)
IsSystem      : True
PrivilegeList : {System.Anonymous}
ServerId      : /VIServer=someuser@xxxx-xxxx:443/
Server        : 
Id            : -4
Name          : Anonymous
Uid           : /VIServer=someuser@xxxx-xxxx:Role=-4/
ExtensionData : VMware.Vim.AuthorizationRole
Client        : VMware.VimAutomation.ViCore.Impl.V1.VimClient

除非 $RoleTable.AllRoles[1]$RoleTable.SlaveRoles 中的项目引用 内存中完全相同的对象-contains 将 return $false,即使在 $RoleTable.SlaveRoles.

中存在 看似 相同的对象

(这 只有 对引用类型正确,对值类型不正确)

这应该可以说明区别:

引用同一对象:

PS C:\> $Collection = @(New-Object psobject -Property @{p=123})
PS C:\> $Item       = $Collection[0]
PS C:\> $Collection -contains $Item 
True 

引用相同的对象:

PS C:\> $Collection = @(New-Object psobject -Property @{p=123})
PS C:\> $Item       = New-Object psobject -Property @{p=123}
PS C:\> $Collection -contains $Item 
False

在您的示例中,您可以使用 Name 或角色 Id 属性(如@jisaak 所建议):

$RoleTable.AllRoles | Select-Object Name, 
@{Name = "OnMaster"; Expression = {$RoleTable.MasterRoles.Id -contains $_.Id}}, 
@{Name = "OnSlave"; Expression = {$RoleTable.SlaveRoles.Id -contains $_.Id}}

如上所示,我可能会使用通用布尔值作为指示符,而不是字符串


此行为是 .NET 中有意的性能优化 - 您永远不知道需要深入到多深的兔子洞才能确保对象所有内部属性的值进行精确比较。

另一方面,值类型更容易执行相等比较(并且不一定有内存引用来比较),结果是:

[int]

PS C:\> $Collection = @(283)
PS C:\> $Item       = $Collection[0]
PS C:\> $Collection -contains $Item
True
PS C:\> $Item       = 283
PS C:\> $Collection -contains $Item
True

[string]:

PS C:\> $Collection = @("SomeString")
PS C:\> $Item       = $Collection[0]
PS C:\> $Collection -contains $Item
True
PS C:\> $Item       = "SomeString"
PS C:\> $Collection -contains $Item
True

等等...