Creating an array of arrays in powershell

Recently I had a need to convert a series of messages from one of my company’s Slack instances into EML files so they could be ingested into our compliance system. In the process of parsing the export file via PowerShell, I had the need to group individual messages by conversations for further processing. This meant I needed an array of message threads, and each thread could be a single or multiple messages (another array). But when I was doing the standard method of adding an object to an array

$MessageTable += $Thread

it was instead adding the individual array members of $Tread to object to $MessageTable instead of adding it as a single object. So for threads with multiple messages I was joining the arrays instead. In order to do this I had to do the following:

$MessageTable += ,$Thread

The big differences was the comma ( , ). This allowed each array to be added as an entire object instead of being joined. As a better explanation, here is an example through pseudo PowerShell code

Create an array to hold all the objects called $MessageTable

$MessageTable = @()

Do some work to create the following thread, which contains only one message object

$Thread =
 
type : message
user : john.mello@contso.com
text : FYI meeting tommorrow
ts : 10/10/2016 8:42:25 PM
MsgType : Direct Message
participants : Chad.Doe@contso.com

Now add it to the $MessageTable as an object

$MessageTable += ,$Thread

Do some more work to create a new thread, which contains 3 message objects

$Thread =
 
type : message
user : john.mello@contso.com
text : do you have tickets for next week? if not i was going to get them.
ts : 10/10/2016 10:40:12 AM
MsgType : Direct Message
participants : {jane.brown@contso.com}
 
type : message
user : john.mello@contso.com
text: have 2 meetings for the AM on the 18th, but afternoon is free
ts&: 10/10/2016 10:40:36 AM
MsgType : Direct Message
participants : {jane.brown@contso.com}
 
type : message
user: jane.brown@contso.com
text: No tickets yet.
ts : 10/10/2016 11:04:56 AM
MsgType: Direct Message
participants : {john.mello@contso.com}

Now add it to the $MessageTable as an object  as well

$MessageTable += ,$Thread

Now when I check the count of the $MessageTable object I see that it only has 2 total objects

$MessageTable.count
2

I can also see that each item is references as the whole object

$MessageTable[0]
 
type : message
user : john.mello@contso.com
text : FYI meeting tommorrow
ts : 10/10/2016 8:42:25 PM
MsgType : Direct Message
participants : Chad.Doe@contso.com
 
$MessageTable[1]
 
type : message
user : john.mello@contso.com
text : do you have tickets for next week? if not i was going to get them.
ts : 10/10/2016 10:40:12 AM
MsgType : Direct Message
participants : {jane.brown@contso.com}
 
type : message
user: john.mello@contso.com
text: have 2 meetings for the AM on the 18th, but afternoon is free
ts : 10/10/2016 10:40:36 AM
MsgType : Direct Message
participants : {jane.brown@contso.com}
 
type : message
user : jane.brown@contso.com
text: No tickets yet.
ts& : 10/10/2016 11:04:56 AM
MsgType : Direct Message
participants : {john.mello@contso.com}

Now if I did it the normal way ($MessageTable += $Thread), each message would have been joined to the array

$MessageTable.count
4
 
$MessageTable[0]
 
type : message
user : john.mello@contso.com
text : FYI meeting tommorrow
ts : 10/10/2016 8:42:25 PM
MsgType : Direct Message
participants : Chad.Doe@contso.com
 
$MessageTable[1]
 
type : message
user : john.mello@contso.com
text : do you have tickets for next week? if not i was going to get them.
ts : 10/10/2016 10:40:12 AM
MsgType : Direct Message
participants : {jane.brown@contso.com}
 
$MessageTable[2]
 
type message
user : john.mello@contso.com
text: have 2 meetings for the AM on the 18th, but afternoon is free
ts: 10/10/2016 10:40:36 AM
MsgType: Direct Message
participants : {jane.brown@contso.com}
 
$MessageTable[3]
 
type : message
user : jane.brown@contso.com
text : No tickets yet.
ts : 10/10/2016 11:04:56 AM
MsgType : Direct Message
participants : {john.mello@contso.com}

Now I could have also used an Array List, which always adds the whole object as one entry in the array. An Array lists also has the following benefits which I frequently use

  • Has a remove() method with Array does not
  • More efficient when adding hundreds of members because the += method makes PowerShell create a new variable equal to the whole of the old one, add our new entry to the end, and then throws away the old variable

Here is how I would use it in the same situations

Create the array list

$MessageTable = New-Object System.Collections.ArrayList

Use the add method to add an object

$MessageTable.Add($Thread)
0
 
#MORE WORK
 
$MessageTable.Add($Thread)
1

Note that an Array list will always return the current addressable location of the object added to the console, in order to avoid that use your favorite out null method. Example

$MessageTable.Add($Thread) | Out-Null

Here is a fully fleshed out example using get-process

#Arrays
$Array1 = @()
$Array2 = @()
$ArrayList = New-Object System.Collections.ArrayList
 
#Data
$Process_W = Get-Process -Name W*
$Process_S = Get-Process -Name S*
 
#Joining Arrays example
$Array1 += $Process_W
$Array1 += $Process_S
$Array1.count
$Array1[1]
 
#Adding arrays to array example
$Array2 += ,$Process_W
$Array2 += ,$Process_S
$Array2.count
$Array2[1]
 
#Array list example
$ArrayList.add($Process_W)
$ArrayList.add($Process_S) | Out-Null
$ArrayList.count
$ArrayList[1]

About mell9185

IT proffesional. Tech, video game, anime, and punk aficionado.
This entry was posted in PowerShell. Bookmark the permalink.

Leave a Reply