Creating PowerShell Custom Objects
When working with PowerShell, creating custom objects is often necessary. This is a great way to store data in a structured way. Starting with PowerShell 3.0, the PSCustomObject type was introduced as a replacement for the PSObject type. PSCustomObjects are more efficient and maintain the order of properties.
You can create custom objects in PowerShell using the New-Object cmdlet or by using the [PSCustomObject] type accelerator.
Using New-Object
The New-Object cmdlet lets you create custom objects by specifying the object type and properties. Here's an example of how to create a custom object using the New-Object cmdlet:
$Object = New-Object -TypeName PSCustomObject -Property @{
"ActiveDirectoryDomain" = "corp.contoso.com"
"ActiveDirectorySite" = "HQ"
}
The New-Object command here is creating an object type of PSCustomObject with two properties defined in a hashtable. The hashtable keys are the property names, and the values are the property values.
Using [PSCustomObject] Type Accelerator
Another, more convenient way to create custom objects is by using the [PSCustomObject] type accelerator. Here's an example of how to create a custom object using the [PSCustomObject] type accelerator:
$Object = [PSCustomObject]@{
"ActiveDirectoryDomain" = "corp.contoso.com"
"ActiveDirectorySite" = "HQ"
}
This method bypasses the use of the New-Object cmdlet and is more concise. Using the same hashtable syntax, you can define the properties of the custom object.
Accessing Custom Object Properties
After creating a custom object, you can access its properties using dot notation. Here's an example of how to access the properties of the custom object we created earlier:
$Object.ActiveDirectoryDomain
> "corp.contoso.com"
$Object.ActiveDirectorySite
> "HQ"
Adding arrays, hashtables, and other objects to custom objects
PSCustomObjects can also contain arrays, hashtables, and other objects as properties. Here's an example of how to create a custom object with an array property:
$Array = @()
$Array += 1, 2, 3, 4, 5
$Object = [PSCustomObject]@{
Numbers = $Array
}
$Object | Select *
> Numbers
> -------
> {1, 2, 3, 4...}
$Object.Numbers
> 1
> 2
> 3
> 4
> 5
$Object.Numbers.Count
> 5
In this example, we create an empty array, then add numbers 1-5 to the array using the "+=" alias for the Add method. A custom object called $Object is then created, with the numbers array as a property. We can then access the array property and the numbers array within as a sub-object.
Creating Complex Custom Objects
A common use of PSCustomObjects is to create complex hashtables with data from various sources. Here's an example of how to create a complex custom object using output from the Get-Process cmdlet, combined with the current date and time:
$Date = Get-Date -Format yyy-MM-dd
$Processes = Get-Process
$SpoolProcess = $Processes | Where-Object {$_.ProcessName -eq "SpoolSV"}
$CustomText = "This is a custom object with process information"
$SpoolProcessInfo = [PSCustomObject]@{
"Title" = $CustomText
"ProcessName" = $SpoolProcess.ProcessName
"Id" = $SpoolProcess.Id
"PagedMemorySize" = $SpoolProcess.PagedMemorySize
"PrivateMemorySize" = $SpoolProcess.PrivateMemorySize
"VirtualMemorySize" = $SpoolProcess.VirtualMemorySize
"CheckDate" = $Date
}
In this example, first get the current date the Get-Date cmdlet. Then get a list of all running processes using the Get-Process cmdlet. Filter the list to find the SpoolSV process using the Where-Object cmdlet. As a final entry for the object, create a text variable for a title column. Finally create a custom object called $SpoolProcessInfo with properties that include the process name, ID, memory sizes, and the current date.
Using the PSCustom Object with other cmdlets
PSCustomObjects can be used to provide syntax to other cmdlets. Here's an example of how to use the Export-Csv cmdlet with a custom object:
$PSCustomObject = [PSCustomObject]@{
"ActiveDirectoryDomain" = "corp.contoso.com"
"ActiveDirectorySite" = "HQ"
"ExtraInfo" = "This is a custom object"
}
$PSCustomObject | Select ActiveDirectoryDomain, ActiveDirectorySite | Export-Csv -Path "C:\Temp\CustomObject.csv" -NoTypeInformation
Here we create a custom object called $PSCustomObject with three properties. We then use the Select cmdlet to select only two of the properties and pipe the output to the Export-Csv cmdlet. The -NoTypeInformation parameter is used to exclude the type information from the CSV file.
Here is an example of how to use the PSCustomObject to provide syntax for another cmdlet:
$Process = Get-Process -Name "Outlook"
$ProcessObject = [PSCustomObject]@{
Name = $Process.Name
Id = $Process.Id
ProcessorTime = $Process.TotalProcessorTime
}
Write-Host "Stopping process: $($ProcessObject.Name)"
Stop-Process -Id $ProcessObject.Id
Conclusion
PSCustomObjects are among the most common tools in the PowerShell utility belt. These allow you to convert and store data from many different sources in a structured way. With that information saved you can use it to export information, provide syntax for other cmdlets, or to create complex objects with data from many different sources.

