SCCM 2012 PowerShell: Create a Global Condition Rule

As I already mentioned using PowerShell with SCCM 2012 is still not optimal. Automating application creation and maintenance is still a lot of manual work. Today I want to show you an solution I created to add an Global condition to a deployment rule.

The advantage you can create is that an application installs only when the hardware is valid according to your policies. Until now there is no function you can call which create a global condition rule. Below you can find my solution

  <#
 
        .SYNOPSIS
            Creates a Global Condition rule of type &#91;Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.Rule&#93;. 
            This rule can be added as a requirement for an deployment type

        .DESCRIPTION
            This function will Create a rule for an global condition
             
        .PARAMETER GlobalCondition
            Name of the global condition you wanted to use
 
        .PARAMETER Operator
            Operator used to validate the rule. Accepted values are Equals,NotEquals,GreaterThan,LessThan,Between,GreaterEquals,LessEquals,BeginsWith,NotBeginsWith,EndsWith,NotEndsWith,Contains,NotContains,AllOf,OneOf,NoneOf,SetEquals
            
        .PARAMETER Value
            Value on which the rule should check. Use MB when data value is needed

        .PARAMETER SiteServerName
           Name of the SCCM Site server to check Global Conditions
 
        .EXAMPLE
            Create-SCCMGlobalConditionsRule "TotalPhysicalMemory" "GreaterEquals" 524288000 .
             
            Creates a rule where Total Phyiscal memory is greater than or equals to 500 MB
 
        .EXAMPLE
            
            Create-SCCMGlobalConditionsRule "CPU" "GreaterThan" 10000 .
            
            Creates a rule where the cpu speed is greater than 1 GHZ
 
 #>
 Function Create-SCCMGlobalConditionsRule($GlobalCondition,$Operator, $Value,$siteServerName){
    if($GlobalCondition.ModelName -eq $null){
        $GlobalCondition = Get-SCCMGlobalCondition $GlobalCondition $siteServerName
    }

    if($GlobalCondition -eq $null){
        Write-Error "Global condition not found"
    }

    $gcTmp =  $GlobalCondition.ModelName.Split("/")
    $gcScope = $gcTmp[0]
    $gcLogicalName = $gcTmp[1]
    $gcDataType = $GlobalCondition.DataType
    $gcExpressionDataType = [Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.DataType]::GetDataTypeFromTypeName($gcDataType)
   
    $arg = @($gcScope, 
              $gcLogicalName, 
              $gcExpressionDataType, 
              "$($gcLogicalName)_Setting_LogicalName", 
              ([Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ConfigurationItemSettingSourceType]::CIM) 
             )
    $reqSetting =  new-object  Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.GlobalSettingReference -ArgumentList  $arg

    $arg = @( $value,
               $gcExpressionDataType
             )
    $reqValue = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.ConstantValue -ArgumentList $arg




    $operands = new-object "Microsoft.ConfigurationManagement.DesiredConfigurationManagement.CustomCollection``1[[Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.ExpressionBase]]"
    $operands.Add($reqSetting) | Out-Null
    $operands.Add($reqValue) | Out-Null
 
    $Expoperator =  Invoke-Expression [Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ExpressionOperators.ExpressionOperator]::$operator
    
    if( $GlobalCondition.DataType -eq "OperatingSystem"){
    
        $operands = new-object "Microsoft.ConfigurationManagement.DesiredConfigurationManagement.CustomCollection``1[[Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.RuleExpression]]"
        foreach( $os in $value){
            $operands.Add($os)
        }
        $arg = @( $Expoperator , 
            $operands
        )
        $expression = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.OperatingSystemExpression -ArgumentList $arg
    
    }else{
        $arg = @( $Expoperator , 
            $operands
        )
        $expression = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.Expression -ArgumentList $arg
    
    }
    
    $anno =  new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.Annotation 
    $annodisplay = "$GlobalCondition.LocalizedDisplayName $operator $value"
    $arg = @(
                "DisplayName", 
                $annodisplay, 
                $null
            )
    $anno.DisplayName = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.LocalizableString -ArgumentList $arg
    
    $arg = @(
                 ("Rule_" + [Guid]::NewGuid().ToString()), 
                 [Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.NoncomplianceSeverity]::None, 
                 $anno, 
                 $expression
            )
    $rule = new-object "Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.Rule" -ArgumentList $arg


    return $rule
 }

The only thing you now have to do is call this function and save it

$rule = Create-SCCMGlobalConditionsRule "CPu" "GreaterThan" 1000 .
$app.DeploymentTypes[0].Requirements.Add($rule)
$rule = Create-SCCMGlobalConditionsRule "Global/OperatingSystem" "OneOF" @("Windows/All_x64_Windows_XP_Professional") .
$app.DeploymentTypes[0].Requirements.Add($rule)
Save-SCCMApplication $app

