Wednesday Tidbit: Using PowerShell to create Group Policy Objects

20150916 - 1We’re using Chef at our company to help us solve our compliance and automation challenges. To enable the software to connect to the servers in our estate first however, there needs to be some sort of agent or remote shell running. For our Windows hosts this can be WinRM, but it is not enabled by default.

Before Chef can work it’s magic, this needs to change.

As a Managed Service Provider, we look after the infrastructure for a large number of customers, each with their own Active Directory structure and often their own systems management software. However as AD is used in each, we decided to use Group Policy to enable WinRM.

The idea is to connect to each customer AD, create a GPO that enables WinRM and link it to the root of the domain.

To do this, I pinched a load of stuff created the following script, which can be run on each domain controller:

# Author:	@virtualhobbit
# Website:	http://virtualhobbit.com
# Ref:		https://virtualhobbit.com/2016/06/08/wednesday-tidbit-using-powershell-to-create-group-policy-objects

# Variables
$modName = "C:\GPWmiFilter.psm1"
$GPOname = "Enable WinRM on 2008 R2+ servers"
$defaultNC = ( [ADSI]"LDAP://RootDSE" ).defaultNamingContext.Value
$domainRoot = $defaultNC
$WMIFilterName = 'Windows 2008 R2 onwards'

Write-Host -ForegroundColor Magenta "Warning! Before starting, make sure you download the GPWmiFilter.psm1 from:"
write-host "`n"
Write-Host -ForegroundColor Green "     http://gallery.technet.microsoft.com/scriptcenter/Group-Policy-WMI-filter-38a188f3"
write-host "`n"
Write-Host -ForegroundColor Magenta "And store in the same folder as this script. Otherwise this script will not work."

# Get the RFC number, exit if process not followed
$rfc = Read-Host "Before we start, please enter the RFC number:"
if ($rfc -eq [string]::empty){
    Write-Host -ForegoundColor Red "Error: The RFC cannot be blank. Exiting"
	
	Exit
}

# Unblock module
Unblock-File $modName

# Import modules
Import-Module ActiveDirectory
Import-Module GroupPolicy
Import-Module $modName -Force
if(!(Get-Module "GPWmiFilter")){
	Write-Host -ForegoundColor Red "Error: The correct module is not loaded. Exiting"
	
	Exit
}

# Create GPO shell
$GPO = New-GPO -Name $GPOname

# Disable User Configuration
$GPO.GpoStatus = "UserSettingsDisabled"

# Set the RFC number as the description
$GPO.Description = "Created as part of RFC # $rfc" 

# Create WMI Filter
$filter = New-GPWmiFilter -Name $WMIFilterName -Expression 'SELECT * FROM Win32_OperatingSystem WHERE Version LIKE "6.0%" OR Version LIKE "6.1%" OR Version LIKE "6.2%" OR Version LIKE "6.3%"' -Description 'Queries for Windows Server 2008 R2 onwards' -PassThru

# Add WMI Filter to GPO
$GPO.WmiFilter = $filter

# Enable WinRM
$winrmkey = 'HKLM\Software\Policies\Microsoft\Windows\WinRM\Service'
$params = @{
    Key = $winrmkey;
    ValueName = 'AllowAutoConfig';
    Value = 1;
    Type = 'Dword';
}
$GPO | Set-GPRegistryValue @params

# Link GPO to domain root
New-GPLink -Name $GPOname -Target $domainRoot | Out-Null

Line 46 creates a WMI Filter which ensures the the GPO is only applied to Windows Server 2008 R2 and later. This is due to earlier OSs requiring a little more work (like WinRM being installed) and being slightly out of scope for this (that and those servers we can count on one hand).

When I have a little more time I’ll automate the downloading of the WMI Filter module using the New-Object System.Net.WebClient function.

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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