Data to array of arrays, or array of objects, or multi dimensional array


Im not sure what to call this, but I’ve run against this problem a few times and have always handled it in a sloppy way. Lets say, you have some data and its got a nice format to it, but it’s still just a bunch of strings. For example, lets say you want to look at connections to your PC, you can use the cmd Query User, which spits out data like this

USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
>jrich                 console             1  Active    2+05:08  9/1/2011 11:52 AM

So, as you can see, there is a nice format to this, its location based. Easy to rip apart, but it’s still a few lines of code to get this to something you can really work with. As you should know, this is an array of strings, so the first line is the definition, second is my connection.

For the most part, you can get rid of the definition line, so we can do this.


$connections = query user

$connections = $connections[1..$connections.lenght]

Some pretty basic stuff. Now that we have a list of connections lets rip it apart. We know the data can be split in a few ways, but what im seeing here is any place there is more than 1 space, so we can use a regex of \s{2,} which says 2 or more white spaces.


$arr = $connections -split "\s{2,}"

$arr

>jar77
console
1
Active
2+04:43
9/1/2011 11:52 AM

That’s all well and good, and fine with a single connection, but with multiple, you need to break it up, in this case, it’s every 6, so you could do a for loop  for($i=0;$i -lt $arr.length;$i=$i+6) which works, but then you have to handle the data.

Based on a Powershell.Com tip I got the other day about arrays and the pipe, I found a neat way around this.


$arr = @()

$connections | %{$arr += ,($_ -split "\s{2,}") }

This works great, what its doing is looping through each line in $connections (ie each connection) and then for each one do the split work on it. Using the ,() instructs powershell to do its work and return an array, which is how we end up with a multi dimensional array.

One small problem with this, it’s a tad sloppy, so lets clean it up a bit.


$arr =@()

$connections | %{$arr += ($_ -split "\s{2,}" | ?{$_ -ne ""} | %{($_ -replace ">","").trim()})}

This gets rid of any blank spaces, removes the > from the username and removes any odd ball white spaces.

Now it’s easy to loop the data!


$arr | ${write-host "$($_[0]) has been connected for $($_[4])"}

Hope this comes in handy!

Advertisements

About jrich

I am the Solutions Architect for Apex Learning in Seattle WA. I've been working with computers since I was 13. Started programming when I was 14. Had my first IT job as tech support at an ISP at the age of 15 and became a network admin at the age of 17. Since then I've worked at a variety of small to mid size companies supporting, maintaining and developing all aspects of IT. Mostly working with Windows based networks but have recently been working with Solaris system as well. I created this blog mostly as a place for me to take my own notes, but also share things that I had a hard time finding the info for.

Posted on September 8, 2011, in WMF (Powershell/WinRM) and tagged , , . Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: