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] |