Everything you wanted to know about PSCustomObject - PowerShell (2024)

  • Article

PSCustomObject is a great tool to add into your PowerShell tool belt. Let's start with the basicsand work our way into the more advanced features. The idea behind using a PSCustomObject is tohave a simple way to create structured data. Take a look at the first example and you'll have abetter idea of what that means.

Note

The original version of this article appeared on the blog written by@KevinMarquette. The PowerShell team thanks Kevin for sharing this content withus. Please check out his blog at PowerShellExplained.com.

Creating a PSCustomObject

I love using [PSCustomObject] in PowerShell. Creating a usable object has never been easier.Because of that, I'm going to skip over all the other ways you can create an object but I needto mention that most of these examples are PowerShell v3.0 and newer.

$myObject = [PSCustomObject]@{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}

This method works well for me because I use hashtables for just about everything. But there aretimes when I would like PowerShell to treat hashtables more like an object. The first place younotice the difference is when you want to use Format-Table or Export-CSV and you realize that ahashtable is just a collection of key/value pairs.

You can then access and use the values like you would a normal object.

$myObject.Name

Converting a hashtable

While I am on the topic, did you know you could do this:

$myHashtable = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}$myObject = [pscustomobject]$myHashtable

I do prefer to create the object from the start but there are times you have to work with ahashtable first. This example works because the constructor takes a hashtable for the objectproperties. One important note is that while this method works, it isn't an exact equivalent. Thebiggest difference is that the order of the properties isn't preserved.

If you want to preserve the order, seeOrdered hashtables.

Legacy approach

You may have seen people use New-Object to create custom objects.

$myHashtable = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}$myObject = New-Object -TypeName PSObject -Property $myHashtable

This way is quite a bit slower but it may be your best option on early versions of PowerShell.

Saving to a file

I find the best way to save a hashtable to a file is to save it as JSON. You can import it back intoa [PSCustomObject]

$myObject | ConvertTo-Json -depth 1 | Set-Content -Path $Path$myObject = Get-Content -Path $Path | ConvertFrom-Json

I cover more ways to save objects to a file in my article onThe many ways to read and write to files.

Working with properties

Adding properties

You can still add new properties to your PSCustomObject with Add-Member.

$myObject | Add-Member -MemberType NoteProperty -Name 'ID' -Value 'KevinMarquette'$myObject.ID

Remove properties

You can also remove properties off of an object.

$myObject.psobject.properties.remove('ID')

The .psobject is an intrinsic member that gives you access to base object metadata. For moreinformation about intrinsic members, seeabout_Intrinsic_Members.

Enumerating property names

Sometimes you need a list of all the property names on an object.

$myObject | Get-Member -MemberType NoteProperty | Select -ExpandProperty Name

We can get this same list off of the psobject property too.

$myobject.psobject.properties.name

Note

Get-Member returns the properties in alphabetical order. Using the member-access operator toenumerate the property names returns the properties in the order they were defined on the object.

Dynamically accessing properties

I already mentioned that you can access property values directly.

$myObject.Name

You can use a string for the property name and it will still work.

$myObject.'Name'

We can take this one more step and use a variable for the property name.

$property = 'Name'$myObject.$property

I know that looks strange, but it works.

Convert PSCustomObject into a hashtable

To continue on from the last section, you can dynamically walk the properties and create a hashtablefrom them.

$hashtable = @{}foreach( $property in $myobject.psobject.properties.name ){ $hashtable[$property] = $myObject.$property}

Testing for properties

If you need to know if a property exists, you could just check for that property to have a value.

if( $null -ne $myObject.ID )

But if the value could be $null you can check to see if it exists by checking thepsobject.properties for it.

if( $myobject.psobject.properties.match('ID').Count )

Adding object methods

If you need to add a script method to an object, you can do it with Add-Member and aScriptBlock. You have to use the this automatic variable reference the current object. Here is ascriptblock to turn an object into a hashtable. (same code form the last example)

$ScriptBlock = { $hashtable = @{} foreach( $property in $this.psobject.properties.name ) { $hashtable[$property] = $this.$property } return $hashtable}

