PowerShell: Desired State Configuration – Getting started.


By now most people will have heard about the Windows PowerShell Desired State Configuration(DSC), the incredibly powerful configuration management platform that comes with PowerShell 4.0. This post will describe the feature in its most basic form and assume you’re new to the topic(or have been living under a rock). This should give you an overview and basic understanding of how PowerShell DSC fundamentally works. From then, I’ll post further and share how I’ve been using DSC to control my Lab environments.

What’s it all about then?

DSC is a management platform in Windows PowerShell that essentially just runs PowerShell scripts in a very clever manner, allowing you to push a configuration to a computer. You can do pretty much anything in PowerShell and as DSC runs on top of PowerShell you have even more power with DSC. Also, the amazing thing is you don’t even need to learn scripting to use it, you just edit a text file.

PowerShell DSC is really cool and the next big thing in the world of deployment. Moving forward I can see DSC replacing (or augmenting) Group Policy, building local and cloud based servers/hydration kits, removing malware/deploying software, etc.

Today’s post will demonstrate how to use PowerShell DSC in ‘Push’ mode by authoring a DSC Configuration using ‘Declarative Syntax’ to create a text file with the words “Hello World” and then ensure that the file and its content will remain compliant.

The same basic process will be used in further posts to build an entire server and domain PoC testlab. The power of PowerShell Desired State Configuration(DSC) is practically limitless.

So is there a script coming any time soon?

Indeed! Enough talk, here’s the Hello World Script. It’s written in DSC declarative syntax and uses a DSC Resource called File to create a text file.

