Creating Objects
There is a post on the PowerShell Team blog about using New-Object - http://blogs.msdn.com/powershell/archive/2009/12/05/new-object-psobject-property-hashtable.aspx
The –property parameter discussed in this post is something that I had only come across recently. In a number of recent posts I have used Add-Type to create a new object by using C# code to define a new class rather than using New-Object and Add-Member. The post on the team blog, plus questions I’d been asked about why I used add-type got me thinking about creating objects.
In PowerShell v1 we used to do this
| 001 002 003
| $new1 = New-Object -TypeName PSObject $new1 | Add-Member -Name p1 -Value 1 -MemberType NoteProperty -PassThru | Add-Member -Name p2 -Value "a" -MemberType NoteProperty |
We would create an object and then use Add-Member to add the properties. The object could then be used
| 001 002 003 004
| $new1 | ft -AutoSize $new1.p1 = "b" $new1 | ft -AutoSize |
This would give the results we expect
p1 p2
-- --
1 a
p1 p2
-- --
b a
Notice that we have been able to change the type of p1 from an integer to a string.
In v2 we get the –property parameter on New-Object
| 001 002 003 004 005
| $p = @{ p1 = 1 p2 = "a" } $new2 = New-Object -TypeName PSObject -Property $p |
In this method we create a hash table holding the properties and the values. It can be used when we create the object so that the properties are immediately populated. This is a neater method than the multiple calls to Add-Member we saw earlier.
The object can be used as before
| 001 002 003 004
| $new2 | ft -AutoSize $new2.p1 = "b" $new2 | ft -AutoSize |
with the following results
p2 p1
-- --
a 1
p2 p1
-- --
a b
Again notice that we can change the type of p1.
If we want to use a PSObject and create properties then using a hash table in v2 involves less typing, looks neater and is probably easier to understand.
In a number of recent posts I have been creating a C# class rather than using PSObject. This is a better variant of that technique showed to me by Doug Finke (thanks Doug)
| 001 002 003 004 005 006 007 008 009 010 011 012 013
| $code = @" public class testobject { public int p1 {get; set;} public string p2 {get; set;} } "@ Add-Type -TypeDefinition $code -Language CSharpversion3 $p = @{ p1 = 1 p2 = "a" } $new3 = New-Object -TypeName testobject -Property $p |
I have created a simple .NET class with our two properties. Add-Type is used to add the definition into PowerShell. I can then create an object using a hash table for the properties. This probably looks more complicated but there is a significant difference when we come to use it
| 001 002 003 004
| $new3 | ft -AutoSize $new3.p1 = "b" $new3 | ft -AutoSize |
gives us
p1 p2
-- --
1 a
Exception setting "p1": "Cannot convert value "b" to type "System.Int32". Error: "Input string was not in a correct format.""
At line:16 char:7
+ $new3. <<<< p1 = "b"
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
p1 p2
-- --
1 a
We can’t change the type of p1 because it is defined by the class we created. This gives me an extra level of protection on what I’m doing as I can’t make a mistake and set the property to the wrong type.
PowerShell often gives us a number of ways of achieving the goal. In this case choose the one that best fits your requirements.
Technorati Tags:
PowerShell,
Objects