Troubleshooting DSC Resources

Use this guide to troubleshoot issues with Puppet code containing DSC resources.

The resource appears to change on each Puppet run

Some DSC resources do not properly validate their own parameters. For example, a resource might accept an integer value, but then retrieve the saved value from the system as a string. When this happens, Puppet cannot tell that the resource is in the desired state and enforces the resource each time it runs.

To resolve this issue, you need to instruct the resource to do resource level validation. Instead of checking each parameter of the resource for desired state, Puppet manages the entire resource as one unit and lets the PowerShell DSC resource identify whether it needs to be updated or not. You do not get log messages about which parameter was corrected, just that the entire resource was changed.

Here is an example of a resource that has this issue:

dsc_securityoption { 'Enforce Anonymous SID Translation':
  dsc_name => 'Enforce Anonymous SID Translation',
  dsc_network_access_allow_anonymous_sid_name_translation => 'Disabled',
}
For this to apply correctly, you need to specify the validation_mode parameter:
# This idempotently applies
dsc_psrepository { 'PowerShell Gallery':
  validation_mode => 'resource',
  dsc_name        => 'Enforce Anonymous SID Translation',
  dsc_network_access_allow_anonymous_sid_name_translation => 'Disabled',
}

Error message about a missing PowerShell file

The maximum length of a path accepted by the Windows API is MAX_PATH or 260 characters. There are some PowerShell DSC resources that include file paths of this length. Once they are vendored in Puppet modules, the paths exceed MAX_PATH and Puppet runs fail with an error, for example:

PS> puppet agent -t
PS C:\Users\Administrator> puppet agent -t
Info: Using configured environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Error: dsc_xrdserver: The term 'Get-RDServer' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Info: Caching catalog for dynamic-trouble.delivery.puppetlabs.net
Info: Applying configuration version '1623366685'
Error: dsc_xrdserver: The term 'Get-RDServer' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Error: /Stage[main]/Main/Node[default]/Dsc_xrdserver[test]: Could not evaluate: undefined method `[]' for nil:NilClass
Notice: Applied catalog in 0.95 seconds

The dsc_xrdserver resource exists, but the PowerShell script it runs cannot create the Get-RDServer cmdlet because one or more files exceeded the path length and were never written to disk.

In Windows 10 and Windows Server 2016 (version 1607 and later), you can enable long path support with a registry key. The long paths are supported by versions 6.23 and 7.8 and later. To enable long path support, update your Windows agents and apply the following Puppet code:

registry::value { 'LongPathsEnabled':
  key  => 'HKLM\SYSTEM\CurrentControlSet\Control\FileSystem',
  type => dword,
  data => '1',
}

Your Puppet run has data type conversion errors

Sometimes a PowerShell DSC Resource uses the wrong data type for parameters. The DSC resource still works with DSC because that system does not validate data types like Puppet can. If you pass the wrong data type to the resource, you might see the following errors:

Error: dsc_psrepository: Convert property 'name' value from type 'SINT64' to type 'STRING' failed
Error: Parameter dsc_name failed on Dsc_psrepository[Foo]: dsc_psrepository.dsc_name expects a String value, got Integer

These errors mean that a string was expected. To resolve this issue, update your code to declare the correct data type or enum value. If this still results in Puppet data type errors, you need to file a bug to the maintainers of the PowerShell DSC resource to correct the data type annotations. When the module has been updated and published to the PowerShell Gallery, it is automatically updated in Puppet Forge the following day.

PowerShell invocation errors

When a DSC invocation goes wrong, Puppet shows the error PowerShell DSC returned. How explicit the error message is depends on the underlying DSC implementation for that resource in PowerShell. It could look something like:

Error: dsc_psrepository[{:name=>"Bar", :dsc_name=>"Bar"}]: Creating: PowerShell DSC resource MSFT_PSRepository  failed to execute Set-TargetResource functionality with error message: The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: The repository could not be registered because there exists a registered repository with Name 'Foo' and SourceLocation 'C:\Foo'. To register another repository with Name 'Bar', please unregister the existing repository using the Unregister-PSRepository cmdlet.

In this example, the error is explicit — the specified source location is already being used with another PSRepository. To clear this error, you need to either change the source location or remove the other PSRepository.

Resolving these kind of errors can require extra troubleshooting.

Access the debug log

If you cannot troubleshoot your issue, file a support ticket and provide the debug log with your ticket.

To access the debug log, add --debug to the end of the Puppet run command:
PS C:\Users\administrator> puppet agent -t --debug | Out-File -FilePath debug.log

Save the debug log as a text file and attach it to your support ticket.

The log tells you what Puppet is doing, which values are being passed to PowerShell, what the outcome of the run was, and provides you with the full text of the PowerShell script being executed (with sensitive information redacted).

Note: The code being run is a PowerShell script. This means you can use the log to debug issues the same way you would with any other PowerShell script.