ss_hqrmreview_codeofconductgood

Tips for HQRM DSC Resources

I’ve spent a fair amount of time recently working on getting some of my DSC Resources (SystemLocaleDsc, WSManDsc, iSCSIDsc and FSRMDsc) accepted into the Microsoft DSC Community Resource Kit. Some are nearly there (SystemLocaleDsc and WSManDsc), whereas others have a way to go yet.

I’ve had one resource already accepted (xDFS) into the DSC Community Resource kit, but this was before the High Quality Resource Module (HQRM) guidelines became available. The HQRM guidelines are a set of standards that DSC modules must meet and maintain to be considered a High Quality Resource Module. Once they meet these requirements they may be eligible to have the ‘x’ moniker removed with ‘Dsc‘ being added to the name.

More information: If you want to read a bit more about the HQRM standards, you can find the HQRM Guidelines here.

Any modules being submitted for inclusion into the DSC Community Resource kit will be expected to meet the HQRM standards. The process of acceptance requires three reviewers from the Microsoft DSC team to review the module.

I thought it might be helpful to anyone else who might want to submit a DSC Resource into the DSC Community Resource kit to get a list of issues the reviewers found with my submissions. This might allow you to fix up your modules before the review process – which will help the reviewers out (they hate having to be critical of your code as much as you do). This enables the submission process to go much faster as well.

More information: If you want to read more about the submission process, you can find the documentation here.

I’ll keep this post updated with any new issues the reviewers pick up. Feel free to ask for clarifications on the issues.

So here is my list of what I have done wrong (so far):

Missing Get-Help Documentation

Every function (public or private) within the DSC resource module must contain a standard help block containing at least a .SYNOPSIS and .PARAMETER block:

This will get rejected:

ss_hqrmreview_gethelpbad

This is good:

ss_hqrmreview_gethelpgood

Examples Missing Explanation

All examples in the Examples folder and the Readme.md must contain an explanation of what the example will do.

This is bad:

ss_hqrmreview_exampledescriptionbad

This is good:

ss_hqrmreview_exampledescriptiongood

Old or Incorrect Unit/Integration Test Headers

There is a standard method of unit and integration testing DSC Resources. Your DSC resources should use these methods where ever possible. Any tests should therefore be based on the latest unit test templates and integration test templates. You should therefore ensure your tests are based on the latest practices and contain the latest header.

This is probably the hardest thing to get right if you’re not paying close attention to the current DSC community best practices around testing. So feel free to ask me for help.

This is bad:

ss_hqrmreview_testheaderbad

This is good:

ss_hqrmreview_testheadergood

Incorrect Capitalization of Local Variables

Local variables must start with a lower case letter. I needed to correct this on several occasions.

Note: this is for local variables. Parameter names should start with Uppercase.

This is bad:

ss_hqrmreview_localparameterbad

This is good:

ss_hqrmreview_localparametergood

Spaces around = in Localization Files

In any localization files you should make sure there is a space on either side of the = sign. This greatly improves message readability.

This is bad:

ss_hqrmreview_localizationbad.png

This is good:

ss_hqrmreview_localizationgood

Missing code of Conduct in Readme.md

All modules that are part of the DSC Resource Kit must contain this message in the Readme.md:

This project has adopted the Microsoft Open Source Code of Conduct.
For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

This is bad:

ss_hqrmreview_codeofconductbad

This is good:

ss_hqrmreview_codeofconductgood

Missing Localization file indent

All strings in localization files should be indented.

This is bad:

ss_hqrmreview_localizationdatabad

This is good:

ss_hqrmreview_localizationdatagood

 

Final Words

There were some other issues raised which I will also document, however I am still in discussion with the DSC team over the best methods to use to solve the issues (specifically the use of InModuleScope in unit tests).

The main thing you can do to help speed this process up and reduce the load on the reviewers however is to implement all the best practices and guidelines listed.

I hope this helps someone out there.

fi_brokencontainers

Failed to Start Docker Service on Windows 10 AE

So, pretty much the first thing I did when the Windows 10 Anniversary Edition was installed onto my primary development machine was to installer the Windows Container Service and Docker on it.

I used the Windows Containers on Windows 10 Quick start guide to perform the installation. This is the same method I’d been using on my secondary development machine (running Insider Preview builds) since it was first available in build 14372.

Note: The Windows Containers on Windows 10 Quick Start guide doesn’t mention the Anniversary Edition specifically, but the method still works.

Unfortunately though, this time it didn’t work. When I attempted to start the Docker Service I received the error:

start-service : Failed to start service 'Docker Engine (docker)'.

ss_docker_startserviceerror

So, after a bit of digging around I found the following error in the Windows Event Log in the Application logs:

ss_docker_startserviceerror_eventlog

