Monthly Archives: September 2011

PowerShell V3 – Finding What’s New?


So I’ve started to play around with PowerShell V3 and outside of some neat IDE stuff in ISE, where do I get started? Well I guess the best spot is to start with what new cmdlets have been added? So let’s do a little comparison.

The first problem we run in to is that PowerShell V3 is an update and not a side by side install. Not a horrible problem since we can start PowerShell in compatibility mode

PowerShell -Version 2

This will only work with the console and not ISE. So lets load that up and do the following.


Get-Command | Export-Clixml ps2cmds.cli

Now that we’ve exported all the cmdlets (and alias and functions) from PS2 lets hop in to PS3 and compare the two.


$v2 = Import-Clixml ps2cmds.cli

$v3 = Get-Command

#filter it to only cmdlets for now - CommandType 8 is cmdlet

$v2cmd = $v2 | where { $_.CommandType -eq 8}

$v3cmd = $v3 | where {$_.CommandType -eq 8}

$newcmds = Compare-Object $v2cmd $v3cmd -Property Name -PassThru

$newcmds.count

#should return 351, or at least it did for me

$newcmds | sort module,name | ft name,module

You’ll notice a few things when running this. First you’ll see that a lot of modules are automatically loaded now. I believe this is done because of the confusion with AD modules and people not knowing they needed to load them first. Secondly you’ll notice there are some cool new modules like CimCmdlets, PSSCheduledJob and PSWorkflow. One other thing to take a peek at is the new core PowerShell cmdlets.


$newcmds | where {$_.module -eq $null}

There are a few here that stand out, for example Get-ControlPanelItem, Unblock-File and Show-Command. The Show-Command is a pretty neat way to explore PowerShell. Basically creates a pop-up window that lets you dig through the cmdlets a little easier.

So many new things to play around with!

The Next version of Powershell, Version 3!


The CTP of the Windows Management Framework 3.0 CTP1 has been released and can be downloaded from here. Install notes and other info can be found on the Technet wiki.

Collect Analyzer results from an EMC storage unit (VNX,CX,Sym) with Powershell


Just wanted to toss a little something up about working with EMC units. I recently had to run analyzer on a unit for EMC to spec out a new system for us and when I tried to pull the logs off, it kept crashing (not a huge fan of java). Even though there are only a handful of files I decided this would be a good use for Powershell.

$SPIPS = "192.168.1.123","192.168.1.124"

foreach($IP in $SPIPS)

{

$files = naviseccli.exe -h $ip analyzer -archive -list | %{$_ -like "(apm.*)"} | ?{$_} | %{naviseccli -h $ip analyzer -archiveretrieve -file $Matches[1]}

}

Hope this helps someone!

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!