Object-New PSObject vs. Object-Custom PSObject

Object-New PSObject vs. Object-Custom PSObject

In regards to the differences between PSObject and PSCustomObject, as well as how they work, there is often some confusion.

Either approach can be used to take a set of values from a collection of PowerShell objects and collect them into a single output. Both avenues will also output the data as NoteProperties in the System.Management.Automation.PSCustomObject object types. What's the difference?

New-Object was introduced in PowerShell v1.0 and has undergone a number of changes while PSCustomObject was introduced in v3.0. New-Object must be used on systems running PowerShell v2.0 or earlier. From an administrative perspective, the main difference between version 2.0 and version 1.0 is the ability to use hash tables. For instance:

New PSObject in v1.0

"1

$Path = "c:\scripts"

2

$Directory = Get-Acl -Path $Path

3

​4

ForEach ($Dir in $Directory.Access){

5

​6

    $DirPermissions = New-Object -TypeName PSObject

7

    $DirPermissions | Add-Member -MemberType NoteProperty -Name Path -Value $Path

8

    $DirPermissions | Add-Member -MemberType NoteProperty -Name Owner -Value $Directory.Owner

9

    $DirPermissions | Add-Member -MemberType NoteProperty -Name Group -Value $Dir.IdentityReference

10

    $DirPermissions | Add-Member -MemberType NoteProperty -Name AccessType -Value $Dir.AccessControlType

11

    $DirPermissions | Add-Member -MemberType NoteProperty -Name Rights -Value $Dir.FileSystemRights

12

13

    $DirPermissions

14

With the New-Object method in PowerShell v1.0, you have to declare the object type you want to create and add members to the collection in individual commands. This changed however in v2.0 with the ability to use hashtables:

New-Object in PS 2.0

"1

$Path = "c:\scripts"

2

$Directory = Get-Acl -Path $Path

3

4

ForEach ($Dir in $Directory.Access){

5

6

    $DirPermissions = New-Object -TypeName PSObject -Property @{

7

8

    'Path' = $Path

9

    'Owner' = $Directory.Owner

10

    'Group' = $Dir.IdentityReference

11

    'AccessType' = $Dir.AccessControlType

12

    'Rights' = $Dir.FileSystemRights

13

14

    }

15

16

    $DirPermissions

17

}"

Here's the output: 

The script now looks much cleaner and saves a great deal of typing time. The downside of both methods is that the output may not be in the same order in which you listed it, so if you're looking for a particular format, it may not work. In addition to streamlining your scripts, PSCustomObject fixed this issue in v3.0.

PSCustomObject in PowerShell v3.0

"1

$Path = "c:\scripts"

2

$Directory = Get-Acl -Path $Path

3

4

ForEach ($Dir in $Directory.Access){

5

    [PSCustomObject]@{

6

    Path = $Path

7

    Owner = $Directory.Owner

8

    Group = $Dir.IdentityReference

9

    AccessType = $Dir.AccessControlType

10

    Rights = $Dir.FileSystemRights

11

    }#EndPSCustomObject

12

}#EndForEach"

Your output will match what you have defined in your hashtable, as shown in the example. PSCustomObject also has the advantage of enumerating data faster than its New-Object equivalent. PSCustomObject can only be used on PSv2.0 and earlier systems.