15 thoughts on “SCCM 2012 PowerShell: Create a Global Condition Rule”

  1. Hi Robert, it’s difficult to find good information to the CM 2012 SDK, so thanks for your interesting blog. since a couple of days I’m looking for a sample to create a Global Condition like “Create-SCCMGlobalCondition”. Do you have some source or hints for C# or PS? Kind Regards Jens

    1. Hi Jens,
      I have a draft version of something that looks like creating a global condition. This one only creates a global condition that looks at a file. Don’t know if your looking for that? Or do you want to create another global condition…. Let me know and I will post the code when I made it better to read.
      Regards Rob

      1. Dear all
        Thank you for the ps script that i try to use to create a desired configuration rule.
        But, i have a problem with Device_oslanguage or OsLanguage global condition because i can’t create a rule, in fact the rule is created but reject by sccm when i check deployment type \ rules

        coul’d you check your script to see what it is eventualy wrong
        i try to resolve my problem without success
        many thanks
        ps : i try parameter 1033, English, en-US…> failed

  2. Hi Rob
    thanks for your answer. We have different ‘operating companies’ in our structure and we can differ them using AD / OU structure. I could made an deployment type rule for an OUValue, but I would prefer a global condition like “Organizational unit (OU) One of {DC=mydomain,DC=com(Include sub OU)}”. And I would prefer to define the AuthoringScopeID and logical name like “COMPANY-GLOBAL/MY-LOGICAL-NAME”.
    Thanks for your help!

  3. Hi Rob,
    I am very new when it comes to powershell! Would appreciate if you could maybe help me with the following:

    I want to add a requirement rule to an existing deployment type. The rule is a Global condition that already exists. I’m not interested in creating a rule but add an existing one to an existing application/deployment type. I have looked at your blog but do not really understand what I need to do to achieve what I want. Would be very happy if you could help me with an example that does what I want and also specify where I need to change for it to work with my rule and application.

    1. The Requirement rule looks like this:
      Category: Custom
      Condition: “Choose my Global condition”
      Rule type: Existential
      X – The selected global condition must exist on client devices

  4. Thanks for this! Very helpful, but do you know how to get it working for the “User Primary Device” condition?

    1. Download my new script
      link
      and use the following command”line
      Create-SCCMGlobalConditionsRule . “PrimaryDevice” “IsEquals” “True”

      1. I’m not sure what I changed last time to get it working but now I am seeing an error on the save function –
        Exception calling “Put” with “0” argument(s): “Generic failure ”

        I had to make some changes to get it working remotely but I did have it working in the last version although it doesn’t appear like you made any drastic changes….

        1. Not that I know. Which command did you use and can you check the smsprov.log on the SCCM server you connect to.

          1. Here are the logs I see…the error seems obvious just not sure why it’s occurring –

            CObjectLock::UserHasLock: ********** User MYDOMAIN\####### has acquired lock for object SMS_Application.CI_ID=16794749 with LockID: F8EF1C38-D560-49E2-8266-BD975036D9A2 ********** $$
            SQL MESSAGE: sp_SetupCI – Caught error: XML Validation: Invalid simple type value: ‘Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.Glo’. Location: /*:AppMgmtDigest[1]/*:DeploymentType[1]/*:Requirements[1]/*:Rule[1]/*:GlobalExpression[1]/@*:LogicalName $$
            error 12: SQL Error Message (null)~ $$
            ERROR CCISource::InsertObject returned 12~ $$
            ~*~*~e:\qfe\nts\sms\siteserver\sdk_provider\smsprov\sspconfigurationitem.cpp(2140) : The digest is not valid~*~*~ $$
            ~*~*~The digest is not valid ~*~*~ $$
            CObjectLock::ReleaseLock: ********** User MYDOMAIN\####### has released lock for object SMS_Application.CI_ID=16794749 with LockID: F8EF1C38-D560-49E2-8266-BD975036D9A2 ********** $$
            Auditing: User MYDOMAIN\####### called an audited method of an instance of class SMS_Application.~ $$
            CExtUserContext::LeaveThread : Releasing IWbemContextPtr=57680336~ $$

          2. Found it –

            $expression = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.GlobalExpression -ArgumentList $arg

            should be

            $expression = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.Expression -ArgumentList $arg

  5. Hi
    Thank you for the ps script that i try to use to create a desired configuration rule about oslanguage,but it failed (no rule created available on console)
    coul’d you tell me what is the parameter to pass to the script
    for example “en-us” ? “0409” for result” Anglais (Etats Unis)”
    i used it for device_operatingsystem or diskspace and it’s ok
    many thanks

  6. Hi, David.
    Thank you for your awesome blog.
    Using this post I was able to create a new custom Global Condition with simple settings.
    Now I need to create Global Condition with expression like when you go to “Create Global Condition” and in “Condition Type” you select “Expression”. After that you can add different clauses.
    I found a way to create such type of Global Condition, but I could not understand the way to add Clauses there. I’m trying to do that for a long time, so if you could help me, I’d very much appreciate it.
    Thanks!

Comments are closed.