I would like to be able to define and use a custom type in some of my PowerShell scripts. For example, let’s pretend I had a need for an object that had the following structure:
Contact { string First string Last string Phone }
How would I go about creating this so that I could use it in function like the following:
function PrintContact { param( [Contact]$contact ) 'Customer Name is ' + $contact.First + ' ' + $contact.Last 'Customer Phone is ' + $contact.Phone }
Is something like this possible, or even recommended in PowerShell?
Prior to PowerShell 3
PowerShell’s Extensible Type System didn’t originally let you create concrete types you can test against the way you did in your parameter. If you don’t need that test, you’re fine with any of the other methods mentioned above.
If you want an actual type that you can cast to or type-check with, as in your example script … it cannot be done without writing it in C# or VB.net and compiling. In PowerShell 2, you can use the ‘Add-Type’ command to do it quite simmple:
Historical Note: In PowerShell 1 it was even harder. You had to manually use CodeDom, there is a very old function new-struct script on PoshCode.org which will help. Your example becomes:
Using
Add-TypeorNew-Structwill let you actually test the class in yourparam([Contact]$contact)and make new ones using$contact = new-object Contactand so on…In PowerShell 3
If you don’t need a ‘real’ class that you can cast to, you don’t have to use the Add-Member way that Steven and others have demonstrated above.
Since PowerShell 2 you could use the -Property parameter for New-Object:
And in PowerShell 3, we got the ability to use the
PSCustomObjectaccelerator to add a TypeName:You’re still only getting a single object, so you should make a
New-Contactfunction to make sure that every object comes out the same, but you can now easily verify a parameter ‘is’ one of those type by decorating a parameter with thePSTypeNameattribute:In PowerShell 5
In PowerShell 5 everything changes, and we finally got
classandenumas language keywords for defining types (there’s nostructbut that’s ok):We also got a new way to create objects without using
New-Object:[Contact]::new()— in fact, if you kept your class simple and don’t define a constructor, you can create objects by casting a hashtable (although without a constructor, there would be no way to enforce that all properties must be set):