SDK: How to create an Application with a requirement rule pointing to a global condition

In a previous post, I demonstrated how to create an application with an enhanced detection rule (EHD). Creating an application with a requirements rule is a bit more complicated. In this post I will provide a sample on how to do this using one of the “out of the box” global conditions that’s provided with the product. In this case, this rule is stating that the free disk space on the system drive must be higher than 5GB.

First use the sample program in this post. Then add this code between line 39 and 41:

    1: // Now create the deployment type and bind it to the installer
    2: DeploymentType scriptDT = new DeploymentType(installer, ScriptInstaller.TechnologyId, NativeHostingTechnology.TechnologyId);
    3: scriptDT.Title = "My Application Installer";
    4: application.DeploymentTypes.Add(scriptDT);
    5:
    6: // Expression for the properties around the drive (in this case, must be system drive)
    7: CustomCollection<ExpressionBase> settingsOperands = new CustomCollection<ExpressionBase>();
    8: GlobalSettingReference driveIdSettingRef = new GlobalSettingReference("GLOBAL", "FreeDiskSpace", DataType.String, "DriveID", ConfigurationItemSettingSourceType.CIM);
    9: GlobalSettingReference systemDriveSettingRef = new GlobalSettingReference("GLOBAL", "FreeDiskSpace", DataType.String, "SystemDrive", ConfigurationItemSettingSourceType.CIM);
   10: settingsOperands.Add(driveIdSettingRef);
   11: settingsOperands.Add(systemDriveSettingRef);
   12: Expression driveSettingsExp = new Expression(ExpressionOperator.IsEquals, settingsOperands);
   13:
   14: // Expression for the drive space, must be greater than n
   15: CustomCollection<ExpressionBase> freeSpaceOperands = new CustomCollection<ExpressionBase>();
   16: GlobalSettingReference freeSpaceSettingRef = new GlobalSettingReference("GLOBAL", "FreeDiskSpace", DataType.Int64, "FreeSpace", ConfigurationItemSettingSourceType.CIM);
   17: ConstantValue constant = new ConstantValue(Convert.ToString((long)5000 * 1024 * 1024) /* 5000MB to KB to bytes */, DataType.Int64);
   18: freeSpaceOperands.Add(freeSpaceSettingRef);
   19: freeSpaceOperands.Add(constant);
   20: Expression freeSpaceExp = new Expression(ExpressionOperator.GreaterEquals, freeSpaceOperands);
   21:
   22: // Outer expression that combines the previous expressions
   23: CustomCollection<ExpressionBase> outerOperands = new CustomCollection<ExpressionBase>();
   24: outerOperands.Add(freeSpaceExp);
   25: outerOperands.Add(driveSettingsExp);
   26:
   27: Expression fullExp = new Expression(ExpressionOperator.And, outerOperands);
   28:
   29: // Now build a rule and add it to the DT
   30: Rule rule = new Rule("MyRule_" + Guid.NewGuid().ToString(), NoncomplianceSeverity.Critical, null, fullExp);
   31: scriptDT.Requirements.Add(rule);

This code builds a tree for the requirement rule based on the global setting “FreeDiskSpace”. If the code is a bit much to take in, here’s the XML it generates internally that may explain the logic a bit better:

 <Rule id="MyRule_bb25f0f3-dca6-4a9b-9182-2712bdca5187" Severity="Critical" NonCompliantWhenSettingIsNotFound="false" xmlns="https://schemas.microsoft.com/SystemsCenterConfigurationManager/2009/06/14/Rules">
   <Expression>
     <Operator>And</Operator>
     <Operands>
       <Expression>
         <Operator>GreaterEquals</Operator>
         <Operands>
           <GlobalSettingReference AuthoringScopeId="GLOBAL" LogicalName="FreeDiskSpace" DataType="Int64" SettingLogicalName="FreeSpace" SettingSourceType="CIM" Method="Value" />
           <ConstantValue Value="5242880000" DataType="Int64" />
         </Operands>
       </Expression>
       <Expression>
         <Operator>Equals</Operator>
         <Operands>
           <GlobalSettingReference AuthoringScopeId="GLOBAL" LogicalName="FreeDiskSpace" DataType="String" SettingLogicalName="DriveID" SettingSourceType="CIM" Method="Value" />
           <GlobalSettingReference AuthoringScopeId="GLOBAL" LogicalName="FreeDiskSpace" DataType="String" SettingLogicalName="SystemDrive" SettingSourceType="CIM" Method="Value" />
         </Operands>
       </Expression>
     </Operands>
   </Expression>
 </Rule>

 

Global conditions can be accessed through the SMS Provider by looking at the SMS_GlobalCondition class instances. You can also view the unique ID information for global conditions directly through the administrator console (this way you can get the authoring scope ID and logical name) by going into Software Library –> Application Management –> Global Conditions and enabling the “CI Unique ID” column.

This is not a comprehensive example in that it only provides one specific way to use requirement rules and doesn’t provide information on how to create global conditions. I hope to provide this information in a future blog post. I hope this is enough to at least get some of you started on this area of the SDK that frequently gets questions asked about it.

Download sample program Program.cs