Debugging and troubleshooting configuration script files

So, you ran a DSC configuration against a target node using either Start-DscConfiguration or a Pull Server and you want to look at the logs for its execution. Where do you go? If you ran it with Start-DscConfiguration and the Verbose parameter, then you will have a log in your console, but that goes away when you close your console, and you don't have this available with a Pull Server.

Worry not, for DSC provides a rich set of information from each operation it performs, although it's not always easy to access this information.

Using DSC event logs

Like most Windows software, DSC writes all event information to a Windows event log, which can be viewed with many applications, including Event Viewer and PowerShell.

DSC logs these events to the Microsoft-Windows-Dsc event log, which has the following channels:

  • Microsoft-Windows-Dsc/Operational
  • Microsoft-Windows-Dsc/Debug
  • Microsoft-Windows-Dsc/Analytic

Enabling verbose logging

The Analytic and Debug channels are not enabled by default, and have to be enabled on each target node before any events are written to them:

# enable analytic and debug DSC channels
wevtutil.exe set-log "Microsoft-Windows-Dsc/Analytic" /q:true /e:true
wevtutil.exe set-log "Microsoft-Windows-Dsc/Debug" /q:True /e:true

What do DSC event logs contain?

DSC events are split over the three event log channels, depending on the importance and purpose of the message. All informational and error messages are logged to the Operational channel. The Analytic channel receives verbose events, which typically means more events in general and events are that more granular in the information they provide. The Debug channel receives debug-level events from the DSC operations.

This is helpful because it separates the information into easily filterable buckets that it makes logical sense to group together. This is also less helpful, however, because it may mean that you have to look in multiple places to find all the information necessary to troubleshoot a problem.

Gathering events from a single DSC operation

We can use Windows Event Viewer or PowerShell to view all events from all DSC channels. Event Viewer is good for interactive sessions, but it is not great for automated scenarios and is not easily exportable. The PowerShell approach requires more typing, but is easier to export to formats that allow easier inspection.

Event Viewer

On Windows 2008 and above, Event Viewer was upgraded with advanced filtering capabilities. We can use the custom view feature to select all the events from the three DSC channels and present them in one view for the purpose of investigation, following the given steps:

  1. Open up the Windows Event Viewer and navigate to the Custom View node in the Action pane.
  2. Right-click on the Custom View node and select Create Custom View.
  3. Click on each event type you want. For now, select all of them.
  4. Click on the drop-down for the event logs and navigate to the DSC channels.
  5. Select all the DSC channels.
  6. Click on OK.
  7. View the DSC events in a single pane.

PowerShell

We can use the Get-WinEvent Cmdlet to gather DSC events. We can query the DSC channels and store the events in an array, and then use the Group-Object Cmdlet to arrange them by the ID property:

# collect all logs from all channels
$dscEvents = @(
  Get-WinEvent "Microsoft-windows-Dsc/operational"
  Get-WinEvent "Microsoft-Windows-Dsc/Analytic" -Oldest
  Get-WinEvent "Microsoft-Windows-Dsc/Debug" –Oldest
) 

If you are wondering if you can skip using Oldest with the Analytic and Debug logs, you can't. The error that appears when you try explains why:

[PS]> Get-WinEvent "Microsoft-Windows-Dsc/Analytic"
Get-WinEvent : The Microsoft-Windows-DSC/Analytic event log can be read only in the forward chronological order
because it is an analytical or a debug log. To see events from the Microsoft-Windows-DSC/Analytic event log, use the
Oldest parameter in the command.
At line:1 char:1
+ Get-WinEvent "Microsoft-Windows-Dsc/Analytic"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (Microsoft-Windows-DSC/Analytic:String) [Get-WinEvent], Exception
    + FullyQualifiedErrorId : SpecifyOldestForLog,Microsoft.PowerShell.Commands.GetWinEventCommand

Further querying can be performed on the resulting data by sorting and grouping the result objects:

# group all logs based on the job ID
$operations = $dscEvents | Group-Object {$_.Properties[0].value}

For example, you can find all events that have the Error severity level by searching for Error:

$operations | Where-Object {$_.Group.LevelDisplayName -contains "Error"}

Or, you could examine the message from a single event:

$operations[0].Group.Message

Or, find all events from a specific job ID:

($operations | Where-Object {$_.Name -eq 2025}).Group

Using the xDscDiagnostics module to analyze DSC logs

