281 1. Open the GPMC snap-in. 2. In the left pane, expand the Forest container, expand the Domains container, browse to the domain of the target GPO, and expand the Group Policy Objects container. 3. Right-click on the target GPO and select Import Settings. 4. Click Next. 5. Click the Backup button if you want take a backup of the GPO you are importing into. 6. Click Next. 7. Select the backup folder location and click Next. 8. Select the backup instance you want to import from and click Next. 9. It then will scan to see if there are any security principals or UNC paths in the GPO being imported from. If there are, it will give you an option to modify those settings. 10. Click Next. 11. Click Finish. 9.7.2.2 Using a command-line interface > importgpo.wsf "<GPOBackupLocation>" "<OrigGPOName>" "<NewGPOName>" 9.7.2.3 Using VBScript ' This code imports the settings from a GPO that has been backed up into ' an existing GPO. ' SCRIPT CONFIGURATION strGPOImportTo = "<GPOName>" ' e.g. Sales GPO strDomain = "<DomainDNSName>" ' e.g. rallencorp.com strBackupLocation = "<BackupLocation>" ' e.g. c:\GPMC Backups ' GUID representing specific backup ' e.g.{3E53B39B-C29B-44FF-857B-8A84528804FF} strBackupID = "<BackupGUID>" ' END CONFIGURATION set objGPM = CreateObject("GPMgmt.GPM") set objGPMConstants = objGPM.GetConstants( ) ' Initialize the Domain object set objGPMDomain = objGPM.GetDomain(strDomain, "", objGPMConstants.UseAnyDC) ' Locate GPO backup set objGPMBackupDir = objGPM.GetBackupDir(strBackupLocation) set objGPMBackup = objGPMBackupDir.GetBackup(strBackupID) WScript.Echo "Backup found:" WScript.Echo " ID: " & objGPMBackup.ID WScript.Echo " Timestamp: " & objGPMBackup.TimeStamp WScript.Echo " GPO ID: " & objGPMBackup.GPOID WScript.Echo " GPO Name: " & objGPMBackup.GPODisplayName WScript.Echo " Comment: " & objGPMBackup.Comment WScript.Echo ' Find GPO to import into set objGPMSearchCriteria = objGPM.CreateSearchCriteria objGPMSearchCriteria.Add objGPMConstants.SearchPropertyGPODisplayName, _ objGPMConstants.SearchOpEquals, cstr(strGPOImportTo) set objGPOList = objGPMDomain.SearchGPOs(objGPMSearchCriteria) if objGPOList.Count = 0 then 282 WScript.Echo "Did not find GPO: " & strGPO WScript.Echo "Exiting." WScript.Quit elseif objGPOList.Count > 1 then WScript.Echo "Found more than one matching GPO. Count: " & _ objGPOList.Count WScript.Echo "Exiting." WScript.Quit else WScript.Echo "Found GPO: " & objGPOList.Item(1).DisplayName end if ' Perform the import set objGPMResult = objGPOList.Item(1).Import(0,objGPMBackup) ' This will throw an exception if there were any errors ' during the actual operation. on error resume next objGPMResult.OverallStatus( ) if objGPMResult.Status.Count > 0 then WScript.Echo "Status message(s): " & objGPMResult.Status.Count for i = 1 to objGPMResult.Status.Count WScript.Echo objGPMResult.Status.Item(i).Message next WScript.Echo vbCrLf end if ' Print results if Err.Number <> 0 then WScript.Echo "Error importing GPO " & objGPMBackup.GPODisplayName WScript.Echo "Error: " & Err.Description else WScript.Echo "Import successful." WScript.Echo "GPO '" & objGPMBackup.GPODisplayName & _ "' has been imported into GPO '" & _ objGPOList.Item(1).DisplayName & "'" end if 9.7.3 Discussion The GPMC import function uses a back up of the source GPO to create the new "imported" GPO. This means you must first back up the source GPO using GPMC. You can then import the settings from that GPO into a new GPO, which may be in the same domain or a completely different forest. Importing a GPO is a great way to help facilitate transferring GPO settings from a test environment to production. Some properties of GPOs, such as security group filters or UNC paths, may vary slightly from domain to domain. In this case, you can use a GPMC migration table to help facilitate the transfer of those kinds of references to the target domain. For more information on migration tables, see the GPMC help file. 9.7.3.1 Using VBScript 283 To import the settings of a backup, I have to first instantiate a GPMBackup object of the source backup by specifying the backup ID (a GUID) with the GPMBackupDir.GetBackup method. If you need to programmatically search for the backup ID, you can use the GPMBackup.SearchBackups method to find the most recent backup or a backup with a particular display name. Next, I instantiate a GPMGPO object of the GPO I'm importing into. To do this, I use a GPMSearchCriteria object to find the GPO that is equal to the display name of the GPO specified in the configuration section. I use an if elseif else conditional statement to ensure that only one GPO is returned. If zero or more than one are returned, I abort the script. If only one was returned, I use the GPMGPO.Import method to import the settings. The first parameter to the Import method is a flag that determines how security principals and UNC path mapping is done. I use 0, which is the default to not copy security settings. You can also use a migration table to do mappings if necessary. The second parameter is the GPMBackup object I instantiated earlier. The rest of the script performs some error handling and prints the results. 9.7.4 See Also Recipe 9.3 for copying a GPO, Recipe 9.17 for backing up a GPO, and MSDN: GPMGPO.Import Recipe 9.8 Assigning Logon/Logoff and Startup/Shutdown Scripts in a GPO 9.8.1 Problem You want to assign either user logon/logoff scripts or computer startup/shutdown scripts in a GPO. 9.8.2 Solution 9.8.2.1 Using a graphical user interface 1. Open the GPMC snap-in. 2. In the left pane, expand the Forest container, expand the Domains container, browse to the domain of the target GPO, and expand the Group Policy Objects container. 3. Right-click on the target GPO and select Edit. This will bring up the Group Policy Object Editor. 4. If you want to assign a computer startup or shutdown script, browse to Computer Configuration Windows Settings Scripts. If you want to assign a user logon or logoff script, browse to User Computer Windows Settings Scripts. 5. In the right pane, double-click on the type of script you want to add. 6. Click the Add button. 7. Select the script by typing the name of it in or browsing to its location. 8. Optionally type any script parameters in the Script Parameters field. 284 9. Click OK twice. 9.8.3 Discussion When you assign a script in a GPO, you can either reference a script that is stored locally on the domain controller somewhere under the NETLOGON share or a UNC path to a remote fileserver. The logon script can also be set as an attribute of the user object (scriptPath). This is provided as legacy support for users migrated from NT 4.0 domains. You should choose either one method of specifying the logon script or the other, but not both, as this will cause the logon script to run twice. Recipe 9.9 Installing Applications with a GPO 9.9.1 Problem You want to install an application on a group of computers using a GPO. 9.9.2 Solution 9.9.2.1 Using a graphical user interface 1. Open the GPMC snap-in. 2. In the left pane, expand the Forest container, expand the Domains container, browse to the domain of the target GPO, and expand the Group Policy Objects container. 3. Right-click on the target GPO and select Edit. This will bring up the Group Policy Object Editor. 4. Under Computer Configuration or User Configuration (depending on which you want to target the installation for), expand Software Settings. 5. Right-click on Software Installation and select New Package. 6. Browse to the network share that has the MSI package for the application and click OK. 7. Select whether you want to Assign the application or Publish it and click OK. 9.9.3 Discussion Installing applications with a GPO is a powerful feature, but you must be careful about the network and client impact it can have. If the MSI package you are installing is several megabytes in size, it will take a while for it to download to the client computer, which can result in sluggish performance on the client, especially over a slow connection. You'll also want to make sure you've thoroughly tested the application before deployment. After you've configured the GPO to install it, it will be only a short period of time before it is installed on all targeted your clients. If there is a bug in the application or the installer program is faulty, the impact could be severe to your user base. Your two options for deploying an application are to assign it or publish it. If you assign an application, it will get automatically installed on the targeted clients. If you publish an 285 application, it will not get automatically installed, but will be available to be installed manually from Add/Remove Programs in the Control Panel on the target computers. Recipe 9.10 Disabling the User or Computer Settings in a GPO 9.10.1 Problem You want to disable either the user or computer settings of a GPO. 9.10.2 Solution 9.10.2.1 Using a graphical user interface 1. Open the GPMC snap-in. 2. In the left pane, expand the Forest container, expand the Domains container, browse to the domain of the target GPO, and expand the Group Policy Objects container. 3. Right-click on the target GPO and select GPO Status 4. You can either select User Configuration Settings Disabled to disable the user settings or Computer Configuration Settings Disabled to disable the computer settings. 9.10.2.2 Using VBScript ' This code can enable or disable the user or computer settings of a GPO. ' SCRIPT CONFIGURATION strGPO = "<GPOName>" ' e.g. Sales GPO strDomain = "<DomainDNSName>" ' e.g. rallencorp.com boolUserEnable = False boolCompEnable = True ' END CONFIGURATION set objGPM = CreateObject("GPMgmt.GPM") set objGPMConstants = objGPM.GetConstants( ) ' Initialize the Domain object set objGPMDomain = objGPM.GetDomain(strDomain, "", objGPMConstants.UseAnyDC) ' Find the specified GPO set objGPMSearchCriteria = objGPM.CreateSearchCriteria objGPMSearchCriteria.Add objGPMConstants.SearchPropertyGPODisplayName, _ objGPMConstants.SearchOpEquals, cstr(strGPO) set objGPOList = objGPMDomain.SearchGPOs(objGPMSearchCriteria) if objGPOList.Count = 0 then WScript.Echo "Did not find GPO: " & strGPO WScript.Echo "Exiting." WScript.Quit elseif objGPOList.Count > 1 then WScript.Echo "Found more than one matching GPO. Count: " & _ objGPOList.Count WScript.Echo "Exiting." WScript.Quit 286 else WScript.Echo "Found GPO: " & objGPOList.Item(1).DisplayName end if ' You can comment out either of these if you don't want to set one: objGPOList.Item(1).SetUserEnabled boolUserEnable WScript.Echo "User settings: " & boolUserEnable objGPOList.Item(1).SetComputerEnabled boolCompEnable WScript.Echo "Computer settings: " & boolCompEnable 9.10.3 Discussion GPOs consist of two parts, a user and a computer section. The user section contains settings that are specific to a user that logs into a computer, while the computer section defines settings that apply to the computer regardless of which user logs in. You can enable or disable either the user configuration or computer configuration sections of a GPO, or both. By disabling both, you effectively disable the GPO. This can be useful if you want to stop a GPO from applying settings to clients, but you do not want to delete it, remove the links, or clear the settings. Disabling the user configuration or the computer configuration is useful in environments that have separate OUs for computers and users. Typically, you would disable the computer configuration for GPOs linked to the users' OU and vice versa. Disabling half the GPO in the way makes GPO processing more efficient and can reduce logon times. 9.10.3.1 Using VBScript First, I have to find the target GPO. To do this, I use a GPMSearchCriteria object to find the GPO that is equal to the display name of the GPO specified in the configuration section. I use an if elseif else conditional statement to ensure that only one GPO is returned. If zero or more than one are returned, I abort the script. If only one is returned, I call the SetUserEnabled and SetComputerEnable methods to either enable or disable the settings per the configuration. 9.10.4 See Also MSDN: GPMGPO.SetUserEnabled and MSDN: GPMGPO.SetComputerEnabled Recipe 9.11 Listing the Links for GPO 9.11.1 Problem You want to list all of the links for a particular GPO. 9.11.2 Solution 9.11.2.1 Using a graphical user interface 287 1. Open the GPMC snap-in. 2. In the left pane, expand the Forest container, expand the Domains container, browse to the domain of the target GPO, and expand the Group Policy Objects container. 3. Click on the GPO you want to view the links for. 4. In the right pane, the defined links for the GPO will be listed under Links. 9.11.2.2 Using a command-line interface > dumpgpoinfo.wsf "<GPOName>" 9.11.2.3 Using VBScript ' This code lists all the sites, OUs, and domains a GPO is linked to. ' SCRIPT CONFIGURATION strGPO = "<GPOName>" ' e.g. SalesGPO strForest = "<ForestName>" ' e.g. rallencorp.com strDomain = "<DomainDNSName>" ' e.g. rallencorp.com ' END CONFIGURATION set objGPM = CreateObject("GPMgmt.GPM") set objGPMConstants = objGPM.GetConstants( ) ' Initialize the Domain object set objGPMDomain = objGPM.GetDomain(strDomain, "", objGPMConstants.UseAnyDC) ' Initialize the Sites Container object set objGPMSitesContainer = objGPM.GetSitesContainer(strForest, _ strDomain, "", objGPMConstants.UseAnyDC) ' Find the specified GPO set objGPMSearchCriteria = objGPM.CreateSearchCriteria objGPMSearchCriteria.Add objGPMConstants.SearchPropertyGPODisplayName, _ objGPMConstants.SearchOpEquals, cstr(strGPO) set objGPOList = objGPMDomain.SearchGPOs(objGPMSearchCriteria) if objGPOList.Count = 0 then WScript.Echo "Did not find GPO: " & strGPO WScript.Echo "Exiting." WScript.Quit elseif objGPOList.Count > 1 then WScript.Echo "Found more than one matching GPO. Count: " & _ objGPOList.Count WScript.Echo "Exiting." WScript.Quit else WScript.Echo "Found GPO: " & objGPOList.Item(1).DisplayName end if ' Search for all SOM links for this GPO set objGPMSearchCriteria = objGPM.CreateSearchCriteria objGPMSearchCriteria.Add objGPMConstants.SearchPropertySOMLinks, _ objGPMConstants.SearchOpContains, objGPOList.Item(1) set objSOMList = objGPMDomain.SearchSOMs(objGPMSearchCriteria) set objSiteLinkList = objGPMSitesContainer.SearchSites(objGPMSearchCriteria) if objSOMList.Count = 0 and objSiteLinkList.Count = 0 Then WScript.Echo "No Site, Domain, or OU links found for this GPO" else WScript.Echo "Links:" 288 for each objSOM in objSOMList select case objSOM.Type case objGPMConstants.SOMDomain strSOMType = "Domain" case objGPMConstants.SOMOU strSOMType = "OU" end select ' Print GPO Domain and OU links WScript.Echo " " & objSOM.Name & " (" & strSOMType & ")" next ' Print GPO Site Links for each objSiteLink in objSiteLinkList WScript.Echo " " & objSiteLink.Name & " (Site)" next end if 9.11.3 Discussion See the Introduction in Chapter 9 for more information on GPO linking and SOMs. 9.11.3.1 Using VBScript First, I have to find the target GPO. To do this, I use a GPMSearchCriteria object to find the GPO that is equal to the display name of the GPO specified in the configuration section. I use an if elseif else conditional statement to ensure that only one GPO is returned. If none or more than one are returned, I abort the script. If only one is returned, I search for all SOMs (domain, OUs, and sites) that have the GPO linked using the GPMSitesContainer.SearchSites and GPMDomain.SearchSOMs methods. 9.11.4 See Also Recipe 9.12 for creating a GPO link to an OU MSDN: GPMDomain.SearchSOMs, and MSDN: GPMSitesContainer.SearchSites Recipe 9.12 Creating a GPO Link to an OU 9.12.1 Problem You want to apply the GPO settings to the users and/or computers in an OU. This is called linking a GPO to an OU. 9.12.2 Solution 9.12.2.1 Using a graphical user interface 1. Open the GPMC snap-in. 289 2. In the left pane, expand the Forest container, expand the Domains container, and browse to the target domain. 3. Right-click on the OU you want to link and Link an Existing GPO. 4. Select from the list of available GPOs and click OK. 9.12.2.2 Using VBScript ' This code links a GPO to an OU ' SCRIPT CONFIGURATION strGPO = "<GPOName>" ' e.g. Sales GPO strDomain = "<DomainDNSName>" ' e.g. rallencorp.com strOU = "<OrgUnitDN>" ' e.g. ou=Sales,dc=rallencorp,dc=com intLinkPos = -1 ' set this to the position the GPO evaluated at ' a value of -1 signifies appending it to the end of the list ' END CONFIGURATION set objGPM = CreateObject("GPMgmt.GPM") set objGPMConstants = objGPM.GetConstants( ) ' Initialize the Domain object set objGPMDomain = objGPM.GetDomain(strDomain, "", objGPMConstants.UseAnyDC) ' Find the specified GPO set objGPMSearchCriteria = objGPM.CreateSearchCriteria objGPMSearchCriteria.Add objGPMConstants.SearchPropertyGPODisplayName, objGPMConstants.SearchOpEquals, cstr(strGPO) set objGPOList = objGPMDomain.SearchGPOs(objGPMSearchCriteria) if objGPOList.Count = 0 then WScript.Echo "Did not find GPO: " & strGPO WScript.Echo "Exiting." WScript.Quit elseif objGPOList.Count > 1 then WScript.Echo "Found more than one matching GPO. Count: " & _ objGPOList.Count WScript.Echo "Exiting." WScript.Quit else WScript.Echo "Found GPO: " & objGPOList.Item(1).DisplayName end if ' Find the specified OU set objSOM = objGPMDomain.GetSOM(strOU) if IsNull(objSOM) then WScript.Echo "Did not find OU: " & strOU WScript.Echo "Exiting." WScript.Quit else WScript.Echo "Found OU: " & objSOM.Name end if on error resume next set objGPMLink = objSOM.CreateGPOLink( intLinkPos, objGPOList.Item(1) ) if Err.Number <> 0 then WScript.Echo "There was an error creating the GPO link." 290 WScript.Echo "Error: " & Err.Description else WScript.Echo "Sucessfully linked GPO to OU" end if 9.12.3 Discussion Linking a GPO is the process whereby you assign a SOM, which can be an OU, site, or domain. The solutions show how to link a GPO to an OU, but they could be easily modified to link to a site or domain. See Recipe 5.11 for details on how to link an OU by modifying the gpLink attribute, instead of using the GPMC interface. 9.12.3.1 Using VBScript To link a GPO, I first have to find the target GPO. I use a GPMSearchCriteria object to find the GPO that is equal to the display name of the GPO specified in the configuration section. I use an if elseif else conditional statement to ensure that only one GPO is returned. If zero or more than are are returned, I abort the script. If only one GPO was returned, I instantiate a GPMSOM object by passing the name of the OU to be linked to the GPMDomain.GetSOM method. Once I instantiate this object, I can call GPMSOM.CreateGPOLink to create a GPO link to the OU. 9.12.4 See Also MS KB 248392 (Scripting the Addition of Group Policy Links) and MSDN: GPMSOM.CreateGPOLink Recipe 9.13 Blocking Inheritance of GPOs on an OU 9.13.1 Problem You want to block inheritance of GPOs on an OU. 9.13.2 Solution 9.13.2.1 Using a graphical user interface 1. Open the GPMC snap-in. 2. In the left pane, expand the Forest container, expand the Domains container, and browse to the target domain. 3. Right-click on the OU you want to block inheritance for and select Block Inheritance. 9.13.2.2 Using VBScript ' This code blocks inheritance of GPOs on the specified OU ' SCRIPT CONFIGURATION strDomain = "<DomainDNSName>" ' e.g. rallencorp.com . instantiated earlier. The rest of the script performs some error handling and prints the results. 9.7.4 See Also Recipe 9.3 for copying a GPO, Recipe 9.17 for backing up a GPO, and MSDN: GPMGPO.Import. table to help facilitate the transfer of those kinds of references to the target domain. For more information on migration tables, see the GPMC help file. 9.7.3.1 Using VBScript 283 To. script, browse to Computer Configuration Windows Settings Scripts. If you want to assign a user logon or logoff script, browse to User Computer Windows Settings Scripts. 5. In the right