可以使用 Microsoft Graph PowerShell cmdlet 从 AdditionalProperties 字典中提取信息吗?

Possible to pull info from AdditionalProperties dictionary with Microsoft Graph PowerShell cmdlets?

我正在尝试使用 PowerShell Graph cmdlet 而不是 Azure AD 模块 cmdlet。使用 Azure AD 模块,我可以这样做:

# This is what I want:
get-azureadgroupmember -objectid $GroupID | select-object -property displayname, `
    mail, userprincipalname, objectid

DisplayName     Mail                        UserPrincipalName  ObjectId
-----------     ----                        -----------------  --------
John Smith      John.Smith@example.org      jsmith@example.org 4bae8291-6ec3-192b-32ce-dd21869ef784
(...)


# All of these properties are directly accessible in the returned objects:
$res = get-azureadgroupmember -objectid $GroupID
$res[0] | fl -prop *
# Shows long list of directly accessible properties

我正在尝试找出与 PowerShell Graph 的等效项:

$res = get-mggroupmember -groupid $GroupID
$res[0] | fl -prop *
# Only properties are DeletedDateTime, Id, and AdditionalProperties

# Want to do something like this, but it doesn't work:
get-mggroupmember -groupid $GroupID | select-object -property id, `
    additionalproperties['displayName'], additionalproperties['mail'], `
    additionalproperties['userPrincipalName']

# This works, but is there a better option???
get-mggroupmember -groupid $GroupID | foreach-object { `
        "{0},{1},{2},{3}" -f $_.id, $_.additionalproperties['displayName'], `
        $_.additionalproperties['mail'], $_.additionalproperties['userPrincipalName']
    }

AdditionalProperties 是一个字典 (IDictionary),其中包含显示名称、邮件和用户主体名称。我的想法是可能有更好的方法来执行此操作或获取信息。

get-mggroupmember 中有几个有趣的参数我不清楚,包括“-expand属性”和“-属性”。我试过玩这些但没有任何运气。我想知道是否有办法使用这些来做我想做的事情。

建议?

给定以下 $object,3 个属性,其中一个 AdditionalPropertiesDictionary<TKey,TValue>

$dict = [Collections.Generic.Dictionary[object, object]]::new()
$dict.Add('displayName', 'placeholder')
$dict.Add('mail', 'placeholder')
$dict.Add('userPrincipalName', 'placeholder')

$object = [pscustomobject]@{
    DeletedDateTime = 'placeholder'
    Id = 'placeholder'
    AdditionalProperties = $dict
}

假设您对 IddisplayNamemail 感兴趣,您可以使用 Select-Object with calculated properties:

$object | Select-Object @(
    'Id'
    @{
        N = 'displayName'
        E = { $_.additionalProperties['displayName'] }
    }
    @{
        N = 'mail'
        E = { $_.additionalProperties['mail'] }
    }
)

然而,一旦您需要从对象中选择更多 属性 值,这就会变得混乱,在这种情况下,带循环的 PSCustomObject 会派上用场:

$object | ForEach-Object {
    [pscustomobject]@{
        Id          = $_.Id
        displayName = $_.additionalProperties['displayName']
        mail        = $_.additionalProperties['mail']
    }
}

两种选择都将输出相同的 "flattened" 对象,可以毫无问题地转换为 Csv:

  • 作为对象
Id          displayName mail
--          ----------- ----
placeholder placeholder placeholder
  • 作为 CSV
"Id","displayName","mail"
"placeholder","placeholder","placeholder"

从这个意义上讲,您可以使用上述技术之一构造一个对象数组,例如:

Get-MgGroupMember -GroupId $GroupID | ForEach-Object {
    [pscustomobject]@{
        Id                = $_.id
        displayName       = $_.additionalproperties['displayName']
        mail              = $_.additionalproperties['mail']
        userPrincipalName = $_.additionalproperties['userPrincipalName']
    }
}

如果您正在寻找一种编程方式来展平对象,您可以从使用这个示例开始,但是请务必注意,这可以只处理属性只嵌套一次的对象,换句话说,它不能处理递归:

$newObject = [ordered]@{}
foreach($property in $object.PSObject.Properties) {
    if($property.Value -is [Collections.IDictionary]) {
        foreach($addproperty in $property.Value.GetEnumerator()) {
            $newObject[$addproperty.Key] = $addproperty.Value
        }
        continue
    }
    $newObject[$property.Name] = $property.Value
}
[pscustomobject] $newObject

此输出将变成像这样的扁平对象,也可以毫无问题地转换为 Csv:

DeletedDateTime   : placeholder
Id                : placeholder
displayName       : placeholder
mail              : placeholder
userPrincipalName : placeholder

同样值得注意的是,上面的示例没有处理可能的键冲突,如果有 2 个或更多属性具有相同的名称,一个将覆盖其他。