При автоматизации развертывания ПО групповыми политиками часто встает вопрос соответствия системы требованиям устанавливаемого продукта. Решается он с помощью механизма WMI-фильтрации, учитывающей конкретные особенности каждой машины и появившейся с выходом Windows Server 2003. Нередко устанавливаемое ПО требует наличия в системе других программных платформ: .Net FX, DirectX, Java Runtime Environment и т.п. Для этой задачи существует простое и логичное решение с привлечением WMI-фильтра, опрашивающего класс win32_Product. Но то, что это еще и наихудшее решение, было прочувствовано на собственной шкуре.
После автоматизации внедрения очередной программы, последовал всплеск инцидентов, связанных с долгой загрузкой компьютеров. Вполне логично, ведь ПО устанавливается как раз в это время, и в следующий раз все будет привычно быстро, о чем и были проинформированы пользователи. Однако на следующий день проблема повторилась несмотря на то, что ПО уже установлено - компьютеры подвисали на этапе “Применения параметров компьютера”. В связи с массовостью явления подозрения логично пали на инфраструктуру групповых политик вцелом, что опять было ошибкой. Диагностика и устранение несуществующих общедоменных проблем не дали никаких результатов, кроме бесполезно потраченного времени и ресурсов. И тогда пришлось перейти к решению проблемы со стороны клиентской станции. Включение на ней отладочного режима журналирования применения групповых политик буквально сразу выявило источник проблем – WMI-фильтрацию.
Для жонглирования конкретными цифрами в качестве примера приведу эксперимент с 3-мя практически холостыми (без настройки) GPO с WMI-фильтрацией, определяющей соответствие компьютеров требованиям для установки OpenProj, Autodesk Design Review 2011 и Autodesk DWG TrueView 2009.
OpenProj – это Java-приложение, и ему нужна Java Runtime Environment. Имя GPO “New Group Policy Object – Java” и соответствующий WQL-запрос для WMI-фильтра:
select * from win32_Product where Name like ‘Java(TM) 6%’
Design Review 2011 требует .Net FX 3.5 sp1, Visual C++ 2005 Redistributable и Visual C++ 2008 Redistributable. Имя GPO “New Group Policy Object – DR” и WQL-запросы:
select * from win32_Product where Name=’Microsoft .NET Framework 3.5 SP1′
select * from win32_Product where Name=’Microsoft Visual C++ 2005 Redistributable’
select * from win32_Product where Name like ‘Microsoft Visual C++ 2008 Redistributable%’
Для DWG TrueView 2009 нужны DirectX не старше сборки от августа 2007 года, .Net FX 3, Visual C++ 2005 Redistributable и msxml6. Имя GPO “New Group Policy Object – TV” и WQL-запросы:
select * from win32_Product where Name like ‘DirectX End-User Runtimes%’ and Version>=’9.24.1400′
select * from win32_Product where Name like ‘Microsoft .NET Framework 3.0%’
select * from win32_Product where Name=’Microsoft Visual C++ 2005 Redistributable’
select * from win32_Product where Name=’MSXML 6.0 Parser’
Про то, как в win32_Product попал DirectX подробно написано в статье - http://icoo.cyberblogger.ru/2010/05/23/directx-po-must-have.html
Включение отладочного логирования на клиентской станции делается через ключ реестра HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon параметром UserEnvDebugLevel = REG_DWORD 0×30002
После перезагрузки станции и впечатляющей паузы на этапе “Применение параметров компьютера” можно переходить к анализу отладочного журнала - %windir%\debug\usermode\UserEnv.log, выдержки из которого я дополнительно несколько подрезал для минимизации вывода:
USERENV(218.540) 13:53:27:508 ProcessGPO: ==============================
USERENV(218.540) 13:53:27:508 ProcessGPO: Searching <cn=…>
USERENV(218.540) 13:53:27:508 ProcessGPO: Machine has access to this GPO.
USERENV(218.540) 13:53:27:508 FilterCheck: Found WMI Filter id of: <…>
USERENV(4a4.580) 13:53:27:649 LibMain: Process Name: C:\WINDOWS\system32\wbem\wmiprvse.exe
USERENV(174.784) 13:53:28:019 LibMain: Process Name: C:\WINDOWS\system32\msiexec.exe
USERENV(218.540) 13:53:45:204 ProcessGPO: GPO passes the filter check.
USERENV(218.540) 13:53:45:204 ProcessGPO: Found functionality version of: 2
USERENV(218.540) 13:53:45:204 ProcessGPO: Found file system path of: <…>
USERENV(218.540) 13:53:45:204 ProcessGPO: Found common name of: <…>
USERENV(218.540) 13:53:45:204 ProcessGPO: Found display name of:<New Group Policy Object - Java>
USERENV(218.540) 13:53:45:204 ProcessGPO: Found machine version of: GPC is 0, GPT is 0
USERENV(218.540) 13:53:45:204 ProcessGPO: Found flags of: 1
USERENV(218.540) 13:53:45:204 ProcessGPO: No client-side extensions for this object.
USERENV(218.540) 13:53:45:204 ProcessGPO: GPO New Group Policy Object - Java doesn’t contain any data since the version number is 0. It will be skipped.
USERENV(218.540) 13:53:45:204 ProcessGPO: ==============================
На выполнение WQL-запроса потрачено 17 сек.
USERENV(218.540) 13:53:45:204 ProcessGPO: ==============================
USERENV(218.540) 13:53:45:204 ProcessGPO: Searching <cn=…>
USERENV(218.540) 13:53:45:204 ProcessGPO: Machine has access to this GPO.
USERENV(218.540) 13:53:45:204 FilterCheck: Found WMI Filter id of: <…>
USERENV(218.540) 13:54:44:229 ProcessGPO: GPO passes the filter check.
USERENV(218.540) 13:54:44:229 ProcessGPO: Found functionality version of: 2
USERENV(218.540) 13:54:44:229 ProcessGPO: Found file system path of: <…>
USERENV(218.540) 13:54:44:229 ProcessGPO: Found common name of: <…>
USERENV(218.540) 13:54:44:229 ProcessGPO: Found display name of: <New Group Policy Object - DR>
USERENV(218.540) 13:54:44:229 ProcessGPO: Found machine version of: GPC is 1, GPT is 1
USERENV(218.540) 13:54:44:229 ProcessGPO: Found flags of: 1
USERENV(218.540) 13:54:44:229 ProcessGPO: Found extensions: […]
USERENV(218.540) 13:54:44:229 ProcessGPO: ==============================
Потрачена 1 мин, что составляет 20 сек на выполнение WQL-запроса.
USERENV(218.540) 13:54:44:229 ProcessGPO: ==============================
USERENV(218.540) 13:54:44:229 ProcessGPO: Searching <cn=…>
USERENV(218.540) 13:54:44:229 ProcessGPO: Machine has access to this GPO.
USERENV(218.540) 13:54:44:229 FilterCheck: Found WMI Filter id of: <…>
USERENV(218.540) 13:55:52:717 ProcessGPO: GPO passes the filter check.
USERENV(218.540) 13:55:52:717 ProcessGPO: Found functionality version of: 2
USERENV(218.540) 13:55:52:717 ProcessGPO: Found file system path of: <…>
USERENV(218.540) 13:55:52:757 ProcessGPO: Found common name of: <…>
USERENV(218.540) 13:55:52:757 ProcessGPO: Found display name of: <New Group Policy Object - TV>
USERENV(218.540) 13:55:52:757 ProcessGPO: Found machine version of: GPC is 1, GPT is 1
USERENV(218.540) 13:55:52:767 ProcessGPO: Found flags of: 1
USERENV(218.540) 13:55:52:767 ProcessGPO: Found extensions: […]
USERENV(218.540) 13:55:52:767 ProcessGPO: ==============================
Потрачено 1 мин 10 сек, что составляет примерно 17 сек на выполнение WQL-запроса.
Имеется явная проблема – общение с WMI-провайдером класса win32_Product очень неторопливое, и его результаты не кэшируются. Можно ли что-то сделать в такой ситуации? - Да! И лучшее решение на мой взгляд – вообще забыть о существовании этого класса, а факт установки ПО проверять по наличию определенных служб, папок и файлов. В частности WQL-запросы для вышеприведенных тестовых GPO можно переписать следующим образом:
Для “New Group Policy Object – Java”:
select * from CIM_DataFile where Name=’C:\\Program Files\\Java\\jre6\\bin\\java.exe’
Для “New Group Policy Object – DR”:
select * from CIM_Directory where Name=’C:\\windows\\Microsoft.NET\\Framework\\v3.5\\Microsoft .NET Framework 3.5 SP1′
select * from CIM_DataFile where Name=’C:\\Program Files\\Common Files\\Microsoft Shared\\VC\\msdia80.dll’ and (FileSize=625152 or FileSize=641536)
select * from CIM_DataFile where Name=’C:\\Program Files\\Common Files\\Microsoft Shared\\VC\\msdia90.dll’ and (FileSize=669184 or FileSize=670016)
Вилка с размерами файлов в 2-х последних запросах связана с тем, что нужные для Design Review 2011 платформы – “Visual C++ 2005 sp1 Redistributable” и “Visual C++ 2008 sp1 Redistributable” выходили в двух сборках – без и с обновлением безопасности (ATL Security Update)
Для “New Group Policy Object – TV”:
select * from CIM_DataFile where Name=’C:\\Windows\\system32\\d3dx9_39.dll’
select * from CIM_Directory where Name=’C:\\windows\\Microsoft.NET\\Framework\\v3.0′
select * from CIM_DataFile where Name=’C:\\Program Files\\Common Files\\Microsoft Shared\\VC\\msdia80.dll’
select * from CIM_DataFile where Name=’C:\\windows\\system32\\msxml6.dll’
Перегрузившись можно опять углубиться в отладочный журнал:
USERENV(21c.5c8) 14:42:35:912 ProcessGPO: ==============================
USERENV(21c.5c8) 14:42:35:922 ProcessGPO: Searching <cn=…>
USERENV(21c.5c8) 14:42:35:932 ProcessGPO: Machine has access to this GPO.
USERENV(21c.5c8) 14:42:35:932 FilterCheck: Found WMI Filter id of: <…>
USERENV(21c.5c8) 14:42:36:493 ProcessGPO: GPO passes the filter check.
USERENV(21c.5c8) 14:42:36:493 ProcessGPO: Found functionality version of: 2
USERENV(21c.5c8) 14:42:36:493 ProcessGPO: Found file system path of: <…>
USERENV(21c.5c8) 14:42:36:523 ProcessGPO: Found common name of: <…>
USERENV(21c.5c8) 14:42:36:543 ProcessGPO: Found display name of:<New Group Policy Object - Java>
USERENV(21c.5c8) 14:42:36:553 ProcessGPO: Found machine version of: GPC is 0, GPT is 0
USERENV(21c.5c8) 14:42:36:553 ProcessGPO: Found flags of: 1
USERENV(21c.5c8) 14:42:36:563 ProcessGPO: No client-side extensions for this object.
USERENV(21c.5c8) 14:42:36:563 ProcessGPO: GPO New Group Policy Object - Java doesn’t contain any data since the version number is 0. It will be skipped.
USERENV(21c.5c8) 14:42:36:573 ProcessGPO: ==============================
Проверка выполнена за 0.5 сек.
USERENV(21c.5c8) 14:42:36:573 ProcessGPO: ==============================
USERENV(21c.5c8) 14:42:36:573 ProcessGPO: Searching <cn=…>
USERENV(21c.5c8) 14:42:36:573 ProcessGPO: Machine has access to this GPO.
USERENV(21c.5c8) 14:42:36:573 FilterCheck: Found WMI Filter id of: <…>
USERENV(21c.5c8) 14:42:38:155 ProcessGPO: GPO passes the filter check.
USERENV(21c.5c8) 14:42:38:165 ProcessGPO: Found functionality version of: 2
USERENV(21c.5c8) 14:42:38:165 ProcessGPO: Found file system path of: <…>
USERENV(21c.5c8) 14:42:38:175 ProcessGPO: Found common name of: <…>
USERENV(21c.5c8) 14:42:38:205 ProcessGPO: Found display name of: <New Group Policy Object - DR>
USERENV(21c.5c8) 14:42:38:205 ProcessGPO: Found machine version of: GPC is 1, GPT is 1
USERENV(21c.5c8) 14:42:38:205 ProcessGPO: Found flags of: 1
USERENV(21c.5c8) 14:42:38:215 ProcessGPO: Found extensions: […]
USERENV(21c.5c8) 14:42:38:215 ProcessGPO: ==============================
Проверка выполнена за 1.6 сек.
USERENV(21c.5c8) 14:42:38:215 ProcessGPO: ==============================
USERENV(21c.5c8) 14:42:38:215 ProcessGPO: Searching <cn=…>
USERENV(21c.5c8) 14:42:38:215 ProcessGPO: Machine has access to this GPO.
USERENV(21c.5c8) 14:42:38:225 FilterCheck: Found WMI Filter id of: <…>
USERENV(21c.5c8) 14:42:39:848 ProcessGPO: GPO passes the filter check.
USERENV(21c.5c8) 14:42:39:848 ProcessGPO: Found functionality version of: 2
USERENV(21c.5c8) 14:42:39:848 ProcessGPO: Found file system path of: <…>
USERENV(21c.5c8) 14:42:39:858 ProcessGPO: Found common name of: <…>
USERENV(21c.5c8) 14:42:39:858 ProcessGPO: Found display name of: <New Group Policy Object - TV>
USERENV(21c.5c8) 14:42:39:868 ProcessGPO: Found machine version of: GPC is 1, GPT is 1
USERENV(21c.5c8) 14:42:39:868 ProcessGPO: Found flags of: 1
USERENV(21c.5c8) 14:42:39:868 ProcessGPO: Found extensions: […]
USERENV(21c.5c8) 14:42:39:868 ProcessGPO: ==============================
Проверка выполнена за 1.6 сек.
В результате то, что ранее выполнялось за 2 мин 40 сек, ускорилось 40-кратно и выполняется за 4 сек.
В заключении приведу еще несколько примеров WQL для проверки наличия ПО:
- 1C:Предприятие 7.7 для SQL - select * from CIM_DataFile where Name=’C:\\Program Files\\1Cv77\\BIN\\1cv7s.exe’
- Avast! Antivirus - select * from win32_Service where caption=’avast! Antivirus’
- .Net FX 2.0 - select * from CIM_Directory where Name=’C:\\windows\\Microsoft.NET\\Framework\\v2.0.50727′
- DameWare - select * from win32_Service where Caption=’DameWare Mini Remote Control’
- Microsoft Office - select * from CIM_Directory where Name=’C:\\Program Files\\Microsoft Office’
- Microsoft Office 2003 - select * from CIM_DataFile where Name=’C:\\Program Files\\Microsoft Office\\Office11\\excel.exe’
- Microsoft Office 2007 – select * from CIM_DataFile where Name=’C:\\Program Files\\Microsoft Office\\Office12\\excel.exe’
- UltraVNC - select * from win32_Service where Name=’winvnc’ or Name=’uvnc_service’
К сожалению подход не лишен недостатка в связи с тем, что при проверке наличия файлов и папок предполагается, что ОС устанавливалась в папку C:\WINDOWS, а программы в C:\Program Files, а на отдельных машинах это может быть и не так.
Ссылки:
Fixing Group Policy problems by using log files - http://technet.microsoft.com/ru-ru/library/cc775423(WS.10).aspx
How to enable user environment debug logging in retail builds of Windows - http://support.microsoft.com/kb/221833
Microsoft Visual C++ 2005 Service Pack 1 Redistributable Package ATL Security Update - http://www.microsoft.com/downloads/details.aspx?familyid=766a6af7-ec73-40ff-b072-9112bab119c2&displaylang=en
Microsoft Visual C++ 2008 Service Pack 1 Redistributable Package ATL Security Update - http://www.microsoft.com/downloads/details.aspx?familyid=2051a0c1-c9b5-4b0a-a8f5-770a549fd78c&displaylang=en