PowerShell Desired State Configuration (DSC) Journey – Day 24

When I last left off I had created my VMM Template with an injected DSC .ps1 file on the Hard Disk.  My next objective is to deploy a VM from this Template and see if it configures the IP Address and joins it to the domain as it states in the injected DSC Configuration.

So, let’s deploy the VM and see what happens.  And keep your fingers crossed.  If this works on the first attempt I don’t even know what I will do.

dsc29

It got all the way to Changing Properties of the VM before crapping the bed with Error (23352) VMM cannot find the device or this device is not valid for a boot device.  Recommended action:  Make sure you specify a valid device as a boot device.  I have deployed a lot of VM’s through VMM, and I haven’t seen this before.  It had a valid hard drive as a boot disk so I am not sure what happened.

Researching the issue I come across this TechNet article (and many like it) where this is a known issue in VMM and deploying a Generation 2 VM from a Template.  So I am going to have to rebuild the template and try again.  Awesome.  Not.

Alright, after rebuilding the VMM Template using the VHD I have successfully deployed a VM based on the template that has the injected DSC Configuration.  So let’s fire this thing up and see what happens.

And naturally, nothing happens.  The scheduled task that was supposed to be created by the RunDSC.cmd file was not created, so the Configuration never ran.  Which also means the Unattend.xml didn’t run (or something isn’t configured properly).

The TechNet article states the following:

  • We have all necessary files ready. Now inject SampleIISInstall.ps1, RunDSC.cmd, and unattend.xml to the VHD. In our case, unattend.xml is copied under root directory while SampleIISInstall.ps1 and RunDSC.cmd are put under %SystemDrive%\DSC. If you boot up from the VHD, or create a VM from the VHD, you will see that IIS gets installed at first boot-up.

I verify that the all the files are where they should be.  I check the path in the Unattend.xml and verify that it goes to the correct place and both the RunDSC.cmd and DSCTemplate.ps1 files are in the directory.

<settings pass=”specialize”>
<component name=”Microsoft-Windows-Deployment” processorArchitecture=”amd64″ publicKeyToken=”31bf3856ad364e35″ language=”neutral” versionScope=”nonSxS” xmlns:wcm=”http://schemas.microsoft.com/WMIConfig/2002/State” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”>
<RunSynchronous>
<RunSynchronousCommand>
<Order>1</Order>
<Path>%SystemDrive%\DSC\RunDSC.cmd</Path>
</RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>

It is at this point that I run the RunDSC.cmd file.  I previously looked for the scheduled task under the regular Task Scheduler Library, and didn’t see it.  After running the RunDSC.cmd I actually looked at the syntax and realized that the scheduled task is in the Desired State Configuration folder in the Task Scheduler Library.  Problem is that I didn’t look there previously so I don’t know if it was actually there already or not.

There isn’t anything useful in either the Desired State Configuration or Task Scheduler event logs so I guess we are just going to roll with this for now.  The scheduled task is set to run at startup so I reboot the VM and see what happens.

I didn’t get a screenshot in time but after I logged in Task Manager showed that Windows PowerShell was running as a background process which I hope is a good sign.  Or at least a sign of progress.

I quickly check the IP address of the VM and it’s not set properly.  The scheduled task does show that the last run time was a little over 3 minutes ago.

The DSC log doesn’t show anything.  Of course the Analytic and Debug logs aren’t enabled by default.  I should probably enable those on the template going forward.  The other event logs don’t have anything in them either (that I can find) so I am going to run the scheduled task manually and see what happens.

The scheduled task runs for about 5 seconds and then stops.  Which doesn’t seem nearly long enough.  Next troubleshooting step is to run the command that is in the scheduled task in PowerShell and see what happens.

And it seems that the latest WordPress updates broke the SyntaxHighlighter Plugin so this is going to have to work for now.

Powershell.exe -ExecutionPolicy RemoteSigned -File C:\DSC\DSCTemplate.ps1

And….I am an idiot.  I feel really dumb.  Here is the error.

At C:\dsc\DSCTemplate.ps1:20 char:43

+ Import-DscResource -Module xNetworking

Unable to load module ‘xNetworking’: module not found.

At C:\dsc\DSCTemplate.ps1:12 char:1

Of course that’s a problem Jacob!  I got so carried away with the other steps that I completely forgot about that (which I knew from previous experience with DSC).  I am already building another template to test whether that Scheduled Task gets carried so lets keep carrying on here.

I copy those Modules from my PC to c:\Program Files\WindowsPowerShell\Modules and restart PowerShell on my DSC Template.  I run Get-DSCResource and I now have the modules for xComputer, xDNSServerAddress,xFirewall and xIPAddress.

I am feeling crazy so let’s reboot and see what happens instead of testing the script again, since I know the scheduled task ran as it was supposed to.  After I login I quickly open up Task Manager and I see there are now two processes for Windows PowerShell and they are still running a minute after logging in.

dsc30

A quick check of the IP shows that it is still set for DNS.  There isn’t anything in the DSC log.  Both background processes are still running so I guess I will let them run for a few minutes and see what happens.  So after a break I come back and those same two processes are running and nothing has happened.  I end the processes and am going to run the .PS1 from PowerShell and see what happens.  And.  The very first thing that happens is that I get a credential box, which is probably why the script was hanging and doing nothing.  I enabled plain text passwords but never stored a credential, because I thought the credentials would be stored.  This is obviously flawed thinking because I never created a .MOF file to store that information, only a .PS1 file.

I enter my domain credentials and magic happens.  The IPAddress is set, the computer is renamed, but it fails to join the domain because “it either does not exist or cannot be contacted.”  Which doesn’t make any sense.  I have a feeling that is because after the IPAddress changed that the box popped up that asks you if you want to trust this network or share devices or whatever the hell it is that it says that you just always say OK to.  Turns out I was wrong (shocking I know).  The VLAN on my network adapter was set incorrectly, once I changed that, however it still didn’t work.

So I go to the network adapter settings and look….and…for the 2nd time today I feel like an idiot.  In my Configuration I set the IPAddress, but I sure didn’t configure the DNS Settings.  Which is clearly a problem.  So I set them manually and try to run my DSCTemplate.ps1 again.  And now, true magic happens.  The entire Configuration is applied successfully.  It asks me to reboot the server so I do that.  After the reboot everything looks wonderful.

I also spun up another VM based off of the template, and the Desired State Configuration task isn’t created on initial boot, so the unattend.xml isn’t working properly.  I don’t know enough about using a file like that and what might be causing that.  I will need to do some more investigation on that front.  For now I think this is a good place to stop.