4 min read
Understanding PowerShell Arrays
PowerShell arrays are a powerful and versatile way of managing collections of data, enabling you to efficiently...
Unlocking the Power of PowerShell: Tips for Success
Ready to take your PowerShell scripts to the next level? Learn how to create structured objects, leverage classes, and ensure clean, efficient code.
It’s always a good practice for scripts to return objects rather than primitive data. When a script or function needs to return multiple pieces of information, consider structuring it as a custom object.
The most common and easiest approach is to start with a hash table and then convert it into a PSCustomObject.
$returnValue = [PSCustomObject]@{
Date = Get-Date
User = $env:username
Id = 12
Status = 'OK'
}
return $returnValue
Note that your object is derived from your hash table, and it’s not called a hash table without reason: the order of its keys is random. Therefore, when you convert it to a PSCustomObject later, the property order of your object may also appear random.
$hash = @{}
$hash.Date = Get-Date
$hash.User = $env:username
$hash.Id = 12
$hash.Status = 'OK'
$returnValue = [PSCustomObject]$hash
return $returnValue
If property order is important to you, start with an ordered hash table. Such hash tables retain the order in which the keys were created.
$hash = [Ordered]@{}
$hash.Date = Get-Date
$hash.User = $env:username
$hash.Id = 12
$hash.Status = 'OK'
$returnValue = [PSCustomObject]$hash
return $returnValue
PSCustomObjects are perfectly fine for returning structured data, but there’s a better (albeit lesser-known) approach: classes. Classes can do a lot, yet it doesn’t take much effort to use them for creating objects.
# define your object structure once
class MyDataSet
{
[DateTime]$Date
[string]$User
[int]$Id
[string]$Status
}
# get a new empty object from your "template" (or type)
$returnValue = [MyDataSet]::new()
# fill the values
$returnValue.Date = Get-Date
$returnValue.User = $env:username
$returnValue.Id = 12
$returnValue.Status = 'OK'
return $returnValue
Classes offer several advantages: they can be strongly typed (with distinct property types), objects derived from your class are guaranteed to have an identical structure (eliminating typos in hash table keys), and your objects always have a specific type (whereas the previous objects were all of type PSCustomObject):
PS> $returnValue.GetType().FullName
MyDataSet
There’s much more to say about classes, but with the simple class definition above, you can already create all kinds of strongly typed objects.
If you’re hungry for more, adding a so-called 'constructor' to your class can make things even easier. A constructor is a method defined inside your class with the same name as the class. It can take arguments to initialize properties, allowing you to not only create new, empty objects (via ::new()), but also initialized ones that already contain all the information you want to encapsulate:
# define your object structure once
class MyDataSet
{
[DateTime]$Date
[string]$User
[int]$Id
[string]$Status
MyDataSet()
{}
MyDataSet([DateTime]$Date,[string]$User,[int]$Id,[string]$Status)
{
$this.Date = $Date
$this.User = $User
$this.Id = $Id
$this.Status = $Status
}
}
return [MyDataSet]::new((Get-Date), $env:username, 12, 'OK')
Once you add constructors, your classes can also be used to convert objects. Just ensure that your class has a constructor with the property names and types matching those in the object you want to convert.
Here’s an example: a simple (untyped) set of CSV data is strongly typed using your new class:
# define your object structure once
class MyDataSet
{
[DateTime]$Date
[string]$User
[int]$Id
[string]$Status
MyDataSet()
{}
MyDataSet([DateTime]$Date,[string]$User,[int]$Id,[string]$Status)
{
$this.Date = $Date
$this.User = $User
$this.Id = $Id
$this.Status = $Status
}
}
# some data, can be originated from anywhere
$data = 'Date,User,Id,Status
2021-01-19 12:10:11, willi, 123, OK
2024-10-09 09:22:42, linda, 44.3, FAIL' |
ConvertFrom-Csv
# strongly typed
[MyDataSet[]]$dataTyped = $data
$data
$dataTyped
Unleash the full potential of PowerShell with our handy poster. Whether you're a beginner or a seasoned pro, this cheat sheet is designed to be your go-to resource for the most important and commonly used cmdlets.
The poster is available for download and in paper form.
Jan 7, 2025 by Aleksandar Nikolić and Dr. Tobias Weltner
PowerShell arrays are a powerful and versatile way of managing collections of data, enabling you to efficiently...
Dec 27, 2024 by Aleksandar Nikolić and Dr. Tobias Weltner
Tired of hidden errors in your PowerShell scripts? Discover how validation and transformation attributes can bring...
Dec 20, 2024 by Aleksandar Nikolić and Dr. Tobias Weltner
Want to make your PowerShell scripts faster and more flexible? Learn how to optimize the pipeline with script blocks...
Tobias Weltner and Aleksandar Nikolić joinly wrote the blog post series 'Tobias&Aleksandar's PowerShell tips'. So we introduce both of them here:
----------------------------
Aleksandar Nikolić is a Microsoft Azure MVP and co-founder of PowerShellMagazine.com, the ultimate online source for PowerShell enthusiasts. With over 18 years of experience in system administration, he is a respected trainer and speaker who travels the globe to share his knowledge and skills on Azure, Entra, and PowerShell. He has spoken at IT events such as Microsoft Ignite, ESPC, NIC, CloudBrew, NTK, and PowerShell Conference Europe.
----------------------------
Tobias is a long-time Microsoft MVP and has been involved with the development of PowerShell since its early days. He invented the PowerShell IDE "ISESteroids", has written numerous books on PowerShell for Microsoft Press and O'Reilly, founded the PowerShell Conference EU (psconf.eu), and is currently contributing to the advancement of PowerShell as member in the "Microsoft Cmdlet Working Group". Tobias shares his expertise as a consultant in projects and as a trainer in in-house trainings for numerous companies and agencies across Europe.