Handling reboots in DSC

This topic contains 9 replies, has 3 voices, and was last updated by Profile photo of Don Jones Don Jones 9 months ago.

  • Author
    Posts
  • #35861
    Profile photo of Ed O'Connor
    Ed O’Connor
    Participant

    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.

  • #35862
    Profile photo of Don Jones
    Don Jones
    Keymaster

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

  • #35865
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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.

  • #35869
    Profile photo of Ed O'Connor
    Ed O’Connor
    Participant

    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

  • #35870
    Profile photo of Ed O'Connor
    Ed O’Connor
    Participant

    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. 🙂

  • #35871
    Profile photo of Don Jones
    Don Jones
    Keymaster

    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.

  • #35876
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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.)

  • #35879
    Profile photo of Don Jones
    Don Jones
    Keymaster

    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.

  • #35880
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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).

  • #35881
    Profile photo of Don Jones
    Don Jones
    Keymaster

    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.

You must be logged in to reply to this topic.