可以从Microsoft Graph PowerShell CMDLET中从其他Properties字典中获取信息吗?

发布于 2025-01-31 14:34:43 字数 1928 浏览 1 评论 0 原文

我正在尝试使用PowerShell图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      [email protected]      [email protected] 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图相等的:

$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']
    }

fromproperties是一个字典(Idictionary),其中包含displayName,mail和userprincipalname。我的想法是,可能有一种更好的方法来做到这一点或获取信息。

get-mggroupmember 中有一些有趣的参数,我尚不清楚包括 -expandProperty and -property 。我尝试过这些玩耍,但没有任何运气。我想知道是否有一种方法可以使用这些方法来完成我想做的事情。

建议?

I am trying to use PowerShell Graph cmdlets instead of the Azure AD module cmdlets. With the Azure AD module, I can do this:

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

DisplayName     Mail                        UserPrincipalName  ObjectId
-----------     ----                        -----------------  --------
John Smith      [email protected]      [email protected] 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

I'm trying to figure out the equivalent with 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 is a dictionary (IDictionary) which contains displayname, mail, and userprincipalname. My thought is there is probably a better way to do this or to get at the information.

There are a few interesting parameters in Get-MgGroupmember that I'm not clear on including -ExpandProperty and -Property. I've tried playing around with these but haven't had any luck. I'm wondering if there's a way to use these to do what I want.

Suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不如归去 2025-02-07 14:34:43

给定以下 $ object ,3个属性和其中一个 fromproperties

$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
}

api/system.collections.generic.dictionary-2?view = net-6.0“ rel =“ nofollow noreferrer”> dictionary< tkey, tvalue 对 ID displayName mail 感兴趣,您可以使用 select-object 带有计算的属性

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

但是,一旦您需要从对象中选择更多属性值, pscustomobject 在这种情况下,loop on Stange in :

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

这两种替代方案都将输出相同的“扁平” 对象,可以将可以转换为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']
    }
}

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

$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个或更多的属性具有相同的名称,那么一个会覆盖其他属性。


奖励函数应与CMDLET返回的对象一起使用的奖励功能noreferrer“> graph , and 模块。此功能可用于将其 dictionary`2 属性变平很有用。只有当属性值实现 idictionary 因此不要指望它会使任何对象变平。对于给定的示例应该很好。

function Select-GraphObject {
    [CmdletBinding(PositionalBinding = $false)]
    param(
        [Parameter(Mandatory, ValueFromPipeline, DontShow)]
        [object] $InputObject,

        [Parameter(Position = 0)]
        [SupportsWildcards()]
        [string[]] $Properties = '*'
    )

    begin {
        $firstObject = $true
        $toSelect    = [Collections.Generic.List[object]]::new()
    }
    process {
        if($firstObject) {
            foreach($property in $InputObject.PSObject.Properties) {
                foreach($item in $Properties) {
                    if($property.Value -is [Collections.IDictionary]) {
                        foreach($key in $property.Value.PSBase.Keys) {
                            if($key -like $item -and $key -notin $toSelect.Name) {
                                $toSelect.Add(@{
                                    $key = { $_.($property.Name)[$key] }
                                })
                            }
                        }
                        continue
                    }

                    if($property.Name -like $item -and $property.Name -notin $toSelect) {
                        $toSelect.Add($property.Name)
                    }
                }
            }
            $firstObject = $false
        }

        $out = [ordered]@{}
        foreach($item in $toSelect) {
            if($item -isnot [hashtable]) {
                $out[$item] = $InputObject.$item
                continue
            }
            $enum = $item.GetEnumerator()
            if($enum.MoveNext()) {
                $out[$enum.Current.Key] = $InputObject | & $enum.Current.Value
            }
        }
        [pscustomobject] $out
    }
}

使用上面示例的 $ object 的副本,如果使用 -properties 的默认值,则示例对象将被扁平:

PS /> $object, $object, $object | Select-GraphObject

DeletedDateTime Id          displayName mail        userPrincipalName
--------------- --          ----------- ----        -----------------
placeholder     placeholder placeholder placeholder placeholder
placeholder     placeholder placeholder placeholder placeholder
placeholder     placeholder placeholder placeholder placeholder

或我们可以特定属性的过滤器,甚至来自 fromproperties 属性的键:

PS /> $object, $object, $object | Select-GraphObject Id, disp*, user*

Id          displayName userPrincipalName
--          ----------- -----------------
placeholder placeholder placeholder
placeholder placeholder placeholder
placeholder placeholder placeholder

Given the following $object, 3 properties and one of them AdditionalProperties is a Dictionary<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
}

Supposing from this object you're interested in Id, displayName and mail, you could use Select-Object with calculated properties:

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

However this gets messy as soon as you need to pick more property values from the objects, PSCustomObject with a loop comes in handy in this case:

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

Both alternatives would output the same "flattened" object that can be converted to Csv without any issue:

  • As Object
Id          displayName mail
--          ----------- ----
placeholder placeholder placeholder
  • As Csv
"Id","displayName","mail"
"placeholder","placeholder","placeholder"

In that sense, you could construct an array of objects using one of the above techniques, for example:

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

If you're looking for a programmatical way to flatten the object, you can start by using this example, however it's important to note that this can only handle an object which's property is nested only once, in other words, it can't handle recursion:

$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

The output from this would become a flattened object like this, which also, can be converted to Csv without any issue:

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

It's also worth noting that above example is not handling possible key collision, if there are 2 or more properties with the same name, one would override the others.


Bonus function that should work with the objects returned by the cmdlets from Graph, AzureAD and Az Modules. This function can be useful to flatten their Dictionary`2 property. It only looks one level deep if the property value implements IDictionary so don't expect it to flatten any object. For the given example should work well.