Then we add it to our object as a script property.

$memberParam = @{ MemberType = "ScriptMethod" InputObject = $myobject Name = "ToHashtable" Value = $scriptBlock}Add-Member @memberParam

Then we can call our function like this:

$myObject.ToHashtable()

Objects vs Value types

Objects and value types don't handle variable assignments the same way. If you assign value types toeach other, only the value get copied to the new variable.

$first = 1$second = $first$second = 2

In this case, $first is 1 and $second is 2.

Object variables hold a reference to the actual object. When you assign one object to a newvariable, they still reference the same object.

$third = [PSCustomObject]@{Key=3}$fourth = $third$fourth.Key = 4

Because $third and $fourth reference the same instance of an object, both $third.key and$fourth.Key are 4.

psobject.copy()

If you need a true copy of an object, you can clone it.

$third = [PSCustomObject]@{Key=3}$fourth = $third.psobject.copy()$fourth.Key = 4

Clone creates a shallow copy of the object. They have different instances now and $third.key is 3and $fourth.Key is 4 in this example.

I call this a shallow copy because if you have nested objects (objects with properties contain otherobjects), only the top-level values are copied. The child objects will reference each other.

PSTypeName for custom object types

Now that we have an object, there are a few more things we can do with it that may not be nearly asobvious. First thing we need to do is give it a PSTypeName. This is the most common way I seepeople do it:

$myObject.PSObject.TypeNames.Insert(0,"My.Object")

I recently discovered another way to do this from thispost by /u/markekraus. He talks about this approach that allows you todefine it inline.

$myObject = [PSCustomObject]@{ PSTypeName = 'My.Object' Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}

I love how nicely this just fits into the language. Now that we have an object with a proper typename, we can do some more things.

Note

You can also create custom PowerShell types using PowerShell classes. For more information, seePowerShell Class Overview.

Using DefaultPropertySet (the long way)

PowerShell decides for us what properties to display by default. A lot of the native commands have a.ps1xml formatting file that does all the heavy lifting. From thispost by Boe Prox, there's another way for us to do this on our custom objectusing just PowerShell. We can give it a MemberSet for it to use.

$defaultDisplaySet = 'Name','Language'$defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',[string[]]$defaultDisplaySet)$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)$MyObject | Add-Member MemberSet PSStandardMembers $PSStandardMembers

Now when my object just falls to the shell, it will only show those properties by default.

Update-TypeData with DefaultPropertySet

This is nice but I recently saw a better way using Update-TypeData to specifythe default properties.

$TypeData = @{ TypeName = 'My.Object' DefaultDisplayPropertySet = 'Name','Language'}Update-TypeData @TypeData

That is simple enough that I could almost remember it if I didn't have this post as a quickreference. Now I can easily create objects with lots of properties and still give it a nice cleanview when looking at it from the shell. If I need to access or see those other properties, they'restill there.

$myObject | Format-List *

Update-TypeData with ScriptProperty

Something else I got out of that video was creating script properties for your objects. Thiswould be a good time to point out that this works for existing objects too.

$TypeData = @{ TypeName = 'My.Object' MemberType = 'ScriptProperty' MemberName = 'UpperCaseName' Value = {$this.Name.toUpper()}}Update-TypeData @TypeData

You can do this before your object is created or after and it will still work. This is what makesthis different than using Add-Member with a script property. When you use Add-Member the way Ireferenced earlier, it only exists on that specific instance of the object. This one applies to allobjects with this TypeName.

Function parameters

You can now use these custom types for parameters in your functions and scripts. You can have onefunction create these custom objects and then pass them into other functions.

param( [PSTypeName('My.Object')]$Data )

PowerShell requires that the object is the type you specified. It throws a validation error ifthe type doesn't match automatically to save you the step of testing for it in your code. A greatexample of letting PowerShell do what it does best.

Function OutputType

You can also define an OutputType for your advanced functions.

