Use PowerShell DSC to Install DSC Resources

IMPORTANT: This post was authored in August 2014, and is out of date. At this point, you should be installing PowerShell DSC resources from the PowerShell Gallery, using the PowerShellGet\Install-Module command.

Introduction

A lot of the functionality provided by Microsoft PowerShell Desired State Configuration (DSC) comes, not from the core product, but from the DSC Resources that are provided by Microsoft and the community. When you spin up a new Windows operating system, whether a physical machine, local virtual machine, or a Microsoft Azure virtual machine, you start out with a pretty barebones set of DSC resources. Those resources are listed here:

  • File
  • Archive
  • Environment
  • Group
  • Log
  • Package
  • Registry
  • Script
  • Service
  • User
  • WindowsFeature
  • WindowsProcess

Unfortunately, most people are going to need more capabilities than what is offered out of the box. To that end, Microsoft has been regularly providing “waves” of DSC resources to manage a variety of different applications. As of this article’s writing, the latest wave of DSC resources from Microsoft was “DSC Wave 6,” published on August 21, 2014. During the remainder of this article, our goal is to make sure that these additional DSC Resources are installed on our systems, in an automated fashion!

Installing DSC Resource Wave 6 using DSC

Now that we understand why we need to install these DSC resources, let’s go ahead and take a look at how to achieve that, using DSC itself. You might think to yourself: “hey, Microsoft provides the xRemoteFile DSC resource, that lets you download the ZIP archive. Then I could use the Archive resource to extract it!” Well, you are definitely half way on to something there, but the problem becomes a chicken-egg scenario, where the xRemoteFile DSC resource is only available once you’ve already installed the DSC Wave 6 resources.

Since xRemoteFile is not available to us on a barebones Windows 8.1/2012 R2 install, we will have to use the fallback option, the Script Resource. While the Script Resource isn’t necessarily ideal in most cases, it provides a massive benefit of allowing you to customize DSC for virtually any scenario, without having to know how to develop a custom DSC resource! In our case, we will use the Script Resource to download the DSC Wave 6 ZIP archive. The script code inside of the Script Resource will use the out-of-box Invoke-WebRequest PowerShell command to download the DSC Wave 6 ZIP file locally onto the filesystem. The properties of the Script Resource that we will use are:

  • GetScript = The script code that retrieves the properties describing the Script Resource
  • SetScript = The script code that brings the system into compliance. In this case, it will download the DSC Wave 6 ZIP archive from Microsoft TechNet, using the Invoke-WebRequest command
  • TestScript = The script code that tests if the system is in compliance or not. In this case, it will ensure that the DSC Wave 6 file exists in the Windows temp directory

Once the DSC Wave 6 ZIP archive has been downloaded, using our Script Resource, we can use the out-of-box Archive Resource to extract the DSC Wave 6 Resources to the appropriate folder. The Archive Resource will use the DependsOn property to create a dependency pointing to the Script Resource. That way, we ensure that the ZIP archive is downloaded by the Script Resource first, and then be extracted by the Archive Resource. When extracting the DSC Resource, the folder where any additional DSC resources should go is: $env:ProgramFiles\WindowsPowerShell\Modules. There are just a few key properties on the Archive Resource, to use its functionality:

  • Path = The local filesystem path to the ZIP archive that will be extracted
  • Destination = The local filesystem path where the ZIP archive will be extracted to
  • Ensure = Set this to ‘Present’ to extract the archive
  • DependsOn = Used to chain the Archive Resource to the Script Resource that downloads the ZIP archive

Creating the DSC Configuration

Now that we have discussed the types of DSC Resources that we will use to install the DSC Wave 6, let’s build the configuration itself. As with any DSC configuration, we need a configuration block.

configuration DSCWave {
}

Script Resource

Earlier, we talked about using a DSC Script Resource to download the DSC Wave 6 ZIP archive. Let’s put that into our DSC configuration block.

configuration DSCWave {
    Script DSCWave {
        GetScript = { @{ Result = (Test-Path -Path "$env:windir\temp\DSC Resource Kit Wave 6 08212014.zip"); } };
        SetScript = {
            $Uri = 'http://gallery.technet.microsoft.com/DSC-Resource-Kit-All-c449312d/file/124120/1/DSC%20Resource%20Kit%20Wave%206%2008212014.zip';
            $OutFile = "$env:windir\temp\DSC Resource Kit Wave 6 08212014.zip";
            Invoke-WebRequest -Uri $Uri -OutFile $OutFile;
            Unblock-File -Path $OutFile;
        };
        TestScript = { Test-Path -Path "$env:windir\temp\DSC Resource Kit Wave 6 08212014.zip"; }
    }
}

Archive Resource

For the final part of constructing our configuration block, we need to extract the DSC Wave 6 ZIP archive into the $env:ProgramFiles\WindowsPowerShell\Modules directory. Let’s add the DSC Archive Resource to our configuration block.

configuration DSCWave {
Archive DSCWave {
DependsOn = '[Script]DSCWave';
Ensure = 'Present';
Path = "$env:windirtempDSC Resource Kit Wave 6 08212014.zip";
Destination = "$env:ProgramFilesWindowsPowerShellModules";
}

Script DSCWave {
GetScript = { @{ Result = (Test-Path -Path "$env:windirtempDSC Resource Kit Wave 6 08212014.zip"); } };
SetScript = {
$Uri = 'http://gallery.technet.microsoft.com/DSC-Resource-Kit-All-c449312d/file/124120/1/DSC%20Resource%20Kit%20Wave%206%2008212014.zip';
$OutFile = "$env:windirtempDSC Resource Kit Wave 6 08212014.zip";
Invoke-WebRequest -Uri $Uri -OutFile $OutFile;
Unblock-File -Path $OutFile;
};
TestScript = { Test-Path -Path "$env:windirtempDSC Resource Kit Wave 6 08212014.zip"; }
}
}

Now our configuration block is completed, and we are ready to deploy it! As with any DSC configuration, you will need to call the configuration, by the name that you gave it. In this case, our configuration name is DSCWave. We will also specify the -OutputPath parameter, to compile the MOF to a specific location on the filesystem.

DSCWave -OutputPath c:\dsc\DSCWave;
DSC Archive Resource
DSC Archive Resource

Once the MOF has been compiled, we can then deploy the DSC configuration to the local system, using Start-DscConfiguration! We will specify the -Path parameter, to point it at our local MOF file, and add the -Wait and -Verbose switch parameters to ensure that it runs synchronously, and provides debugging output.

Start-DscConfiguration -Path c:dscDSCWave -Wait -Verbose;

After running these commands, you should see some blue text, which is the verbose output stream, indicating that the DSC Wave 6 Archive was successfully unpacked (unzipped) to the specified location. Once this has been completed, you are ready to start building DSC configurations using the DSC Resources that are included with DSC Wave 6! Happy configuring!

YouTube Video

I’ve developed a YouTube video that demonstrates how to use this PowerShell DSC configuration to deploy the Microsoft PowerShell DSC Resource Kit to Microsoft Azure virtual machines, using the Azure VM DSC extension. Additionally, the code (and documentation) that is used in the video is available for download from this GitHub repository.