function Select-GraphObject {
    [CmdletBinding(PositionalBinding = $false)]
    param(
        [Parameter(Mandatory, ValueFromPipeline, DontShow)]
        [object] $InputObject,

        [Parameter(Position = 0)]
        [SupportsWildcards()]
        [string[]] $Properties = '*'
    )

    begin {
        $firstObject = $true
        $toSelect    = [Collections.Generic.List[object]]::new()
    }
    process {
        if($firstObject) {
            foreach($property in $InputObject.PSObject.Properties) {
                foreach($item in $Properties) {
                    if($property.Value -is [Collections.IDictionary]) {
                        foreach($key in $property.Value.PSBase.Keys) {
                            if($key -like $item -and $key -notin $toSelect.Name) {
                                $toSelect.Add(@{
                                    $key = { $_.($property.Name)[$key] }
                                })
                            }
                        }
                        continue
                    }

                    if($property.Name -like $item -and $property.Name -notin $toSelect) {
                        $toSelect.Add($property.Name)
                    }
                }
            }
            $firstObject = $false
        }

        $out = [ordered]@{}
        foreach($item in $toSelect) {
            if($item -isnot [hashtable]) {
                $out[$item] = $InputObject.$item
                continue
            }
            $enum = $item.GetEnumerator()
            if($enum.MoveNext()) {
                $out[$enum.Current.Key] = $InputObject | & $enum.Current.Value
            }
        }
        [pscustomobject] $out
    }
}

Using copies of the $object from above examples, if using the default value of -Properties, the example objects would be flattened:

PS /> $object, $object, $object | Select-GraphObject

DeletedDateTime Id          displayName mail        userPrincipalName
--------------- --          ----------- ----        -----------------
placeholder     placeholder placeholder placeholder placeholder
placeholder     placeholder placeholder placeholder placeholder
placeholder     placeholder placeholder placeholder placeholder

Or we can filter for specific properties, even Keys from the AdditionalProperties Property:

PS /> $object, $object, $object | Select-GraphObject Id, disp*, user*

Id          displayName userPrincipalName
--          ----------- -----------------
placeholder placeholder placeholder
placeholder placeholder placeholder
placeholder placeholder placeholder
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文