As the February deadline approaches for the implementation of FDCC settings approaches, management of the FDCC Group Policy Objects (GPOs) is a common question Federal IT professionals (IT Pros) have today. FDCC GPO management spans a few areas, including settings review, initial import and linking, and ongoing import and linking. NIST and OMB have taken a very simple, systematic approach by providing exported GPOs with all of the FDCC settings included in them. This removes the need for Federal organizations to go through the previously cumbersome process of reading several hundred pages of settings and definitions and attempting to craft their own GPOs to contain these settings. This significantly reduces the time to implement and human error often associated with implementing any standards in Group Policy. This leaves many IT Pros with the question – How do I get these backed up GPOs into my organization’s Active Directory environment? First, let’s look at what we have.
Currently, when you download the quarterly zip file containing the GPOs (found at http://fdcc.nist.gov/download_fdcc.html), you will notice that there are three categories of FDCC GPOs:
1. Vista GPOs (found in the “\Vista” folder)
2. XP GPOs (found in the “\XP” folder)
3. Common GPOs (found in the “\Both” folder)
Note that in the future as new Windows platforms are released or are deprecated, the platform choices will likely change. The Vista and XP GPOs contain platform specific settings in the following GPOs:
· FDCC <Quarter> <Year> <Platform> Security Settings – Contains low level operating system security settings including User Rights Assignment, local audit policy, security options, services configuration and system ACLs
· FDCC <Quarter> <Year> <Platform>-Specific Additional Settings - Contains additional platform settings such as error reporting
· FDCC <Quarter> <Year> <Platform> Firewall Settings – Contains Domain and standard profile settings for the Windows Firewall
The “Common” GPOs contains settings which apply to either platform in the following GPOs:
· FDCC <Quarter> <Year> IE7 Settings – Contains Internet Explorer settings, including zone information, URL Action settings, etc
· FDCC <Quarter> <Year> Additional Settings - Contains behavioral settings for users and computers
· FDCC <Quarter> <Year> Account Policy – Contains settings such as Password policy, Kerberos policy, etc.
The key concept here is that if you are running one platform within your organization, such as Windows Vista, you would need to import six (6) GPOs in total – The platform specific GPOs and the Common GPOs. If you are running both platforms, you would import all nine (9) GPOs. If you only deploy the platform specific settings, you are only deploying half of the FDCC GPO solution, so take care to understand which GPOs contain which settings for your organization.
Now that we have an understanding of the GPOs included in the FDCC releases, how do we get them into our environment? First, you need to have the Group Policy Management Console (GPMC) running. For Windows Server 2003, the SP1 version of GPMC can be found here: http://www.microsoft.com/downloads/details.aspx?FamilyID=0a6d4c24-8cbd-4b35-9272-dd3cbfc81887&displaylang=en. For Windows Vista RTM and Windows Server 2008, this toolset is included in the platform. Once GPMC is installed, the following simple steps must be followed to import the settings in your environment:
Step 1: Create a new empty GPO
Step 2: Run the GPMC “Import Settings Wizard” by right-clicking the new GPO and selecting “Import Settings…” from the context menu
Step 3: Import the FDCC GPO settings into your new empty GPO
Step 4: Review the imported settings and link the new FDCC GPO accordingly
Note to manage and review the Vista FDDC GPOs in your Windows Server 2003 environment, you will need to establish the ADMX central store in your forest. Steps to do this are outlined here: http://technet2.microsoft.com/WindowsVista/en/library/02633470-396c-4e34-971a-0c5b090dc4fd1033.mspx?mfr=true.
While this procedure is all well and good, it can still be a bit cumbersome to create new GPOs and walk through the wizard over and over again. After all, we have to do this every quarter and depending on how many domains and forests you might have, this can be a daunting task. To help with that, I have written a little script to make it easy to import the FDCC GPOs based on the GPMC scripting examples provided with the GPMC download. It uses the object model from GPMC, so you will still need to ensure that GPMC is installed and working on your platform. The script is pretty simple and requires a single argument – the folder path where you unzipped the FDCC GPOs (specified in the PATH argument).
cscript Import_FDCC_GPO_v1.1.vbs /PATH:”C:\FDCC\FDCC-Q3-2007-Final-GPO-20070730\FDCC Q3 2007 Final GPOs”
The script takes a bit of the guesswork out of importing the FDCC GPOs. First, it enumerates the GPO folders in the FDCC download and allows you to choose which GPO you wish to import. Next, it enumerates the GPOs in the FDCC export and allows you to choose which GPO you wish to import. Once these choices are made, it creates a new empty GPO with a new GUID and the exact name of the FDCC GPO in your environment. After final confirmation, it then imports the settings found in the downloaded FDCC GPOs. An example of the script execution is provided below:
$cscript Import_FDCC_GPO_v1.1.vbs /PATH:"C:\FDCC\FDCC-Q3-2007-Final-GPO-20070730\FDCC Q3 2007 Final GPOs"
The following FDCC GPO Folders are available:
1) Both
2) Vista
3) XP
Enter the number of the FDCC GPO Folder you wish to import: 2
1) FDCC Q3 2007 Vista-Specific Additional Settings
2) FDCC Q3 2007 Vista Security Settings
3) FDCC Q3 2007 Vista Firewall Settings
Enter the number of the FDCC GPO you want to import: 2
STEP 1: Starting GPO Import for FDCC Q3 2007 Vista Security Settings...
Creating GPO...
New GPO created
STEP 2: Align new GPO to FDCC GPO for import ...
Found GPO "FDCC Q3 2007 Vista Security Settings" for importing
STEP 3: Import FDCC GPO? (y or n) y
Importing "FDCC Q3 2007 Vista Security Settings"...
"FDCC Q3 2007 Vista Security Settings" successfully imported.
Would you like to import another FDCC GPO from this path? (y or n)
Based on user input, the script will loop through all of the FDCC GPOs and import them individually. GPOs are not linked since each organization will first need to carefully review the imported settings and each Active Directory environment is obviously different. The script also takes two optional arguments: /? – to display the script help information and /v – to display verbose debugging information while the script executes.
Just as the NIST and OMB exported FDCC GPOs attempt to make implementation and standardization of the settings easier, this script should take some of the bite and guesswork out of importing these GPOs into your organization’s Active Directory environment. I have included the source for the script below. Enjoy and hopefully this helps get your organization headed in the right direction with respect to FDCC!
' =========================================
' = FDCC GPO Import Script
' = Version 1.1
' = Last updated 11:37 AM 12/1/2007
' = Joel Yoker <joely@microsoft.com>
' =========================================
'On error Resume Next
' strDbg toggles display messages on and off (VALUE: 1 = on, 0 = off)
If WScript.Arguments.Named.Exists("V") Then
WScript.Echo vbCrLf & "Debugging ON" & vbCrLf
strDbg = 1
Else
strDbg = 0
End If
' Ensure this script is being run from the command line by calling the IsCScript function
If Not IsCScript() Then
WScript.Echo WScript.ScriptName & " must be run with CScript."
Call DisplayUsage
WScript.Quit 1
End If
' Check and see what arguments were passed and perform the functions required
' per what arguments are passed. Arguments are documented in DisplayUsage subroutine
If WScript.Arguments.Named.Exists("?") Then
Call DisplayUsage
Else
If WScript.Arguments.Named.Exists("PATH") Then
strFDCCGPOPath = WScript.Arguments.Named.Item("PATH")
Call ImportFDCCGPO(strFDCCGPOPath)
Else
wscript.echo "ERROR: /PATH is required" & vbCRLF
Call DisplayUsage
End If
End If
' Subroutines
Sub ImportFDCCGPO(gpoBackupFolderFullPath)
'Create Objects
Set gpm = CreateObject("gpmgmt.gpm")
Set gpmConstants = gpm.GetConstants
Set RootDSE = GetObject("LDAP://RootDSE")
adsiDomain_DN = RootDSE.Get("DefaultNamingContext")
dnsDomain = ConvertToDNS(adsiDomain_DN)
'Create a GPM domain object
set gpmDomain = gpm.GetDomain(dnsDomain,"",gpmConstants.UsePDC)
wscript.echo "The following FDCC GPO Folders are available: "
' Initialize strChoice
strChoice = "y"
' Get the Folder of the GPOs to restore
strFolderPath = gpoBackupFolderFullPath
arrSF = EnumSubFolders(strFolderPath)
For i = 0 to Ubound(arrSF)
rs1 = i + 1 & ") "
rs1 = rs1 & arrSF(i)
WScript.Echo rs1
Next
WScript.Stdout.write vbCrLf & "Enter the number of the FDCC GPO Folder you wish to import: "
rs1 = int(WScript.StdIn.ReadLine)
If strDbg <> 0 Then WScript.Echo
'If strDbg <> 0 Then WScript.Echo "** Choice: " & rs1
restoreGPOFolder_ID = rs1 - 1
'If strDbg <> 0 Then WScript.Echo "** FolderArray number: " & restoreGPOFolder_ID
gpoBackupSubFolder = arrSF(restoreGPOFolder_ID)
If strDbg <> 0 Then WScript.Echo "** Subfolder: " & gpoBackupSubFolder
gpoBackupFolderFullPath = gpoBackupFolderFullPath & "\" & gpoBackupSubFolder
If strDbg <> 0 Then WScript.Echo "** New GPO Backup Path: " & gpoBackupFolderFullPath
If strDbg <> 0 Then WScript.Echo
do while strChoice <> "n"
' Get the GPOs in the folder
set gpmBackupSearchCriteria = gpm.CreateSearchCriteria()
gpmBackupSearchCriteria.Add gpmConstants.SearchPropertyBackupMostRecent, gpmConstants.SearchOPEquals, True
Set gpmBackupDir = gpm.GetBackupDir(gpoBackupFolderFullPath)
Set gpmBackup_List = gpmBackupDir.SearchBackups(gpmBackupSearchCriteria)
For i=1 To gpmBackup_List.Count
With gpmBackup_List.Item(i)
rs = i & ") "
rs = rs & .GPODisplayName
End With
WScript.Echo rs
Next
WScript.Stdout.write vbCrLf & "Enter the number of the FDCC GPO you want to import: "
rs = int(WScript.StdIn.ReadLine)
If rs >= 1 AND rs <= gpmBackup_List.Count Then
restoreGPO_ID = gpmBackup_List.item(rs).ID
set gpmImportGPO = gpmBackupDir.GetBackup(restoreGPO_ID)
importGPODisplayName = gpmImportGPO.GPODisplayName
WScript.Echo vbCrLf & "STEP 1: Starting GPO Import for " & importGPODisplayName & "..."
Else
WScript.Echo vbCrLf & "Please run the script again and select a number in the displayed range."
WScript.Quit()
End If
If strDbg <> 0 Then WScript.Echo "Importing into " & adsiDomain_DN
' Create a new GPO with the name of the GPO selected
wscript.echo " Creating GPO..."
strNewGPODisplayName = importGPODisplayName
Set objNewGPO = gpmDomain.CreateGPO()
objNewGPO.DisplayName = strNewGPODisplayName
If strDbg <> 0 Then wscript.echo vbCrLf
If strDbg <> 0 Then wscript.echo "----CREATING NEW GPO----"
If strDbg <> 0 Then wscript.echo "--Name: " & objNewGPO.DisplayName
If strDbg <> 0 Then wscript.echo "--GUID: " & objNewGPO.ID
If strDbg <> 0 Then wscript.echo "--Path: " & objNewGPO.Path
If strDbg <> 0 Then wscript.echo "------------------------"
wscript.echo " New GPO created"
'Search the production domain to verify that a GPO of the same name exists
WScript.Echo vbCrLf & "STEP 2: Align new GPO to FDCC GPO for import ..."
set gpmGPOSearchCriteria = gpm.CreateSearchCriteria()
'gpmGPOSearchCriteria.Add gpmConstants.SearchPropertyGPODisplayName, gpmConstants.SearchOPContains, cstr(importGPODisplayName)
gpmGPOSearchCriteria.Add gpmConstants.SearchPropertyGPOID, gpmConstants.SearchOpEquals, objNewGPO.ID
set gpmProductionGPOCollection = gpmDomain.SearchGPOs(gpmGPOSearchCriteria)
If gpmProductionGPOCollection.count = 1 Then
WScript.Echo " Found GPO " & Chr(34) & objNewGPO.DisplayName & Chr(34) & " for importing"
For Each item In gpmProductionGPOCollection
If strDbg <> 0 Then wscript.echo vbCrLf
If strDbg <> 0 Then wscript.echo "----FOUND GPO----"
If strDbg <> 0 Then wscript.echo "--GUID: " & item.ID
If strDbg <> 0 Then wscript.echo "-----------------"
set gpmProductionGPO = item
Next
Else
wscript.echo " Unable to find " & objNewGPO.DisplayName & " in " & adsiDomain_DN
wscript.quit
End If
WScript.StdOut.Write vbCrLf & "STEP 3: Import FDCC GPO? (y or n) "
rs = wscript.StdIn.ReadLine
If StrComp(rs,"y",vbTextCompare) = 0 Then
WScript.Echo " Importing " & Chr(34) & objNewGPO.DisplayName & Chr(34) & "..."
Set gpmResult = gpmProductionGPO.Import(0,gpmImportGPO)
Set gpmResult_Status = gpmResult.Status
If gpmResult_Status.count <> 0 Then
For i=1 to gpmResult_Status.Count
WScript.Echo gpmResult_Status.Item(i).Message
Next
gpmResult.OverallStatus()
Else
WScript.Echo " " & Chr(34) & objNewGPO.DisplayName & Chr(34) & " successfully imported."
End If
Else
WScript.Echo " Operation aborted. Exiting..."
End If
' Prompt to see if we need to loop again
WScript.StdOut.Write vbCrLf & "Would you like to import another FDCC GPO from this path? (y or n) "
strChoice = wscript.StdIn.ReadLine
wscript.echo vbCrLf
Loop
wscript.echo "Exiting FDCC GPO import script"
End Sub
Sub DisplayUsage()
' Documents every named argument and how the script is to be used
WScript.Echo "USAGE: cscript.exe //nologo " & WScript.ScriptName & " [/OPTIONS]" & _
VbCrLf & _
VbCrLf & "Script to import FDCC Group Policy Objects (GPO)" & _
VbCrLf & "into a given Active Directory domain. (Note: Requires" & _
VbCrLf & "administrative rights to perform the action)" & _
VbCrLf & _
VbCrLf & "Enumerates FDCC GPO backups, creates new GPO with " & _
VbCrLf & "same name, and imports FDCC settings into new GPO" & _
VbCrLf & _
VbCrLf & "Switches:" & _
VbCrLf & "/PATH (required) - The path of the FDCC GPOs" & _
VbCrLf & _
VbCrLf & "Examples: " & _
VbCrLf & "To specify that FDCC GPO subfolders were extracted" & _
VbCrLf & "to a folder called C:\FDCC type the following:" & _
VbCrLf & _
VbCrLf & "cscript " & WScript.ScriptName & " /PATH:C:\FDCC\FDCC-Q3-2007-Final-GPO-20070730\FDCC Q3 2007 Final GPOs" & _
VbCrLf & _
VbCrLf
wscript.quit
End Sub
' Functions
Function ConvertToDNS(distinguishedName)
' ConvertToDNS - Converts the DN of a domain to a FQDN
'Skip past the first "DC=" in the DN
initialStrip = Mid(distinguishedName,4)
'Replace the remaining typeful prefixes with periods
rs = Replace(initialSTrip,",dc=",".",1,-1,1)
'Return the FQDN
ConvertToDNS = rs
End Function
Function EnumSubFolders(strFolderPath)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(strFolderPath)
Set objSubFolder = objFolder.SubFolders
intSize = 0
For Each folder in objSubFolder
ReDim Preserve arrSubFolders(intSize)
arrSubFolders(intSize) = folder.name
intSize = intSize + 1
Next
EnumSubFolders = arrSubFolders
End Function
Function IsCScript()
' This function returns whether the script is being run from cscript (command line)
Dim objRegExp
Set objRegExp = New RegExp
objRegExp.IgnoreCase = True
objRegExp.Pattern = "cscript.exe$"
IsCScript = objRegExp.Test(WScript.FullName)
Set objRegExp = Nothing
End Function