Update Group Policy ADM Files Script

Mike Stephens, Microsoft Corporation

Caution
Administrative Templates are stored on the system volume of domain controllers. The system volume uses the File Replication service (FRS) to synchronize the system volumes of all domain controllers in the domain. Updating ADM files should be done during non-peak hours as it has the potential to cause a large amount of FRS replication traffic.

Updateadm.vbs leverages the scriptable Group Policy Management Console to enable administrators to easily update Group Policy Administrative Templates which reside on the system volume of domain controllers.

This script will only update ADM files already assigned to your policies. It will not copy any new ADMs into the policies.

Requirements

The console host (cscript.exe) of Windows Scripting Host version 5.6 or higher
(comes standard with Windows XP and Windows Server 2003)

Windows XP SP1 or Windows Server 2003

Group Policy Management Console

Script Code

'==========================================================================
'
' VBScript Source File
'
' NAME: UpdateAdm.vbs
'
' AUTHOR: Michael Stephens , Microsoft Corporation
'
' VERSION 1.00.00 DATE: 02.22.2004  Intial Release
' VERSION 1.00.10 DATE: 05.23.2005
'Added Error Checking to Determin if the sysvol path is valid.
' VERSION 1.00.16 DATE: 08.01.2005
'     Changes to display NULL GPOs (Thanks to Jeremy Moskowitz for your help).
'
' COMMENT: Script used to update the ADM Files for GPOs on Sysvol
'
'==========================================================================
Option Explicit

Dim argc, argv
Dim fso, oGPM, oGPDom, oGPSearch, oGPConst, oGPSearchResults
Dim oGPO, counter, sysvolPath, oSource, oTarget 

' ==========[ Token Variables ]============
Dim gSearchVal, gSearchStr, gSourcePath, gBackupPath
Dim gFileCopyOn, gDnsDomStr

' ==========[ Token Values ]============
const CMD_GUID_SEARCH = "GUID"
const CMD_FILECOPY = "FILECOPY"
const CMD_ADM_SOURCE_PATH = "ADMSRC"
Const CMD_BACKUP_PATH= "ADMBACKUP"
Const CMD_NAME_SEARCH= "NAME"
const CMD_ALL_SEARCH= "ALL"
Const CMD_DNS_DOMAIN= "DNSDOM"

' ==========[ CONSTANTS ]============
Const SCRIPT_REQ_MAX_VERSION ="5"
Const SCRIPT_REQ_MIN_VERSION="6"
Const SEARCH_GUID_VAL= 1
Const SEARCH_NAME_VAL=2
Const SEARCH_ALL_VAL=3


CheckScriptEngine SCRIPT_REQ_MAX_VERSION, SCRIPT_REQ_MIN_VERSION

' Get the command line parameters
CrackCommandLine argc, argv 

Set oGPM = CreateObject("GPMgmt.GPM")
Set oGPConst = oGPM.GetConstants()
Set oGPSearch = oGPM.CreateSearchCriteria()
Set oGPDom = oGPM.GetDomain( gDnsDomStr, "", oGPConst.UsePDC )

Select Case gSearchVal
Case SEARCH_GUID_VAL
If Left(gSearchStr,1) <> "{" Or  Right(gSearchStr,1) <> "}" Then
Print "Guid search string is missing open/closing brace" & vbCrLf
WScript.Quit(255)
End If 
oGPSearch.Add  oGPConst.SearchPropertyGPOID, oGPConst.SearchOpEquals, gSearchStr

Case SEARCH_NAME_VAL
oGPSearch.Add oGPConst.SearchPropertyGPODisplayName, oGPConst.SearchOpEquals , gSearchStr

Case SEARCH_ALL_VAL
' Do nothing because we want to return All GPOs
End Select 

Set oGPSearchResults = oGPDom.SearchGPOs( oGPSearch)

WScript.StdOut.WriteLine VbCrLf
WScript.StdOut.WriteLine WScript.ScriptName & " - Updates Group Policy ADM files "

' Check the return amount
If oGPSearchResults.Count <= 0 Then 
WScript.Echo "No GPOs found during this search."
WScript.Quit 
End If 

' Loop through the return results 
For Each oGPO In oGPSearchResults
Dim ldapPath : ldapPath = oGPO.Path 
Dim gpc, tfile, sfile 
 
 ' Make AD Call to the GPC object 
 Set gpc  = GetObject("LDAP://" & ldapPath )
 
 ' Get the sysvol path and assign ADM to the back
 sysvolPath = gpc.gPCFileSysPath
 sysvolPath = sysvolPath & "\ADM"
  
WScript.StdOut.WriteLine "Checking " & oGPO.DisplayName  & " Adm Files..."
  
  If gFileCopyOn =  False  Then
 WScript.stdout.WriteLine "File Copy Mode:***Disabled***"
