4

I have a collection of objects with properties like id, username, email, current_sign_in_at, identities. Where Identities property is an array of objects with two properties. This would be a json representation of an object:

{
        "id": 45,
        "name": "Emilio Roche",
        "username": "EROCHE",
        "state": "active",
        "identities": [
            {
                "provider": "ldapmain",
                "extern_uid": "cn=roche\\, emilio,ou=xxxxxxxxxx"
            }    
          ]
    }

But some of the elements in the list do not have the identities property. So, when I do:

Get-Collection | Select-Object id, username  -ExpandProperty identities

I get only those elements with identities property. I need all the entities, with or without identities property

mklement0
  • 382,024
  • 64
  • 607
  • 775
mnieto
  • 3,744
  • 4
  • 21
  • 37
  • The answer that you've accepted does not match your question, which will be confusing to future readers. Even if your true problem turned out to be something different, it is more helpful to future readers to accept the answer that solves the problem in the question _as asked_. – mklement0 Dec 04 '18 at 15:09

2 Answers2

6

If there are not too many properties to handle, you could use something like this:

Get-Collection | Select-Object id, 
    username,
    @{n='provider';e={$_.identities.provider}}, 
    @{n='extern_uid';e={$_.identities.extern_uid}}

This will return $null on the properties provider and extern_uid for those objects, that do not have the identities property:

id username provider extern_uid                     
-- -------- -------- ----------                     
45 EROCHE   ldapmain cn=roche\, emilio,ou=xxxxxxxxxx
46 EROCHE                                           

EDIT

As mklement0 pointed out, that approach doesn't work, if the identities property holds more than one object.

mklement0's answer has an elegant solution to this problem and should have been the accepted answer.

Manuel Batsching
  • 3,406
  • 14
  • 20
  • The use of calculated properties is promising, but note that `identities` is an _array_, so with a given object having _multiple_ identities, your output objects will have arrays stored in the `.provider` and `.extern_uid` properties, which is not the same as using `-ExpandProperties identities`, which _enumerates_ the identities and creates an output object for each. – mklement0 Dec 04 '18 at 14:01
  • 1
    You are absolutely right! I did miss the part, that there can be multiple objects in the identities property. – Manuel Batsching Dec 04 '18 at 15:07
4

Note: This answer addresses the question as asked, but, judging by what answer was accepted, the real problem must have been different.

Select-Object -ExpandProperty identities id, username outputs an object for each individual identity in the identities array.

In order to include input objects that lack an identities property, you must therefore provide a placeholder dummy identity for them, which is what the following code demonstrates, using placeholder identity [pscustomobject] @{ provider='none'; extern_uid='none' } via an auxiliary Select-Object call that uses a calculated property to ensure the existence of an identities property.

# Sample JSON:
#  * The 1st object has *2* identities,
#  * the 2nd one none.
$json = '[
  {
    "id": 45,
    "name": "Emilio Roche",
    "username": "EROCHE",
    "state": "active",
    "identities": [
      {
          "provider": "ldapmain",
          "extern_uid": "cn=roche\\, emilio,ou=xxxxxxxxxx"
      },    
      {
          "provider": "ad",
          "extern_uid": "cn=roche\\, emilio,ou=yyyyyyyyyy"
      }    
    ]
  },
  {
    "id": 46,
    "name": "A. Non",
    "username": "ANON",
    "state": "dormant"
  }
]'

($json | ConvertFrom-Json) | 
  Select-Object id, username, @{ n='identities'; e={ 
      if ($_.identities) { $_.identities }
      else               { [pscustomobject] @{ provider='none'; extern_uid='none' } } 
    } } |
      Select-Object id, username -ExpandProperty identities 

The above yields:

provider extern_uid                      id username
-------- ----------                      -- --------
ldapmain cn=roche\, emilio,ou=xxxxxxxxxx 45 EROCHE
ad       cn=roche\, emilio,ou=yyyyyyyyyy 45 EROCHE
none     none                            46 ANON

Note how EROCHE is represented twice, once for each identity.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    OP clearly states, that identity is an array of objects. A requirement that I overlooked. So I agree, that your answer should be the accepted one. – Manuel Batsching Dec 04 '18 at 15:00