Creating Custom Objects in PowerShell from Scratch

Welcome back to our four-part series on creating custom objects in PowerShell! In part one, I discussed the basics of creating custom objects in PowerShell to meet your needs; however, in this version, we lost the original object. In part two, I showed you how to modify and create the custom object while retaining the original. Today we’ll learn how to create a custom object from scratch.

Later, in part four I’ll go deeper and include the enhancements found in PowerShell 3.0.

Creating Custom Objects Using Add-Member

First, let’s use Add-Member to create our objects.

​$obj=New-Object PSObject
$obj | Add-Member Noteproperty -Name Name -value "Jeff Hicks"
$obj | Add-Member Noteproperty -Name Memory -value ((Get-WMIObject
win32_computersystem).TotalPhysicalMemory/1gb -as [int])
$obj | Add-Member Noteproperty -Name Title -value "PowerShell Pro"
$obj | Add-Member Noteproperty -Name MVP -value $True
$obj | Add-Member Noteproperty -Name Blog -value http://jdhitsolutions.com/blog

I create an empty object and pipe it to Add-Member, adding new items. When I write $obj to the pipeline, I end up with this:

Sponsored Content

Maximize Value from Microsoft Defender

In this ebook, you’ll learn why Red Canary’s platform and expertise bring you the highest possible value from your Microsoft Defender for Endpoint investment, deployment, or migration.

​PS C:\> $obj

Name : Jeff Hicks
Memory : 8
Title : PowerShell Pro
MVP : True
Blog : http://jdhitsolutions.com/blog

This is a reasonable solution if you are gathering values to assign to your custom object throughout the script. I’ve also seen the following approach – which, although it does work, it is really more of a kludge.

​$obj = "" | Select Name,Memory,Title,MVP,Blog
$obj.Name="Jeff Hicks"
$obj.Memory=(Get-WMIObject win32_computersystem).TotalPhysicalMemory/1gb -as [int]
$obj.Title="PowerShell Pro"

Select-Object automatically creates the property names which are saved to $obj. You can then set each property. The end result is the same.

​PS C:\> $obj

Name : Jeff Hicks
Memory : 8
Title : PowerShell Pro
MVP : True
Blog : http://jdhitsolutions.com/blog

…well, almost. If I pipe the first example to Get-Member, my object type is System.Management.Automation.PSCustomObject. In the latter it is a Selected.System.String. Granted, this is a subtle distinction, but it could affect how items are formatted for display. It is possible to create your own formatting files and types, but that’s a whole ‘nother kettle of fish (or rather, series of articles). This second approach has some merits in an interactive session, but if you are creating custom objects in your scripts or functions, I think there is a better way to go about this in PowerShell 2.0.

Creating Custom PowerShell Objects Using New-Object

Since we’re talking about objects, let’s use a cmdlet that creates them: New-Object. You briefly saw this in the first example. With New-Object, you can create a blank custom object using the PSObject type. And while you could use the Add-Member technique, if you are only defining properties you can define them all at once by using a hash table, also known as an associative array.
You might start with something like this:

[email protected]{
Name="Jeff Hicks"
Memory=(Get-WMIObject win32_computersystem).TotalPhysicalMemory/1gb -as [int]
Title="PowerShell Pro"

If you put all the elements on one line, you will need to separate them with a semicolon. But because each entry is on its own line, PowerShell knows where to separate them. I typically use this technique collecting new property names. I can even add to the hash table.

$hash.Add("Book","PowerShell in Depth: An Administrator's Guide")

When I’m ready, I can call New-Object and use this hash table for all of my property values.

​New-Object -TypeName PSObject -Property $hash

This object is written to the pipeline.

​Help : http://bit.ly/AskJeffHicks
Name : Jeff Hicks
MVP : True
Book : PowerShell in Depth: An Administrator's Guide
Blog : http://jdhitsolutions.com/blog
Memory : 8
Title : PowerShell Pro

One potential downside in the second version is that you can’t predict in what order the properties will be displayed. You could create a custom format file, or if you’re in for really quick and dirty scripting, you could create something like this:

​New-Object -TypeName PSObject -Property $hash | Select Name,Title,MVP,Help,Book,Blog,Memory

In my example, I’m creating a one-off kind of object. But this approach works very well when working with objects in the pipeline.

​Function Get-SysInfo {



Process {
$os=Get-WmiObject Win32_OperatingSystem -ComputerName $computername
$cs=Get-WmiObject Win32_ComputerSystem -ComputerName $computername
$running=Get-Service -ComputerName $computername | where {$_.Status -eq "Running"}
$procs=Get-Process -ComputerName $computername

New-Object -TypeName PSObject -Property @{
System=("{0} {1}" -f $cs.Manufacturer.Trim(),$cs.Model.Trim())

} #close Process
} #close function

This function creates an entirely new object that pulls information from a variety of sources on a remote computer. Instead of creating a hash table in advance, I define one as the value for the –Property parameter. You can see the results of my efforts below in Figure 1.

Creating Custom Objects in Windows PowerShell
Figure 1: The custom object in action

This I can pipe to any other cmdlet, such as Export-CSV because it is an object. You can download Get-Sysinfo from the site.

Have I hit you over the head enough with my mantra that PowerShell is “all about the objects”? We’ll wrap up this series with part four, in which we’ll look at some new ways of creating objects in PowerShell 3.0.

Related Topics:

External Sharing and Guest User Access in Microsoft 365 and Teams

This eBook will dive into policy considerations you need to make when creating and managing guest user access to your Teams network, as well as the different layers of guest access and the common challenges that accompany a more complicated Microsoft 365 infrastructure.

You will learn:

  • Who should be allowed to be invited as a guest?
  • What type of guests should be able to access files in SharePoint and OneDrive?
  • How should guests be offboarded?
  • How should you determine who has access to sensitive information in your environment?

Sponsored by:

Live Webinar: Active Directory Security: What Needs Immediate Priority!Live on Tuesday, October 12th at 1 PM ET

Attacks on Active Directory are at an all-time high. Companies that are not taking heed are being punished, both monetarily and with loss of production.

In this webinar, you will learn:

  • How to prioritize vulnerability management
  • What attackers are leveraging to breach organizations
  • Where Active Directory security needs immediate attention
  • Overall strategy to secure your environment and keep it secured

Sponsored by: