Saturday, November 12, 2011

Using the PowerShell ISE–two cool finds

I’ve been using PowerShell’s Integrated Scripting Environment ever since it was in beta. Despite being relatively slow to load, it sure beats using Notepad for simple script development/debugging. The colour coding alone makes it even more useful! I love how you can add functionality to the editor via object model. It’s neat how that object model is exposed inside PowerShell as the $ISE variable – and how easy it is to use it to add menu items (and keyboard short cuts for the menu items).

A freely available module that offers a lot of ISE customisation is the IsePack, which is part of the PowerShellPack mega-module issued by Microsoft as part of the Windows 7 Resource Kit. You can download the full PowerShellPack from http://archive.msdn.microsoft.com/PowerShellPack. The PowerShellPack module is actually a set of 10 sub-modules. You can import the entire module (Import-Module PowerShellPack) or the sub-components. In my ISE Profile file, I add the ISE pack in specifically (Import-Module IsePack). That in turn exposes me an additional Add-On menu item, ISEPACK. This menu contains a set of sub-menus which add a lot of features to the ISE.

My two cool finds are partly what’s in IsePack and what I could easily add to it. The ISEPack creates a number of functions based on the ISE’s object model. It then leverages those in additional functions that PowerShell associates with menu items and keyboard shortcuts when the module is imported. And since the module is just a text file – you can easily edit it and add more features.

The first cool find is the Search-Bing function, which is associated with a menu item (Add-ons/IsePack/Search-Bing) and a keyboard shortcut (Ctrl-B). The Search-Bing function uses a lower level function,  Select-CurrentText, that gets the text that is currently selected somewhere on the ISE', then pipes it to copy of IE which points http://www.bing.com/search?q=$_. Thus, if I have the text ‘ToString’ highlighed in an open editor window, and hit Ctrl, I get a Bing Search Page, like this:

image

 

The second cool thing was how easy it was to ammend the IsePack module to add a Search-Google function. In the IsePack.PSM1 file, there’s a fragment of code that implements the Search-Bing feature (and adds it to the menu) This fragement is part of a larger script, but here’s the starting poing:

