Invoke-DscBuild | Test-Lab

Posts in this series

  1. Test-HomeLab -InputObject ‘The Plan’
  2. Get-Posh-Git | Test-Lab
  3. Get-DSCFramework | Test-Lab
  4. Invoke-DscBuild | Test-Lab
  5. Test-Lab | Update-GitHub

In the last post we forked a copy of the DSC tools and cloned a copy locally

Today I’m going to get the example configuration working.

Now looking at the under examples seems straightforward, but I know for a fact that it’s missing a few steps.

This folder contains some very basic examples of what a DSC configurationData folder structure, script, and call to Invoke-DscBuild might look like.  If you want to execute SampleBuild.ps1, there are a few dependencies you need to set up ahead of time:

– You must install all of the DSC tooling modules from this repository into your PSModulePath (typically into C:\Program Files\WindowsPowerShell\Modules\)
– You must also copy the Tooling\Examples\SampleConfiguration folder to the PSModulePath.
– You must copy [Pester]( (version 3.0.0 or later) and [ProtectedData]( (version 2.1 or later) into the PSModulePath.
– You should create a DSC_Resources folder in the same directory as SampleBuild.ps1 and DSC_Configuration.  Copy the following modules into that DSC_Resources folder:
– [StackExchangeResources](
– [cWebAdministration](
– [cSmbShare](

Once these dependencies are set up, you can execute SampleBuild.ps1.  It will run tests against the 3 modules in your DSC_Resources folder, compile your configuration into MOF documents, produce zip files for the resource modules, generate checksums for everything and copy them into C:\Program Files\WindowsPowerShell\DscService\

Looks like we are going to need a few more DSC resources. I’m going to go and fork/clone them just like before. (don’t forget to update the URL’s to match your own fork. )

# Download required files via Git
#Next line not needed if you were following along with my last blog
git clone c:\GitHub\PshOrgDSC --branch development
git clone c:\GitHub\StackExchangeResources
git clone c:\GitHub\cWebAdministration
git clone c:\GitHub\cSmbShare 
git clone c:\GitHub\Pester
git clone c:\GitHub\ProtectedData

Now I’m going to create some folder structure and place all the files where they need to go

#Create Folders
mkdir c:\DSC
mkdir C:\DSC\BuldOutput
mkdir C:\DSC\DSC_Configuration
mkdir C:\DSC\DSC_Resources
mkdir C:\DSC\DSC_Script
mkdir C:\DSC\DSC_Tooling

#Copy Files
copy C:\github\PshOrgDSC\Tooling\* C:\DSC\DSC_Tooling\ -Exclude 'examples', '' -Recurse
copy C:\github\PshOrgDSC\Tooling\* 'C:\Program Files\WindowsPowerShell\Modules' -Exclude 'examples', '' -Recurse
copy C:\github\* 'C:\Program Files\WindowsPowerShell\Modules' -Include 'Pester','ProtectedData' -Recurse 
copy C:\github\* C:\DSC\DSC_Tooling\ -Include 'Pester','ProtectedData' -Recurse 
copy C:\github\PshOrgDSC\Tooling\Examples\SampleBuild.ps1 c:\dsc\SampleBuild.ps1
copy c:\github\* C:\DSC\DSC_Resources -Include 'cSmbShare', 'cWebAdministration', 'StackExchangeResources' -Recurse
copy c:\github\* 'C:\Program Files\WindowsPowerShell\Modules' -Include 'cSmbShare', 'cWebAdministration', 'StackExchangeResources' -Recurse
copy C:\github\PshOrgDSC\Tooling\Examples\DSC_Configuration\* C:\DSC\DSC_Configuration -Recurse
copy C:\github\PshOrgDSC\Tooling\Examples\* C:\DSC\DSC_Script -Include 'SampleConfiguration' -Recurse

#delete unneeded folders. 
dir -Path c:\dsc -Include '.git' -Recurse | del -Recurse -Force #-Confirm:$false
dir -Path 'C:\Program Files\WindowsPowerShell\Modules' -Include '.git' -Recurse | del -Recurse -Force

Then result should give us a folder structure like this

│   ├───AllNodes
│   ├───Services
│   └───SiteData
│   ├───cSmbShare
│   │   └───DscResources
│   │       └───PSHOrg_cSmbShare
│   ├───cWebAdministration
│   │   ├───DSCResources
│   │   │   ├───PSHOrg_cAppPool
│   │   │   └───PSHOrg_cWebsite
│   │   └───Examples
│   └───StackExchangeResources
│       ├───DSCResources
│       │   ├───StackExchange_CertificateStore
│       │   ├───StackExchange_FirewallRule
│       │   ├───StackExchange_NetworkAdapter
│       │   ├───StackExchange_Pagefile
│       │   │   ├───StackExchange_en-US
│       │   │   └───StackExchange_nl-NL
│       │   ├───StackExchange_PowerPlan
│       │   │   └───StackExchange_en-US
│       │   ├───StackExchange_ScheduledTask
│       │   ├───StackExchange_SetExecutionPolicy
│       │   │   └───StackExchange_en-US
│       │   └───StackExchange_Timezone
│       └───test
│           ├───integration
│           │   └───StackExchange_PageFile
│           │       └───pester
│           └───unit
│               └───StackExchange_Pagefile
│                   └───pester
│   └───SampleConfiguration
    │   ├───bin
    │   ├───en-US
    │   ├───Examples
    │   │   ├───Calculator
    │   │   └───Validator
    │   ├───Functions
    │   │   └───Assertions
    │   ├───Snippets
    │   └───vendor
    │       └───tools
    │           ├───OneGet
    │           │   └───Etc
    │           └───PowerShellGet
    │               └───en-US

│   └───DscResources
│       └───PSHOrg_cSmbShare
│   ├───DSCResources
│   │   ├───PSHOrg_cAppPool
│   │   └───PSHOrg_cWebsite
│   └───Examples
│   ├───bin
│   ├───en-US
│   ├───Examples
│   │   ├───Calculator
│   │   └───Validator
│   ├───Functions
│   │   └───Assertions
│   ├───Snippets
│   └───vendor
│       └───tools
│           ├───OneGet
│           │   └───Etc
│           └───PowerShellGet
│               └───en-US
│   └───en-US
    │   ├───StackExchange_CertificateStore
    │   ├───StackExchange_FirewallRule
    │   ├───StackExchange_NetworkAdapter
    │   ├───StackExchange_Pagefile
    │   │   ├───StackExchange_en-US
    │   │   └───StackExchange_nl-NL
    │   ├───StackExchange_PowerPlan
    │   │   └───StackExchange_en-US
    │   ├───StackExchange_ScheduledTask
    │   ├───StackExchange_SetExecutionPolicy
    │   │   └───StackExchange_en-US
    │   └───StackExchange_Timezone
        │   └───StackExchange_PageFile
        │       └───pester

now lets fix C:\DSC\SampleBuild.ps1

    Import-Module Pester -ErrorAction Stop
    Import-Module dscbuild -ErrorAction Stop
    Import-Module dscconfiguration -ErrorAction Stop

    $params = @{
        WorkingDirectory = (Get-TempDirectory).FullName
        SourceResourceDirectory = "$PSScriptRoot\DSC_Resources"
        SourceToolDirectory = "$PSScriptRoot\DSC_Tooling"
        DestinationRootDirectory = "$PSScriptRoot\BuldOutput"
        DestinationToolDirectory = $env:TEMP
        ConfigurationData = Get-DscConfigurationData -Path "$PSScriptRoot\DSC_Configuration" -Force -verbose
        ModulePath = "$PSScriptRoot\DSC_Script"  , "$PSScriptRoot\DSC_Tooling"
        ConfigurationModuleName = 'SampleConfiguration'
        ConfigurationName = 'SampleConfiguration'
        Configuration = $true
        Resource = $true

    Invoke-DscBuild @params -verbose

    function Get-TempDirectory
        param ( )

            $tempDir = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ([System.IO.Path]::GetRandomFileName())
        until (-not (Test-Path -Path $tempDir -PathType Container))

        return New-Item -Path $tempDir -ItemType Directory -ErrorAction Stop

So what is different?

  • DestinationRootDirectory = “$PSScriptRoot\BuldOutput”
    • Changed to point to a relative output. this is a test, so there is no need to place it into the common location for a pull server, although in production you may want to. I prefer to copy the files after a build, as it’s usually built on a machine other then the pull server
  •  ConfigurationData = Get-DscConfigurationData -Path “$PSScriptRoot\DSC_Configuration” -Force -verbose
    • added verbose so I can see how its progresses and help with troubleshooting
  • ModulePath = “$PSScriptRoot\DSC_Script”  , “$PSScriptRoot\DSC_Tooling”
      This is the big one. ModulePath and SourceResourceDirectory are going to be the only path’s in $psmodulepath when the configuration module (the module referenced by ConfigurationModuleName ) is loaded and when the configuration in ConfigurationName  is executed. This feature was added to resolve a problem when your modules used to build .mof files may be newer then the ones used to configure the machine running them. Something I ran into and Dave Wyatt was kind enough to solve
  • Invoke-DscBuild @params -verbose
    • Added -verbose. I’m a bit of a verbose junky.

With the updates to SampleBuild.ps1 we are ready to build our first sample set of .mof files

I do this in a clean environment so I’m opening PowerShell as an administrator and running C:\DSC\SampleBuild.ps1. After a long bit of scrolling if it works the last few lines should look like this.

VERBOSE: Moving 718aec80-e8fe-41b5-ac31-fbcd5d0186b1.mof to C:\DSC\BuldOutput\Configuration
VERBOSE: Moving b4519959-9724-40d5-ab62-5c4f82bbcd80.mof to C:\DSC\BuldOutput\Configuration
VERBOSE: Moving fc107c0b-1fc8-45fb-9991-a0a1f0fd6c21.mof to C:\DSC\BuldOutput\Configuration

Congratulations you have your first set of .mof files working with the DSC tools.

Next up. Creating a pull request to update the and SampleBuild.ps1


Get-DSCFramework | Test-Lab

Posts in this series

  1. Test-HomeLab -InputObject ‘The Plan’
  2. Get-Posh-Git | Test-Lab
  3. Get-DSCFramework | Test-Lab
  4. Invoke-DscBuild | Test-Lab
  5. Test-Lab | Update-GitHub

In the last post we got the posh-git installed, Now we are going to fork the DSC tools development branch and clone that locally.

I already have an account with GitHub, You will need one to be able to contribute.

I had over the the repository and click the fork button


with that done next is to get a copy of the clone URL.


I create a folder to store the repository in

C:\> mkdir github
    Directory: C:\
Mode                LastWriteTime     Length Name                                                                                                              
----                -------------     ------ ----                                                                                                              
d----          5/1/2015   5:25 PM            github                                                                                                            

C:\> cd github

now i have everything I need to make a clone.

C:\github> git clone PshOrgDSC --branch development
git : Cloning into 'PshOrgDSC'...
At line:1 char:1
+ git clone PshOrgDSC --branch developme ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Cloning into 'PshOrgDSC'...:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

C:\github> cd .\PshOrgDSC

C:\github\PshOrgDSC [development]> dir

    Directory: C:\github\PshOrgDSC

Mode                LastWriteTime     Length Name                                                                                                              
----                -------------     ------ ----                                                                                                              
d----          5/1/2015   5:38 PM            Tooling                                                                                                           
-a---          5/1/2015   5:38 PM        605 .gitattributes                                                                                                    
-a---          5/1/2015   5:38 PM        366 .gitignore                                                                                                        
-a---          5/1/2015   5:38 PM       1099 LICENSE.txt                                                                                                       
-a---          5/1/2015   5:38 PM       1231                                                                                                         
-a---          5/1/2015   5:38 PM       7305                                                                                                     

C:\github\PshOrgDSC [development]> 

I’m not sure why PowerShell thought it was an error but the clone worked.

Next up will be getting the example config to build.

C:\github\PshOrgDSC [development]> cd .\Tooling\Examples

C:\github\PshOrgDSC\Tooling\Examples [development]> dir

    Directory: C:\github\PshOrgDSC\Tooling\Examples

Mode                LastWriteTime     Length Name                                                                                                              
----                -------------     ------ ----                                                                                                              
d----          5/1/2015   5:38 PM            DSC_Configuration                                                                                                 
d----          5/1/2015   5:38 PM            SampleConfiguration                                                                                               
-a---          5/1/2015   5:38 PM       1770                                                                                                         
-a---          5/1/2015   5:38 PM       1203 SampleBuild.ps1       

Get-Posh-Git | Test-Lab

Posts in this series

  1. Test-HomeLab -InputObject ‘The Plan’
  2. Get-Posh-Git | Test-Lab
  3. Get-DSCFramework | Test-Lab
  4. Invoke-DscBuild | Test-Lab
  5. Test-Lab | Update-GitHub

My instal test lab starting to take shape.

I have a vyos router bridging my production environment and my isolated virtual switch similar to what Greg Altman talks about on

And I have one Windows 8.1 Pro VM to setup the DSC tools

Now I’m going to get the development branch, as it has some major fixes, including a re-working of how modules are tested and package, and how passwords are stored.  The part on password is the big item for me.

Now I could just download it via GitHub using IE.

DevBranch  downloadzip

But this blog is about giving back to the community so I’m going to using the GitHub client, and it’s included Posh-Git module for PowerShell.

The GitHub client is a nice simple GUI client, but I have one issue with it. It installs into a users profile. While all store apps and downloaded .net apps do this and it’s a good thing for isolation. In a secure environment like where i work it’s frowned apon. So ifyour in that boat, Posh-Git can be downloaded from github and works with other git clients.

Now I dont plan on using the GUI for the purpose of this blog so I’m going to change my PowerShell profile to load posh-git. GitHub client has to be ran once to create the files I use in my profile.

The commands for that are.

 #create/add posh-git to profile
 if (-not (test-path (split-path -Path $profile.CurrentUserAllHosts -Parent)))
 mkdir (split-path -Path $profile.CurrentUserAllHosts -Parent)
 '. (Resolve-Path "$env:LOCALAPPDATA\GitHub\shell.ps1")' | out-file -Path $profile.CurrentUserAllHosts -Append
 '. $env:github_posh_git\profile.example.ps1' | out-file -Path $profile.CurrentUserAllHosts -Append

restart powershell and I can run get-module to see what modules are loaded.

C:\> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script    ISE                                 {Get-IseSnippet, Import-IseSnippet, New-IseSnippet}
Manifest    Microsoft.PowerShell.Management     {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Content...}
Manifest    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Script     0.0        posh-git                            {Add-SshKey, Enable-GitColors, Get-AliasPattern, Get-GitDirectory...}

Now we are ready to fork the DSC repository and clone it locally.

Test-HomeLab -InputObject ‘The Plan’

Posts in this series

  1. Test-HomeLab -InputObject ‘The Plan’
  2. Get-Posh-Git | Test-Lab
  3. Get-DSCFramework | Test-Lab
  4. Invoke-DscBuild | Test-Lab
  5. Test-Lab | Update-GitHub

The Plan

What I intend to do is to create and in home test lab that I can use to test and develop DSC.  I’m basing my lab from Greg Altman excellent post over on

The only exception I to this is that I have 2 machines to use a Hyper-V hosts. Now the second one I plan on installing Nano if/when it got into preview. Baring that I will use Hyper-V server 2012 R2.

Now to keep the lab services into the virtual realm as Greg mentioned, _and_ use two hosts. I have spend the weekend trying to create a vyos VPN tunnel between two isolated networks.

Needless to say not everything go according to plan. the Tunnel reports the link is up, but their is no traffic between network.

I have already wasted most of the weekend on this, so I’m going to move forward for now with with out the VPN.  It’s not like I need it yet.

So, onward.

I’m going to first build a windows 8.1 dev PC by hand, and load the DSC tooling on it. From there I can build configs for building a as much of the rest of the environment as possible.

I hope to have a Pull Server, DC, PKI CA, up first, then move on to other servers that I can use to build resources for.

I have been running DSC in production for the last year, and I hope I can share may experience via a how to for a test environment and how it relates back to problems in the enterprise.