我有两个角色的对象数组。
我正在尝试创建一个包含3列的格式化表:roles,master,slave
后两栏中会有“存在”或“缺失”。
我认为发生的问题是当它发现主角中存在角色时,它会以某种方式将从属列标记为“缺失”,即使我知道它在那里。
我只有几个月进入Powershell,任何人都可以看到我的逻辑有什么问题吗?
编辑:RoleTable.AllRoles,RoleTable.MasterRoles和RoleTable.SlaveRoles都是对象数组
$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.Allroles对象的示例:
$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
答案 0 :(得分:2)
Unless $RoleTable.AllRoles[1]
and an item in $RoleTable.SlaveRoles
refer to the exact same object in memory, -contains
will return $false
, even if a seemingly identical object exists in $RoleTable.SlaveRoles
.
(this is only true for reference types, not value types)
This should illustrate the difference:
Reference to same object:
PS C:\> $Collection = @(New-Object psobject -Property @{p=123})
PS C:\> $Item = $Collection[0]
PS C:\> $Collection -contains $Item
True
Reference to identical object:
PS C:\> $Collection = @(New-Object psobject -Property @{p=123})
PS C:\> $Item = New-Object psobject -Property @{p=123}
PS C:\> $Collection -contains $Item
False
In your example, you could use the Name
or role Id
property (as suggested by @jisaak):
$RoleTable.AllRoles | Select-Object Name,
@{Name = "OnMaster"; Expression = {$RoleTable.MasterRoles.Id -contains $_.Id}},
@{Name = "OnSlave"; Expression = {$RoleTable.SlaveRoles.Id -contains $_.Id}}
As shown above, I would probably use generic boolean values as indicators, rather than strings
This behaviour is a deliberate performance optimization in .NET - you never know how deep down the rabbit hole you would need to go to ensure exact value comparison of all internal attributes of an object.
Value types, on the other hand, are easier to perform equality comparisons against (and also don't necessarily have a memory reference to compare), resulting in:
[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
and so on...