0

I'm trying to get to Azure user extension properties which are synced via AADC (Azure AD Connect) from on-prem to target tenant. As a pre-reading -> good article here : https://www.xtseminars.co.uk/post/azure-ad-schema-and-directory-extensions.

The issue is that those extensions might be or not populated on target user object. So let assume that with single REST API call (https://graph.microsoft.com/beta/users?$select=id,extension_c16821412f864d419a92205ad4820f0c_something&$top=5) I get following response:

$json = '{
    "value": [
        {
            "id": "91c0b90e-4ed0-4c69-8b96-b67c07bbb061"
        },
        {
            "id": "fdcd34dc-e7ab-4045-881d-0fee024c2b55",
            "extension_c16821412f864d419a92205ad4820f0c_something": "INXXXXXX213423"
        },
        {
            "id": "90ebc867-6a67-4cf0-a5d9-e4c07c9d3905"
        },
        {
            "id": "80134f5f-892f-4800-9087-924a0c69b7f1"
        },
        {
            "id": "36fae4de-c685-4da5-9458-e165d99fe670"
        }
    ]
}'

Question is - how to nicely get to note properties which are defined 'optionally' ? As below gives just id:

PS> ($json | ConvertFrom-Json).value

id
--
91c0b90e-4ed0-4c69-8b96-b67c07bbb061
fdcd34dc-e7ab-4045-881d-0fee024c2b55
90ebc867-6a67-4cf0-a5d9-e4c07c9d3905
80134f5f-892f-4800-9087-924a0c69b7f1
36fae4de-c685-4da5-9458-e165d99fe670

Or in general - is it even doable with ConvertFrom-JSON() ?

Peter S.
  • 11
  • 2
  • 1
    What is your expected output format? – Bhargavi Annadevara Sep 28 '20 at 18:09
  • Might be new PSobject with all properties - it really doesn't matter. The question is - is it expected that Convertfrom-json() trimms down properties which are not visible on every instance of returned JSON response ? – Peter S. Sep 28 '20 at 18:36

2 Answers2

1

Ok, seems after reading this nice piece - Understanding NewtonSoft in PowerShell was able to figure out the solution using newtonsoft.json module

PS > Import-Module newtonsoft.json
PS >
PS > $json = '{
>> "value": [
>>         {
>>             "id": "91c0b90e-4ed0-4c69-8b96-b67c07bbb061"
>>         },
>>         {
>>             "id": "fdcd34dc-e7ab-4045-881d-0fee024c2b55",
>>             "extension_somedata": "XXXXXX213423"
>>         },
>>         {
>>             "id": "90ebc867-6a67-4cf0-a5d9-e4c07c9d3905"
>>         },
>>         {
>>             "id": "80134f5f-892f-4800-9087-924a0c69b7f1"
>>         },
>>         {
>>             "id": "36fae4de-c685-4da5-9458-e165d99fe670"
>>         }
>>     ]
>> }'
PS >
PS >
PS > $u = ($json |ConvertFrom-JsonNewtonsoft).value
PS > $u

Name                           Value
----                           -----
id                             91c0b90e-4ed0-4c69-8b96-b67c07bbb061
id                             fdcd34dc-e7ab-4045-881d-0fee024c2b55
extension_somedata             XXXXXX213423
id                             90ebc867-6a67-4cf0-a5d9-e4c07c9d3905
id                             80134f5f-892f-4800-9087-924a0c69b7f1
id                             36fae4de-c685-4da5-9458-e165d99fe670


PS > $allRows = @()
PS > foreach($o in $u){
>> $lineObject = New-Object PSObject
>>             add-member -inputobject $lineObject -membertype noteproperty -name "id" -value $o.id
>>             add-member -inputobject $lineObject -membertype noteproperty -name "extension_somedata" -value $o.extension_somedata
>> $allRows+=$lineObject
>> }
PS >
PS > $allRows

id                                   extension_somedata
--                                   ------------------
91c0b90e-4ed0-4c69-8b96-b67c07bbb061
fdcd34dc-e7ab-4045-881d-0fee024c2b55 XXXXXX213423
90ebc867-6a67-4cf0-a5d9-e4c07c9d3905
80134f5f-892f-4800-9087-924a0c69b7f1
36fae4de-c685-4da5-9458-e165d99fe670
Peter S.
  • 11
  • 2
0

Yes, you shouldn't need another module as it is possible with ConvertFrom-JSON itself, but with an additional parameter -AsHashtable.

There are some constraints with the ConvertFrom-JSON cmdlet and -AsHashtable helps overcome some of them. Quoting from the docs:

  • If the JSON contains a list with keys that only differ in casing. Without the switch, those keys would be seen as identical keys and therefore only the last one would get used.
  • If the JSON contains a key that is an empty string. Without the switch, the cmdlet would throw an error since a PSCustomObject does not allow for that but a hash table does. An example use case where this can occurs are project.lock.json files.
  • Hash tables can be processed faster for certain data structures.

Do note that this switch was introduced in PowerShell 6.0.

Applying this to the same example that you specified:

PS > $json = '{
>>     "value": [
>>         {
>>             "id": "91c0b90e-4ed0-4c69-8b96-b67c07bbb061"
>>         },
>>         {
>>             "id": "fdcd34dc-e7ab-4045-881d-0fee024c2b55",
>>             "extension_somedata": "INXXXXXX213423"
>>         },
>>         {
>>             "id": "90ebc867-6a67-4cf0-a5d9-e4c07c9d3905"
>>         },
>>         {
>>             "id": "80134f5f-892f-4800-9087-924a0c69b7f1"
>>         },
>>         {
>>             "id": "36fae4de-c685-4da5-9458-e165d99fe670"
>>         }
>>     ]
>> }'
PS >
PS > $u = ($json | ConvertFrom-Json -AsHashtable).value
PS >
PS > $u

Name                           Value
----                           -----
id                             91c0b90e-4ed0-4c69-8b96-b67c07bbb061
id                             fdcd34dc-e7ab-4045-881d-0fee024c2b55
extension_somedata             INXXXXXX213423
id                             90ebc867-6a67-4cf0-a5d9-e4c07c9d3905
id                             80134f5f-892f-4800-9087-924a0c69b7f1
id                             36fae4de-c685-4da5-9458-e165d99fe670

PS > $allRows = @()
PS >
PS > foreach($o in $u){
>>     $lineObject = New-Object PSObject
>>     Add-Member -InputObject $lineObject -MemberType NoteProperty -Name "id" -Value $o.id
>>     Add-Member -InputObject $lineObject -MemberType NoteProperty -Name "extension_somedata" -Value $o.extension_somedata
>>     $allRows+=$lineObject
>> }
PS >
PS > $allRows

id                                   extension_somedata
--                                   ------------------
91c0b90e-4ed0-4c69-8b96-b67c07bbb061
fdcd34dc-e7ab-4045-881d-0fee024c2b55 INXXXXXX213423
90ebc867-6a67-4cf0-a5d9-e4c07c9d3905
80134f5f-892f-4800-9087-924a0c69b7f1
36fae4de-c685-4da5-9458-e165d99fe670

References:

Bhargavi Annadevara
  • 4,923
  • 2
  • 13
  • 30
  • Hello Bhargavi. Indeed - figured out the same in the later stage, that **AsHashTable** provides the same results, but I don't have to use external module. But really appreciate above! – Peter S. Oct 10 '20 at 13:56
  • @PeterS. Thank you! :) Please [mark the response](https://stackoverflow.com/help/someone-answers) if it helped so it benefits others in the community with similar asks. – Bhargavi Annadevara Oct 10 '20 at 14:07