Minimal WSMan requirement to push locally a Desired State Configuration

I’ve been working on a deployment scenario where I’ll provision new computers from a PBR (Push Button Reset) image.

These laptops will run Windows 8.1 and the PBR image is actually a sysprep image that is configured to run a post-install script.

When the PC is provisionned or reset, the PBR image is applied/expanded to the C: drive and the post-install script is run at the end of the OOBE (Out-of-Box Experience) phase, just before the user can logon.

To configure Windows Updates settings, some registry keys, services,… DSC (Desired State Configuration) is the way to go as it’ll ensure the PC remains compliant even if there’s a drift later between 2 resets or/and the PC isn’t connected to any network.

As you may know DSC depends on WSMan and not on PSRemoting.
There’s a myth about PSRemoting that was uncovered by PowerShell Magazine and Windows PowerShell MVP Aleksandar Nikolic:

If I push a DSC config without configuring WSMan, I hit a wall and get this message:
The client cannot connect to the destination specified in the request.
Verify that the service on the destination is running and is accepting requests.
Consult the logs and documentation for the WS-Management service running on the destination, most commonly IIS or WinRM.
If the destination is the WinRM service, run the following command on the destination to analyze and configure the WinRM service: “winrm quickconfig”.
+ CategoryInfo : ConnectionError: (root/Microsoft/…gurationManager:String) [], CimException
+ FullyQualifiedErrorId : HRESULT 0x80338012
+ PSComputerName : localhost

I’d also get the above error message whenever the WinRM service is stopped or the WSMan listener is absent.

To fix it, I should run the following the Set-WSManQuickConfig because the computer isn’t joined to a domain.

Set-WSManQuickConfig -SkipNetworkProfileCheck

This would enable the WinRM firewall rule for the ‘Public’ profile and expose the WinRM to the localNetwork it’s connected to.
It would also set the LocalAccountTokenFilterPolicy registry value to remove the UAC remote restriction.

The above steps aren’t required to push locally (vs. over the wire) a DSC configuration.
The attack surface can actually be reduced so that the DSC configuration can only be pushed locally.
The non-domain joined Windows 8.1 PBR images can leverage DSC as soon as I:

# 1. Enable and start the WinRM service
Stop-Service -Name WinRM -PassThru | 
Set-Service -StartupType Automatic -PassThru | 

# 2. Enable and restrict the firewall rules 
# to localhost instead of LocalNetwork
Get-NetFirewallRule -Name @(
    'WINRM-HTTP-In-TCP', # Pubic
    'WINRM-HTTP-In-TCP-NoScope') | #Domain,Private
Enable-NetFirewallRule -PassThru | 
Get-NetFirewallAddressFilter | 
Set-NetFirewallAddressFilter -RemoteAddress ""

# 3. Add a listener (the firewall already enforces a restriction)
Get-ChildItem -Path WSMan:\localhost\Listener -Include listener* | 
Remove-Item -Recurse
New-WSManInstance winrm/config/Listener -SelectorSet @{

# 4. Disable Kerberos, not required in workgroup for local authentication
Set-Item -Path WSMan:\localhost\Service\Auth\Kerberos  -Value $false -Force
Set-Item -Path WSMan:\localhost\Service\Auth\Negotiate -Value $true  -Force

Voilà, my post-installation DSC configuration can be pushed locally whenever Windows 8.1 is reset on the device.


One thought on “Minimal WSMan requirement to push locally a Desired State Configuration

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s