Basically what this was telling me was that the Docker Daemon couldn’t create the new virtual network adapter that it needed – because it already existed. So a quick run of Get-NetAdapter and I found that the docker adapter “vEthernet (HNS Internal)” already existed:

ss_docker_startserviceerror_eventlog

So what I needed to do was uninstall this adapter so that the Docker Service could recreate it. I’m not actually aware of a command line method of doing (except for using DevCon) so I had to resort to using Device Manager:

ss_docker_startservice_uninstalldevice

You’ll need to use the output of the Get-NetAdapter to find he right adapter uninstall. Once it has been uninstalled you should be able to start the service again:

ss_docker_startservice_dockerstarts

This time the service should start successfully. A quick call to docker ps shows that the container service is indeed working. So now I can get onto the process pulling down the base container images.

Hopefully if anyone else runs into this problem in Windows 10 AE this will help them resolve it.

 

 

 

fi_useproxy

Allow PowerShell to Traverse a Secure Proxy

One of the first things I like to do when setting up my development machine in a new environment is to update PowerShell help with the update-help cmdlet. After that, I will then go and download a slew of modules from the PowerShell Gallery.

However, recently I needed to set up my development machine on an environment that is behind an internet proxy that requires authentication. This meant that a lot of PowerShell cmdlets can’t be used because they don’t have support for traversing a proxy – or at least, not one that requires authentication. Take the aforementioned update-help and install-module cmdlets – I just couldn’t do with out these.

So I set about trying to find a way around this. So after lots of googling and trial and error (and also getting my Active Directory account locked out on more than one occasion) I came up with a solution.

Basically it requires using the NETSH command to configure the proxy settings and then configure the web client with my proxy credentials (which were AD integrated):

The code I needed to traverse the proxy could then be executed. Once it has completed the task using the proxy I would then reset it back to the default state (using settings from internet explorer):

After using this a bit I thought it would be great to turn it into a function that I could just call, passing a script block that I wanted to be able to traverse the proxy with. So I came up with this:

To use this script, simply save it as a PS1 file (e.g. Use-Proxy.ps1), customizing the default proxy URL if you like and then dot source the file. Once it has been dot sourced it can be called, optionally passing the URL of the proxy server and credentials to use to authenticate to it:

If you don’t pass any credentials, you will be prompted to enter them. I also added some code into this function so that you can specify a global variable containing the credentials to use to traverse the proxy. This can save on lots of typing, but might be frowned upon by your security team.

Finally, I also added the proxy reset code into the finally block of a trycatch to ensure that if the code in the script block throws an error the proxy will be reset. In my case I also loaded this function into a PowerShell module that can be distributed to other team members.

Happy proxy traversing!

 

 

 

ss_verticalruler_visualstudiocodesettingsrulers

VisualStudio and ISE Steroids Vertical Guides

