Author Posts

March 1, 2016 at 8:20 am

In my DSC config I am using both the Registry Resource and Script resource that adds registry keys. How can I ensure that the server reboots if DSC adds/removes a key if needed as specified in those sections. I have the 'RebootNodeIfNeeded' set in the LCM and I don't see how to incorporate the xPendingReboot module to tie into these changes.

For the script modules I suppose I could just add a line of code to reboot in the 'Set Script' section but am not sure if that is the best way. Still, how can I handle the registry resource parts?

Any advice and guidance is greatly appreciated.

March 1, 2016 at 8:23 am

I believe there's a global variable in the LCM, $DSCMachineStatus, which you set to 1.

March 1, 2016 at 8:27 am

In your Script resource, it's easy; you can keep track of whether you've changed anything, and trigger a reboot with the global variable as Don mentioned.

When using the Registry resource, I have no idea. I was looking into some sort of "conditional script" resource that would work based on what happened earlier in the currently-executing configuration, but the only way I could get it working was if the Analytic / Debug logs were enabled for DSC. This is something I hope they add support for in the future without needing those ETL logs to be enabled.

March 1, 2016 at 8:38 am

Hi Don,

I did see reference to the $DSCMachineStatus but don't understand how to implement it for what I am looking to do with regard the changes made via the registry resource and script resource.

How would I tell a server to reboot after a registry setting/key has been changed using the registry resource.
Example:

#Registry Resource: to add a SNMP Community
        Registry mckreed
        {
            Ensure = "Present"
            Key = "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\SNMP\Parameters\ValidCommunities"
            ValueName = "mckreed"
            ValueType = "DWord"
            ValueData = "4"
        }
#Script Resource: Disables LMHosts on all Enabled Adapters
        Script "Disables LMHosts on enabled adapters"
        {
          SetScript = {
            $NicEnabled = $null
			$NicGUID = $null
			$NicEnabled = Get-WMIObject -class Win32_NetworkAdapterConfiguration | where-object {$_.IPEnabled -eq "True"}
			
			Foreach ($Nic in $NicEnabled) {
			$NicGUID = $Nic.SettingID

			Set-ItemProperty "HKLM:\System\CurrentControlSet\Services\TCPIP\Parameters\Interfaces\$NicGUID" -Name "EnableLMHOSTS" -Value "0"
			}
        }
        TestScript = {
          #false
			$LMHostsDisabled = $True
			$NicEnabled = $null
			$NicGUID = $null
			$NicEnabled = Get-WMIObject -class Win32_NetworkAdapterConfiguration | where-object {$_.IPEnabled -eq "True"}
			foreach ($Nic in $NicEnabled) {
			$NicGUID = $Nic.settingID
			$LMHosts = Get-ItemProperty "HKLM:\System\CurrentControlSet\Services\TCPIP\Parameters\Interfaces\$NicGUID"
			If ($LMHosts.EnableLMHOSTS -notlike "0") {$LMHostsDisabled = $false}
			}
			$LMHostsDisabled
		
		}
        GetScript = {
        return @{Result="Disables LMHosts on Enabled Adapters"}
    }
    }

How could I make a node reboot if either of these changes gets applied?

Thanks

March 1, 2016 at 8:41 am

Thanks Dave, I just saw your response after I updated. I suspected as much regarding the Script resource but was hoping I was just missing something regarding the Registry resource.

Thanks for the explanation. 🙂

March 1, 2016 at 8:44 am

I would probably create myself a custom version of the Registry resource that accepts a RebootIfChanged setting. If you set that to True, then the Set will set the global variable.

        MyBetterRegistry mckreed
        {
            Ensure = "Present"
            Key = "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\SNMP\Parameters\ValidCommunities"
            ValueName = "mckreed"
            ValueType = "DWord"
            ValueData = "4"
            RebootIfNeeded = $True
        }

You could also code this up as a Script resource, I suppose. Setting the registry obviously isn't all that hard.

But as Dave mentioned, there's no straight-up way to do this using the Microsoft Registry resource, because it wasn't designed to.

March 1, 2016 at 9:00 am

The only problem with that is that the system will reboot after each key that gets modified, which is just ugly. What I'd rather see is a bunch of registry changes done, then a single reboot, and that's not very cleanly done with a single resource (but easily accomplished if we can get one DSC resource to check the status of others later down the line.)

March 1, 2016 at 9:32 am

You'd almost want a custom Registry resource that could take a batch of keys to check and set, all in one atomic operation. If ANY of them needed Set, you'd trigger the reboot when you exited.

We almost need a syntactical ResourceGroup{} element – "these things all go together, but can be treated apart from everything else in this document." I'm not sure it'd every apply to more than rebooting, but from that perspective it'd be nice.

March 1, 2016 at 9:40 am

That's exactly what I wanted to accomplish with the ConditionalScript resource. Something like:

ConditionalScript RebootIfNeeded
{
    TriggeredBy = @('[Registry]KeyOne', '[Registry]KeyTwo', 'etc')
    DependsOn = @('same', 'as', 'TriggeredBy')
    Action = { $global:DSCMachineStatus = 1 }
}

The problem was that I couldn't find a good way to determine the status of the _current_ DSC operation (unless the Analytic log was already enabled).

March 1, 2016 at 11:04 am

The easy and dirty fake would be...

1. Modify Registry to accept some kind of "RebootWillBeRequired." If it runs a Set, set a $global:RegistryWantsReboot to $True.

2. Write a Script resource that depends on all your Registry ones, and if $globalRegistryWantsReboot then set $global:DscMachineStatus.

Dave, your bigger suggestion would require changes in the LCM, which you should suggest. A global variable listing the current operation ($global.DscCurrentOperation, with properties for resource, name, and a hash table of properties). Ideally, some temp version of the Analytics log that exists only for the current consistency run, and tracks what's been run, and is programmatically accessible. it'd add some state to what is essentially a stateless thing.