Setting 'RebootIfNeeded' throughout the Configuration

Tagged: 

This topic contains 3 replies, has 3 voices, and was last updated by Profile photo of Joe Joe 1 month, 3 weeks ago.

  • Author
    Posts
  • #69807
    Profile photo of Jacqueline Porter
    Jacqueline Porter
    Participant

    Dear all,
    I have a huge configuration of an application development server that needs to reboot a few times.
    I've configured the LCM with 'RebootNodeIfNeeded = $True' and I'm using xPendingReboot to control the reboots throughout the config. I'm not using a pull server.

    At some point in the config I don't want the node to auto-reboot anymore. But AFAIK I can only change the RebootNodeIfNeeded setting by running Set-DscLocalConfigurationManager again.

    I tried something like this:

    Script DisableAutoReboot {  
        SetScript  = {
            Set-DscLocalConfigurationManager -Path c:\DSC\DisableAutoReboot
        }
        TestScript = {
        $val = $True
        If ((Get-DscLocalConfigurationManager).RebootNodeIfNeeded) {
                 $val = $False
            }
        return $val
        }
        GetScript  = {
            @{Result = (Get-DscLocalConfigurationManager).RebootNodeIfNeeded}
            }
        }
       }
     }
    

    But then I get: The Start-DscConfiguration cmdlet is in progress and must return before Set-DscLocalConfigurationManager can be invoked.

    My question is, is this even possible? Apologies if this is a beginner question.

    Jacqueline

  • #69808
    Profile photo of Don Jones
    Don Jones
    Keymaster

    It's really not. You're correct in that you have to reconfigure the LCM, and you can't do that while it's processing a configuration. The most you could do is manually inject a new meta-MOF, but it wouldn't be processed until the next run.

    • #69838
      Profile photo of Jacqueline Porter
      Jacqueline Porter
      Participant

      Thanks for the answer. I will break up the Configuration in smaller pieces then.

  • #71926
    Profile photo of Joe
    Joe
    Participant

    I have a similar problem and ended up breaking it into sections and then checking to see it a reboot needed to occur. In some cases I wanted to trigger a reboot in others the various resources were potentially triggering a reboot.

    I ended up using the Get-PendingReboot script by Brian Wilhite, and modifying it to also look for my particular reboot trigger

    So I use the following function to Push my configurations, you will notice the call to WaitForServer that takes a parameter of $EncodedText. $EncodedText is just a structure of server information that I use to set up the configuration data and track which servers I want to deploy as part of this scenario.

     Function DoDscStuff($mofpath,$title)
            {
              if (Test-Path (Join-path $mofpath -ChildPath "*") -Include *.mof)
              {
                #
                # To get the output to a log file
                # https://github.com/PowerShell/SharePointDsc/issues/218
                #
                Dump  '----------------------------------------------------------------------------'
                Dump  "               $title"
                Dump  '----------------------------------------------------------------------------'
    	    Dump  ' '
                Dump  ('MOFPath     = {0}' -f $mofPath)
                $errorCount = 0
                $Error.Clear()	       
    	
    		    if($LogToScreen)
    		    {
    			    Start-DscConfiguration -Path $mofpath -Wait -Force -credential $InstallerCredential  -Verbose 
    
                    if( $error.Count -gt $errorCount )
                    {
                        $AccessDeniedError = $false
                        $dscErrors = $error[$errorCount..($error.Count - 1)];
                        Foreach($prob in $dscErrors)
                        {
                            if($prob.FullyQualifiedErrorId -like '*0x80070005*')
                            {
                                $AccessDeniedError = $true
                                break;
                            }
                        }
                        if($AccessDeniedError)
                        {
                            $errorCount = 0
                            $Error.Clear()
                            Write-Host 'Attempting alternate credentials' -ForegroundColor Yellow
                            Start-DscConfiguration -Path $mofpath -Wait -Force -credential $ChildDomainCred  -Verbose 
                        }
                    }
    		    }
    		    else
    		    {
    			    Start-DscConfiguration -Path $mofpath -Wait -Force -credential $InstallerCredential -Verbose -Debug *>>  $logFile
    
                    if( $error.Count -gt $errorCount )
                    {
                        $AccessDeniedError = $false
                        $dscErrors = $error[$errorCount..($error.Count - 1)];
                        Foreach($prob in $dscErrors)
                        {
                            if($prob.FullyQualifiedErrorId -like '*Access is Denied*')
                            {
                                $AccessDeniedError = $true
                                break;
                            }
                        }
                        if($AccessDeniedError)
                        {
                            $errorCount = 0
                            $Error.Clear()
                            Write-Host 'Attempting alternate credentials' -ForegroundColor Yellow *>> $logFile
                            Start-DscConfiguration -Path $mofpath -Wait -Force -credential $ChildDomainCred  -Verbose -Debug *>>  $logFile 
                        }
                    }
    		    }
                Dump  ' '
    		    Dump  '----------------------------------------------------------------------------'
    		    if( $error.Count -gt $errorCount )
                {
                    $dscErrors = $error[$errorCount..($error.Count - 1)];
                    Dump "The following errors occurred during dsc configuration"
                    Dump ($dscErrors | fl * | out-string)
    
                    $NonTermErrorFound = $false
                    Foreach($prob in $dscErrors)
                    {
                        if($prob.FullyQualifiedErrorId -like '*NonTerminatingError*')
                        {
                            $NonTermErrorFound =$true
                            break
                        }
                    }
                    if(!$NonTermErrorFound){throw $dscErrors[-1];}
                }
                else
                {
                  WaitForServers $EncodedText
                }
              }
            } 
    Function WaitForServers{
        [CmdletBinding()]
        Param(
        [Parameter(Mandatory = $true,Position=0)] 
        [string]$EncodedText
    
        ,[Parameter(Mandatory = $false)] 
        [int]$sleep=20
        )
        
        $Servers = ConvertFrom-Json ([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($EncodedText)))
    
        $Computers = $Servers | ?{$_.BuildMe -eq 1} | Select-Object -ExpandProperty name
    
        $ServersToReboot = ((Get-PendingReboot -ComputerName $Computers)|?{$_.RebootPending -eq $true} | Select-Object -ExpandProperty Computer)
    
        if ($ServersToReboot -ne $null)
        {
            Restart-Computer $ServersToReboot -Force -Wait -For WinRM -Timeout 300 -Delay 5
    
            #Clean up any reboots triggered by ECI
            $HKLM = [UInt32] "0x80000002"
            Foreach($server in $ServersToReboot)
            {         
                $WMI_Reg = [WMIClass] "\\$server\root\default:StdRegProv"
                $WMI_Reg.DeleteKey($HKLM, "Software\DesiredStateConfiguration\RebootPending") | Out-Null
            }
        }
    }

    I use the following script to set my Reboot Flag so that I can control when it gets set

    Script Reboot
            {
                SetScript = Format-DscScriptBlock -Node $Node -ScriptBlock {
                    Write-Verbose "Setting Reboot Pending"
                    New-Item -Path "HKLM:\Software\DesiredStateConfiguration\RebootPending" -Force ;
                    return $true;
                }            
                TestScript =Format-DscScriptBlock -Node $Node -ScriptBlock  {
                    return (Boolean result from your Test);
                }
                GetScript = {@{Result = 'Doing Nothing'}} 
            }

    Hope this help in some small way.

    Joe

You must be logged in to reply to this topic.