8

We have been handling all of our targeting logic for Packages (and now Applications) with Collections. Now that we have moved from SCCM 2007 to SCCM 2012 SP1 it was recommended that we move that logic to the Application-Program model and implement it using Global Conditions and Requirements. This has a number of positive benefits - Collections are used purely for hierarchical or logical grouping, we get a more seamless Application deployment when using Supercedence, and improved Detection logic.

I'll use Adobe Flash Player Plugin as an example. We only want to deploy Adobe Flash Player Plugin to workstations that have Firefox installed. Using the SCCM 2007 Package-Program model we would create a Collection based on a WQL query that contained all workstations with Firefox installed:

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"

Once we had the Collection created we would then deploy our Package-Program against it. I'm trying to replicate the same logic using the Application-Program's Global Conditions and Requirements logic. All my attempts to build my WQL query based Global Condition result in a wbemErrTypeMismatch error (2147749893 (0x80041005)).



Now that best practices recommends that we keep our targeting logic bundled with the Application what we need to do is create an appropriate WQL query Global Condition and then we can evaluate it using the Application's Requirements.

Let's start with the WQL query. I used Scriptomatic to just dump everything in the SMS_InstalledSoftware WMI Class which is part of the root\cimv2\sms namespace. I'm reasonably sure that SMS_InstalledSoftware is the best place to run queries against when trying to evaluate whether or not something is installed as Win32_Product is only for Windows Installer installed software.

I find the following Firefox related object:

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



Running the WQL against the ProductName property seems to be a good way to go. If I run SELECT * FROM SMS_InstalledSoftware WHERE ProductName like '%Firefox%' in wbemtest against the root\cimv2\sms namespace I get the following:

wbemtest results



Let's try building the Global Condition in SCCM next:

Global Condition Query



This is completely unintuitive but I think I understand it correctly. Global Conditions just set up the conditional part of the whole Application-Program logic not any of the evaluative Application-Program logic. For that reason, I'm not doing anything in the WHERE clause. This Global Condition should look in the root\cimv2\sms namespace for the SMS_InstalledSoftware class and "return" the ProductName property. I should now be able to evaluate the value/s of that Property with my Applications' Deployment Type Requirement, right?

SCCM Requirements



Again - I'm either not understanding how the whole Global Condition/Requirements logic hangs together or it is just this unintuitive but the above Requirement should be able to look at all the Strings returned from the ProductName property, evaluate if any of them contain 'Firefox' and if so happily deploy Adobe Flash Player Plugin.

Unfortunately it doesn't work. Almost all of machines in the Deployment return the following error:

2147749893 (0x80041005) Type Mismatch

I take this to mean that Global Condition is returning a different type of variable than I'm evaluating in my Requirement but I have no idea how to troubleshoot it from here. I've tried setting my Global Condition's type to Boolean, and setting the WHERE clause (Name like '%Firefox%') but this yields the same error.

How can I replicate my WQL query-based Collection using the Application-Program's Global Condition/Requirements targeting logic? What am I missing here (other than apt-get)?

3 Answers3

1

The Global Condition dialog is probably the most unintuitive part of SCCM I've seen so far.

Give this a try:

  1. recreate your Firefox 2 Global Condition the same way, but this time in the WQL Query Where Clause field at the bottom, put: ProductName like "%Firefox%"

  2. In the Requirements tab of your Application's Deployment Type, use the Firefox 2 Global Condition, but change the Rule Type to Existential

1.618
  • 669
  • 1
  • 4
  • 17
0

This is qualified guesswork, as I have no way to test this, hands-on

As WQL does not have a native containment operator, I believe that the Contains operator is treated as in PowerShell:

$referenceCollection -Contains $testValue

If this theory is correct, your underlying Requirement logic will expand to this:

"Microsoft Firefox 23 (en-us)" -Contains "firefox"

If the left-hand operand of -Contains is not a collection, but a single instance of the same type as the test value (as in your example, two strings), -Contains is treated exactly as -eq.

Therefore, "Microsoft Firefox 23 (en-us)" -Contains "firefox" will always return false.

Mathias R. Jessen
  • 24,907
  • 4
  • 62
  • 95
0

I would personally use a powershell script for this rather than a WQL query. My powershell would pretty much do exactly the same thing as the WQL you are doing (even querying the same WMI Class) but it would work using a booleean e.g.

$Firefox = Get-WmiObject -namespace root\cimv2\sms -class SMS_InstalledSoftware -filter "ARPDisplayName LIKE '%Firefox%'"
if($Firefox){return $true}else{return $false}

This will essentially return true if the WMI query returns a result and false if not. You can then basically use the global condition on your application along the lines of: Firefox 2 must equal true. I have done this a lot now using this method mostly for configuration items and application detection methods where an MSI if not being used.

If you wanted to keep doing things as you currently are then I would have to agree with @1.618 comments.

d4rkcell
  • 11
  • 1