PowerShell DSC Journey – Day 16

When I left off yesterday I had a somewhat functioning Set-TargetResource function. I use functioning in the way that when something kind of works and doesn’t throw errors but doesn’t actually do anything functions. So, today I am going to be figuring out where I screwed up my logic and getting this Resource to work. And hopefully this doesn’t turn into a smaller version of War and Peace.

Here is my Set-TargetResource in it’s entirety.

The first problem I noticed is that when I run this test of my Set-TargetResource (in which I am testing for a Hardware Profile that doesn’t exist), here is the output I get.

Couple of things to note here. It didn’t find the Hardware Profile, so it created it. However, I didn’t specify anything for the DVD Drive, but the verbose output indicates that it was set to False, so it did not create a DVD Drive, so that needs to be fixed. The second issue is that the verbose output indicates that the CPU count set to 0 or not specified, CPU count should be at least 1. If I don’t specify a CPU count the Hardware Profile creation defaults to 1 CPU, so the message should indicate that. And lastly it just errored out on setting the VMNetwork because I didn’t specify one.

First things first, here is the section of code I have to handle the DVD Drive.

While thinking about this, it occurs to me that maybe I should set this to default to True, because I imagine that in almost every case you are going to want a DVD Drive on your server. I feel like that is a better solution than adding in another ElseIf section that has the Null case. Do people agree? I changed the parameter in the Set-TargetResource Function so that $DVDDrive = $True, and that means the existing code block should work fine.

Second minor issue is changing the Verbose text when the CPU Count is set to 0 or not specified. This particular section of code I changed from:

To:

Of course after doing this I think, should I just set the CPUCount parameter to default to 1? I mean, you need a CPU for it to run, and it defaults to 1 anyways without even setting anything. I realize the code in the Else block is a little redundant, but for consistency sake I left it that way so somebody reading it wouldn’t be like “why did he set the hardware profile in the first section and not the second?”. I could also make CPUCount a mandatory parameter, but that seems a little excessive when it just defaults to 1 anyways. Hmm. I don’t think there is a good answer to this. I am going to set CPUCount to default to 1 and just change the Else statement to use -CPUCount $CPUCount for now. I don’t like the idea of hard coding parameter values into a DSC Configuration, but in this particular case I think it is justifiable.

Alright, now for the last problem with the VMNetwork. If I don’t specify it, it shouldn’t just freak out and throw and error, it needs to say something useful. Here is my current code.

The problem here is that I thought that checking to see if the parameter was not equal to Null mean it would also check to make sure it wasn’t empty. Clearly this is not the case. So how do I check for both cases? It appears based on some Google searches the best way to do this is to change it from If($VMNetwork -ne $null) to just If($VMNetwork) which checks for Null or Empty.

With those changes done, lets test again and see what happens (I deleted the Hardware Configuration created from the previous test).

Much better!

The one thing I don’t like about this, is that it still sets it set the CPUCount, when in all actuality it was already set by default. So, I am going to change that section again to this.

I verified that the Hardware Profile has 1 CPU, the DVD Drive is Enabled, and the Virtual Network is not set. Not setting a VMNetwork appears to mean that no settings in VirtualNetworkAdapters are set, which is good to know.

Ok, with that all done, I run it again because I remember there was a problem with this. Here are the important parts from this test.

Uh. What. That looks to be a massive fail on my part. Although, I don’t understand what the problem is here. It checks if it exists, it finds that it exists, and then it is going through the block where $Ensure = Absent, even though I have $Ensure = Present. Of course, then it is removing the profile as well, which is fun. I add this line to my code right above the line for If($Ensure = Absent), Write-Verbose “Ensure set to $Ensure”.

And I get this, which is even more puzzling.

It says that $Ensure = Present, so why the hell is it going through that block of code? I don’t understand! If I set it to Absent it does the same thing, which is fine, but why is it doing it when it is set to present????

I feel like this is a good place to stop for now so I can think a little about this and try to figure out what is going on.