Blog by: Dmitry Sotnikov
Find him on LinkedIn or Twitter.
Question from Robb during our webinar, “Microsoft Graph Basics for PowerShell Admins”:
- Couldn’t you use $_.id?
In PowerShell, we are used to just be able to pipe the output of one cmdlet to the next one. For example:
Get-ADGroup beatles | Get-ADGroupMember | Get-ADUser –Properties City | Where-Object {$_.city -eq “Liverpool”} | Export-CSV c:\band.csv
Unfortunately, as of right now (version 0.7), this is broken in Microsoft Graph PowerShell SDK, and a pipeline like the following will fail:
Get-MgGroupMember -GroupId 12f1791c-54cb-44b3-9100-2f1c02a6a021 | Get-MgUser
It will fail, because Get-MgUser and other *-MgUser cmdlets expect -UserId as the object identifier from the pipeline. Similarly, Get-MgGroup and Get-MgGroupMember and other group-related cmdlets want -GroupId. However, all cmdlets output objects that simply have the Id property. This naming mismatch (hopefully to be fixed soon) is causing the failure.
Unfortunately, you cannot just do the following (it will fail too):
Get-MgGroupMember -GroupId 12f1791c-54cb-44b3-9100-2f1c02a6a021 | Get-MgUser -UserId $_.Id
That fails, because $_ only works in specific situations when PowerShell iterates through pipeline objects: in script blocks, filters, the process clause of functions, where-object, ForEach-object and switch.
Instead, there are a couple of ways that you can use the ForEach-Object cmdlet to do the iteration for you.
You can simply make it call the next cmdlet for each of the objects:
Get-MgGroupMember -GroupId 12f1791c-54cb-44b3-9100-2f1c02a6a021 | ForEach-Object { Get-MgUser -UserId $_.Id }
Or make it create temporary objects with the mapping and pass them through the pipeline:
Get-MgGroupMember -GroupId 12f1791c-54cb-44b3-9100-2f1c02a6a021 | ForEach-Object { @{ UserId=$_.Id}} | Get-MgUser
For more, watch the on-demand webinar, Microsoft Graph Basics for PowerShell Admins.