It’s funny how I can write code and then a long time afterwards need to write something for the same goal and come up with it in an easier way. It makes sense, since I’ve likely learned more and grown in the time that has passed. Still, to look back on the old cold and see how I fumbled through it or took a very long time to accomplish it and then do it in just a few lines makes me chuckle.
Take, for instance, NetStat. Now, I know there are plenty of functions and cmdlets out there that other folks have written to get you “objectized” results for NetStat. I’m sure they work well but I wouldn’t be who I am if I didn’t write my own code to do something. Lately I’ve been guilty of using the cmdlets from Citrix and VMWare to interact with their items but for the sake of practicality, I have to. Anyway… I’m troubleshooting slowness reports with one of our Citrix PVS environments but one of the problems is I don’t get told until hours afterwards and/or no one is willing to troubleshoot on the spot. I can’t do anything if I can’t get data. So, I needed to write a script that did not require a lot of resources and could run on the servers at the same time the users were using them at the heaviest time of the day – without impacting them. At the time of this writing it hasn’t run for the first time yet out in the live environment, so after it does (and it’s successful *fingers crossed*) I may just create a post for the whole script.
Part of the script is collecting latency data. I’m using a standard ping with the default packet size, doing an average of three pings and reporting back. The piece that I wrote anew, despite having code already, was getting all of the connection data so that I could ping each connection and find latency. Here’s what I do first:
I’m pulling net stat and then only selecting the lines that 1) match a 4 octet IPv4 address and 2) are using TCP. You can always further qualify it by adding a “-notmatch” and putting in any IP address you don’t want like local loopback stuff or all the 0.0.0.0. I get something like this (I’m using just a sample of the data off a vm):
Then, to pull out the “Foreign” address (the remote machine’s IP) I do some splitting and replacing of each line to widdle it down to just the IP address:
As I go through each line (which is just a string of text) I first split it by spaces, which is the part of the code up to the first | (pipe) which ends up looking like this:
It looks like a mess but it’s made it a lot simpler. Now each non-blank string of text is on it’s own line, and thus, it has an index. But, I can further widdle this down by only matching those items that begin with an octet. That’s where I pipe part one above into the “where” clause and get:
Awesome. So I know that the foreign address is always the second one (index “1”) but there’s also that port on there which will break the ping attempt so we need to take that off. That’s where the rest of the code at the end of the “where” clause comes in. I tell it I want index 1 (), which is the line “127.0.0.1:59964” and then I split by the “:” which produces two lines, “127.0.0.1” and “59964” I only want the IP and that is index “0” and so my line ends with a . Note that each step I’ve explained above is in it’s own set of parenthesis.
I know I didn’t do the best job of explaining the breakdown but hopefully it has helped make sense of nesting commands with PowerShell and been an example of how powerful piping and one line of code can be. My overall code here is 3 lines but it took a mess of a string and brought it down to the exact piece of data that I wanted. I think that’s pretty darn cool. For anyone wishing to take this a step further and make their own “objectized” version of NetStat or another text-output tool you should be able to go from here using this. Maybe a quick google search on how to eliminate blank lines from a multi-line string, too. I know I have that code somewhere…. If I were smart I’d do the same, that way I can reuse the function no matter which individual piece of data in the results I was looking for and not had to modify anything…