Author Archive

Iron Scripter 2019 Prequel 1

The Chairman has arranged for another prequel challenge to prepare you for the upcoming Iron Scripter battle. A suggested solution will eventually be provided. In the mean time, see what you can do with this problem.

Using a set of Windows features, like Windows Internal Database, on a baseline server, configure a target server to match. Remove features that aren’t installed on the baseline and install features that are missing on the target. You can configure the source server with any combination of Windows features you’d like. Your goal is to copy the feature set to a target server.

This does not need to be a one-liner or even a function, although you are welcome to do so. What commands would you run in a PowerShell remoting session to accomplish this task? While it is true you could use a technology like Desired State Configuration, see if you can accomplish this task through traditional PowerShell scripting techniques.

Jeffery Hicks

A Warm-Up Solution

To prepare you for the upcoming battle you were offered a warm-up challenge. The basic challenge was to take the output from Get-Counter and pipe it through a command you created to output more user-friendly output. As a bonus you were also challenged  to display the default results as a table. As with almost everything in the PowerShell world there are options and alternatives.Today the Chairman shares one possible solution and some of the reasoning behind it. This solution is not necessarily better than yours but rather should be something you can learn from.


Because this is going to be a stand-alone function it has to live in .ps1 file. You might have to consider who might be using this script. What operating system or version of PowerShell will they be running? The suggested solution requires that the user be running PowerShell 5.1 or later, even though technically you could get by with earlier versions. The script is also requiring the Microsoft.PowerShell.Diagnostics module.

This is the module that contains the Get-Counter cmdlet which you need in order for you command to work. Requiring it also has the added benefit of loading it into your PowerShell session if it is not running. This is important for parameters definitions.


The only parameter the sample solution requires is one for the performance counter samples. This should be mandatory and come in from the pipeline.

It is often useful to indicate the object type which we’ve done here. Note that without the requirement for the diagnostics module, PowerShell throws an error when loading this function because the type has not been loaded yet. But using the requires statement imports the module if not already loaded which adds the necessary type.


We were able to see a few people’s efforts on this challenge. One major variance was in naming the function. There is no reason not use a verb from the list created by Get-Verb. There are plenty of choices that should work such as Optimize, Format, or Convert. If you wanted to use a non-standard verb, you could create it as an alias.

There is nothing wrong with providing an alias that someone can use at the command prompt to run your code.

Creating Custom Objects

The core of this challenge was restructuring the output from Get-Counter into something easier to read and consume. You would piped Get-Counter to Get-Member to discover property names. In the work we saw many of you figured out that you needed to process the CounterSamples property. Parsing the values is where you can get creative. You could use regular expression patterns to get the computername and other values. In the sample solution we took the easy way and split the Path property into an array.

One thing we noticed using this technique was an extra blank element. Piping the array to Where-Object is telling PowerShell to only keep objects where something exists. If there is a value then $_ will implicitly be True.

Because the array is consistent, it is easy to generate a custom object.

We’ll come back to the use of PSTypename in a bit.

The Result

Here is our sample solution in action.

Converting Get-Counter samples

The function can consume counter information and write objects to the pipeline.

Consuming Converted Counters


The formatting challenge was to take the default output which is a list and present it as a table. In other words, the output of your command should display results in a table, not a list. In order to achieve this you need to create a format.ps1xml file using the object’s typename. In the sample solution we are adding a PSTypename property.

Viewing the custom type name

You might also have used a PowerShell class or created a custom object and inserted a new typename.

Regardless of technique you now need to create a custom xml file. Often the best thing to do is fine an object type in an existing file $pshome\DotNetTypes.format.ps1xml that is close the output you want, copy and paste it into a new file and modify to fit your needs. This is admittedly a tedious process. Another option is to use the New-PSFormatXML command that is part of the PSScriptTools module which you can install from the PowerShell gallery. This functions will create a format.ps1xml file based on an object.

You only need to give it a single instance of the object. Here is what the result can look like.

You can modify the file as you need to changing column headings or creating custom values. Here is the final format.ps1xml file we came up with.

Our solution creates a default view grouped by a custom scriptblock that shows the computername and timestamp. It also creates a second view called ‘TimeStamp’. This comes in handy when processing counters over a period of time. In order to use this file, it has to be imported into PowerShell. We put the file in the same folder as the ps1 file and add this command:

One thing to point out if you are new to working with format files is that because there is often a bit of trial and error you may need to start a new PowerShell session to load each revision. Here is the new result.

Formatted Output

When processing multiple computers you need to sort on the Computername property.

Processing multiple computers

The other custom view we defined is useful when monitoring samples over a period of time.

Formatting results over time

The Final Result

Here is the complete script file of our sample solution.

Remember, these warm-up exercises and preludes aren’t really a competition. They are designed to get you ready for the Iron Scripter event at the PowerShell+DevOps Global Summit and hopefully teach you something new along the way.

Stay tuned for the next prelude exercise.

Jeffery Hicks

Preparing for Battle

Over the course of the next several weeks there will be even more preparatory challenges. There is not necessarily any right answer as long as it meets the criteria of your chosen faction and produces the desired result. As you prepare yourself, you are encouraged to share and discuss your work with others in the community and in your faction. Use whatever social media platform and online resources that you prefer.

You might create a public GitHub repository and spread the word via Twitter. Or you might post your work on your own blog and invite the world to marvel at your work.

The choice is yours.

Jeffery Hicks

Iron Scripter 2019 is Coming

It is a new year and the Chairman is preparing a fiendish new challenge for this year’s PowerShell + DevOps Summit. That time is rapidly. If you partook in last year’s battle then you understand what is expected of you. if you have not already done so align yourself with the faction that best suits you.

In order to prepare you for battle the Chairman has prepared a series of preparatory challenges. It is a foolish warrior who goes into battle unprepared. Just sayin’.

To prepare you for the upcoming battle, see what you can create according to the guiding principles of your faction that solves the following problem. The bottom line is that your solution should work.

The Challenge

The Get-Counter cmdlet is very useful in obtaining performance counter information. Unfortunately, the Chairman feels the output is less than friendly. Especially if you wish to consume the output such as with additional filtering, exporting to a json file or writing to a database.

Your challenge is to create a PowerShell function that takes the output from Get-Counter and transforms it into a more user friendly object. Each counter sample should be a separate object with these properties:

  • Timestamp
  • Computername
  • CounterSet
  • Counter
  • Value

You are free to use whatever property names you want as long as it is clear what the values represent. A sample might look like this:

Advanced Challenge

If you want to really challenge yourself, define a custom type and format view that gives you a result like this:

All the information you need to know is included in this post. The Chairman will share a possible solution within the week. Good Luck and Good Scripting!

Jeffery Hicks

Iron Scripter 2018 prelude 4

This is your fourth and last prelude Iron Scripter Prelude 4

Success is the preludes may gain insights into the main challenge that will be advantageous to your faction.

Jeffery Hicks

Iron Scripter 2018 prelude 3


Jeffery Hicks

Iron Scripter 2018 prelude 2

This is your second prelude for Iron Scripter 2018 Iron Scripter Prelude 2

Success will bring favour to your faction. Failure on the other hand ….

Jeffery Hicks

Iron Scripter 2018 prelude 1

This is the first prelude to Iron Scripter 2018. Iron Scripter Prelude 1

Successful will gain favour for your faction

Jeffery Hicks