Tuesday, December 6, 2016

Why does my Custom Objects goes all {} on me?

Well, when working with AD in i.e. ADSI you don't get single objects in return but collections.

So if adding a property of such an object, it will be presented to PoSH as multivalued and thus entered as a collection instead of a value.

For this example I've done an LDAP query to an AD returning a DN object, $objDN.

Now this collection has some properties I'm interested in.

Path             Properties
----             ----------
LDAP://CN=...    {operatingsystem, countrycode, cn, lastlogoff...}
LDAP://CN=...    {operatingsystem, countrycode, cn, lastlogoff...}


The properties property is obviously a collection.

PS U:\> $objDN[0].properties

Name                           Value
----                           -----
operatingsystem                {Windows Server 2008 R2 Standard}
countrycode                    {0}
cn                             ...
lastlogoff                     {0}
flags                          {16}
dscorepropagationdata          {2016-06-15 15:31:24, 2015-12-28 18:53:43, 2015-12-28 18:53:37, 2015-12-28 18:53:33...}
dnshostname                    ...
usncreated                     {1548162366}
objectguid                     ...

...


But all values of the properties is also collections, *even* when they are single valued.

So using one of the values will look kind if weird on some occasions.

Pure string handling is ok.

PS U:\> $objDN[0].properties.operatingsystem
Windows Server 2008 R2 Standard


 But Custom Object will look funny.

PS U:\> $objComp = @{}
PS U:\> $objComp.OS = $objDN[0].properties.operatingsystem
PS U:\> $objComp.Purchase = "2015-01-01"
PS U:\> $objComp.Modell = "Dell Lattitude"
PS U:\> $objComp

Name                           Value
----                           -----
Modell                         Dell Lattitude
Purchase                       2015-01-01
OS                             {Windows Server 2008 R2 Standard}


The .OS property can still be used as a string when needed, but it looks darned ugly. And the value is actually a string.

The collection type:

PS U:\> $objComp.OS
Windows Server 2008 R2 Standard


PS U:\> $objComp.OS.gettype()

IsPublic IsSerial Name                               BaseType
-------- -------- ----                               --------
True     False    ResultPropertyValueCollection      System.Collections.ReadOnlyCollectionBase


The type of the single value:

PS U:\> $objComp.OS[0]
Windows Server 2008 R2 Standard


PS U:\> $objComp.OS[0].gettype()

IsPublic IsSerial Name                               BaseType
-------- -------- ----                               --------
True     True     String                             System.Object


So for single valued collections, simply just use the first entry of the collection.

$objComp.OS = $objDN[0].properties.operatingsystem[0]

PS U:\> $objComp

Name                           Value
----                           -----
Modell                         Dell Lattitude
Purchase                       2015-01-01
OS                             Windows Server 2008 R2 Standard





No comments:

Post a Comment