"Search-Bing" = {
        $Shell = New-Object -ComObject Shell.Application
        Select-CurrentText | Where-Object { $_ } | ForEach-Object {
            $shell.ShellExecute("
http://www.bing.com/search?q=$_")
        }
    } | Add-Member NoteProperty ShortcutKey "CTRL+B" –PassThru

 

As you can see, Search-Bing is associated with a script block that first opens the currently configured Web Browser (FireFox in my case). Then it executes a Bing Search on the currently selected text. This results in the search window coming up. So how hard was it to add to add a Search-Google? Trivial as it turns out. I just added the following text directly below the Search-Bing definition:

    "Search-Google" = {
        $Shell = New-Object -ComObject Shell.Application
        Select-CurrentText | Where-Object { $_ } | ForEach-Object {
            $shell.ShellExecute("http://www.Google.com/search?q=$_")
        }
    } | Add-Member NoteProperty ShortcutKey "CTRL+Shift+G" -PassThru

 

Sadly, Ctrl+G was already taken by something (a puzzle for another day!), so I used Ctrl+Shift+G and that brings up something like this:

image

 

As I am currently working on my next Pluralsight course on Formatting with PowerShell, I’m finding a need to look stuff up in MSDN and these two functions sure are useful to me!

Wednesday, November 09, 2011

PowerShell PowerCamp–A great weekend!!!

I’m now recovered from the most recent PowerShell PowerCamp – an intense two days of PowerShell training. I ran the event in London last weekend, and had 21 booked. Sadly there were two very last minute cancellations, so we we ended up with 19 eager souls. We walked through the basics of PowerShell at the command line on the Saturday, then on Sunday, started looking at scripting and other enterprise aspects of PowerShell. And on Sunday, we has Lync MVP superstar Tom Arbuthnot of Modality Systems in to talk some real world approaches to PowerShell.

On Saturday night we took over a small pub nearby, to the amusement of the locals, and continued chatting about PowerShell. I My lovely wife came up to London and we enjoyed a most interesting meal in Sobraine, a Russian restaurant in Victoria. Great food and very, um, interesting décor.

The delegates took home a memory stick with as many PowerShell goodies as I can find and will shortly be getting licenses for PowerGui professional and PowerShell Plus Pro, thanks to Quest and Idera!

I have no specific dates for the next PowerShell PowerCamp, but depending on interest, I would like to run another session sometime in the late spring (March/April). As ever, dates are tricky at that time of year what with half term and Easter, etc – but I’m sure we can find a good weekend should there be anyone wanting this level of training! And for those corporate readers – I’m happy to come to your place of work and run this same training for your team on your premises. If you have 6 or more delegates, this could be financially beneficial.

And in closing – a big thanks for Claire Smyth of Microsoft who was an enormous help in getting this event off the ground. Without her help and passion for the community, this event probably would not have happened! Thanks Claire!! And thanks too to Michael Sullivan for letting his hosting channel know about the event.

For any enquires about the next PowerCamp or running a PowerCamp privately, email me at DoctorDNS@Gmal.Com.

 

Technorati Tags: ,

Performance with PowerShell

Over the weekend, at the most recent PowerShell PowerCamp, I got to discussing the performance of PowerShell. The point I was making was that PowerShell made doing some things very easy, even though they were not performant. Two examples are the early filtering  of WMI data using –Filter (vs using Where-Object after you retrieve all the data from a remote machine) and the two variants of ForEach.

In the case of WMI, where you early filter properties/occurrences on the target machine, PowerShell has less data to serialize and transmit across the network. Also, late filtering requires more local memory, and additional processing. Thus I’d expect early filtering to be faster. We are thus comparing two statements which might look something like this:

Get-WMIObject win32_share -computer  Cookham1 -filter "Description='remote admin'"

versus

Get-WMIObject win32_share -computer  Cookham1  | Where {$_.description -eq 'remote admin'}

In the first example, only one share is returned from Cookham1, whereas in the second example multiple shares are returned and are then filtered locally (aka late filtering). If I wrap both of these commands in a Measure-Command, and do the operation a number of times, the code and results look like this:

 

Psh[Cookham8:fmt:\]>"Early Filter:"
" {0} ms"  -f  ((Measure-command {1..100 | foreach {
Get-WMIObject win32_share -computer  Cookham1 -filter "Description='remote admin'"}}).totalmilliseconds).tostring("f")

"Late filter:"
" {0} ms"  -f  ((Measure-command {1..100 | foreach {
Get-WMIObject win32_share -computer  Cookham1  | Where {$_.description -eq 'remote admin'}}}).totalmilliseconds).tostring("f")
Early Filter:
1948.91 ms
Late filter:
2715.44 ms

So the difference between late filter and early filter is around 28%, although if I run this test a few times, the numbers do vary a bit, but almost always early filtering is in the region of 20% faster.

But a much bigger difference was observed by Anita Boorboom, a Dutch SharePoint guru, in the second case, i.e. using For-Each-object (vs using ForEach in a pipeline).

When you use the foreach operator in a pipeline, PowerShell is able to optimise the creation of objects at one stage of a pipeline and their consumption in the next. Using Foreach-Object, you need to first persist all the objects you wish to iterate across, then perform the iteration. The latter clearly requires a bit more processing and it is likely to require more memory (which can be a bad thing if the collection of objects is large! I knew this, but Anita’s results were a little more than I was expecting, so I duplicated her scripts, well nearly, and found here results were indeed correct, like this:

$items = 1..10000
Write-Host "ForEach-Object: "
" {0} ms"  -f ((Measure-Command { $items | ForEach-Object { "Item: $_" } }).totalmilliseconds).tostring("f") 
Write-Host "Foreach: "
" {0} ms" -f ((Measure-Command {Foreach ($item in $items) { "Item: $item" }}).totalmilliseconds).tostring("f")
ForEach-Object:
  629.73 ms
Foreach:
31.84 ms

Thus the pipelined foreach is nearly 20 times faster for this experiment. I ran this code several times, and the multipler was consistently in the 20-30 times as fast range. That floored me. The For-Each Object does require PowerShell to instantiate every object in memory, then to iterate over it, vs iterating as it instantiates. But I did not expect a 20-30 fold difference in performance!

So it’s obvious that some language constructs will be a little more efficient, You also need to consider the time it takes to write the code, and how often it will be run.  In the first case above, I managed to save just over 750ms by using early WMI filtering. But it probably took me more than that just to write the code for early binding. And for a lot of admins that don’t know WMI very well, filtering using Where-Object is familiar and uses PowerShell Syntac (the –filter clause on Get-WMIObject used WQL which is different). In the second case, the difference was staggering. Of course, when the processing you want to apply to the collection members is non-trivial (i.e. more than a couple of lines of code), you often find the improvement in readability of the resulting script block to be worth considering. By using task oriented variable names, the resulting code is easier to read then when you use $_. And for some production orient5ed scripts, that improvement in readability may be worthwhile.

In summary, there always a lot of different ways to achieve the same result in PowerShell. I advocate using what is easiest for you to remember. At the same time, PowerShell can provide some big performance differences between the approaches – and it pays to know more!

Technorati Tags: ,

Thursday, November 03, 2011

PowerShell PowerCamp Soon Come!

We’re locked and loaded for this week-end’s PowerShell PowerCamp event in London this Saturday and Sunday November 5 and 6 in London Victoria. We had a few last minute cancellations, but in all we have 19 folks signed up (and room for 2 more late bookers should you be interested). And owing to landlord works, the event has been moved to the building next door – but everything will be alight on the night as they say.

I’ve got a box of nice new memory sticks to copy all the collateral onto – one for each attendee. I’ve also got copies of some cool software for all who turn up as well. And in the unlikely event that Wiley gets their act together and the books actually arrive, I may have a copy or two of our PowerShell Bible book (but as Wiley ship books by surface, it’s a month after the copies shipping but they’ve still not arrived).

Should you be at a loose end this weekend and fancy a two day PowerShell boot camp, please email me (DoctorDNS@Gmail.com) as due to the two late cancellations, there’s still a bit of room. Alternatively, I am hoping to do another weekend event in the Spring (and will announce it as soon as I get the dates etc. lined up which will probably not be till late-November/early-December).

And for any PowerShell addicts who happen to find themselves in London on Saturday, we’ll be having PowerDrinks (also known as beer and other drinks!)starting at 17:15 on Saturday. Send me mail and I’ll send you the co-ordinates of the event!

Technorati Tags: ,,

Tuesday, November 01, 2011

Introduction to WMI and PowerShell – A NEW Pluralsight Course

I am quite pleased to be able to announce I’ve finished my first video class for Pluralsight, Introduction to WMI and PowerShell. It’s now available for viewing for Pluralsight subscribers.  I’ve been watching it a bit this morning and it’s not bad, if I do say so myself. Smile

The course is a total of 2:29, and is broken down into 5 modules as follows:

  • Introduction to WMI and PowerShell (21:28) – Describes WMI in Windows and discusses some of the key WMI exploration tools. The module then looks at PowerShell support for WMI in PowerShell V3, and describes the WMI cmdlets. The module finishes with some of the gotchas you need to be aware of when using WMI with PowerShell.
  • Using PowerShell and WMI  (34:37) This module looks at accessing WMI data, including instances, instance properties and methods, WMI classes, and static class methods. We cover the use of the key WMI cmdlets and explain the use of Type Accelerators.
  • Practical PowerShell (24:42)  - This module looks at the range of data you can use in WMI. We show key namespaces and key classes you might leverage. The module also looks at some of the security settings you might make use of when using WMI in a Enterprise environment.
  • Using WMI Query Language (29:36) – Describes the WMI Query Language and how to use it with the PowerShell WMI cmdlets.
  • WMI Eventing (39:16) - This final module looks at accessing WMI events. It shows how to create both temporary and permanent event subscribers for intrinsic, extrinsic, and timer events. It also explains all those terms and shows how to leverage WMI’s eventing subsystem.

So if you are currently a Pluralsight subscriber, why not consider it? If nothing else, take the free trial – 10 days access to the entire library, including this course.

And also: a big thank you to Alexandar Nikolic (@alexandair on Twitter) for his proof reading of the course – much appreciated!!