Tome's Land of IT

IT Notes from the Powertoe – Tome Tanasovski

Enable WinRM with Group Policy, but use PowerShell to Create the Policy

This past weekend I finished my chapter on Group Policy for the PowerShell Bible.  One of my coauthors asked me if I was going to include a script that configures WinRM (PowerShell remoting) via group policy in my chapter.  Truth be told, I hadn’t thought of it, but I love a challenge!

Unfortunately, when all was said and done the script that I wrote was a bit overly wordy and dug deeply into concepts that were out of scope for the 12 page chapter I was writing on the GroupPolicy module that ships with the Group Policy Management Console (GPMC) in 2k8R2 and RSAT.  Except for a few minor quirks like using ‘Yes’ and ‘No’ for parameter values instead of using $true and $false, the GroupPolicy module is a really great set of cmdlets because of what you can do with it.  You can create GPO reports, RSOPs, manage links, manage security, adjust inheritance, and backup and restore extremely easily (feel free to preorder the book to see just how easy ;)).

The final bit that makes this module amazing is that you can dynamically manipulate the GPO settings themselves as long as they are either ADMX/ADML registry changes or the relatively new 2008 registry settings under preferences.  Actually, you don’t even need an ADMX/ADML with a registry specified to create an ad-hoc registry change within a policy via the cmdlets (mind you this screws up your normal GPMC view when you do so – they look like orphaned settings like you would see when someone accidentally deletes an admx from your system).  The problem with the cmdlets that let you modify and work with these registry settings is that they are completely disconnected from the ADMX/ADMLs.  In other words you must specify the registry key, name, and value you want the policy to change rather than the name of the setting you are looking to change that is shown in the ADML and the GPMC – names like “Allow automatic configuration of listners”.  The only way you can get these registry keys and possible values is to manually crack open the ADMX/ADML files to see what each setting is touching.  This means you need to do a lot of detective work in order to script changes to a GPO.

Enabling WinRM via group policy is pretty decently documented on many blogs out there on the Internet.  It requires you to touch three places: the WinRM settings, the firewall, and the place where you configure services to start up automatically.  The WinRM settings were easy to track down because it has an ADMX and ADML file.  I was able to crack them open to find that the policy makes changes to this key: HKLM:\Software\Policies\Microsoft\Windows\WinRM\Service.  The firewall setting was a bit trickier because there is no direct ADMX and ADML file, but I saw that the following key was created after the GPO was applied to my computer: HKLM:\Software\Policies\Microsoft\WindowsFirewall\FirewallRules.  The name and value you need to set are both long and undocumented (as far as I can tell), but they make perfect sense.  The final bit was figuring out how to start the service.  This wound up being ridiculously tricky.  After a lot of tinkering I learned that service startup and security information is stored in a flat file in sysvol called GptTmpl.inf underneath the GUID for the policy.  In the end the script really speaks for itself.

I am dying to have someone else try this script out to see if everything works perfectly on another 2k8R2 domain.  It’s possible that I have something tied directly to my domain (other than the OU at the beginning), but I’m not sure.  I’m concerned that the firewall settings need LDAP objects to be created or updated.  Please let me know in the comments if you get it to work or have any problems.

Without further ado, todo, and blahdoo, I present a script to generate a GPO to enable WinRM in your domain that will be bound to an OU you specify in $OU (yes I’m too lazy to param()).

Import-Module GroupPolicy

# Specify the OU to link the GPO to
$OU = 'OU=TheIsland,DC=home,DC=toenuff,DC=com'

# Create the GPO
$gpo = New-GPO Remoting -Comment 'GPO that will enable remoting'

# Add the policy to allow WinRM
$winrmkey = 'HKLM\Software\Policies\Microsoft\Windows\WinRM\Service'
$params = @{
    Key = $winrmkey;
    ValueName = 'AllowAutoConfig';
    Value = 1;
    Type = 'Dword';
$gpo |Set-GPRegistryValue @params

# Set the filters to allow IPv4 and IPv6 traffic from all IPs for WinRM
$winrmkey = 'HKLM\Software\Policies\Microsoft\Windows\WinRM\Service'
$params = @{
    Key = $winrmkey;
    ValueName = 'IPv4Filter';
    Value = '*';
    Type = 'String';
$gpo |Set-GPRegistryValue @params
$params.ValueName = 'IPv6Filter'
$gpo |Set-GPRegistryValue @params

# Add the firewall rule to allow port 5985 for WinRM HTTP traffic
$fwrule = 'v2.10|Action=Allow|Active=TRUE|Dir=In|Protocol=6|LPort=5985|'
$fwrule += ',-30256|EmbedCtxt=@FirewallAPI.dll,-30252'

$params = @{
    Key = 'HKLM\Software\Policies\Microsoft\WindowsFirewall\FirewallRules';    
    ValueName = 'WINRM-HTTP-In-TCP';
    Value = $fwrule;
    Type = 'String';
$gpo |Set-GPRegistryValue @params

# Manually add the inf setting to configure WinRM to start automatically
$inf = @'
[Service General Setting]

$sdsad = [System.DirectoryServices.ActiveDirectory.Domain]
$domain = $sdsad::GetCurrentDomain().name
$path = "\\$domain\sysvol\$($env:LOGONSERVER)\Policies\$($gpo.Id)\Machine\"
$path += "Microsoft\Windows NT\SecEdit"
if (!(Test-Path $path)) {
    md $path
$inf |Out-File (Join-Path $path 'GptTmpl.inf')
# Link the GPO to the OU
$link = $gpo |
    New-GPLink -Target $OU -LinkEnabled 'Yes'

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

%d bloggers like this: