If you’ve configured the Server Authentication Certificate Template GPO option, which determines the certificate that the machine uses for Remote Desktop connections, and applied it to 2008 R2 or older servers then you may find that you’re getting a lot of duplicate certificates being issued. It’s a problem with an easy solution but it’s not an obvious one.

You see, if you read the documentation for the setting (something which is helpfully not included in the GPO explanation text in the GPMC) you’ll soon discover that:

Important
You must set the certificate template’s attributes Template display name and Template name to the same value.

Due to a disparity in the way the API checks to see if a certificate already exists on the machine for this purpose if the Template Name is not the same as the Template Display name it fails to identify that it already has a matching certificate and so requests a new one.

This problem is resolved in Server 2012 R2. It’s possibly resolved in Server 2012 as well but I don’t have a box to hand I can test with.

As far as I can tell the “Do not automatically reenroll if a duplicate certificate exists in Active Directory” option has no impact on this issue.



You know how it is, you don’t pay attention to the management of your domain for just 5 or 6 years and suddenly you have hundreds of GPOs with no idea what half of them do or even if they’re actually linked somewhere. For some reason, the Powershell GPO module doesn’t have a simple cmdlet or property that lets you tell if a GPO is linked or not, because that would be far too helpful, but it’s not too hard to do if you don’t mind parsing some XML.

This code is based on a much more complicated script from here, designed to let you search for individual settings within a GPO. It will accept a number of arguments, but run without any it will simply output to the console a list of all of the unlinked GPOs in the current domain.

<#
Copyright (c) 2014, Adam Beardwood
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: 
 
1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer. 
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution. 
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
 
#Find Unlinked Linked GPOs in a domain
#Adam Beardwood 20/05/2014
#v1.0 - Initial Release
 
param (
[Parameter(Mandatory=$false)]
[boolean] $outfile=$false,
[Parameter(Mandatory=$false)]
[string] $filename="UnlinkedGPO-$(get-date -f HHmmss).txt",
[Parameter(Mandatory=$false)]  
[string] $DomainName = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
)
 
Import-Module GroupPolicy;
 
[string] $Extension="Enabled"
 
$allGposInDomain = Get-GPO -All -Domain $DomainName | Sort DisplayName;
 
$xmlnsGpSettings = "http://www.microsoft.com/GroupPolicy/Settings";
$xmlnsSchemaInstance = "http://www.w3.org/2001/XMLSchema-instance";
$xmlnsSchema = "http://www.w3.org/2001/XMLSchema";
 
$QueryString = "gp:LinksTo";
 
$host.UI.WriteLine();
 
foreach ($Gpo in $allGposInDomain)
{				
	$xmlDoc = [xml] (Get-GPOReport -Guid $Gpo.Id -ReportType xml -Domain $Gpo.DomainName);		
	$xmlNameSpaceMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable);
 
	$xmlNameSpaceMgr.AddNamespace("", $xmlnsGpSettings);
	$xmlNameSpaceMgr.AddNamespace("gp", $xmlnsGpSettings);
	$xmlNameSpaceMgr.AddNamespace("xsi", $xmlnsSchemaInstance);
	$xmlNameSpaceMgr.AddNamespace("xsd", $xmlnsSchema);
 
	$extensionNodes = $xmlDoc.DocumentElement.SelectNodes($QueryString, $XmlNameSpaceMgr);
 
	$stringToPrint = $($Gpo.DisplayName) + " is not linked in this domain";
 
	if($extensionNodes[0] -eq $null){
		if($outfile -eq $true){
			$stringToPrint | Out-File $filename -Append
		}else{
			write-host $stringToPrint -foregroundcolor red
		}
	}
}


I’m doing a lot of Group Policy work at the moment (who’d have guessed) and I’ve run into an old friend of mine: The 2008R2/Win7 Group Policy Management Console keyboard bug. As Microsoft put it:

  • You have a computer that is running Windows 7 or Windows Server 2008 R2.
  • You customize a Microsoft Management Console (MMC) that has the Group Policy Management Console (GPMC) snap-in. (As far as I can tell it happens just as often with the provided gpmc.msc)
  • You select any Group Policy object (GPO), and then you click the Settings tab in the details pane.
  • You select another node in the console tree, and then you use the BACKSPACE or arrow keys to perform some operations.
  • In this scenario, the BACKSPACE or arrow keys do not work. You have to use the mouse to perform operations.

Which is extremely annoying, as you might imagine. As with many of their Known Issues, Microsoft have opted not to make a generally available patch for this, probably because it affects such a small proportion of their users. Nonetheless, there is a Hotfix available for it, which can be acquired here: http://support.microsoft.com/kb/2466373

If you do any serious amount of GPO work on a Windows 7 or 2008 R2 box, you will want to install it.



As we all know, there are certain published standards for things like Windows Security and Group Policy that companies can use as baselines for their systems; standards such as the CIS Security Configuration Benchmarks. These standards often mandate the configuration of certain GPO settings that fall under the “MSS” category which do not appear in the Security Configuration Editor or Group Policy Management Editor by default.

In order to add these settings so that you can easily configure them without screwing around in the registry or writing your own ADMX templates, you can download and import them as part of the Microsoft Security Compliance Management Toolkit. Unfortunately, getting access to this toolkit requires the installation of the Management software with its associated requirement of a SQL Express instance, which is ludicrous.

So, I am including below, the WSF script that is required to import these settings into the Group Policy Editor on a given 7/2K8R2 machine (and probably Vista/2K8 as well, but I haven’t tried it). Use cscript LocalGPO.wsf /ConfigSCE to import the settings, which will then appear under “Computer Configuration->Policies->Windows Settings->Security Settings->Local Policies->Security Options” in the Group Policy Editor (Or the appropriately reduced path in the Security Configuration Editor).

Download LocalGPO.wsf

If you’re dumb enough to download and run a VBScript from an untrusted source without doing the usual safety checks then you probably shouldn’t be using this kind of “hack” in a production environment (in fact, you probably shouldn’t be allowed near a production environment in the first place…).