To make it easier for reviewers and other programmers to read PowerShell code it is recommended that lines of PowerShell code don’t exceed 100 characters. If you run past this limit you should usually split the line using a backtick (`). I also find that this limit prompts me to rethink my code logic if the line gets too long. Besides, no one wants to have to scroll several pages horizontally to be able to read your whole line of code.

However, one of the most common issues I run into when reviewing (or writing my own) PowerShell DSC resources is going over the 100 character limit. For your own projects you’re most welcome to use any styles that you want (although I’d still recommend this one for the reasons above). However, if you’re going to commit this code to the PowerShell DSC community resources you’ll need to ensure your code meets this requirement, otherwise reviewers will likely ask you change it.

But there is an easy way to help identify this problem if you’re using Visual Studio Code or PowerShell ISE Steroids: Setup a vertical guide/ruler at 100 characters.

ss_verticalruler_visualstudiocode

A nice easy to see vertical ruler/guide tells us when our lines get too long… oh dear this line is too long.

To Set up a Vertical Ruler in Visual Studio Code

  1. Select User Settings (you can use Workspace Settings if you want) from Preferences in the File menu:
    ss_verticalruler_visualstudiocodemenu
  2. Your user settings.json file will load on the right, with the Default Settings on the left:
    ss_verticalruler_visualstudiocodesettings.png
  3. Add the following line to your settings.json file in between the braces:
    "editor.rulers": [100]

    ss_verticalruler_visualstudiocodesettingsrulers

  4. Save the file and restart Visual Studio Code.

To Set up a Vertical Ruler in ISE Steroids

  1. Select Show Secondary Toolbar from the View menu.ss_verticalruler_isesteroidsmenu
  2. Click the Vertical Guides button and select Global Guide…ss_verticalruler_isesteroidsverticalguidebutton
  3. Enter 100 in the input box and press enter.

    ss_verticalruler_isesteroidsruleradded

    The vertical guide is added – better fix that long line!

That is all there is to using vertical guides. Having them setup if you’re planning on committing code to a community project might save you some extra commits and help the community reviewers merge your code faster.

Happy coding!

 

fi_dsc_allthethings
ss_azuresmt_nanoserverupdatecomplete

Bulk Updating Nano Servers using PowerShell and CIM

Introduction

Feel free to skip this introduction and jump down to the Updating via CIM section to see the actual update process.

Yesterday, I decided to connect up my Windows Server 2016 TP5 Active Directory lab up to the new Azure Server Management Tools. This was mainly to look at the experience with managing Nano Server using these new Azure based tools.

ss_azuresmt_nanoserverupdate

The interface is very slick, as you’d expect from anything managed within the new Azure Portal.

I did run into a minor glitch when installing updates, but the team over at Azure (major thanks @BrendanPower) had the problem identified and solved within 24 hours (and was rolled out while I was writing this post). Also remember, this is a Azure Preview Feature updating a Windows Server 2016 Technical Preview 5 operating system, so you’d expect a few glitches. I did a lot of experimenting with these new features and this is the only thing I ran into. I’m still extremely impressed with the responsiveness of the team over there in Redmond.

In fact while I was writing this very post I was contacted to let me know the fix had gone in to production and it worked perfectly:

ss_azuresmt_nanoserverupdatecomplete

Anyway, this post isn’t about how to configure an Azure Server Management Tools Gateway (it is extremely easy, but if anyone would be interested in a video let me know and I’ll make one), it is about updating Nano Servers using CIM and by extension updating lots of servers in one go.

Updating via CIM

In Windows Nano Server TP4 Microsoft included CIM cmdlets. This enabled us to use the root/Microsoft/Windows/WindowsUpdate CIM Namespace to use Windows Update to install updates on a Nano Server. After a bit of searching around I found this blog post covering the process.

However, I have lots of Nano Servers and updating them one at a time would be a real pain. So I decided to write a short PowerShell snippet to update all of them at once. This snippet should actually work with any Windows Server 2016 TP4 (or greater) version.

This snippet contains a simple function that takes three parameters:

  • Credential – this is the credentials to use to connect to the Nano Server and update it. If not passed you will be presented with a login dialog asking for them. It is assumed that all servers being updated use the same credentials.
  • Servers – this is the array of server names to apply updates to.
  • Install – setting this optional switch will cause the updates to be installed. If it is not set you will just be told for each server the list of updates that are required.
  • Restart – this optional switch will cause the servers to automatically restart after updates are installed (even if they don’t technically need a restart). Only set this switch if the Install switch is set.

For example, calling the function with:

Get-AvailableUpdates `
    -Servers 'SA-NANO1','SA-NANO2','SA-NANO3','SA-NANO4','SA-NANO5','SA-NANO6','SA-NANO7','SA-NANO8'

Would show the update status of the eight listed Nano Servers and show any updates available to be installed:

ss_updatenano_updatesavailable

However, adding an -install parameter to the call:

Get-AvailableUpdates `
    -Servers 'SA-NANO1','SA-NANO2','SA-NANO3','SA-NANO4','SA-NANO5','SA-NANO6','SA-NANO7','SA-NANO8' `
    -Install

Will cause all available updates to be installed onto the listed Nano Servers:

ss_updatenano_updatesinstalled

You may still need to restart these servers after the updates are installed. If you run the function again without restarting the servers first you will be told the updates still need to be installed. If you want the servers to automatically be restarted, add a -restart parameter:

Get-AvailableUpdates `
    -Servers 'SA-NANO1','SA-NANO2','SA-NANO3','SA-NANO4','SA-NANO5','SA-NANO6','SA-NANO7','SA-NANO8' `
    -Install `
    -Restart

Like this:

ss_updatenano_updatesinstalledrestart

This is even more useful when you consider that you can update standard (Core and GUI) Windows Server 2016 installations like this as well. This might also work on earlier versions of Windows Server (2012, 2012 R2) as well, but I don’t have time to try this out.

Edit: 21 May 2016 – I tested this on Windows Server 2012 R2, but it does not work because the required CIM classes are not available on that version Operating System.

Note: I really haven’t put much work into error checking or reporting on this process, so if you run into any errors (servers not online, bad credentials etc) then they might not be handled elegantly. This code is really an example of what can be easily done.

This function would be a definite candidate for a PowerShell Workflow – allowing complete parallelization of the process.

I hope this is useful and have a great weekend!

 

cDFS is dead, long live xDFS

The xDFS DSC resource module has been officially released to the PowerShell Gallery thanks to the awesome review efforts of the Microsoft PowerShell Team. The cDFS DSC Resource has now been unlisted from the PowerShell Gallery. So now is the time to update any DSC configuration scripts to use xDFS.

ss_xdfs_releasepsgallery

Important: There were some minor changes to xDFS when it was converted from cDFS. For information on what you’ll need to change to convert to xDFS see my earlier post.