Using DSC with the WinRM service disabled


Every once in a while I come across a weird scenario where the customer’s requirements and/or limitations are so challenging that they take me to a interesting discovery journey.

This time, the requirement was to use Desired State Configuration (DSC) in remote machines where there was no connectivity (with any protocol or port) to them from the central management point except with their proprietary agents. And the most strict requirement was to have the WinRM service locally disabled. So how can we use DSC to configure the machines and have them constantly compliant, when the simple Start-DSCConfiguration cmdlet fails because the WinRM service is disabled?

We ended up using their agent to transmit text commands, where those commands would include the content of the mof files as a byte array, then write the bytes to a local mof file and initiate a CIM method to start the configuration. The last part is pretty much the same as what Start-DscConfiguration does.

Below are snippets of the code I used for this:




# Declare the configuration:

Configuration TestDscWithoutWinRm {


    Import-DscResource –ModuleName PSDesiredStateConfiguration


    node localhost {


        File akada {

            Ensure          = ‘Present’

            Type            = ‘File’

            Contents        = ‘Martin was here!’

            DestinationPath = ‘C:\Temp\test.log’





# Run the configuration to create the MOF file:








# This will NOT work without the WinRM service running:

Start-DscConfiguration -Wait -Verbose -Path .\TestDscWithoutWinRm


# This is one a workaround for the first apply:

Copy-Item -Path .\TestDscWithoutWinRm\localhost.mof C:\Windows\System32\Configuration\pending.mof -Force

Invoke-CimMethod -Namespace root/Microsoft/Windows/DesiredStateConfiguration -ClassName MSFT_DSCLocalConfigurationManager -Method PerformRequiredConfigurationChecks -Arguments @{Flags = [System.UInt32]1}


# This is another workaround for the first apply:

$configData = [byte[]][System.IO.File]::ReadAllBytes((Resolve-Path -Path ‘.\TestDscWithoutWinRm\localhost.mof’))

Invoke-CimMethod -Namespace root/Microsoft/Windows/DesiredStateConfiguration -ClassName MSFT_DSCLocalConfigurationManager -Method SendConfigurationApply -Arguments @{ConfigurationData = $configData; force = $true}







# This is the workaround for re-applying the current configuration:

Copy-Item -Path C:\Windows\System32\Configuration\current.mof C:\Windows\System32\Configuration\pending.mof -Force

Invoke-CimMethod -Namespace root/Microsoft/Windows/DesiredStateConfiguration -ClassName MSFT_DSCLocalConfigurationManager -Method ApplyConfiguration -Arguments @{force = [bool]$true}







# This doesn’t work without the WinRM service:



# This is a workaround:

Invoke-CimMethod -Namespace root/Microsoft/Windows/DesiredStateConfiguration -ClassName MSFT_DSCLocalConfigurationManager -Method TestConfiguration





With all the above being said, the WinRM protocol is secured, especially if you are in a domain environment and the traffic is encrypted with the Kerberos ticket. You can also use https (configure SSL certificates in the plugins) to to have the traffic encrypted in a non-domain environment (e.g. DMZ, or cross domains with no trust). Unfortunately, too much (where not really needed) security is just an unpleasant overhead in administration.




Comments (2)

  1. Michael King says:

    Is this an officially support method by Microsoft for using PowerShell DSC?

    1. No. This is just a workaround I had to implement in an extreme scenario.
      Official documentation for supported workarounds are published as KB articles at

Skip to main content