Thursday 22 September 2016

Pulling teeth!

Ok, let me just say up front, the Pull Server rocks! The centralised management and scale that it delivers is great. It is all good dude, but...

When learning how to use a Pull Server to distribute node configuration you have to keep a few things in mind in order to make things work. This is what I have learnt so far:

  • The event log is your friend, get to know it well
    • There is a resource available to help diagnose DSC issues called xDscDiagnostics - it is a good place to start.
  • Remember that publishing a new configuration to the pull server does not mean it is just going to get applied on the target the next time the target node LCM fires up, it depends what the state of the Pending Configuration is.
    • Remove-DscConfigurationDocument can be used to pull the plug on a misbehaving config
    • Removing a misbehaving config will not remove a misbehaving Resource (ermm, deleting the resource folder on the target node seems an easy way to fix this but not necessarily the right way)
      • You can delete a Resource from the module directory on the Target Node but the old one will still be in memory (it's cached) so you may have to bounce the node for it to start using the new one {I'm open to suggestions here}
      • I am playing with versioning to resolve this one too
      • DebugMode = 'All' breaks the LCM with Custom Resources that are classes :-(
So here is my plan of action for a Pull Server Scenario
  1. Configure the LCM on the Target Node for PULL
  2. Use Get-DscLocalConfigurationManager cmdlet to verify LCM settings
  3. Publish necessary Resources to Pull Server
  4. Publish the Target Node Configuration to the Pull Server
  5. Use Update-DscConfiguration cmdlet to get LCM on Target Node to look for the configuration
  6. Use Get-DscLocalConfigurationManager cmdlet to check that LCM is Busy applying the configuration
  7. Use xDscDiagnostics to query the event log of the Target Node to see what is going on
This is all good except for the last step. One thing I really like about the PUSH scenario is that you can use the -verbose and -wait parameters of the Start-DscConfiguration cmdlet to watch what is going on as it happens. I decided to write a function that would give me similar output in a PULL scenario so that I don't have to use different tools and techniques for diagnostics just because I changed from PUSH to PULL.

So far, this helps:

function Get-DscOperationsEventInfo
{
    Param(
        [String]$ComputerName = $env:COMPUTERNAME,
        
        [Int]$Range = 30
    )

 # ensure firewall is configured
 [String]$firewall_group = 'Remote Event Log Management';
 if (Get-NetFirewallRule -CimSession $ComputerName -DisplayGroup $firewall_group | Where-Object { $_.Enabled -ne $true})
 {
  Write-Host "Enabling Firewall for $firewall_group on $ComputerName" -ForegroundColor Cyan;
  Enable-NetFirewallRule -CimSession $ComputerName -DisplayGroup $firewall_group;
 }

    # get all dsc events   
    $dsc_events = [System.Array](Get-WinEvent -ComputerName $ComputerName -LogName "Microsoft-Windows-Dsc/Operational");
             
    $low_boundry_date = (Get-date).AddMinutes(-$Range);    
    $filtered_dsc_events = $dsc_events | Where-Object {$_.TimeCreated -gt $low_boundry_date} | Sort-Object TimeCreated;
    
    foreach($event in $filtered_dsc_events){
        $output = "$($event.TimeCreated):`n`r$($event.Message)`n`r";
        if($event.LevelDisplayName -eq 'Error'){
            Write-Host $output -ForegroundColor Red;
        } else {
            Write-Host $output -ForegroundColor Cyan;
        }
    }
}

No comments:

Post a Comment