function Get-MyObject{ [OutputType('My.Object')] [CmdletBinding()] param ( ...

The OutputType attribute value is only a documentation note. It isn't derived from the functioncode or compared to the actual function output.

The main reason you would use an output type is so that meta information about your functionreflects your intentions. Things like Get-Command and Get-Help that your development environmentcan take advantage of. If you want more information, then take a look at the help for it:about_Functions_OutputTypeAttribute.

With that said, if you're using Pester to unit test your functions then it would be a good ideato validate the output objects match your OutputType. This could catch variables that just fallto the pipe when they shouldn't.

Closing thoughts

The context of this was all about [PSCustomObject], but a lot of this information applies toobjects in general.

I have seen most of these features in passing before but never saw them presented as a collection ofinformation on PSCustomObject. Just this last week I stumbled upon another one and was surprisedthat I had not seen it before. I wanted to pull all these ideas together so you can hopefully seethe bigger picture and be aware of them when you have an opportunity to use them. I hope you learnedsomething and can find a way to work this into your scripts.

Everything you wanted to know about PSCustomObject - PowerShell (2024)

FAQs

What is PSCustomObject in PowerShell? ›

PSCustomObject is a great tool to add into your PowerShell tool belt. Let's start with the basics and work our way into the more advanced features. The idea behind using a PSCustomObject is to have a simple way to create structured data. Take a look at the first example and you'll have a better idea of what that means.

What is the difference between PSObject and PSCustomObject? ›

Long description. The [pscustomobject] type accelerator was added in PowerShell 3.0. Since PowerShell 3.0, casting a Hashtable to [pscustomobject] achieves the same result. PSObject type objects maintain the list of members in the order that the members were added to the object.

What is the difference between array and PSCustomObject in PowerShell? ›

Understanding arrays and objects in PowerShell

An array is a collection of values, while an object is a collection of properties and their corresponding values. The PsCustomObject is a type of object in PowerShell that allows you to create custom objects with properties and values.

How do you get information about an object in PowerShell? ›

To get the properties of an object, use the Get-Member cmdlet. For example, to get the properties of a FileInfo object, use the Get-ChildItem cmdlet to get the FileInfo object that represents a file. Then, use a pipeline operator ( | ) to send the FileInfo object to Get-Member .

What is the main purpose of PowerShell *? ›

As a scripting language, PowerShell is commonly used for automating the management of systems. It's also used to build, test, and deploy solutions, often in CI/CD environments. PowerShell is built on the .NET Common Language Runtime (CLR).

How PowerShell can be used for malicious purposes? ›

PowerShell uses a fileless approach that executes commands and scripts directly in memory, making it hard to detect. It can access nearly any Windows device by initiating a remote connection. Threat actors can leverage PowerShell using other malicious tools such as Empire, DeathStar and CrackMapExec.

What are the three types of variable in PowerShell? ›

There are several different types of variables in PowerShell.
  • User-created variables: User-created variables are created and maintained by the user. ...
  • Automatic variables: Automatic variables store the state of PowerShell. ...
  • Preference variables: Preference variables store user preferences for PowerShell.
Mar 7, 2024

How do you check if an object is an array in PowerShell? ›

You can use the GetType() method on just about anything to see what kind of variable it is (string or array). Probably the easiest way to see if an array has more then one element in it is to use the COUNT property ($array. Count).

What is the difference between array and PowerShell? ›

Arrays are a fundamental feature of PowerShell. Arrays make it possible to ingest, manipulate and output true data structures (and not just raw strings). This capability makes PowerShell different and more useful than other scripting languages.

What does $_ mean in PowerShell? ›

PowerShell includes the $PSItem variable and its alias, $_ , as automatic variables in scriptblocks that process the current object, such as in the pipeline. This article uses $PSItem in the examples, but $PSItem can be replaced with $_ in every example.

How do I get hidden items in PowerShell? ›

To get only hidden items, use the Hidden parameter, its "h" or "ah" aliases, or the Hidden value of the Attributes parameter. To exclude hidden items, omit the Hidden parameter or use the Attributes parameter. Gets only read-only files and directories (folders).

What is the difference between get item and Get-ChildItem? ›

The difference is more clear with a folder than with a file. Get-Item C:\folder will get you the folder, and Get-ChildItem c:\folder will get you the items inside the folder. There is an overlap in their behaviour if you ask for one file.

What is an object in PowerShell? ›

Everything in PowerShell is an object. An object is a combination of variables and functions. Each object has: Properties: Variables that describe the object (characteristics). Methods: Functions that define how to use the object (actions).

What is a PowerShell virus? ›

What Is the Windows Powershell Virus? The Windows PowerShell virus is a malicious script or program that uses Windows PowerShell to display and run unwanted pop-ups. The pop-ups come from different channels.

What is PowerShell injection? ›

PowerShell scripts, like other programming languages, can be vulnerable to injection attacks. An injection attack occurs when a user provides input to a vulnerable function that includes extra commands. The vulnerable function runs the extra commands, which can be a serious security vulnerability.

What is trigger in PowerShell? ›

Triggers allow for automation jobs to be started when certain events happen within PowerShell Universal. For example, this allows you to take action when jobs complete, the server starts or dashboards stop. Triggers are useful for assigning global error handling or sending notifications when certain things happen.

Top Articles
How to Tell if Money Is Fake: Guide to Spotting Counterfeit Money
What affects the price of travel insurance? | Staysure™
English Bulldog Puppies For Sale Under 1000 In Florida
Katie Pavlich Bikini Photos
Gamevault Agent
Pieology Nutrition Calculator Mobile
Hocus Pocus Showtimes Near Harkins Theatres Yuma Palms 14
Hendersonville (Tennessee) – Travel guide at Wikivoyage
Doby's Funeral Home Obituaries
Compare the Samsung Galaxy S24 - 256GB - Cobalt Violet vs Apple iPhone 16 Pro - 128GB - Desert Titanium | AT&T
Vardis Olive Garden (Georgioupolis, Kreta) ✈️ inkl. Flug buchen
Craigslist Dog Kennels For Sale
Things To Do In Atlanta Tomorrow Night
Non Sequitur
Crossword Nexus Solver
How To Cut Eelgrass Grounded
Pac Man Deviantart
Alexander Funeral Home Gallatin Obituaries
Shasta County Most Wanted 2022
Energy Healing Conference Utah
Aaa Saugus Ma Appointment
Geometry Review Quiz 5 Answer Key
Hobby Stores Near Me Now
Icivics The Electoral Process Answer Key
Allybearloves
Bible Gateway passage: Revelation 3 - New Living Translation
Yisd Home Access Center
Home
Shadbase Get Out Of Jail
Gina Wilson Angle Addition Postulate
Celina Powell Lil Meech Video: A Controversial Encounter Shakes Social Media - Video Reddit Trend
Walmart Pharmacy Near Me Open
Marquette Gas Prices
A Christmas Horse - Alison Senxation
Ou Football Brainiacs
Access a Shared Resource | Computing for Arts + Sciences
Vera Bradley Factory Outlet Sunbury Products
Pixel Combat Unblocked
Cvs Sport Physicals
Mercedes W204 Belt Diagram
'Conan Exiles' 3.0 Guide: How To Unlock Spells And Sorcery
Teenbeautyfitness
Where Can I Cash A Huntington National Bank Check
Topos De Bolos Engraçados
Sand Castle Parents Guide
Gregory (Five Nights at Freddy's)
Grand Valley State University Library Hours
Holzer Athena Portal
Hello – Cornerstone Chapel
Stoughton Commuter Rail Schedule
Selly Medaline
Latest Posts
Article information

Author: Melvina Ondricka

Last Updated:

Views: 5747

Rating: 4.8 / 5 (48 voted)

Reviews: 87% of readers found this page helpful

Author information

Name: Melvina Ondricka

Birthday: 2000-12-23

Address: Suite 382 139 Shaniqua Locks, Paulaborough, UT 90498

Phone: +636383657021

Job: Dynamic Government Specialist

Hobby: Kite flying, Watching movies, Knitting, Model building, Reading, Wood carving, Paintball

Introduction: My name is Melvina Ondricka, I am a helpful, fancy, friendly, innocent, outstanding, courageous, thoughtful person who loves writing and wants to share my knowledge and understanding with you.