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
Tuesday, December 6, 2016
Tuesday, April 12, 2016
Duh...
Remember me having some issues with Custom Objects not beeing ordered in PoSH v2?
$propertyOfSven = @{}
$propertyOfSven.first = "Sven"
$propertyOfSven.last = "Karlsson"
$propertyOfSven.phone = "040-11 12 13"
> $propertyOfSven
Name Value
---- -----
last Karlsson
phone 040-11 12 13
first Sven
> $sven = New-Object PSObject -Property $propertyOfSven
> $sven
last phone first
---- ----- -----
Karlsson 040-11 12 13 Sven
Well, why don't we just Sort the object output (thanks to Bill Stewart)?
> $sven = New-Object PSObject -Property $propertyOfSven | Select-Object first,last,phone
> $sven
first last phone
----- ---- -----
Sven Karlsson 040-11 12 13
And done.
$propertyOfSven = @{}
$propertyOfSven.first = "Sven"
$propertyOfSven.last = "Karlsson"
$propertyOfSven.phone = "040-11 12 13"
> $propertyOfSven
Name Value
---- -----
last Karlsson
phone 040-11 12 13
first Sven
> $sven = New-Object PSObject -Property $propertyOfSven
> $sven
last phone first
---- ----- -----
Karlsson 040-11 12 13 Sven
Well, why don't we just Sort the object output (thanks to Bill Stewart)?
> $sven = New-Object PSObject -Property $propertyOfSven | Select-Object first,last,phone
> $sven
first last phone
----- ---- -----
Sven Karlsson 040-11 12 13
And done.
Tuesday, March 15, 2016
Objects made easy
Ok, so you've noticed me struggle.
But that's how you learn.
In my last post I was trying to simplify the creation of objects in various way but I forgot about the golden rule, KISS (Keep It Simple, Stupid).
That is, if it looks complex, write a function...
So the only way to create an object in PowerShell v2 with ordered properties is like this, right?
So lets make it a an advanced function.
function New-CustomObject
{
param (
[array]$PropertyArray
)
$Object = New-Object PSObject
foreach ($Property in $PropertyArray){
$Object | Add-Member -MemberType 'NoteProperty' -Name $Property -Value $null
}
return $Object
}
Then putting the new function to use
$Kalle = New-CustomObject -PropertyArray "First","Last","Phone"
$Kalle.First = "Kalle"
$Kalle.Last = "Svensson"
$Kalle.Phone = "555 - 55 55 55"
And I'm done
But that's how you learn.
In my last post I was trying to simplify the creation of objects in various way but I forgot about the golden rule, KISS (Keep It Simple, Stupid).
That is, if it looks complex, write a function...
So the only way to create an object in PowerShell v2 with ordered properties is like this, right?
$Kalle = New-Object PSObject$Kalle| Add-Member -MemberType NoteProperty -Name First -Value "Kalle"$Kalle| Add-Member -MemberType NoteProperty -Name Last -Value "Svensson"$Kalle| Add-Member -MemberType NoteProperty -Name Phone -Value "555-55 55 55"$Kalle
First Last Phone
----- ---- -----
Kalle Svensson 555-55 55 55
So lets make it a an advanced function.
function New-CustomObject
{
param (
[array]$PropertyArray
)
$Object = New-Object PSObject
foreach ($Property in $PropertyArray){
$Object | Add-Member -MemberType 'NoteProperty' -Name $Property -Value $null
}
return $Object
}
Then putting the new function to use
$Kalle = New-CustomObject -PropertyArray "First","Last","Phone"
$Kalle.First = "Kalle"
$Kalle.Last = "Svensson"
$Kalle.Phone = "555 - 55 55 55"
$Kalle
First Last Phone
----- ---- -----
Kalle Svensson 555-55 55 55
And I'm done
Thursday, March 3, 2016
Finally, objects is making sence
I've been struggling with one last part of MS PowerShell for a while now, namely the internal data structures of PowerShell objects (and all .Net objects for that matter).
They are neat, but how do I define custom outputs in an easy way to read in my script code?
You've all read about Add-Member -type and New-Object System.Object.
They do work, but they are a pig to write.
Now, you might say "But why don't simply use hash tables?".
Well, they can't be ordered in PowerShell v2. You'll need PowerShell v3 to build it, i.e.
[ordered]@{First = "Sven"; Last = "Karlsson"}
and then there's the matter of hash tables only containing two values (key and value) which makes the construct confusing :/
Say I want to output a phone list as an object in PowerShell.
$propertyhashSven = @{}
$propertyhashSven.first = "Sven"
$propertyhashSven.last = "Karlsson"
$propertyhashSven.phone = "040-11 12 13"
> $propertyhashSven
Name Value
---- -----
last Karlsson
phone 040-11 12 13
first Sven
> $sven = New-Object PSObject -Property $propertyhashSven
> $sven
last phone first
---- ----- -----
Karlsson 040-11 12 13 Sven
The properties is not ordered at ALL :/
But how about this...
First thing is to define the object. The easiest way I found is to first create my own data type in C#.
add-type @"
public struct contact {
public string First;
public string Last;
public string Phone;
}
"@
Then, simply create the objects using that data type.
> $sven = New-Object contact
> $kalle = New-Object contact
And then populate it with some properties
> $sven.First = "Sven"
> $sven.Last = "Karlsson"
> $sven.Phone = "040-11 12 13"
> $kalle.first = "Kalle"
> $kalle.last = "Svensson"
> $kalle.phone = "08-555 555"
And then finally wrapping it up in a phone book as an array.
> $phonebook = @($sven,$kalle)
And there you go :)
> $phonebook
First Last Phone
----- ---- -----
Sven Karlsson 040-11 12 13
Kalle Svensson 08-555 555
Want to sort it by first name? No problems.
> $phonebook | Sort-Object First
First Last Phone
----- ---- -----
Kalle Svensson 08-555 555
Sven Karlsson 040-11 12 13
And adding more entries is just a matter of expanding the array...
> $sture = New-Object contact
> $sture.first = "Sture"
> $phonebook = $phonebook + $sture
> $phonebook
First Last Phone
----- ---- -----
Sven Karlsson 040-11 12 13
Kalle Svensson 08-555 555
Sture
And hopefully, it won't break anything ;)
They are neat, but how do I define custom outputs in an easy way to read in my script code?
You've all read about Add-Member -type and New-Object System.Object.
They do work, but they are a pig to write.
Now, you might say "But why don't simply use hash tables?".
Well, they can't be ordered in PowerShell v2. You'll need PowerShell v3 to build it, i.e.
[ordered]@{First = "Sven"; Last = "Karlsson"}
and then there's the matter of hash tables only containing two values (key and value) which makes the construct confusing :/
Say I want to output a phone list as an object in PowerShell.
$propertyhashSven = @{}
$propertyhashSven.first = "Sven"
$propertyhashSven.last = "Karlsson"
$propertyhashSven.phone = "040-11 12 13"
> $propertyhashSven
Name Value
---- -----
last Karlsson
phone 040-11 12 13
first Sven
> $sven = New-Object PSObject -Property $propertyhashSven
> $sven
last phone first
---- ----- -----
Karlsson 040-11 12 13 Sven
The properties is not ordered at ALL :/
But how about this...
First thing is to define the object. The easiest way I found is to first create my own data type in C#.
add-type @"
public struct contact {
public string First;
public string Last;
public string Phone;
}
"@
Then, simply create the objects using that data type.
> $sven = New-Object contact
> $kalle = New-Object contact
And then populate it with some properties
> $sven.First = "Sven"
> $sven.Last = "Karlsson"
> $sven.Phone = "040-11 12 13"
> $kalle.first = "Kalle"
> $kalle.last = "Svensson"
> $kalle.phone = "08-555 555"
And then finally wrapping it up in a phone book as an array.
> $phonebook = @($sven,$kalle)
And there you go :)
> $phonebook
First Last Phone
----- ---- -----
Sven Karlsson 040-11 12 13
Kalle Svensson 08-555 555
Want to sort it by first name? No problems.
> $phonebook | Sort-Object First
First Last Phone
----- ---- -----
Kalle Svensson 08-555 555
Sven Karlsson 040-11 12 13
And adding more entries is just a matter of expanding the array...
> $sture = New-Object contact
> $sture.first = "Sture"
> $phonebook = $phonebook + $sture
> $phonebook
First Last Phone
----- ---- -----
Sven Karlsson 040-11 12 13
Kalle Svensson 08-555 555
Sture
And hopefully, it won't break anything ;)
Subscribe to:
Comments (Atom)