Need for PSCustomObject in PowerShell
PSCustomObjects are an essential part of PowerShell’s toolkit. PowerShell being a scripting language needed to provide users (mainly admins) ability to create objects for purposes like creating excel reports. Hashtable’s alone did not provide the flexibility like exporting to csv.
Why PSCustomObject
Being part of .net and Object Oriented programming paradigms ideally we need a class to create an object. I have covered this topic briefly here. PowerShell targeted for admins didn’t want users to create complex class and object structures for scripting tasks. Through PSCustomObject, PowerShell gave its users ability to create objects on the fly. If needed PowerShell does provide option to create a class.
PSCustomObject is mainly used when a custom object needs to be created which has information from two or more commands. For example,
This PowerShell script combines service information with the current date and exports it to a CSV file
# Get all services
$services = Get-Service
# Get today's date
$date = Get-Date -Format "yyyy-MM-dd"
# Create a custom object for each service including the date
$report = $services | ForEach-Object {
[PSCustomObject]@{
ServiceName = $_.Name
DisplayName = $_.DisplayName
Status = $_.Status
Date = $date
}
}
# Export the report to a CSV file
$report | Export-Csv -Path "ServiceReport_$date.csv" -NoTypeInformation
Write-Host "Report generated: ServiceReport_$date.csv"
Creating PSCustomObject
PSCustomObject can be created using few ways. Previously we used New-Object cmdlet as mentioned in this Microsoft doc.
More concise and commonly used method is to use the [PSCustomObject] as below. Using below structure, objects can be created with properties and methods as well. Generally for reporting objects will only have properties as in example below.

PSCustomObject Internals
Internally PowerShell uses hashtables to store properties and methods created from a PSCustomObject. A hashtable is a data structure that stores data as key-value pairs. Each key is unique within the hashtable and is used to retrieve its associated value. In a sense its a glorified hashtable in that, general hashtable don’t have format or export csv options built-in.
You can easily add or remove properties from a PSCustomObject to adapt it to your specific needs. This flexibility allows you to extend the object’s functionality.
PSCustomObject Example 1
A simple example of creating an object from date and disk.
# Get today's date
$date = Get-Date # command 1
# Get disk information
$disk = Get-Disk # command 2
# Create a custom object with date and disk size in GB
$diskInfo = [PSCustomObject]@{
date = $date
diskSize = [math]::Round($disk.Size / 1GB, 2)
}
# Output the object (can be exported to CSV)
$diskInfo
PSCustomObject Example 2
Below is an example of which, say you have a list of computers and want to get process info of all the machines. Script below can run and get a csv for all machines.
Each line of the excel needs be an object. While creating script, think of the output and construct PSCustomObject in accordance to that.
Export Process Information with Date and Computer Name
This PowerShell script collects all running processes along with the current date and computer name, then exports the data to a CSV file.
# Get today's date
$date = Get-Date # Getting date
# Get all running processes
$processes = Get-Process # Getting all processes
# Get computer system info
$computerName = Get-WmiObject -Class Win32_ComputerSystem # Getting Computer info
# Initialize array to hold custom objects
$processInfo = @()
# Loop through each process and create a custom object
foreach ($process in $processes) {
$processInfo += [PSCustomObject]@{
date = $date
computerName = $computerName.Name
processId = $process.Id
processName = $process.Name
}
}
# Export the collected information to a CSV file
$processInfo | Export-Csv "ProcessReport.csv" -NoTypeInformation