configuration HelloWorld {
 param ()
 Node Localhost 
   # Create a Test File
   File CreateTestFile
     Ensure          = "Present"
     DestinationPath = "C:\ScriptimusExMachina\example.txt"
     Contents        = "Hello World."
     Type            = "File"

# Create MOF Files
HelloWorld -OutputPath C:\ScriptimusExMachina\HelloWorld

# Start DSC Configuration
Start-DscConfiguration -Path C:\ScriptimusExMachina\HelloWorld -ComputerName Localhost -Verbose -Wait

I still don’t get it?

What we’re trying to do here is generate a folder that contains a configuration file in MOF format.

Erm , I’m still not getting it. This MOFF fellow, is this the guy Darth Vader choked or the old guy played by Peter Cushing?

Grand Moff Tarkin. (Not to be confused with a MOF file in PowerShell DSC)

Erm, neither. A MOF is just a text file in Managed Object Format (MOF). We’re going to use this MOF file to apply a configuration to our host computer. We don’t actually need to learn how to write a complex MOF file. We’re going to use the Configuration in the script above to create the MOF file for us.

For demo purposes we paste the Configuration into the console.


The Configuration works like a Function and has 3 parameters InstanceName, OutputPath and ConfigurationData. Ed Wilson (The Scripting Guy) does a great job of describing these here.


We now run our HelloWorld Configuration in its simplest form.

HelloWorld -OutputPath C:\ScriptimusExMachina\HelloWorld


As you can see, it creates a folder with the same name as our Configuration with a .MOF file inside. The MOF filename is the same as the target hostname specified in the Hello world configuration earlier. If you had multiple hostnames in your configuration then you would have one for each host.


What this means is that when the configuration is applied, each MOF (one for each machine) file will be applied. In this case however, we’re just using Localhost.

Just do it already!

We use this command to start the DSC configuration.

Start-DscConfiguration -Path C:\ScriptimusExMachina\HelloWorld -ComputerName Localhost -Verbose -Wait

The Configuration is applied using the Start-DscConfiguration cmdlet, pointing it to the folder path of our MOF files. If you had multiple hosts configured then you could just apply one by name by using the ComputerName parameter as shown in the example. Using the Verbose and Wait Parameters causes DSC to output its data in real time as shown below.


Walking through the syntax used in the script earlier. First we ensure that our configuration is present. We could use Absent to delete a file or folder.

Ensure          = "Present"

We specify the name and path of the file that we’re going to create. The type could also be a folder instead.

DestinationPath = "C:\ScriptimusExMachina\example.txt"
Type            = "File"

Here we ensure that its contents are a specific string.

Contents        = "Hello World."

Looking in the folder, we have a new text file with the desired content.


Now that’s PowerShell DSC in its simplest form.

We can test that our Configuration is compliant using the Test-DSCConfiguration CmdLet. This will return a Boolean response.


Watch what happens when I change the content of the file.


Now I can use Restore-DscConfiguration to re-apply the configuration.


This is made possible because the MOF file that was applied last has been copied to C:\Windows\System32\Configuration\Current.mof. You could use Restore-DscConfiguration to re-apply the configuration without the source.Configuration

By using the source I could also re-apply the configuration by using the Start-DscConfiguration cmdlet again.


You’ll see that this time, by not using the Verbose and Wait Parameters that DSC is showing me that the process is running as background Job.

You can retrieve the job as usual.


Finally, you can use the Get-DscConfiguration cmdlet to view the current configuration.


In future posts I’ll be discussing more complex configurations so keep reading.

Posted in Desired State Configuration, PowerShell | Tagged , | 2 Comments

PowerShell: New-Password Function

Scriptimus PowerShell Banner

OK, so I’ve been off the grid for a while now. But that doesn’t mean I’ve not been busy. Quite the opposite in fact. I’ve taken a year out from work on paternity with my baby Son. During this time, I did a lot of training in my lab developing new skills and solidifying other more fundamental skills. I’ve also passed a couple of certified exams and have built a new lab from a new HP Micro-server that I juiced up. I’m currently planning to take the MCSA: Server 2012 R2 exam and have been training in my lab and doing a lot of PowerShell DSC based automation. Hopefully I’ll be able to share some if not all of this knowledge and experience soon. I thought it best to return with a simple post so here goes.

During my time off I wrote a simple function to generate a password from random characters. I posted it yesterday here in the Microsoft Script Center Script Repository . Here’s a quick screenshot demo:


And here’s a simplified version for discussion.

Function New-Password {








        If ($Uppercase) {$CharPool += ([char[]](65..90))}
        If ($LowerCase) {$CharPool += ([char[]](97..122))}
        If ($Numeric) {$CharPool += ([char[]](48..57))}
        If ($Symbolic) {$CharPool += ([char[]](33..47))
                       $CharPool += ([char[]](33..47))}

        If ($CharPool -eq $null) {
            Throw 'You must select at least one of the parameters "Uppercase" "LowerCase" "Numeric" or "Symbolic"'

        (Get-Random -InputObject $CharPool -Count $length) -join ''


The only issue with this was working out each of the character types. Fortunately I learned, through testing, that you could return a series of ASCII characters by indexing them.


PowerShell Characters

For example, this line of code places the lowercase characters a-z in a variable (really a string type object) called $L.

$L = ([char[]](97..122))

PowerShell Characters LowerCase

Here you add 92 characters in turn to a string object called $CharPool.

$CharPool += ([char[]](65..90))
$CharPool += ([char[]](97..122))
$CharPool += ([char[]](48..57))
$CharPool += ([char[]](33..47))
$CharPool += ([char[]](33..47))

Yes, I really counted them!

PowerShell Count Characters

Next, I needed to work out how to get a number of random characters from the pool so I used the Get-Random cmdlet.

$CharPool = ([char[]](97..122))
Get-Random -InputObject $CharPool -Count 5

The problem with this though is that each of the characters are on a new line.


Then I remembered the -Join operator.

(Get-Random -InputObject $CharPool -Count 5) -join ''

PowerShell Get-Random Join


Posted in PowerShell | Tagged , , | 10 Comments

SCCM PowerShell: Connect to SCCM Function



Today’s post is another time-saver function I wrote to connect to SCCM. Again, it is designed to eliminate the need to hard code the module path and/or the SCCM primary site. It allows me to just type Connect-SCCM to import the module then enter to the SCCM PSdrive.

Like my MDT function this one locates the install path from the registry to help discover the module location. It will then detect the SCCM PS drive automagically and set the location to it.

I’ve uploaded it to the Technet script repository here and again below is the simplified version.

Function Connect-SCCM { 

    If (!(Get-Module ConfigurationManager)) { 

        [String]$SCCMInstall = ((Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\ConfigMgr10\Setup').'UI Installation Directory') 

            Import-Module ($SCCMInstall +'bin\ConfigurationManager.psd1') -Scope Global 


    Set-Location ((get-psdrive -PSProvider CMSite).Name+":") 

Posted in MDT 2010, MDT 2012, MDT 2013, PowerShell | Tagged , , | 2 Comments

MDT PowerShell: Connect to MDT Function


Todays post is a time-saver function I wrote to connect to MDT shares. It allows me to just type Connect-MDT to import the module then enter to the MDT PSdrive.

It discovers the location of the MDT module(from the registry) and uses the Restore-MDTPersistentDrive cmdlet to restore the hosts existing MDT PSDrives. It will then set the location to the first MDT PSDrive thus eliminating the need to hard code the deployment share path. Ta-daa!



I’ve uploaded it to the Technet script repository and below is the simplified version.


Function Connect-MDT {

 If (!(Get-Module MicrosoftDeploymentToolkit)) {

     [String]$MDTInstall = ((Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Deployment 4').Install_Dir)

     Import-Module ($MDTInstall +'Bin\MicrosoftDeploymentToolkit.psd1') -Scope Global


 $MDTPSDrive = Restore-MDTPersistentDrive -verbose

 Set-Location ($MDTPSDrive.Name +':')

Posted in MDT 2010, MDT 2012, MDT 2013, PowerShell | Tagged , , | 5 Comments

The malware apocalypse for Windows XP begins in just 1 day! Or does it?


It doesn’t seem like 12 years since Windows XP and Office 2003 first arrived but now their time will draw closer to the end in less than 2 days. At this point Microsoft will drop Enterprise support for the products potentially making the products legacy and an increasing security risk?

What does this really mean for security? Well if I was a ‘bad guy’ I’d be waiting until the 8th April 2014 before unleashing any exploits I discovered for Windows XP and Office 2003. The reason is Microsoft will no longer engineer security patches for the products. Experts are describing this time as the malware apocalypse for Windows XP.


The fact that most UK cashpoints, Self service retail tills and NHS hospitals are still on XP is really surprising. There is a wealth of free information on the internet to help organisations make the move from XP. This kinda makes me think of my mum’s old Jamaican saying:

“Those who wont hear, must feel!”

As with Y2K, the apocalypse came and went without so much as a flutter and I was looking forward this time to observe this foretold carnage however, this time the government has stepped in to try to stay the execution. This gives the public sector security patches for a further 12 months while they migrate from XP. After then perhaps the darkness will really begin.


Posted in Uncategorized | 5 Comments

LTI/ZTI Scripting: Add computer to an AD Group

I’m currently doing some intense SCCM 2012 training so I’ve not been posting or in the forums recently. I’ve still been responding to emails though.

I received an email from a reader earlier this week. He wanted to add the current computer to an AD security group during his deployment.

It turns out that I wrote such a script a few weeks earlier. It’s in the repository here.

The script will add the current computer to an AD Group that is set in the customsettings.ini

The script is then run in a task sequence with the command line:

cscript.exe “%SCRIPTROOT%\ZTIAddMember.wsf

The code below is a sample of the customsettings.ini changes.

Properties=CustomProperty, ADGroup 

ADGroup = LDAP://CN=IT Computers,OU=Groups,DC=corp,DC=continuum,DC=com

The code is “As is”. No refunds!

Posted in MDT 2010, MDT 2012, SCCM, Scripting | Tagged , , , , | 24 Comments

Hotfix rollup released for Windows 7 SP1 and Windows Server 2008 R2 SP1.


Big news in deployment right now. Microsoft has release a hotfix rollup is for Windows 7 SP1 and Windows Server 2008 R2 SP1. So it’s kinda like Service Pack 1 and a half. There are 4 flavours 2008R2 Itanium/x64 and Windows 7 x86/x64.

You can get it from Microsoft Update Catalog by clicking the link here.


You can then add the updates to your basket and download them.

There’s a Microsoft KB article here. Article KB2775511

The updates are in a format suitable for importing into the Packages folder of your MDT deployment share.


Posted in Deployment, Windows 7 | Tagged , , , , | 9 Comments