After reading the previous explanation, you may throw up your hands in frustration at the amount of work that needs to be done to view any useful information. The xDscDiagnostics PowerShell module provided by Microsoft directly addresses this frustration. It wraps much of the tasks above into two Cmdlets that can help you identify DSC events on both the local machine and remotely against a target node. This is a great help in diagnosing and pinpointing issues with DSC.

For the purposes of this module, we will define a DSC operation as the set of events that describe a DSC execution from start to finish. For example, the events generated from Start-DscConfiguration will be separate from those generated from Test-DscConfiguration.

Get-xDscOperation

The Get-xDscOperation Cmdlet works on both local and remote target nodes and returns an object that contains the collection of events produced by each DSC operation run on the target node. Each object returned is a Microsoft.PowerShell.xDscDiagnostics.GroupedEvents object, which is the collection of all events for a specific DSC execution. This object reports the sequence ID, the time the DSC operation began, the name of the target node being queried, the success or failure result, and all events produced by the DSC operation.

Trace-xDscOperation

The Trace-xDscOperation Cmdlet works on both local and remote target nodes, and returns a collection of events related to a specified sequence ID. Typically, you will run Get-xDscOperation and choose a specific sequence ID to run Trace-xDscOperation against.

While Get-xDscOperation provides a general overview of what happened during a DSC operation, Trace-xDscOperation provides specific detail. The most notable part of this detail is the message field, which reports the exact text or error reported by DSC when executing the operation.

Resetting the DSC engine cache

The DSC engine caches any DSC Resources or DSC composite resources stored in any of the PSModule locations. DSC does this to speed up the discovery, parsing, and execution of the various elements inside DSC, but this can cause problems if you are activating developing DSC configurations using DSC Resources or DSC composite resources that are also in active development. DSC will keep these resources cached until the DSC processes are restarted.

The only way to make or force DSC to reset its cache is to restart the process hosting the DSC engine. The easiest but least preferable way to do this is rebooting the server. When you restart, the DSC engine will have cleared its cache and read in your current resources. To reset the cache without restarting the server, you must stop and start the host process. How you go about doing this differs in DSC v4 and v5.

In DSC v4, you perform a brute force approach:

Get-Process *wmi* | Stop-Process -Force;
Restart-Service winrm –Force

In DSC v5, there is a way provided:

$dscProcessID = Get-WmiObject msft_providers |
    Where-Object {$_.provider -like 'dsccore'} |
    Select-Object -ExpandProperty HostProcessIdentifier
Get-Process -Id $dscProcessID | Stop-Process

While this is effective, there is a way to avoid having to take this brute force approach in DSC v5. In the next paragraph, we'll take a look at how to configure DSC to not cache DSC Resources.

Enabling the debug mode

We can avoid having to reset the DSC cache frequently by enabling the debug mode in DSC. However, this mode is only available in DSC v5, so if you are still using v4, you will have to keep refreshing the cache.

To enable the debug mode, we use the same methods we described in the previous chapter to configure the LCM:

LocalConfigurationManager
{
    DebugMode = $true
}

Fixing a stuck DSC run

You may come across a situation where a DSC configuration run has been executed, but failed at some point in the process. Perhaps you have fixed the problem or simply want to run it again, but DSC provides the following error:

Cannot invoke the SendConfigurationApply method. The SendConfigurationApply method is in progress and must return
before SendConfigurationApply can be invoked.
+ CategoryInfo  : NotSpecified: (root/Microsoft/...gurationManager:String) [], CimException
+ FullyQualifiedErrorId : MI RESULT 1
+ PSComputerName: box1

This means that DSC thinks there is an execution run currently in progress and it's trying to protect you by not running another execution run. If more than one execution is allowed to run at the same time, then DSC could not guarantee that the desired state is in effect. So, we need to tell DSC to ignore the failed last run and start a new one. We do this by following the same procedure for refreshing the DSC cache with one additional step. We also remove the pending.mof file so that DSC does not have any record of a past run that failed. Don't worry; the last run is still recorded for the target node's state if you set up the DSC compliance server part of the DSC Pull Server, as shown:

Remove-Item $env:systemRoot/system32/configuration/pending.mof -Force;
Get-Process *wmi* | Stop-Process -Force;
Restart-Service winrm -Force 

In WMF5, we could use Start-DscConfiguration –Force to avoid having to do this.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset