*****Warning. This is from a preview release******
PowerShell v2 brought the ability to create a custom object via the following method:
1
$CustomObject1 =New-Object psobject-Property @{a=1; b=2; c=3; d=4}
2
3
$CustomObject1 |Format-List
PowerShell v3 brings the possibility to create a custom object via
[pscustomobject]
1
$CustomObject2 = [pscustomobject]@{a=1; b=2; c=3; d=4}
2
3
$CustomObject2 |Format-List
Note: both methods create a PSCustomObject with NoteProperties, not a hashtable object
1
$CustomObject1 |Get-Member
2
3
$CustomObject2 |Get-Member
So, why would you want to do it this way? Well firstly it preserves the insertion order,which helps with my OCD issues again. However, the main reason I have seen so far is that it is also a lot quicker. Fellow PowerShell MVP Tome Tanasovski carried out some basic performance testing which I thought I would highlight here.
There are four different ways you can create a custom object and a typical use case would be using PowerShell for reporting purposes, e.g. iterating through a list of VMs and pulling out various properties of them to create a report. With a very basic example, let’s have a look at the speed differences:
1) Select-Object
Not everybody knows that it’s possible to create a custom object with Select-Object. This was a handy trick since v1 days and was pretty quick too.
1
$TestSelect = {
2
(0..5000) |ForEach-Object {$CustomObject ="" |Select-Object Name,ID
3
$CustomObject.Name ="Test Name"
4
$CustomObject.ID = $_
5
$CustomObject
6
}
7
}
8
Measure-Command $TestSelect |Format-Table TotalSeconds-Autosize
2) Add-Member
1
$TestAddMember = {
2
(0..5000) |ForEach-Object {$CustomObject =New-Objectpsobject
3
$CustomObject |Add-Member -Name "Name" -Value "Test Name"
4
$CustomObject |Add-Member -Name "ID" -Value $_
5
$CustomObject
6
}
7
}
8
Measure-Command $TestAddMember |Format-Table TotalSeconds-Autosize
3) Property Parameter
1
$TestProperty = {
2
(0..5000) |ForEach-Object {New-Object psobject-Property@{Name ="Test Name"; ID = $_}}
3
}
4
Measure-Command $TestProperty |Format-Table TotalSeconds-Autosize
4) [pscustomobject]
1
$TestProperty = {
2
(0..5000) |ForEach-Object {[pscustomobject]@{Name ="Test Name"; ID = $_}}
3
}
4
Measure-Command $TestPSCustomObject |Format-TableTotalSeconds-Autosize
So a summary of the these basic testing results looks pretty good for [pscustomobject]!
Select-Object = 7.74s
Add-Member = 28.87s
Property = 7.29
[pscustomobject] = 0.94s
I hope to try out [pscustomobject] on some of my reporting scripts and see what difference it makes to real world testing.