Using PSObject to store data in PowerShell

When writing PowerShell scripts, I often search for specific data, store that data in an object and then most times I export it to CSV format. This article shows you how to do all of this using PSObject.

The easiest way I find to store data for an object is to store it using a PSObject. If you have multiple objects you need to store data for then you can then store each PSObject in an array. This array can then be exported to CSV.

A PSObject is very much like a hashtable where data is stored in key-value pairs. You can create as many key-value pairs as you like for each PSObject.

Creating a PSObject

As mentioned, the PowerShell PSObject uses a key & value pair type structure. To store data in the PSObject all you need to do is define a key and then store a value in the key. The examples below creates a new PSObject and stores some data in the object. In this example we are creating two “keys” (Key1 and Key2). Each of these contain bits of data about the object (Value1 and Value2).

In a real-life scenario keys and values contain description type information about the object. So for example if we were storing information about a file, some of the key-value pairs we might create would be Name, FileExtension, Path, and Size.

Here is the how to create a PSObject in both PowerShell 2.0 and 3.0 and above:

PowerShell 2.0

$MyPSObject = New-Object -TypeName psobject -Property @{    
  Key1 = 'Value1'
  Key2 = 'Value2'

PowerShell 3.0 & above

In PowerShell 3.0 and above, it is recommended that you use the following code to create a PSObject. This is because it maintains the order of each key value created, which means when exporting to CSV the sort order is maintained.

$MyPSObject = [PSCustomObject]@{    
  Key1 = 'Value1'
  Key2 = 'Value2'

Storing multiple PSObjects in an array

So far we have looked at storing information about a single object (e.g. a file). What if we are enumerating a folder and need to store information about all the files in the folder? In that case, we would create a PSObject for each file (to store its individual data) and then we would store all of these PSObjects in an array. This makes it really easy to store and export information for multiple objects.

Here is how you store a PSObject inside an array. To do this for multiple files you would just do this inside the ForEach loop:

# Initialising the array
$MyArray = @()

# Storing PSObject in an array
$MyArray += $MyPSObject

An Real World Example

Let’s setup a quick example to help with the demonstration. In this example we are going to doing the following:

Reading a text file that has a list of employee names. For each name we will look them up in AD and gather some additional information, including username and email address. We will then be outputting this data to CSV.

Example Solution

The script below enumerates all of the employee names in the text file, and for each one searches AD for their additional employee information. Each of this data is stored in its own PSObject called $hItemDetails.

To ensure the data is in the correct order when it is exported to CSV, we use the [PSCustomObject]@{} method of creating a new PSObject (only available in PowerShell 3.0 and above). Finally, as there are multiple employees, I store each PSObject in an array called $aResults. This array is then exported to CSV.

Import-Module ActiveDirectory

$aResults = @()
$List = Get-Content "C:\Temp\List.txt"
ForEach ($Item in $List) {
  $Item = $Item.Trim()
  $User = Get-ADUser -Filter { displayName -like $Item -and SamAccountName -notlike "a-*" -and Enabled -eq $True } -Properties SamAccountName, GivenName, Surname, telephoneNumber
  $sEmail = $User.GivenName + "." + $User.Surname + ""

  $hItemDetails = [PSCustomObject]@ {    
    FullName = $Item
    UserName = $User.SamAccountName
    Email = $sEmail
    Tel = $User.telephoneNumber

  #Add data to array
  $aResults += $hItemDetails

$aResults | Export-CSV "C:\Temp\Results.csv"

Hope this helps! Any questions or comments, let me know below.

Leave a Comment