What I try to do is quite simple: create a custom object with some properties, and then define "groups" of properties (columns) for use in Select-Object. Let me clarify:
$props = @{"Mary"=1;"Jane"=2;"Frank"=3;"John"=5;"Brenda"=6}
$obj = New-Object PSObject $props
I now have a custom object with some bogus data. What I now want to be able to do is
$obj | select Male
$obj | select Female
And what I had thought would do the trick, is something like this:
$obj | Add-Member PropertySet "Male" @("Frank","John")
$obj | Add-Member PropertySet "Female" @("Mary","Jane","Brenda")
It doesn't work - I get this error:
Add-Member : Cannot convert the "System.Object[]" value of type
"System.Object[]" to type "System.Collections.ObjectModel.Collection`1[System.String]".
I guess I should provide another object type than my array to Add-Member
, but I'm unsure how I should do that.
Does anyone have experience with this?
Important note: I'm on Powershell 2, and I read on various sites that it has a bug that doesn't allow setting the default properties. That's not what I want to do - I want to create a custom property set and not a default one - but it could be that this bug also prevents me from getting what I want.
You are very close. The problem is that you're not creating the object correctly. You need to specify the -Property
parameter before you specify a hashtable of properties. Without it, you just create a hashtable. This works:
$props = @{"Mary"=1;"Jane"=2;"Frank"=3;"John"=5;"Brenda"=6}
$obj = New-Object -TypeName PSObject -Property $props
$obj | Add-Member PropertySet "Male" @("Frank","John")
$obj | Add-Member PropertySet "Female" @("Mary","Jane","Brenda")
$obj | select male
Frank John
----- ----
3 5
Why did this happend?
If you read the syntax for New-Object
using Get-help new-object
or Get-Command New-Object -Syntax
, you will see that for normal .Net types, the syntax is:
New-Object [-TypeName] <String> [[-ArgumentList] <Object[]>] [-Property <IDictionary>]
Notice that -ArgumentList
is the 2nd paramter, not -Property
as you expected. So your code actually did:
$obj = New-Object -TypeName PSObject -ArgumentList $props
instead of:
$obj = New-Object PSObject -Property $props
EDIT The solution above only worked in PS3.0 . It's still valid though, as the -Property
parameter is required in PS2.0 also. In PS2.0 you need to cast the propertyset-array to string[]
(string-array) and not an object-array (object[]
) which is the default array. A complete solution for PS2.0 is:
$props = @{"Mary"=1;"Jane"=2;"Frank"=3;"John"=5;"Brenda"=6}
$obj = New-Object -TypeName PSObject -Property $props
$obj | Add-Member PropertySet "Male" ([string[]]@("Frank","John"))
$obj | Add-Member PropertySet "Female" ([string[]]@("Mary","Jane","Brenda"))
$obj | select male
Frank John
----- ----
3 5