Saturday, January 31, 2015

Office 365 Plans

Licensing with Office 365 is a bit different than normal on-premises software. With Office 365, rather than purchase a SKU, you subscribe to a Plan. A plan represents a set of services the user of that plan receives. In the early days of Office 365, the plans and the ability to move between them was problematic. If you took out a small business type plan and then wanted to move that subscription up to an Enterprise plan – you couldn't. It was all a bit messy. Then MS did two things: they simplified the plan structure, and enabled you to mix and match with the plans.

The new plan structure for Office 365 contains 6 separate plans:

  • Office 365 Business Essentials
  • Office 365 Business
  • Office 365 Business Premium
  • Office 365 Enterprise E1
  • Office 365 Pro Plus
  • Office 365 Enterprise E3

The Office 365 Business/Pro Plus plans are just the on-Prem fully installed set of Office software products. This includes Word, Excel, PowerPoint, Outlook, Publisher and One note). The Pro Plus plan adds Access. These plans are a way of subscribing to Office, versus outright purchase. These two plans just include the software – there's no on-line services or server software. These plans appeal to organisations that are looking to spread the cost over time. Once nice aspect of these plans is that you can load Office on up to 5 systems (e.g. laptop, desktop, home, etc).

The Business Essentials and Enterprise E1 plans are, in effect, online Office (including the Office Online Apps, plus and Exchange mailbox, file and storage space, plus both SharePoint and Lync. The E1 plan has a few added features appropriate to larger firms, such as compliance, BI and enterprise management of applications.

Finally, the Business Premium and E3 plans are the combination of the first two: full office plus mail, SharePoint, Lync. The E3 plan as above gets a bit more.

For fuller details of precisely what each plan offers, see

What this now means is that any organisation can mix and match any of the plans. The restriction is that a a given subscription is limited to 300 seats of less of the business plans. So you could give the Business/ProPlus subscription to the road warriors who need off line access, while giving Business Essentials to in-house staff could use Office in the cloud. This offers a lot of flexibility. Tags: ,

Friday, January 30, 2015

PowerShell Patterns and Azure Cmdlets

Get-Process Power* As anyone learning PowerShell quickly finds out, there are a number of basic patterns of usage that work well across a huge range of PowerShell cmdlets/modules. One of the most basic pair of patterns I try to teach, by way of example here, are early vs late filtering. The following two commands accomplish the same result:

Get-Process Power*
Get-Process | Where-Object name -like Power*

I wrote a little script to measure the performance difference between these two ( Running each of these 1000 times, the result was that early filtering was 3 times as fast as later filtering. So as a general rule – always early filter. BUT: sadly some cmdlets that emit useful objects do not support early filtering, so the later filtering pattern always works. I try to teach both of these patterns and why they are different since so many scripts can make use of these patterns.

Which brings me to Azure. In much of my PowerShell use, there is a cmdlet to set some value for some object or perform some operation on an object. For example, to change the number of CPUs in a Hyper-V VM, you use the Set-VM cmdlet, like this:


To do this in Azure is a bit more complicated. To change the number of processors in an Azure VM, you need to change a different property on the Azure VM object. Plus, the say you do it is different. With Azure, each VM runs in a given instance. The instance determines the number of CPUs and memory each Azure VM gets. So I would expect to do something like this:

Set-AzureVM –name xxx –service xxx –instancesize 'extrasmall'

Unfortunately, that cmdlet does not exist, and that wouldn't be the right way to do it anyway. The good news is that in Azure, there is a specific cmdlet to change the instance size (Set-AzureVMSize). So Azure VMs, the most common pattern is like this:

Get-AzureVM –VM psh1 –Service psh1 -Verbose |
  Set-AzureVMSize -Instancesize $VmSize   -Verbose |
     Update-AzureVM -Verbose

A different pattern. Unlike Set-VM, Set-AzureVMSize takes an Azure VM object (not the name of the VM). Secondly, Set-AzureVMSize does not persist the updated instance size value – it just updates an in memory object relating to the VM. To persist the value you have to write it back to Azure using Update-AzureVM. While you can do it step at a time, and avoid using the pipeline – in this case, using the pipeline makes seems easier.

In the Azure VM cmdlets, we see a great deal of use of the Pipeline based patterns. For example, to create an Azure VM, you first create a VM config object (Technically, New-AzureVMConfig produces an object of type Microsoft.WindowsAzure.Commands.ServiceManagement.Model.PersistentVM) which you then pipe to New-AzureVM (see This general pattern of getting or creating an in-memory object, updating that in-memory object typically via the pipeline and finally persisting it to Azure is easy to apply.

When you start to use Azure you quickly find that while many of the features of Azure are similar to those in Windows – in this case, Azure VMs – the methods you use to manage the features does differ. You  have different patterns of usage you need to learn and understand.  When I explained this to a class this week, I got the obvious question: why? Why is it different?

Since I was not on the dev team, I can't really answer that. But, I suspect the main technical reason is that the Azure VMs are, in effect, a wrapper around the REST API exposed by Azure. I am guessing it was easier to write the cmdlets using this pipeline pattern (or the cmdlet's approach of passing a VM object vs a VM name). Having said this, incorporating the Get-AzureVM and the Update-AzureVM cmdlets inside the Set-AzureVMSize cmdlet would have not been that difficult. But that wasn't what MS implemented.

So go with the flow; learn the patterns and enjoy Azure! Tags: ,

Updated Azure PowerShell Module

I've been playing a lot with the Azure cmdlets and noticed that there's an updated version of the module. My recent Azure related posts have been based on the version of the tools Ioaded before the New Year:


If you got to the download page,, and run the platform installer, you see an updated version of the tools is available:


The download is around 13 mb and took around 45 seconds to download and install. After installation:


Sadly, there appear to be no release notes, or readme.txt file in the installation folder. Given the huge amount of change, better release notes would be useful. AND it would be nice to have the latest module available via PowerShellGet. We can hope! Tags: ,,

Thursday, January 29, 2015

Using Azure – Get a Free Month's Trial

I've been doing a lot of work around Azure of late and have been running Azure training around Western Europe. Most of the folks I see in classes are new to Azure – it's an unknown that is challenging their existing approach to computing (i.e. everything on premise, each app running on it's own physical hardware). In our classes, we give the students access to Azure and get them to use Azure backup, let them create web sites, VMs, virtual networks, etc. In one class, we have the students build out an 'on premise' environment (in Azure!), then use that 'on premise' environment to integrate with Office 365.

What I am seeing is that Azure is fairly easy, but very different in places. Certainly, the exposure to Azure in class gets the attendees over the initial learning curve and allows them to play. The key feature of all this playing is the free Azure Pass we give each student. But what if you were not able to attend the training but still want to play with Azure.

The answer is easy: if you live in the UK, go here: and sign up for a free Azure Pass. From the UK, at least, you go there, sign up for free and get £125 worth of Azure credit. Signup does require a credit card, but Microsoft states: "We use the phone number and credit card for identity verification. We want to make sure that real people are using Azure. We do not bill anything on the credit card".

Should you exceed the credit amount, your new Azure account will be suspended. At any time, you can optional upgrade the trail to a Pay-As-You-Go Azure subscription. BUT you will not be billed anything if you use your credits and let the subscription expire.

This trial is not just available here in the UK: it's available in 140 countries around the world. See the FAQ section of the free trial page to see the countries where it's available.

So if you have not used Azure and want to experiment, go and sign up. And join in the fun that is Azure. You can even use the scripts I've posted here to play with PowerShell and Azure! So what are you waiting for?? Tags: ,

Tuesday, January 27, 2015

Azure Networking Fundamentals- MVA Course

I just noticed that the Microsoft Virtual Academy has a new course: Azure Networking Fundamentals for IT Pros. It's narrated by Aaron Farnell, and consists of 4 modules comprising of 4 modules taking around 120 minutes (including assessment time).  The MVA rates the technical level as 300 – which is fairly deep but not overly deep!

This MVP course consists of 4 modules:

  • Intro to Azure Network Basics and VPN requirements
  • Plan and Design your Cloud network infrastructure
  • Configuring Azure and On-Premises
  • Testing Connectivity and Monitoring

This is a good start to understanding Azure Networking! And like all MVA courses, you can download the MP4s of each module and take then on the road with you. Tags: ,,,

Monday, January 26, 2015

Azure and Compliance

Over the past 6 months, I've been conducting quite a lot of cloud technology training, particularly Azure and Office 365. I've been speaking to a number of European MSPs in the SMB space who are now looking to take on Azure as a platform for their customers, to some degree replacing their old historical favourite, Small Business Server. SBS (rip) was a great platform for the small business – cheap, comprehensive and relatively easy to manage. But it's gone and not coming back.

When extolling the virtues of the cloud, I hear a number of objections – some valid, some possibly less so. One objection I hear to Azure revolves around compliance. For customers in compliance-affected businesses, compliance is not an option.

It's clear that Microsoft recognise the need to have Azure seen as a product that can comply with most, if not all, of the world's compliance regimes. It was comforting, therefore, to read Lori Woehler's recent blog article about Azure and compliance.

In her article, she notes that Azure has recently completed successfully an audit against ISO/IEC 27001:2013. carried out by the highly independent British Standards Institute Americas. BSI also validated that Azure was compliant with the ISO 27081 code of practice for protection of Personally Identifiable Information (PII) in clouds.

Woehler goes on to note that Azure has expanded the services in scope for SOC 1 and 2, the US Department of Health and Humans Services has granted the US FedRAMP authority to operate to both Office 365 and Azure AD, Azure Government is one of the first cloud platforms to meet US. Criminal Justice Information Services certification requirements for state and local governments. She mentions other, non-US compliance initiatives for Azure, including Singapore Multi Tier Cloud Security (MTCS's first Level 1 end to end cloud service offering), and the Australian Government Information Security Registered Assessors Program (IRAP) accreditation.

These, and the other Azure initiatives mentioned, should  help to bridge the confidence gap (as well as enabling Azure to be used in many compliance-bound industries. And this work just keeps going on, both to comply with new and additional compliance schemes as well as to re-certify on a regular basis. Azure is changing on what appears to be a weekly basis – the compliance certifications need to keep pace.

Hopefully, this continuing effort will go a long way towards assuaging at least some of the concerns of the SMB market space. Tags: ,

Friday, January 23, 2015

Creating Azure VMs with PowerShell

I've been playing for the past few weeks with Azure VMs. I can, obviously, do most things from the GUI, but somehow, as a PowerShell guy, that just seems wrong! So I've been honing up my PowerShell Skills. The Azure module contains over 500 commands. In the version on my home workstation, there are 509 commands, of which 35 are aliases.

As an aside, those aliases are use to alias the old 'windows azure pack' cmdlets which have in effect been replaced with newer cmdlets. For example, the old Get-WAPackSubscription is now an alias for Get-AzureSubscription. This is a great idea for helping to ensure forwards compatibility. I suspect we'll see more of it. For those of you with older Windows Azure Pack based scripts – you may consider upgrading those to use the new Azure Module native cmdlets.

The first thing you have to know about Azure VMs is that, while they are in the end 'just' a Hyper-V VM, they are a bit more complex than on-premise VMs. There are several Azure features, including storage accounts, images, endpoints, locations, and azure services to consider).

In azure, each VM runs within an Azure service. I like to think of the Azure service as the load balancer. In the simplest case of a single VM, you have a VM and the service and use the name and IP of the service to access the VM. The Service also allows you to provide more instances of the VM in an lbfo fashion. But today, I just want to create a simple VM. The VM I am creating runs inside a new Azure service of the same name as the VM

To create an Azure VM, you have two main options: use and Azure VM Image as the starting point for your VM, or create the VM on premise, and ship it's VHD up to azure and then create a VM using that uploaded VHD. In this blog post, I'll concentrate on the first, leaving the second for another day.

A VM image is a sysprepped operating system image often with additions and customisations. The image was built from some base OS with some changes possibly made. You can get simple base OS images – in effect what would be on the product DVD. Others have been customised, some heavily. Azure images come from a host of places, including Microsoft and the family. Once the reference Image is created, the creator then prepares.

You can easily create a VM from an existing VM image. To see the VM images in Azure, you simply use Get-AzureVMImage. As of writing there are 438 images. Of these, 187 are Linux based and 251 Windows based. A given image is in one and typically all Azure locations. An image belongs to an image family and has a unique image name. With 125 image families to chose from finding your image (and it's specific image name is based on Get-AzureVmImage and piping the output to your normal PowerShell toolset!

One suggestion if you are experimenting. Doing a Get-AzureVMImage call takes a while as you are going out to the internet (in my case behind a slow adsl line) is to save the images to a variable, then pipe the variable to where/group/sort/select thus avoiding the round trip up to the azure data center.

Today, I just want to create an image of Windows Server 2012 R2 Datacenter. So to find the image I do this:


Next, in creating the Azure VM, you need an Azure Storage Storage Account in which you are going to store the VHD for your VM. The VHD starts off as, in effect, a copy of the image (i.e. a syspreped version of Windows) stored in Azure Storage VM. You can pre-create the storage account, although in this case, I let the cmdlets build the storage account for me.

So here's the script:

# Create-Azurevm.ps1
# This script creates an azure VM
# Set Values
# VM Label we are looking for
$label          = 'Windows Server 2012 R2 Datacenter, December 2014'
#vm and vmservice names
$vmname         = 'psh1'
$vmservicename  = 'psh1'
# vm admin user and username
$vmusername     = 'tfl'
$vmpassword     = '~+aQ8$3£-4'
# instance size and location
$vminstancesize = 'Basic_A3'
$vmlocation     = 'West Europe'

# Next, create a credential for the VM
$Username = "$vmname\$vmusername"
$Password = ConvertTo-SecureString $vmpassword -AsPlainText -Force
$VMcred = new-object $username,$Password

# Get all Azure VM images
$imgs = get-AzureVMImage 

# Then get the latest image's image name
$img = $imgs| where label -eq $label
$imgnm = $img.imagename

# OK - do it and create the VM

New-AzureVMConfig -Name $vmname -Instance $vminstancesize -Image $imgnm `
| Add-AzureProvisioningConfig -Windows -AdminUser'tfl' -Pass $vmpassword `
| New-AzureVM -ServiceName 'psh1' -Location $vmlocation

Once the VM is created, you can then start and use it. Having said that, there are some pre-requisites, like setting up end points and enabling remote management inside the VM. I'll cover these topics in later blog posts. Tags: ,

MVA Training For Azure

I see that Microsoft are continuing to post more great Azure training into the Microsoft Virtual Academy. If you look here, you will find some great videos that can ultimately prepare you for 70-533 (Implementing Microsoft Azure Infrastructure Solutions)

There are several great things about this training – first it's pretty current. Azure changes literally weekly which means some of the printed material from other training outlets can be woefully out of date!. Second, it's free. And finally, being simple videos, it's easy to watch in your spare time (Ed: what is that?). Tags: ,,,

Monday, January 19, 2015

Azure VMs – Improving the Display XML

The cmdlets that come with Azure (all 508 of them) also come with a little bit of display XML. But as I play with the cmdlets, I find either the display XML non-existent or less than helpful. To that end, I've started developing some supplemental .format.ps1xml.

Today, I was playing with the output of Get-AzureVM. By default, the output looks like this:


I have taken the liberty of creating some new display XM, and with that output, Get-AzureVM now produces better looking (IMHO) output.

image As you can see, there is some more information (including IP address, FQDN) that is useful when you are troubleshooting.

To get the display XML, take a look at and there you can grab the screen, save it in a local file, then use Update-FormatData to load it.

It's kind of cool to be able to improve released cmdlet sets! I wonder if anyone from the Azure team reads this. If so, you guys are welcome to the  XML!

Friday, January 16, 2015

Fun with the PowerShell Pipeline

I've been having some fun with the PowerShell Pipeline. This started with a post to a PowerShell question over on Spiceworks ( The OP wanted to stop the spooler, remove any temp files then restart. Simple enough – but the first response suggested using pipes like this:

Stop-Service -Name Spooler |
Remove-Item C:\Windows\System32\spool\PRINTERS\* |
Start-Service -Name Spooler

I looked at this for a long while wondering what the heck the pipeline would be doing here. More importantly, I could not believe it would work – surely the output of Stop-Service would be null thus the remove-item would fail, etc. Then it tried it and much to my surprise – it actually works!

Then I began to wonder two things – WHY does it work at all – and what is the performance impact. To understand why requires a good understanding of how the pipeline works. In this case, Jason Shirk has a great explanation of the underpinnings over on Stack Overflow: I highly recommend reading it to help you better understand what the pipeline is doing.

Ok – so I know WHY it works, but what is the performance impact if any? To answer this question, I first constructed a little script.

Function Measureit {$m1 = (Measure-Command -Expression {
      Stop-Service -Name Spooler |
      Remove-Item C:\Windows\System32\spool\PRINTERS\* |
      Start-Service -Name Spooler

  $m2 = (Measure-Command -Expression {
      Stop-Service -Name Spooler
      Remove-Item C:\Windows\System32\spool\PRINTERS\*
      Start-Service -Name Spooler

  "{0,-10}{1}" -f $m1, $m2

1..20 | %{measureit}

Now please read the script and guess which is going to be faster – with or without pipelines? The results absolutely astounded me:

15        307
2         273
2         270
254       280
2         277
10        267
2         271
2         269
2         276
2         268
2         268
2         277
2         272
2         268
2         268
2         268
10        267
2         269
2         267
2         271

I know why this works, but I sure as heck have NO idea how adding the pipeline, in this care can offer up 100-fold improvement in the speed of execution in most cases. Hmmm.

Thursday, January 15, 2015

Using Azure VMs for an Exchange DAG Witness Server

Last week, the Azure team released a cool new feature: support for a DAG Witness server inside an Azure VM. With the latest version of exchange, you can configure automatic data centre failover. But to do that, you new require three physical sites. However, according to Microsoft, many customers only had two physical sites deployed. This is where Azure comes in, since these clients can use Azure as their third physical site. This provides a cost-effective method for improving the overall availability and resiliency of their Exchange deployment, and requires no up front capital expenditure.

OF course, deployment of production Exchange servers is still unsupported on Azure virtual machines. But I can't help thinking that in due course we'll see this restriction changed.  MS kind of hint that by saying; "Stay tuned for future announcements about additional support for Azure deployment scenarios.".

Yet another cool scenario available to Azure customers today . For more details on how to do it, see the TechNet article at:

Thursday, January 08, 2015

Azure Storage Architecture

I've been doing a lot of work, recently, around Azure – and one interesting aspect is Azure Storage. Azure Storage enables you to store and retrieve large amounts of unstructured data, such as documents and media files with Azure Blobs; structured nosql based data with Azure Tables; reliable messages with Azure Queues and use SMB-based Azure Files that can help to migrate on-premises applications to the cloud. The first three of these feature have been offered by Azure for several years, while Azure Files is newer. Azure files is still in preview – and you can learn a bit more about the File Service from the Azure Strorage team's team blog.

As an aside, the Azure module you can download enables you to manage Azure Storage features from PowerShell. The cmdlet set is rich (and richer with Azure Files) with 48 storage related cmdlets in the latest version of the Azure Cmdlets (0.8.12). These cmdlets are fairly easy to use, but I've found the error handling is a bit harder than with equivalent on-premise cmdlets. Many errors, for instance, return little useful information to help you troubleshoot. There is room for improvement – and knowing the Azure team, will come as fast as they can get to it!

In order both to scale and to provide great recovery from failure, the architecture of Azure storage is a bit more complex than the NTFS file system we are used to. Although it's now a couple of years old, the Azure team also published a detailed description of the Azure Storage Architecture. It's true level 400 stuff – and you can find it here. The paper does not cover the Azure File Service – hopefully Microsoft will provide an update to this great white paper at some point in the future.

If you are planning on architecting solutions utilising Azure Storage, this paper is one you should read and absorb. And, in due course, apply when you implement your solution(s)! Tags: ,

Thursday, January 01, 2015

Happy New Year

Just a quick post to wish all the readers of this blog a very happy and joyous new year. I hope 2015 turns out to be a great year. For me, this year sees the start of my retirement, although the way things look, I'll be busier than ever. My best to you and yours.

Tuesday, December 16, 2014

Sometimes When You Ask – You Get! Thanks Azure!

Over the past few months, I've been running a set of 1-day sessions for Microsoft SMB partners – these sessions are a combination of lecture and lab work. This material shows them how to position key Azure and Windows Server 2012 R2 features and gives them experience in using the products.

In a recent session, I was asked about Azure Backup and client systems. At that point (early September this year), the answer was no – Azure Backup did not support Windows 8 (or any client problem). The scenario here is the road warrior who never got back to base, but was forever somewhere in the cloud (via whatever networking they may find in their travels!). They just want their data backed up so if the laptop dies, is stolen or the disk itself dies – they can recover their data once the replacement hardware is up and running fully. Seemed to me to be a service I might buy for myself!

This seemed to me to worthy of consideration. So I posted a request over on A couple of days later, I got surprise email from the Azure  Backup PM who wanted to chat with me about the suggestion I'd posted. We then had a conference call and I was able to explain the user need, and the potential for the suggestion. He listened, asked great questions then hinted that this is something they could consider for a future release. I did not hold out much hope of features any time soon, but it was nice to be listened to and to maybe having an impact down the road.

Imagine my surprise and delight when I read today's post on the Azure Team Blog, which announced support for Windows Cliewnt OS's! From asking to delivery in 14 weeks. Nice job!

Sunday, December 07, 2014

Type Accelerators and TypePx

Last week, I updated some earlier scripts related to Type Accelerators over on my PshScripts blog – and I've had some great feedback. Kirk Munro (@Poshoholic on twitter and all around PowerShell superstar) pointed out there is a TypePX module he's published to GitHub.

As to be expected of anything Kirk touches, the TypePX module is rich and well implemented. His module is production ready – so you could easily copy it to your modules folder and start to use it. The TypePx functions are pipeline friendly and have good error handling. 

What I've published is much more simple and designed for a different audience. The whole idea of what I published, and indeed the whole point of my PshScripts blog, is to illustrate simple concepts, apis, etc in a simple script. In this case, the essence of type accelerators is wrapped up in a few lines of code. This is what I strive to publish in Pshscripts – showing you how to do one thning simply (per script!). What Kirk publishes is enterprise grade production scripting. I readily admit they are different – but I'd like to think there is room for both. One ofr learning with, one for using in production.

Saturday, December 06, 2014

Type Accelerators – And a Module

Over the years, I've written about type accelerators and PowerShell. A type accelerator is simply a synthetic type name that you can create to serve as an alias to another type name. For example, you could use the int16 type to refer to the System.Int16, or guid instead of [system.guid]. Type accelerators are meant to simplify handling of types by IT Pros in PowerShell scripts.

TAs were first introduced in a beta of PowerShell V2, and I posted code that worked (then). However, I have been recently updating my script library blog (, I discovered that TAs stopped working that way. After some fun and effort, I've now found hot how they work today, and how you can play with them!

TAs work by just providing you with an alias to a full type name. To some degree, TAs make up for the lack of a Using statement such as in the C# language. Some common TAs in use include [ADSI], [WMI], [String], [regex] and many more.

This week, I have published a new TypeAccelerators modules. This module contains scripts that define 4 TA-related functions:

  • Get-TypeAccelerator– this gets the TAs active in your current PowerShell Session. This function also takes a parameter (AliasRE) which is a regular expression over the type accelerators to return.
  • Measure-TypeAccelerator – this just returns a count of the TAs active.
  • New-TypeAccelerator – this adds a new type accelerator that aliases an existing type
  • Remove-TypeAccelerator – this removes a type accelerator from your current system.

Here's a screen shot of using these TAs


The scripts also create aliases for these functions: GTA, CTA, NTA and RTA as you might imagine. The module also includes an about_ file for help – you get this importing the module!

You can get the module at I will also look to publish this module to the new PowerShell V5 Internet module repository (and maybe Chocolatey too if I get time).

A small footnote: this module and the scripts therein are intended to illustrate the concepts around type accelerators. They lack any sort of pipeline friendliness or error handling. So if you decide to make use of the concepts here – make sure you add the production quality aspects to your code, leveraging mine.

Thursday, December 04, 2014

Azure Documentation on GitHub

Late last night, I was looking for some information on a topic within Azure. After a search, I ended up here: a good page describing Azure cloud services. As I read through it, I noticed that at the bottom there was this link


The highlighting is mine, but I looked at this for a bit before the import sunk in: MS is open sourcing the Azure documentation! WOW!!

So I went off to GItHub (in this case to to have a look. From here, if you create a GitHub id, you can create a fork, edit one (or more documents) and submit them back via a pull request. Once approved the documentation goes live.

What a cool idea – well done Microsoft.

Monday, December 01, 2014

What is Coming in the Next Version of Hyper-V?

Savision have just sent mail about an upcoming web cast on this topic. On Dec 2 and Dec 4, Symon Perriman (Microsoft Senior Technical Evangelist) will co-host (with Savision) that will cover an overview of the new capabilities coming in the next Version of Hyper-V. I can't wait!

Mark your calendar for these dates:
Tuesday, December 2, 2014 | 3:30 PM CET/ 9:30 AM EDT   
Thursday, December 4, 2014 | 8:00 PM CET/ 2:00 PM EDT 

Register now for these exclusive webinars by Microsoft's Symon Perriman as there is limited space available.

Friday, November 28, 2014

Keeping up with Azure PowerShell Tools Changes

Microsoft is developing the Azure PowerShell tools (and for that matter all of Azure) in an agile way – delivering frequent incremental changes and new features. Keeping up is, to say the least, non-trivial. One way to keep up with the PowerShell tools is to look at the ChangeLog.Txt file on the Azure SDK tools site on GitHub. That page lists, at a high level, the changes implemented in each new version of the tools.

As an indication of how fast Azure, and the PowerShell tools are evolving there has been over a dozen updates this year – roughly one a month, with some months more. That is a very fast pace of development. Tags: ,,

New Blog Layouts For My Blogs

I've had two blogs on BlogSpot (both before and after the take over by Google!): this blog (aka Under The Stairs) and a PowerShell Script blog. Until recently, the format of these two blogs has been pretty static. But promoted by a couple of comments, I've updated the layout of both blogs. Both blogs are now a bit wider and both use new templates.

An issue with the PowerShell scripts blog is that the formatter I was using also used an online CSS. Sadly, both the site and the CSS object are gone – more Internet goodness that is impermanent. I have switched over to a new formatter, but it's going to take some time to get around to fixing all of the post. I've done a few, but there are around 300 more to do! Eventually!

I'd be happy to get comments about the blog. Has anyone actually noticed?

Thursday, November 27, 2014

Capturing Different Types of PowerShell Output

When a PowerShell script runs, it can create a number of different types of output, including success output, errors, warning messages, verbose output, and debug messages. By default, each of these streams of output are merged to the console host when your script runs. This usually makes sense, but some times, you may want to capture the different streams of output separately.

Simon Wahlin has published an interesting article that shows you how you can combine the redirect operator (">") and the stream number to achieve that. This is great information about a somewhat obscure feature. The technique involves combining the re-direct operator with the stream number based on:

Stream Stream Number
All Output *
Success output 1
Error output 2
Warning messages 3
Verbose output 4
Debug output 5

Then you follow the command you want to capture on, the stream number, redirect operator and where you want the output to go. Simon has a simple function that creates each type of output (Write-ToStreams). If you want to capture the output of, say, the verbose stream, you'd run the function like this:

Write-ToStreams 4>4out.txt

And if you wanted to send the verbose output one way, and the error output another, you could achieve it like this:

Write-ToStreams 4>4out.txt 2>2out.txt Tags: ,

Wednesday, November 26, 2014

Creating a Hyper-V Generation 2 Disk with PowerShell Tags: ,

With the latest version of Windows Server, you can now create a new type of Virtual Machine – A generation 2 VM. These VMs now suppport a number of new features, but require a new format of disk drive. You might have thought that it would be very simple: just do a New-VHD and specify a –Generation 2 parameter. If only it were that simple.

I've struggled with working out how to do this and have not found much help out on wider interweb. Until I came across a great post from Jeff Hicks, Creating a Generation 2 Disk with PowerShell. In this post he goes over the steps required to make a Generation 2 disk – which is actually not all that easy. Unfortunately, the whole job is not doable via PowerShell cmdlets – you need to cheat a bit and use diskpart.exe. But once you know how, you can hide the details inside a function and just use that function going forward.

I am working on updating my scripts to build out my training course test lab based on Windows 10 server. I will be moving over to Gen 2 VMs (and VHDs), so this article is especially important to me!

Tuesday, November 25, 2014

Writing Classes With PowerShell V5 – Part 2

In a previous article, I set out what a class was and what it contains, and showed examples of using those classes in your PowerShell scripts. As I mentioned last time, you should use cmdlets where possible to create and manage objects. But when you can't you can always delve into the .NET Class Framework and it's huge class library.
But what if there are no applicable .NET objects and you need to create your own class? Some admins might be asking: why bother? The answer is one of flexibility and reuse. If you are writing scripts to automate your day to  day operations, you are inevitably passing objects between scripts, functions, cmdlets. There are always going to be cases where you'd like to create your own object simple as a means of transporting sets of data between hosts/scripts/etc.
In PowerShell V5, Microsoft has included the ability to create your own classes. When I started writing this set of articles, I had initially intended to just introduce Classes in V5, but as I looked at it, you can already create your own objects using earlier versions of PowerShell. These are not fully fledged classes, but are more than adequate when you just want to create a simple object to pass between your scripts/functions.
Creating Customised Objects
There are several ways you can achieve this. The first, but possibly hardest for the IT pro: use Visual Studio, author your classes in C# then compile them into a DLL. Then in PowerShell, you use Add-Type to add the classes to your PowerShell environment. The fuller details of this, and how to speed up loading by using Ngen.Exe are outside the scope of this blog post.
Bringing C# Into PowerShell
Now for the semi-developer audience amongst you, there's a kind of halfway house. In my experience, IT pros typically want what I call data-only classes. That is a class that just holds data and can be exchanged between scripts. For such cases, there's a simple way to create your class, although It does require a bit of C# knowledge (and some trial and error).
Here's a simple example of how to so this:
Add-Type @' 
public class Aeroplane
     public string Model = "Boeing 737";   
     public int    InFleet = 12;
     public int    Range = 2400;
     public int    Pax   = 135;
This code fragment defines a very small class – one with just 4 members (Model, number in fleet, range, and max number of passengers).  Once you run this, you can create objects of the type AeroPlane, like this:
As you can see from the screen shot, you can create a new instance of the class by using New-Object and selecting your newly created class.
If you are just creating a data-only class – one that you might pass from a  lower level working function or script to some higher level bit of code – then this method works acceptably. Of course, you have to be quite careful with C# syntax.  Little things like capitalising the token Namespace or String will create what I can only term unhelpful error messages.
Using Select-Object and Hash Tables
Another way to create a custom object is to use Select-Object. Usually, Select object is used to subset an occurrence – to just select a few properties from an object in order to reduce the amount of data that is to be transferred. In some cases, this may be good enough and would look like this:
Dir c:\foo\*.ps1 | Select-Object name,fullname| gm
  TypeName: Selected.System.IO.FileInfo
Name        MemberType   Definition                                  
----        ----------   ----------                                  
Equals      Method       bool Equals(System.Object obj)              
GetHashCode Method       int GetHashCode()                           
GetType     Method       type GetType()                              
ToString    Method       string ToString()                           
FullName    NoteProperty System.String FullName=C:\foo\RESTART-DNS.PS1
Name        NoteProperty System.String Name=RESTART-DNS.PS1          
Note that when you use Select-Object like this, the object's type name changes. In this case, the dir (Get-ChildItem) cmdlet was run against the File Store provider and yielded objects of the type: System.Io.FileInfo. The Select-Object, however, changes the type name to SELECTED.System.IO.FileInfo (emphasis here is mine). This usually is no big deal, but it might affect formatting in some cases. 
But you can also specify a hash table with the select object to create new properties, like this:
PSH [C:\foo]: $Filesize = @{
    Name = 'FileSize   '
    Expression = { '{0,8:0.0} kB' -f ($_.Length/1kB) }

Dir c:\foo\*.ps1 | Select-Object name,fullname, $Filesize
Name                   FullName                  FileSize               
----                   --------                  -----------               
RESTART-DNS.PS1       C:\foo\RESTART-DNS.PS1         1.1 kB               
s1.ps1                C:\foo\s1.ps1                  0.1 kB               
scope.ps1             C:\foo\scope.ps1               0.1 kB               
script1.ps1           C:\foo\script1.ps1             0.5 kB               

PSH [C:\foo]: Dir c:\foo\*.ps1 | Select-Object name,fullname, $Filesize| gm
   TypeName: Selected.System.IO.FileInfo
Name        MemberType   Definition                                  
----        ----------   ----------                                  
Equals      Method       bool Equals(System.Object obj)              
GetHashCode Method       int GetHashCode()                           
GetType     Method       type GetType()                              
ToString    Method       string ToString()                           
FileSize    NoteProperty System.String FileSize = 1.1 kB       
FullName    NoteProperty System.String FullName=C:\foo\RESTART-DNS.PS1
Name        NoteProperty System.String Name=RESTART-DNS.PS1          
As you can see form this code snippet, you can use Select-object to create subset objects and can extend the object using a hash table. One issue with this approach is that the member type for the selected properties (the ones included from the original object and those added) become NoteProperties, and not String, or Int, etc. In most cases, IT Pros will find this good enough.
In the next instalment in this series, I will be looking at using New-Object to create a bare bones new object and then adding members to it by using the Add-Member cmdlet and how to change the generated type name to be more format-friendly.

Monday, November 24, 2014

Dell Bios Module

I have previously written about hardware vendors shipping PowerShell hardware related modules. I just ran across another one – this time a BIOS module from Dell, which comes with a rather cool provider! You can get the module itself from Dell's Mobile Solution site.

The provider is used to configure the SMBIOS on Dell's 'BizClient' systems. It was originally build for PowerShell V3, but I've installed and am using it on Windows 8.1 and PowerShell V5 November Preview.  Before you can use the module you need to install Dells HAPI driver (provided in module download noted above. See the release notes for specifics, but installing the driver is painless - done by unzipping the files, then running HAPIInstall.exe. I created a sub folder and extracted the files into the sub folder before running the installation, which looks like this:


This screen shot comes from my Latitude E6520 laptop. Once the driver has installed, you can then access and use the module. Typing Get-BiosSettings, brings up a sweet grid view containing all the current bios settings, something like this:


The provider itself is also pretty cool – you can use the CD/LS commands to view various items as well as set their values. For example, you could change the Bios Setup Admin password, or whether numlock should be turned on at boot, etc. As with most providers , you can easily retrieve information from Dell's provider that would be helpful for troubleshooting as well as for reporting. You can also use the provider to change BIOS settings. Using the provider is easy and looks like this:

imageThis module should work on most of the Dell range, although I have not tested it extensively.  One neat looking feature is the ability to remove the bios setup password.

Saturday, November 22, 2014

Using Pre-Release Software Not Always A Great Experience

Over the years in the industry, I've had the opportunity to use pre-release software. Some of it has been pretty awful, while others perfect or nearly so – and more in between. Using software that has not been richly tested is always a bit of a gamble, although some vendors are better than others. Of course, issues during pre-release typically get resolved prior to general release – so these errors really only affect those of us mad enough to use beta code!

With that in mind, I downloaded the latest build of PowerShell V5 as soon as it was released. I was anxious to see what, if anything, had become of the Chocolatey provider for Find-Package (OneGet) as it had been removed in an earlier beta version (as previously noted!). So my first test was to do both Get-Module and Get-Package to see the two 'get' package managers in action.

Much to my surprise, running Find-Module produced a ton of errors:

imageWeird, to say the least. I tried to see if other beta testers were seeing this issue the ones I was able to chat with did not see this error. Then I was having a Skype conversation with Aleksander Nikolic who asked me what culture I was using. As you can see in the above screen shot, I'm using my home culture (en-GB). He suggested it was culture related. To test this, I spun up an Azure VM, loaded the new version of PowerShell V5 and, as if by magic:

imageJust as I expected! This looks to be another culture issue – one that will no doubt be sorted out by the time RTM comes around (or, hopefully, a newer build is released that works with En-GB).

It's easy to understand this issue, but I guess I'd have been less surprised and frankly less disappointed, if the issue had been mentioned in the otherwise excellent release notes (or possibly even acknowledged in the release notes). One for the future perhaps.

So for the foreseeable future, I'm stuck with using a partly broken beta build. I can live with OneGet being broken in exchange for the other goodies in V4. And yes, this bug has been reported on Connect ( Feel free to vote it up!

The joys of using Beta software!

Friday, November 21, 2014

A New Build of PowerShell – Chocolatey Regained

Having posted previously about a recent PowerShell V5 interim build that resulted in Chocolatey not being available by default – as if by magic, Microsoft have issued a new build of PowerShell V5 Preview AND it's includes Chocolatey by default. You can get more details from the PowerShell team Blog.

This build only operates on Windows Server 2012 and 2012 R2, and Windows 8.1.

Technorati Tags: ,

Wednesday, November 19, 2014

Yet Another PowerShell V5 Preview Build!

Microsoft has just released a updated build of PowerShell V5. I am particularly excited at the sheer pace of progress that is in evidence. Many features, particularly Desired State Configuration, are unfinished – works in progress. But what progress is being made!

To get the new build, go here: This link has the binaries for X64 and x86 systems plus one for what appears to be windows RT, which would be very cool. More on this when I get home to play on my RT Windows Surface device.

In the mean time: let the downloads begin!

Technorati Tags:

Tuesday, November 18, 2014

Chocolatey Lost, Chocolatey Found

A possibly obscure blog post title, but please read on. In PowerShell V5, Microsoft includes two cool modules: PowerShellGet and OneGet. PowerShell get is meant to find and manage PowerShell modules while OneGet is meant to find and manage 'packages'. This allows you to search for, download and install a substantial library of software and a library of PowerShell modules. This is a great way to leverage the community!

In the first drop of PowerShell V5, Get-Package got it's list of packages, inter alia, from Chocolatey a Windows friendly package provider. But unfortunately, the link to Chocolatey was removed in the latest V5 drop. I'm not sure why, although I'm sure there is a sensible explanation. And after all, this is a work in progress. But no matter why it's gone – I want it back. Turns out it's pretty easy to do that.

To setup Chocolatey as a package provider in the latest V5 drop, it's easy:

Register-PackageSource -Name chocolatey -Provider PSModule `
-Trusted –Location

Life is so simple when you know how! And once you do that, Find-Package returns a LOT more packages. SO happy hunting.

I am looking forward to more clarity around the differences between OneGet and PowerShellGet, particularly in how Enterprises are meant to make use of them. I can see several approaches that could be taken and hope to see more information as we progress towards the release of PowerShell V5.

Technorati Tags: ,

Friday, November 14, 2014

More 3rd Party PowerShell Goodness – this time from EMC

Another company, EMC, joins the ever lengthening list of 3rd party firms that are incorporating PowerShell, or a PowerShell interface into their products. If you go over to, you can see more details of the REST api and the cmdlets. Tags: ,

Wednesday, November 12, 2014

Microsoft takes .NET Open Source AND Cross-Platform

Microsoft has this week announced that it is providing the full .NET Server stack into Open Source. This includes ASP.NET, the .NET compiler, the .NET Core Runtime including the Framework and Libraries. This Microsoft says this should enable "developers to build with .NET across Windows, Mac or Linux".  For the details, see

And as if that were not enough Open Source goodness, Microsoft also announced Visual Studio Community 2013 – a free, fully featured version of Visual Studio including full extensibility.  Developers, or anyone else interested, can get started with Visual Studio Community 2013 HERE.


Technorati Tags: ,

Tuesday, November 11, 2014

CBT Nuggets Publish a Course for Microsoft Exam 70-337

I see that CBT Nuggets have just announced the release of their video training course Microsoft Lync Server 2013 70-337.

This course covers all the key parts of the syllabus for the 79-337 exam along with some exam preparation tips and a case study to help you further prepare.

I've not yet looked at the videos in the course, but CBT Nuggets material is usually of a good standard. I'd be interested in any feedback.

Monday, November 10, 2014

Writing Classes With PowerShell V5-Part 1

As I noted in previous blog posts (here and here) one of the many cool features coming with PowerShell V5 is the ability to develop Classes and Enums using PowerShell. in Monday's blog post, I showed how you could create an Enum, one important construct useful to creating classes.

Before I look at creating classes with PowerShell V5, it might make sense to go over what a class is and what creating them means. Many PowerShell users may be under familiar with the concepts involved.


The first thing to cover is classes. But what IS a class? A class is the definition of an object. In PowerShell everything you do relates to instances of objects that belong to some class. If you issue Get-ChildItem on the file system provider, you get zero, one, or more object occurrences, or instances, of either the System.Io.DirectoryInfo or System.Io.FileInfo classes. The number 42 is an object of the class System.Int32,

The Class defines the object (and occurrences of that object). Each class has a number of members. These include constructors, properties, and methods. The constructor is how you create a new class instance (creating a System.Io.Fileinfo object (instance) pointing to c:\ Properties are attributes of object are actions you can apply to the object, such as the name of a file. The  properties and methods of a class can be either static (belonging to the class) or dynamic (belonging to a class instance). This is a difference new PowerShell – see below for more on the difference.


A constructor is code that creates a new instance of the class. Constructors can take parameters that describe the object instance to be created. You can also overload constructors – creating more than one constructor with different sets of parameters. In the System.Net.Mail.MailMessage class, you can see 4 different constructors; one takes no parameters, while the other three take different sets of parameters, as you can see in MSDN. Each constructor creates an object instance (a mail message) but with different properties.


A properties is some attribute, either of the class itself or of an class instance. For example, the class [system.int32]. Each property has a type and this can be a value type (such as a string, or an integer) or a more complex object. An occurrence of the System.Net.Mail.MailMessage  class, for example, has a simple Priority property that takes a string (Low, High, Normal). It also has a property, To, which takes an object of the class System.Net.Mail.MailAddresss. The point here is that an object instance (a mail message) has a property (to) that itself is an object which has properties (e.g. DisplayName). Of course, that property too could be an object etc etc (although in the case of System.Net.MailAddress it doesn't!).


A method is some function that the class is capable of performing – either on an specific instance (a dynamic or instance method) or based on the class (a static method). Dynamic methods usually do something to the instance, while static methods do something that relates to class itself. The System.Int32 class, for example, has both static and instance based methods. Individual instances of the the System.Int32 class contain methods that convert the instance's value to another form (e.g. Boolean, or System.Int64, etc). Those dynamic methods work on the the instance of the class. The ToString method on instances of System.Int32 converts the value into a nicely formatted string, with the help of a CultureInfo object, like this:


Static Methods and Static Properties

One concept that many new-to-PowerShell folks find harder to understand is concept of static (vs dynamic of instance) methods and properties. A static method is a method that does not make use of a specific instance of the class. Instead it works by doing something class related. The System.Int32 class has a neat static method, Parse. The Parse method takes a string and either parses that string into a 32-bit number or raises an exception if it can't correctly parse the string.  The PowerShell Syntax to invoke a static method is: [<class name>]::methodname(<array of method parameters, or nothing>]. For example:


The System.Int32 class also has static properties or properties of the class. For example, MaxValue is the largest value that a System.Int32 can hold, while MinValue is the smallest value. In PowerShell, the Syntax for static properties is: [<class name>]::<propertyname>.

Here is an illustration of static methods and properties.


As you can see in this screen shot, the Parse method parses nicely the string '42' into a 32-bit integer. But the string ('4223452354234523452345235234'') could not be parsed and the Parse method threw an exception, the Overflow exception, as you can . You could use the Parse method inside a Try/Catch block to, for example, validate that some value passed in from a user is of the right form (i.e. a 32-bit integer) and catch and handle any exceptions to that validation.

A static property is some property related to the class not an instance. System.Int32 also also has some static properties, including MaxValue (the largest 32-bit integer), and MinValue (the smallest integer).

Creating Object Instances

PowerShell users typically create the object instance by using cmdlets (or functions, aka script cmdlets). Thus you use Get-ChildItem cmdlet and get instances of System.Io.FileInfo and/or System.Io.DirectoryInfo classes. In most cases, you process the objects instances by using cmdlets for example using Set-ADUser to update user information in Active Directory. Best practice says to use cmdlets where you can and only then drop down into lower level code.

There are three ways you can create new instances of an object (class). The first is via a cmdlet, but in the absence of cmdlets/functions, then you can either  use a static method of the class or use the New-Object cmdlet and specify the class of which you wish to create an instance. One example is the  class System.Guid, which it defines and manages guids. There are no cmdlets to manage this object type. If there had been, then you would most likely have a New-Guid cmdlet to create a new guid. Since that cmdlet does not exist, to create a new guid, you use a static method, like this:



The other way to create new instances is to use the New-Object cmdlet. This cmdlet uses the class constructors available and matches the parameters you specify with the various constructors. For example, you can create a new instance of the System.Mail.Mailmessage class using one of four constructors. To Create an empty mail message, you would do this:

# Create an empty massage
$EmptyMsg = New-Object System.Net.Mail.Mailmessage

# Create a message from and to
$To= ''
$MailMsg = New-Object System.Net.Mail.MailMessage $Fm, $To

So What?

In Windows, Microsoft and other vendors have provided thousands of cmdlets, but as yet, there is not full coverage of all the objects in the .NET framework. Thus if you need to use objects of those types (belonging to some less well known .NET Class). A good example is localisation. If you want to present a price in say US$, Norwegian crowns and UK Pound sterling. Assuming you know how to use the ServiceEx web services, the script looks like this:

# Get Curency conversion rates
$From = 'GBP'
$Tous  = 'USD'
$Tono  = 'NOK'
$CurrencyConvertor = New-WebServiceProxy ""
$USrate = $currencyConvertor.ConversionRate($from,$tous)
$NOrate = $currencyConvertor.ConversionRate($from,$tono)

# Calculate price
$priceUK = 12345.669
$priceNO = $PriceUK * $NOrate
$priceUS = $PriceUK * $USrate

# Convert to nice strings
$usinfo = [System.Globalization.CultureInfo]::CreateSpecificCulture('en-us')
$Noinfo = [System.Globalization.CultureInfo]::CreateSpecificCulture('no-nb')

"The UK price is:  $($PriceUK.tostring('c'))"
"The NO price is:  $($priceNO.tostring('c',$noinfo))"
"The US price is:  $($priceUS.tostring('c',$usinfo))"

And the output looks like this:


Pretty easy, when you know how to manage .NET classes and can use XML web services. The .NET framework contains a wealth of classes that have value, depending what you are working with. Being able to just reach out and grab them, when there are no cmdlets, provides you with a lot of power. Plus, if you understand what is going on with objects, troubleshooting scripts becomes easier – if nothing else, the error messages may make a bit more sense.

In the next article I'll look at actually combining the information presented here with how to create these things using PowerShell V5.


PowerShell Desired State Configuration – More Resources

As noted on the PowerShell Team Blog,  Microsoft has published many new experimental resources for Windows PowerShell in the form of the DSC Resource Kit Wave 8. This latest release brings the number of rerources available to over ONE HUNDRED (138 for those of you who are counting – a 53% increase from the earlier release).

The sheer number of resoures now available is staggering – and I expect the pace of delivery here to continue as the team approach RTM for PowerShell 5 and Windows 10.

As Clifton Chenier sings: Laissez les bon temps roulez.

Tuesday, November 04, 2014

Writing Better PowerShell Scripts with ISESteroids

I’ve been working a lot recently with a nice package called ISESteroids.  As an ISE user, the name got my attention before anything! As the name kind of indicates, the package improves PowerShell’s Integrated Scripting Environment.

So what IS ISESteroids? ISESteroids is a commercial module that you add into the ISE converting the ISE from a good development tool into a much better one. My view is simple: ISESteroids makes me able to write better code, more legible code quickly and easily.

Installing ISESteroids is trivial. Just download the package (it comes as an archive), unblock the archive (after download, right click the archive, select properties then select unblock). Then create an ISESteroids folder under your modules folder, and copy the contents of the archive there.  It should look something like this:


Once the module is in place, you just need to add a line to your ISE Profile:


The first time you run this cmdlet, you have to accept the license agreement, but after a second or two, you can start to experience the added value ISESteroids gives you.

But what is that, I hear you say? There were several things I noticed after first installing ISESteroids. The first of which is that the whole UI changes. The top part of the ISE has the original tool bar expanded and with a second pull down tool bar with more tools. Plus the tool bar at the bottom of the ISE window has been enhanced and now includes a community information feed. This bottom tool bar also has a REALLY nice feature I’ve always wanted – the ability to just take the last command typed at the console and put it into the edit tab. 

Here’s a before and after look (without, then with ISE Steroids installed and running)




The community feed at the bottom is a very nice touch, although all the new tools was surprising (in a nice way). After using it a bit, on a  system without ISESteroids, the ISE felt somewhat more primitive (not unlike using PowerShell V2’s ISE today!).

All those extra tools and a lot of the features in ISESteroids are focused on helping you to write better PowerShell code and streamlining that process as much as you can. In short: good practice built in, and more, more, more automation of the code development process.

Once I started writing scripts with ISESteroids enabled  I saw some changes in the ISE’s Edit pane. Some language elements were marked with a ‘squiggle’ underneath. And the edit pane itself has been reformatted with some new elements. Here’s an example of a very simple script


Just above the number 1 and 2 are two things ISESteroids ‘complains’ about. The first thing is that I used an alias (LS) instead of the full cmdlet name (Get-ChildItem); the second thing is that I am using a string but it is delimited with a double quote, not a single quote. Single quotes, unless you are including variable expansion, are less performant. The third cool thing shown here is that ISESteroids keeps track of functions and shows you how often they are referenced. You can see here the FOO function was referenced just once just once. The final thing to notice is the new search bar – just type a function name, and PowerShell, jumps to that function definition in the code. Great for when you need to update a function definition you call a dozen times in your script!

ISESteroids also makes it easy to get rid of those squiggles. To fix the two issues above, you just hover over the bottom bar in the ISE windows and ISESteroids pops up messages like:



This makes it really simple to fix issues like this. I would have liked to have been able to just right click over the squiggle and select the fix from there – but the bottom of the window works too.

As you delve into using the ISE, just about every menu and tool bar is expanded. To name a few:

  • The File Menu now has an sub menu to open your profile files (you can open both console and ISE profiles).
  • The file Menu also has a Print menu item.
  • The Tools Menu now has a couple of new tools and options.
  • The Add-ons menu has new menu items for moving tool panes around the ISE UI. Useful if you are using some of the tools!

This is just scratching the surface. I’ve got a bit of a coding project coming up and so will be using ISESteroids more heavily and will gladly provide more feedback.

For more information about the product, see the documentation:

One final thing – ISESteroids is not a free product. Single use is €99 although there are volume discounts. BUT because the author is such a fan of the community, he has created what they call their ‘Helping Hands Programme’ – in effect they offer free NFR (not for resale) personal ISESteroids 2.0 Enterprise license in exchange for 3-5 hours of your work, helping them to  make ISESteroids better known, and better documented. A very generous offer!

In summary, ISESteroids is a tool that adds value to the PowerShell ISE and helps you to write  better scripts. If you are writing scripts and other PowerShell related artifacts as a key part of your job then this product is certainly worth the money.

Technorati Tags: ,,