Else
 WScript.StdOut.WriteLine "File Copy Mode:Enabled"
End If
  
  Set fso = CreateObject("Scripting.FileSystemObject")
 Set oSource = fso.GetFolder(gSourcePath )
 
 'Validate GPT Path
 WScript.StdOut.WriteLine "Validating Sysvol Path..."
  
 On Error Resume Next  ' Try 
 Set oTarget = fso.GetFolder( sysvolPath )

 ' Catch 
 If Err.Number = 76 Then
 'WScript.StdOut.WriteLine ""
 'WScript.StdOut.WriteLine "The sysvol path " & sysvolPath & VbCrLf & "does not exist or cannot be accessed."
 'WScript.StdOut.Write "Please validate the Group Policy Template and the gpcFileSysPath on the Group "
 'WScript.StdOut.WriteLine "Container object."
 'WScript.Quit(1)
 WScript.StdOut.WriteLine "Path: " & sysvolPath
 WScript.StdOut.WriteLine "Error: NULL Group Policy"
 Elseif Err.Number > 0 Then 
 WScript.StdOut.WriteLine  "Unexpected Error"
 WScript.StdOut.WriteLine  Err.Number 
 WScript.StdOut.Writeline  Err.Description 
 WScript.StdOut.WriteLine Err.Source 
 WScript.Quit(1)
 End If
 
 'finally
 On Error GoTo 0 
  
 If fso.FolderExists(sysvolPath) Then 
 For Each sfile In oSource.Files 
 If fso.FileExists( oTarget.Path & "\" & sfile.name ) = True  Then 
 WScript.StdOut.WriteLine "Copying File " & sfile.path &_
 " to " & VbCrLf &  oTarget.Path & "\" & sfile.name
 If gFileCopyOn =  True Then 
 fso.CopyFile sfile.path, oTarget.Path & "\" & sfile.Name, True 
 End If 
 End If
 Next
 End If 
 
 Set gpc = Nothing 
 Set oSource = Nothing 
 Set oTarget = Nothing 
Set fso = Nothing
WScript.StdOut.WriteLine VbCrLf 
Next

WScript.StdOut.WriteLine "Command Completed." 
WScript.Quit 



Sub CrackCommandLine(argc,argv)
'*********************************************************
' Purpose: Cracks the CommandLine Parameters that were passed
'          to the script and puts them into Global Vars argv & argc
' Inputs: No input is needed.
'         Gobal Varialbe Declarion is needed for:
'  argc
'  argv
' Returns: Does not return a Value 
'
'  Date: 3-11-2003mstephenVersion 1.00.03 Removed Support for Unamed Args. 
'  
'*********************************************************
Dim oArg
Dim i

Set oArg = WScript.Arguments

' ==========[ Named Arg Processing ]============
argc = oArg.Named.count 
If argc < 1  Then ShowUsage 

' ==========[ Process Named Args]============

If oArg.Named.Exists("h") Then ShowUsage
If oArg.Named.Exists("?") Then ShowUsage
If oArg.Named.Exists("help") Then ShowUsage

' Insert IF statements for each Command line arg that you need to
' Test for. 
gSearchVal = 0
gSearchStr = ""
If oArg.Named.Exists(CMD_GUID_SEARCH) = True Then 
gSearchVal = SEARCH_GUID_VAL
gSearchStr = oArg.Named.item(CMD_GUID_SEARCH)
End If 

If oArg.Named.Exists(CMD_NAME_SEARCH) = True Then
If Len(gSearchStr) > 1 Then 
Print "Syntax Error: search arguments cannot be combined." & vbcrlf
Print "Please choose only one search parameter and try again."
End If 
gSearchVal = SEARCH_NAME_VAL
gSearchStr = oArg.Named.Item(CMD_NAME_SEARCH)
End If 

If oArg.Named.Exists(CMD_ALL_SEARCH) = True Then 
If Len(gSearchStr) > 1 Then 
Print "Syntax Error: search arguments cannot be combined." & vbcrlf
Print "Please choose only one search parameter and try again."
End If 
gSearchVal = SEARCH_ALL_VAL
gSearchStr = "ALL"
End If 

gFileCopyOn = False 
If oArg.Named.Exists(CMD_FILECOPY) = True Then 
If UCase(oArg.Named.Item(CMD_FILECOPY)) = "ON" Then 
gFileCopyOn = True 
Else
gFileCopyOn = False
End If
End If

If oArg.Named.Exists(CMD_ADM_SOURCE_PATH) = True Then 
gSourcePath = oArg.Named.Item(CMD_ADM_SOURCE_PATH)
End If 

If oArg.Named.Exists(CMD_BACKUP_PATH) = True Then 
gBackupPath = oArg.Named.Item(CMD_BACKUP_PATH)
End If 

If oArg.Named.Exists(CMD_DNS_DOMAIN) = True Then 
gDnsDomStr = oArg.Named.Item(CMD_DNS_DOMAIN)
End If 

' Verify what must be set 
If gSearchVal = 0 Then ShowUsage
If Len(gSearchStr) = 0 Then ShowUsage
If Len(gSourcePath) = 0 Then ShowUsage
'If Len(gBackupPath) = 0 Then ShowUsage 
If Len(gDnsDomStr) = 0 Then ShowUsage 

Set oArg = Nothing 
End Sub


Sub CheckScriptEngine(strMajorVersion, strMinorVersion)
'*********************************************************
' Purpose: Checks the Scripting Engine Version
'          
' Inputs: strMajorVersion: Required Major Version of the ScriptEngine
'            strMinorVersion: Required Minor Version of the ScriptEngine
' Returns:  None
'         
'*********************************************************
Dim bWrongVersion
bWrongVersion = True

If ScriptEngineMajorVersion >= CInt(strMajorVersion) Then 
bWrongVersion = False
elseif ScriptEngineMinorVersion >= CInt(strMinorVersion) Then 
bWrongVersion = False
End If 

If bWrongVersion = True Then
WScript.Echo("You current scripting version does not meet the required Version.")
WScript.Echo("Current Version: " & ScriptEngineMajorVersion & "." & ScriptEngineMinorVersion)
WScript.Echo("Required Version: " & StrMajorVersion & "." & StrMinorVersion)
WScript.Quit(1)
End If 
End Sub      

 
Sub ShowUsage
'*********************************************************
' Purpose: Displays the Useage of the script to the screen
'          
' Inputs: None
'         
' Returns: None
'          
'          
'*********************************************************
Print WScript.ScriptName & " - Updates Group Policy ADM files "
Print ""
Print "Usage: cscript " & WScript.ScriptName & "  /GUID:{gpoguid} | /NAME:GPOFriendlyName | /ALL "
PrintTab 37," /DNSDOM:fqdnDomainName /ADMSRC:admSourcePath [/FILECOPY:on]"
Print ""
PrintTab 5,"/GUID:{gpoguid} - Sets the Search Criteria to match the gpoGUID."
PrintTab 5,"  Be sure to include the braces {} when searching for GUIDS."
PrintTab 5,""
PrintTab 5,"/NAME:GPOfriendlyName - Sets the Search Criteria to match the Name of the GPO."
PrintTab 5,"  This search will return all GPOs that have match the name specified."
PrintTab 5,""
PrintTab 5,"/ALL: - Sets the search Criteria to return All Group Policy Objects within the Domain."
PrintTab 5,""
PrintTab 5,"/DNSDOM:fqdnDOmainName - Expects the FQDN of the domain you want to update. (Ex domain.com)."
PrintTab 5,""
PrintTab 5,"/ADMSRC:admSourcePath - The Source Location where your most current ADM Files are stored."
PrintTab 5,"  These are the files that will overwrite your Current ADMs."
PrintTab 5,""
PrintTab 5,"/FILECOPY:ON - This changes the Filecopy mode of the script.  Without this option the "
PrintTab 5," FileCopyMode is set to Disabled and thus will not perform the file copy"
PrintTab 5," Adding this Argument will allow the script to acutally perform the"
PrintTab 5," Filecopy Operation and overwrite your current ADM Files."
Print ""
Print "MORE INFORMATION:"
PrintTab 5, "This script will only replace the existing ADM files that are assigned to your policies"
PrintTab 5, "It will not copy any additional ADMs into the polices."
PrintTab 5, "It only updates what is currently there."
Print ""
WScript.Quit
End Sub

Sub Print (text)
'*********************************************************
' Purpose: Send Text to the console.
'          
' Inputs: text - String Expression to Print
'         
' Returns: None
'          
'*********************************************************
WScript.StdOut.WriteLine text
End Sub

Sub PrintTab(spaces,text)
 '*********************************************************
 ' Purpose: Send Text to the console with the Option to indent
 '          
 ' Inputs: spaces - the number of spaces to indent before printing
 '         text   - String Expression to Print 
 '
 ' Returns: None
 '          
 '*********************************************************
 WScript.StdOut.WriteLine Space(spaces) & text
 End Sub
 



For online peer support, join the microsoft.public.windows.server.scripting community on the msnews.microsoft.com news server. To provide feedback or report bugs in sample scripts or the Scripting Guide, please contact Microsoft TechNet.

Disclaimer

This sample script is not supported under any Microsoft standard support program or service. The sample script is provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.


Top of pageTop of page