Мы обрабатываем всю нашу логику таргетинга для пакетов (а теперь и приложений) с помощью коллекций. Теперь, когда мы перешли с SCCM 2007 на SCCM 2012 SP1, было рекомендовано перенести эту логику в модель «приложение-программа» и реализовать ее с использованием глобальных условий и требований. Это имеет ряд положительных преимуществ - коллекции используются исключительно для иерархической или логической группировки, мы получаем более плавное развертывание приложений при использовании Supercedence и улучшенную логику обнаружения.
В качестве примера я буду использовать плагин Adobe Flash Player. Мы хотим развернуть плагин Adobe Flash Player только на рабочих станциях с установленным Firefox. Используя модель пакета-программы SCCM 2007, мы могли бы создать коллекцию на основе запроса WQL, содержащего все рабочие станции с установленным Firefox:
select * from SMS_R_System inner join SMS_G_System_SoftwareProduct
on SMS_G_System_SoftwareProduct.ResourceId = SMS_R_System.ResourceId
where SMS_G_System_SoftwareProduct.ProductName like "Mozilla Firefox"
Как только у нас будет создана Коллекция, мы развернем против нее нашу Пакетную Программу. Я пытаюсь воспроизвести ту же логику, используя логику глобальных условий и требований прикладной программы. Все мои попытки создать глобальное условие на основе WQL-запроса приводят к wbemErrTypeMismatch ошибка (2147749893 (0x80041005)
).
Теперь, когда лучшие практики рекомендуют нам сохранить нашу логику таргетинга в комплекте с приложением, нам нужно создать соответствующее глобальное условие WQL-запроса, а затем мы сможем оценить его, используя требования приложения.
Начнем с WQL-запроса. Я использовал Scriptomatic, чтобы просто сбрасывать все в SMS_InstalledSoftware
Класс WMI, который является частью root\cimv2\sms
пространство имен. Я достаточно уверен, что SMS_InstalledSoftware это лучшее место для выполнения запросов при попытке оценить, установлено ли что-либо, поскольку Win32_Product предназначен только для установленного программного обеспечения Windows Installer.
Я нахожу следующий объект, связанный с Firefox:
ARPDisplayName: Mozilla Firefox 23.0.1 (x86 en-US)
ChannelCode:
ChannelID:
CM_DSLID:
EvidenceSource: CPXCCCCCCXCXCXCXXXXXCXXXXX
InstallDirectoryValidation: 4
InstalledLocation: C:\Program Files (x86)\Mozilla Firefox
InstallSource:
InstallType: 0
Language: 0
LocalPackage:
MPC:
OsComponent: 0
PackageCode:
ProductID:
ProductName: Mozilla Firefox 23.0.1 (x86 en-US)
ProductVersion: 23.0.1
Publisher: Mozilla
RegisteredUser:
ServicePack:
SoftwareCode: mozilla firefox 23.0.1 (x86 en-us)
SoftwarePropertiesHash: 63896ed23146ec91dbc763b45c127ba31216e2f9d657a87953440d30b7f306bc
SoftwarePropertiesHashEx: 67c2ecc42f0e0b9da6ee55bc0dea67a4d90b9e8452c9fdb25db57d4891698f25
UninstallString: "C:\Program Files (x86)\Mozilla Firefox\uninstall\helper.exe"
UpgradeCode:
VersionMajor: 2147483647
VersionMinor: 2147483647
Запуск WQL для свойства ProductName кажется хорошим способом. Если я сбегу SELECT * FROM SMS_InstalledSoftware WHERE ProductName like '%Firefox%'
в wbemtest
против root\cimv2\sms
пространство имен я получаю следующее:
Давайте попробуем построить Global Condition в SCCM следующим образом:
Это совершенно не интуитивно, но я думаю, что правильно понимаю. Глобальные условия просто настроили условный часть всей логики прикладной программы, а не оценочный Прикладно-программная логика. По этой причине я ничего не делаю в предложении WHERE. Это глобальное условие следует искать в root\cimv2\sms
пространство имен для SMS_InstalledSoftware
class и "вернуть" свойство ProductName. Теперь я должен иметь возможность оценить значение этого свойства с учетом требований типа развертывания моих приложений, верно?
Опять же - я либо не понимаю, как взаимосвязана вся логика глобальных условий / требований, либо это просто неинтуитивно, но указанное выше Требование должно иметь возможность просматривать все строки, возвращаемые из ProductName
, оцените, содержит ли какой-либо из них «Firefox», и, если да, успешно разверните подключаемый модуль Adobe Flash Player.
К сожалению, это не работает. Почти все машины в развертывании возвращают следующую ошибку:
2147749893 (0x80041005) Type Mismatch
Я понимаю, что это означает, что Global Condition возвращает переменную другого типа, чем я оцениваю в моем Требовании, но я понятия не имею, как устранить его здесь. Я попытался установить для своего глобального условия тип Boolean и установить предложение WHERE (Name like '%Firefox%'
), но это дает ту же ошибку.
Как я могу реплицировать мою коллекцию на основе запросов WQL, используя логику таргетинга Global Condition / Requirements прикладной программы? Что мне здесь не хватает (кроме apt-get)?
Диалог Global Condition - вероятно, самая неинтуитивная часть SCCM, которую я когда-либо видел.
Попробуйте:
воссоздайте свое глобальное условие Firefox 2 таким же образом, но на этот раз в поле WQL Query Where Clause внизу введите: ProductName like "%Firefox%"
На вкладке Требования в Типе развертывания вашего приложения используйте Глобальное условие Firefox 2, но измените Тип правила на Существующий.
Это квалифицированное предположение, поскольку у меня нет возможности проверить это на практике.
Поскольку WQL не имеет собственного оператора включения, я считаю, что Contains
Оператор обрабатывается как в PowerShell:
$referenceCollection -Contains $testValue
Если эта теория верна, ваша базовая логика требований расширится до следующего:
"Microsoft Firefox 23 (en-us)" -Contains "firefox"
Если левый операнд -Contains
не коллекция, а отдельный экземпляр того же типа, что и тестовое значение (как в вашем примере, две строки), -Contains
рассматривается в точности как -eq
.
Следовательно, "Microsoft Firefox 23 (en-us)" -Contains "firefox"
всегда будет возвращать false.
Я бы лично использовал для этого сценарий PowerShell, а не WQL-запрос. Моя оболочка PowerShell в значительной степени будет делать то же самое, что и WQL, который вы делаете (даже запрашивая тот же класс WMI), но он будет работать с логическим значением, например.
$Firefox = Get-WmiObject -namespace root\cimv2\sms -class SMS_InstalledSoftware -filter "ARPDisplayName LIKE '%Firefox%'"
if($Firefox){return $true}else{return $false}
По сути, это вернет истину, если запрос WMI вернет результат, и ложь, если нет. Затем вы можете в основном использовать глобальное условие в своем приложении в следующем порядке: Firefox 2 должен быть равен true. Я делал это много сейчас, используя этот метод в основном для элементов конфигурации и методов обнаружения приложений, где MSI не используется.
Если вы хотите продолжать делать то, что делаете сейчас, я должен согласиться с комментариями @ 1.618.