Wednesday, July 24, 2019

Powershell - Arrays and how they handle multi-lined input data

For years with various methods of scripting I've often fallen to using temporary files as a means to store and retrieve the information my scripts were working on. I've always felt it was a 'poor mans' solution that any good scripter would look to avoid as much as possible.

So as I've spent more time with powershell recently, I've been making an effort to move away from temporary files, and trying to use powershell's hash table and array functions to store and retrieve the scripted info I need.

I had a case, where I needed to create a report and the data I was gathering was seemingly going into my array the same way that it was being displayed in my console...but everytime I went to extract the data I had put into my arrays, the returned info in code was junk and my reports never built.

After much trial and error I found 2 ways around my problem, the first was modifying export-csv command within my script to update my data as it was extracted so it would display properly .. . the second was "cleaning" my data before i imported it into the array . .and that's what I want to discuss with this post.

But first, the problem that powershell attempts to help you with.

You have a text file, with the following data within it:

the quick brown fox
jumped over the slow
brown cow who ate grass
with ducks by the pond

This is multi-lined data, here's how powershell displays this info once it's been pulled into an array:



Where did those comma's come from?

Did the text data, have comma separators?  Hmm..Looks like no...


This would be an example of powershell "adapting" your content, because it realized as it was ingesting data that was 'multi-line' so it had to adjust it so it could work with it within the array framework.

Line separations are defined within the array as "commas" and the entire set of data is bracketed "{}".

And so the question becomes, once you know this limitation of powershell arrays exist, how do you plan around it?

For me, the "best" way around this is going back to what I know well . . LOL . . using text files as temporary staging areas to "clean" the data the I'm importing into my arrays so that it can be exported cleanly with export-csv and no special tricks.

"Data cleaning of the txt file" in this case, means removing empty lines, adding semi-colons to the end of each line, and merging all lines into a single line . . . the commands that help with those are:

Remove empty lines:

(GC $txtfile) | foreach {$_.trimend()} | where {$_ -ne ""} | sc $txtfile

Adding semi-colons:

(gc $txtfile) | foreach {$_ + ";"} | sc $txtfile

Turning all lines into one line for array import (2 liner):

$txtarrayimport=gc $txtfile
$DataToImport=$txtarrayimport -join ""

This may seem like an extreme amount of effort, but it's been extremely important lesson for me in terms of knowing that powershell can and will adjust your data on it's own. Taking the time to import data into powershell arrays in a format it can handle better can mean a big difference in exporting that data later.