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 + "@test.com"

  $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.

Comments

  1. Hello Luca,

    What if I want to add another field to the pscustomobject?

    I tried it like this:
    $hItemDetails += @{“nickname” = “nickname for user”}
    or
    $hItemDetails += [pscustomobject]@{“nickname” = “nickname for user”}

    But i got this error in both cases:
    Method invocation failed because [System.Management.Automation.PSObject] does not contain a method named ‘op_Addition’.

    thanks in advance for your help!
    mariodeleon@gmail.com

    1. Two years and no rely luca…

      The error tells you the issue, there is no addition method for psobjects. You need to call add-member e.g. $psobject | Add-Member -MemberType NoteProperty -Name “Nickname” -Value “Gertrude”

    2. You can add another field by using add-member.

      $hItemDetails | Add-Member -Type NoteProperty -Name ‘nickname’ -Value “nickname for user”

  2. How to append the results on the same row using new-object in powershell.
    my sample results is look like this
    Header1 Header2
    Test
    Yes
    The results should be aligned to Test row

  3. How to add an array of values to a single key,
    for example:
    $Properties = @{
    SystemLog_Index = $EventLog_System_Last30Days_Error.Index
    SystemLog_InstanceID=$EventLog_System_Last30Days_Error.InstanceID
    SystemLog_Message= $EventLog_System_Last30Days_Error.Message
    SystemLog_Time=$EventLog_System_Last30Days_Error.Time
    SystemLog_EntryType=$EventLog_System_Last30Days_Error.EntryType
    SystemLog_Source=$EventLog_System_Last30Days_Error.Source
    }
    $obj = New-Object PSObject -Property $Properties
    $obj | Export-CSV

    “The CSV does not able to show the array in its columns”

  4. Luca, this was excellent-O! I have of late trying to do an EXPORT-CSV on a file that wasn’t an object. I saw other articles saying my fields needed to be properties in a object, etc. Very confusing, I was just getting the length property of each record in the .csv files. All said, this cleared everything up, excellent code example at the end. Thanks again!

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.