Delayed Enforcement of Active Directory Group Policy Using WMI Filter
I recently had the need to delay the enforcement of a group policy object until 24 hours after a computer had been deployed with Windows Vista. In this article I will explain how I addressed this requirement through the use of a WMI group policy filter.
A WMI group policy filter can be used to restrict the enforcement of a policy to a subset of users or computers. Only those users or computers satisfying the filter will receive the policy object.
Group policy filters are written using WQL, which is a kind of crippled SQL syntax. There are several restrictions that apply when using WQL. Firstly, a WQL query can only target a single table. Therefore, in the context of WMI, you can only query a single namespace. The following is not permitted:
SELECT * FROM Win32_OperatingSystem, Win32_Environment WHERE LocalDateTime > PolicyTime
Where LocalDateTime is a property of Win32_OperatingSystem and PolicyTime is a custom-defined environment variable accessed via Win32_Environment.
Secondly, you cannot perform any kind of arithmetic in the query. For example, the following is not permitted:
SELECT * From Win32_OperatingSystem WHERE (LocalDateTime - InstallDate) > 1000000
Where both LocalDateTime and InstallDate are properties of Win32_OperatingSystem.
These limitations make it difficult to build a group policy WMI filter that can be used to exclude computers that were deployed in the past 24 hours.
I resolved this issue by storing the date after which the group policy object is to apply in the Description property of the Win32_OperatingSystem namespace. I chose this property for two reasons. Firstly, the attribute is writeable, and is not assigned a default value. Secondly, the Win32_OperatingSystem namespace includes a property called LocalDateTime that can be used to query the current system time. This configuration permits the use of the following WMI filter:
SELECT LocalDateTime, Description FROM Win32_OperatingSystem WHERE LocalDateTime > Description OR Description = ''
Where Description is specifically set during the operating system deployment process to the UTC time after which the group policy object should be applied. The "OR Description = ''" component of the query ensures the filter applies in the event that the Description property is not set. This was important in our environment, as the policy had to apply to computers that were built without a value assigned to Description.
Now that the query is established, the next step is to show how the Description property is correctly set during the build process (computers in the environment are built using Microsoft SCCM 2007). This is achieved by running the following script at the completion of the build:
Const CONVERT_TO_LOCAL_TIME = True
Set dtmPolicyDate = CreateObject("WbemScripting.SWbemDateTime")
Set oWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set oWin32OS = oWMIService.Get("Win32_OperatingSystem").SpawnInstance_
Set cItems = oWMIService.ExecQuery("Select * From Win32_OperatingSystem")
For Each oItem In cItems
dtmInstallDate = DatetimeToDate(oItem.InstallDate)
dtmTempDate = DateAdd("h", 24, dtmInstallDate)
dtmPolicyDate.SetVarDate dtmTempDate, CONVERT_TO_LOCAL_TIME
Set oProperty = oWin32OS.SpawnInstance_
oProperty.Description = dtmPolicyDate
oProperty.Put_
WScript.Echo oItem.Description
Next
Function DatetimeToDate(strDate)
DatetimeToDate = _
CDate(Mid(strDate, 5, 2) & _
"/" & _
Mid(strDate, 7, 2) & _
"/" & _
Left(strDate, 4) & _
" " & _
Mid (strDate, 9, 2) & _
":" & _
Mid(strDate, 11, 2) & _
":" & _
Mid(strDate, 13, 2))
End Function
The script queries the Win32_OperatingSystem namespace to retrieve the InstallDate property (which stores the time at which the operating system was deployed in UTC format). This value is then converted to VT_DATE format using the DatetimeToDate function. The time is then incremented through DateAdd by 24 hours. The incremented time is then converted back to UTC format through the SetVarDate method of the WbemScripting.SWbemDateTime object. Finally, this value is written into the Description property.
You can confirm the Description field has been set correctly by looking at the Computer Name tab of the System Properties dialog as shown below:

As you can tell, the time is recorded in UTC format, which lists the year, month, day, hour, minutes, and seconds, then a period, 6 zeros, and then a timezone differential (in this case, +600, which equates to 600 minutes, or 10 hours ahead of GMT):
20090909115853.000000+600
By changing the DateAdd line in the script above, it is possible to change the size of the delay between building a computer and enforcing specific group policy settings. In our environment, we used this technique to delay the enforcement of power management settings to 1 day after the completion of the build process. This ensures computers will not go to sleep until at least 24 hours after the build completes.