Constructive criticism wanted

by althought at 2012-10-08 02:58:30

Hi All,

I wanted to write a script to gather network connections active on a remote computer & allow me to drag them back in to a csv file for analysis. I’ve had a go, & think I have something that works, but Id like to air it & see what I could do differently to be both easier on myself (typing) and easier on the eye.

As I didn’t know any native PSH 2 way to accomplish this, I started to look at what I got from netstat & planned to create a wrapper to export that out as csv. I thought i might make it a bit more flexible & make it work for other similar utilities that return tables with headers & lists of data that I may want to pinch in the future. I’ve come up with a function that I can give the output from a cmdline exe & parse it in to custom ps objects that can then be manipulated. When ran, it needs the line from which you want it to take the property names and the separator it will use for the columns.

There are things that I already know need to be done;
*I’d like it to accept pipeline input
*I should probably look at better verbose statements.
*I’ve used 2 different methods of splitting my strings - mainly because in the output from netstat, i needed keep headers that had a space in them together (& space was my separator) . Then i used the .net method for the values as they did not have spaces (but i did have empty strings that i needed to remove). Looking at this now, I can see I should probably just use the regex method with where command to remove the empty ones. On to do list!

Here it is

function convertto-Custobj{
param (
[Parameter(Position=0,Mandatory=$false,ValueFromPipeline=$false,ParameterSetName=‘OpenConnection’)][string]$delim = " "
$somegreen =@{}
write-verbose “Headers being defined from $($strings[$headLinePos])”
$heads = ($([regex]::split($strings[$headLinePos],$delim)) |where {$_ -ne ‘’})
write-verbose “headers are $heads”

foreach($str in $strings){
write-verbose “Line to parse: $str Progress through supplied strings array $x”
if ($x -gt $headLinePos){
$i = 0
foreach($h in $heads){
write-verbose “Value for $h is $($str.split($delim,[StringSplitOptions]::RemoveEmptyEntries)[$i]) Counter is on $i”
$somegreen.Add($h, $($str.split($delim,[StringSplitOptions]::RemoveEmptyEntries)[$i]))
$i = $i +1
#sleep 2
Write-Verbose $somegreen.values
New-Object psobject -Property $somegreen
$somegreen =@{}
$x ++

Here’s an example of it being called…
$a = (netstat)

convertto-Custobj -strings $a -headLinePos 3 |Sort-Object -Unique "Foreign Address"

Thanks to anyone who has look/ has suggestions. Apologies I am not posting what I consider to be my very best attempt - I don’t have as much time for learning PS as I would like & it is one of those situations where if I don’t do it now, it wont get done!

All the best.
by Lembasts at 2012-10-08 20:58:39
Its great that you are trying to write advanced functions which are just like cmdlets.
Have a look at this series to get more hints: … wn+cmdlet/
For example, if you want to pipe input you need to code something like [string[]]$strings in your parameter list.
And I would separate each parameter value on its own line e.g.
[string]$delim = " "

Just makes it a bit easier to read IMHO…
by althought at 2012-10-16 23:33:40
Thanks David for that link and encouraging words :-). I shall try and make my way through that article and apply it where I can.

All the best,
by nohandle at 2012-10-18 07:52:32
Hi, besides the mentioned point you should avoid spaces in property names.
(convertto-Custobj -strings (netstat -n) -headLinePos 3)[0] | gm |?{$ -match “\s+”}