Alright. So yesterday I worked through some issues in the Set-TargetResource Function and left off with a big one still remaining. Namely, that even though I have Ensure = Present in my test of the Function, it is running through the Ensure = Absent portion of the script if the Hardware Profile already exists, which doesn’t make any sense.
Here is the section of the Function in question.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#Check to see if Hardware Profile exists Write-Verbose "Checking if the Hardware Profile $Name exists" $HWProfile = Get-SCHardwareProfile -VMMServer $VMMServer If($HWProfile.Name -match $Name) { Write-Verbose "The Hardware Profile was found" #Set Variables for the Hardware Profile $ResourceHWProfile = Get-SCHardwareProfile -VMMServer $VMMServer | Where-Object Name -eq $Name #Set this variable for use later $HWProfileID = $ResourceHWProfile.ID #If Hardware Profile Should not exist, remove it Write-Verbose "Ensure set to $Ensure" If($Ensure = "Absent") { Write-Verbose "Hardware Profile $Name Should be $Ensure" Get-SCHardwareProfile -VMMServer $VMMServer -ID $HWProfileID | Remove-SCHardwareProfile Write-Verbose "Hardware Profile $Name is $Ensure" } |
And if I run this Test with a Hardware Profile that already exists, this is the output that I get.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Set-TargetResource -Name "DSCWEB Hardware Profile" -VMMServer MY-VMM-SERVER1 -Ensure Present -Verbose PS C:\USERS\jacob.benson\Downloads\physdiskwrite-0.5.3> Set-TargetResource -Name "DSCWEB Hardware Profile" -VMMServer MY-VMM-SERVER1 -Ensure Present -Verbose VERBOSE: VMMServer is MY-VMM-SERVER1 VERBOSE: Hardware Profile Name is DSCWEB Hardware Profile VERBOSE: Loading module from path 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\virtualmachinemanager.R2Aliases.ps1'. VERBOSE: Loading module from path 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\VirtualMachineManagerLibraryClientCleanup.ps1'. VERBOSE: Loading module from path 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\psModules\virtualmachinemanager\..\..\virtualmachinemanager.R2AdvFunc.psm1'. VERBOSE: Loading module from path 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\psModules\virtualmachinemanager\..\..\Microsoft.SystemCenter.VirtualMachineManager.dll'. VERBOSE: Checking if the Hardware Profile DSCWEB Hardware Profile exists VERBOSE: The Hardware Profile was found VERBOSE: Ensure set to Present VERBOSE: Hardware Profile DSCWEB Hardware Profile Should be Absent (Then it displays the Hardware Profile) VERBOSE: Hardware Profile DSCWEB Hardware Profile is Absent |
And I know it’s removing it because the Hardware Profile disappears from VMM. The question is, why? I can see from the Verbose output that $Ensure is set to Present, so why is the Function ignoring that? As another test, if I run the same test but set $Ensure to Absent, it removes it. But that was really just a diversion to avoid thinking about the real problem because I am completely stumped.
I change my Else block to ElseIf($Ensure = “Present”) and that has no effect. It just jumps right into the If Absent block and deleted the Hardware Profile. Lacking ideas I start going through the xVMHyperV Set-TargetResource function searching for Ensure to see how they do it. And they are using -eq in the If statement instead of =. Does this really make a difference? Yes, that’s the answer. After I change it to that, it evaluates the parameter properly. I feel like this is a very simple mistake that I made solely because of my lack of experience and knowledge of PowerShell.
Doing a little research in PowerShell using Get-Help I discover the following:
- = is an Assignment Operator. It sets the value of a variable to a specified value
- -eq is a Comparison Operator. It compares to objects looking for an identical value
- Thus, = does not equal -eq. I feel dumb. I should have known that.
That being said, when I run my test using an existing Hardware Profile now (with Ensure = Present), I get this for output.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
PS C:\scripts> Set-TargetResource -Name "DSCWEB Hardware Profile" -VMMServer MY-VMM-SERVER1 -Ensure Present -Verbose VERBOSE: VMMServer is MY-VMM-SERVER1 VERBOSE: Hardware Profile Name is DSCWEB Hardware Profile VERBOSE: Loading module from path 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\virtualmachinemanager.R2Aliases.ps1'. VERBOSE: Loading module from path 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\VirtualMachineManagerLibraryClientCleanup.ps1'. VERBOSE: Loading module from path 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\psModules\virtualmachinemanager\..\..\virtualmachinemanager.R2AdvFunc.psm1'. VERBOSE: Loading module from path 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\psModules\virtualmachinemanager\..\..\Microsoft.SystemCenter.VirtualMachineManager.dll'. VERBOSE: Checking if the Hardware Profile DSCWEB Hardware Profile exists VERBOSE: The Hardware Profile was found VERBOSE: Ensure set to Present VERBOSE: DVDDrive is already set properly VERBOSE: CPUCount is Default Hardware Configuration efault Hardware Configuration - Gen 2 DSCWEB Hardware Profile.CPUCount, should be 1 VERBOSE: CPUCount Set to 1 VERBOSE: VMNetwork set to Default Hardware Configuration Default Hardware Configuration - Gen 2 DSCWEB Hardware Profile.VirtualNetworkAdapters.VMNetwork, should be Set-SCVirtualNetworkAdapter : Cannot validate argument on parameter 'VirtualNetwork'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. At line:101 char:144 + ... rofile $Name | Set-SCVirtualNetworkAdapter -VirtualNetwork $VMNetwork + ~~~~~~~~~~ + CategoryInfo : InvalidData: (:) [Set-SCVirtualNetworkAdapter], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.SystemCenter.VirtualMachineManager.Cmdlets.SetNICCmdlet VERBOSE: VMNetwork set to |
Clearly there are a couple of issues here. The DVDDrive section looks OK, but then in the CPU section I get this beauty for Verbose output.
1 |
VERBOSE: CPUCount is Default Hardware Configuration Default Hardware Configuration - Gen 2 DSCWEB Hardware Profile.CPUCount, should be 1 |
Yeah, that’s not real useful. Looking at this it appears that $HWProfile.CPCount is not what I think it is. Actually I think it’s because I used $HWProfile instead of the $ResourceHWProfile variable. This is going to require a fix in a lot of places. I make those changes and try my test again. I get the expected output, except that I get the same error about the VirtualNetworkAdapter that I got above. This goes back to my work in the previous blog post about how to handle this, because I don’t want to make this parameter mandatory. So, I need to add in some additional logic to my Function here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
If($VMNetwork) { If($VMNetwork -ne $ResourceHWProfile.VirtualNetworkAdapters.VMNetwork) { Write-Verbose "VMNetwork set to $ResourceHWProfile.VirtualNetworkAdapters.VMNetwork, should be $VMNetwork" Get-SCVirtualNetworkAdapter -VMMServer $VMMSErver -HardwareProfile $Name | Set-SCVirtualNetworkAdapter -VirtualNetwork $VMNetwork Write-Verbose "VMNetwork set to $VMNetwork" } Else { Write-Verbose "VMNetwork is already set to $VMNetwork" } } Else { Write-Verbose "No VMNetwork was specified" }#EndVMNetwork |
And now when I run my test, I get exactly the output that I would expect.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
PS C:\scripts> Set-TargetResource -Name "DSCWEB Hardware Profile" -VMMServer MY-VMM-SERVER1 -Ensure Present -Verbose VERBOSE: VMMServer is MY-VMM-SERVER1 VERBOSE: Hardware Profile Name is DSCWEB Hardware Profile VERBOSE: Loading module from path 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\virtualmachinemanager.R2Aliases.ps1'. VERBOSE: Loading module from path 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\VirtualMachineManagerLibraryClientCleanup.ps1'. VERBOSE: Loading module from path 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\psModules\virtualmachinemanager\..\..\virtualmachinemanager.R2AdvFunc.psm1'. VERBOSE: Loading module from path 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\psModules\virtualmachinemanager\..\..\Microsoft.SystemCenter.VirtualMachineManager.dll'. VERBOSE: Checking if the Hardware Profile DSCWEB Hardware Profile exists VERBOSE: The Hardware Profile was found VERBOSE: Ensure set to Present VERBOSE: DVDDrive is already set properly VERBOSE: CPUCount is already set to 1 VERBOSE: No VMNetwork was specified |
Boom!
I do various tests with different CPU, DVDDrive and VMNetwork settings and everything looks good. I do make a change to one line of Verbose output, but other than that everything checks out fine. This is really cool. I have an actual functioning DSC Custom Resource. Tomorrow I am going to turn this thing into a Module, and try out an actual DSC Configuration and see if that actually works before adding in my additional parameters.