Skip to content

Instantly share code, notes, and snippets.

@Stephanevg
Last active July 20, 2020 19:32
Show Gist options
  • Save Stephanevg/e69198bc6fd59748e1fd6843452688d8 to your computer and use it in GitHub Desktop.
Save Stephanevg/e69198bc6fd59748e1fd6843452688d8 to your computer and use it in GitHub Desktop.
The New-SCCMDetectionRuleForDeploymentType helps to creates a new detection method for a deploymentType on an existing Application
Function New-SCCMDetectionRuleForDeploymentType {
Param(
[Parameter(Mandatory=$True)]
[ValidateSet("RegistryKey","File","Folder","MSI","Assembly","Other")]
$DetectionType,
[Parameter(Mandatory=$False,ParameterSetName="FileDetection")][ValidateNotNullOrEmpty()][String]$FileName,
[Parameter(Mandatory=$False,ParameterSetName="FileDetection")][ValidateNotNullOrEmpty()][String]$FolderPath,
[Parameter(Mandatory=$False,ParameterSetName="FileDetection")]$Is64bit,
[ValidateSet("And,","Or","IsEquals","NotEquals","GreaterThan","Between","GreaterEquals","LessEquals","BeginsWith","NotBeginsWith","EndsWith","NotEndsWith","Contains","NotContains","AllOf","OneOf","NoneOf","SetEquals","SupportedOperators")]
[Parameter(Mandatory=$False,ParameterSetName="FileDetection")]
[Parameter(Mandatory=$False,ParameterSetName="RegistryDetection")]
$Operator,
[Parameter(Mandatory=$false)]
[ValidateSet("None","Informational","Warning","Critical","CriticalWithEvent")]
$NoncomplianceSeverity = "None",
$ApplicationName,
$DeploymentTypeName,
[Parameter(Mandatory=$False,ParameterSetName="RegistryDetection")]
[ValidateSet("HKEY_LOCAL_MACHINE","HKEY_USERS","HKEY_CLASSES_ROOT","HKEY_CURRENT_CONFIG","HKEY_CURRENT_USER")]
[ValidateNotNullOrEmpty()][String]$RegistryHyve,
[Parameter(Mandatory=$False,ParameterSetName="RegistryDetection")][ValidateNotNullOrEmpty()][String]$RegistryKey,
[Parameter(Mandatory=$False,ParameterSetName="RegistryDetection")][String]$RegistryKeyValue,
[Parameter(Mandatory=$False,ParameterSetName="RegistryDetection")][string]$RegistryKeyValueDataType = "String",
[Parameter(Mandatory=$False,ParameterSetName="RegistryDetection")]
[Parameter(Mandatory=$false)][switch]$CheckForConstant,
[Parameter(Mandatory=$False,ParameterSetName="RegistryDetection")]
$ConstantValue,
[Parameter(Mandatory=$False,ParameterSetName="RegistryDetection")]
$ConstantDataType,
[Parameter(Mandatory=$False,ParameterSetName="RegistryDetection")]
$DcmObjectModelPath = "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\DcmObjectModel.dll",
[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer
)
$application1 = [wmi](Get-WmiObject -Query "select * from sms_application where LocalizedDisplayName='$ApplicationName' AND ISLatest='true'" -ComputerName $sccmserver.Machine -Namespace $sccmserver.Namespace).__PATH
#Deserialize the SDMPackageXML
$App1Deserializedstuff = [Microsoft.ConfigurationManagement.ApplicationManagement.Serialization.SccmSerializer]::DeserializeFromString($application1.SDMPackageXML)
$oEnhancedDetection = New-Object Microsoft.ConfigurationManagement.ApplicationManagement.EnhancedDetectionMethod
switch ($DetectionType){
"File" {
write-verbose "--> Creating Enhanced File Detection Method"
$oDetectionType = [Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ConfigurationItemPartType]::File
$oFileSetting = New-Object Microsoft.ConfigurationManagement.DesiredConfigurationManagement.FileOrFolder( $oDetectionType , $null)
if ($oFileSetting -ne $null) { write-verbose " oFileSetting object Created"} else {write-warning " oFileSetting object Creation failed"; break}
$oFileSetting.FileOrFolderName = $FileName
$oFileSetting.Path = $FolderPath
if ($Is64bit){$Is64bits= 1}else{$Is64bits = 0}
$oFileSetting.Is64Bit = $Is64bits#$Is64bits
$oFileSetting.SettingDataType = [Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.DataType]::Int64
#$oFileSetting.ChangeLogicalName()
$oEnhancedDetection.Settings.Add($oFileSetting)
#$oFileSetting
write-verbose "Settings Reference"
$oSettingRef = New-Object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.SettingReference(
$App1Deserializedstuff.Scope,
$App1Deserializedstuff.Name,
$App1Deserializedstuffation.Version,
$oFileSetting.LogicalName,
$oFileSetting.SettingDataType,
$oFileSetting.SourceType,
[bool]0 )
# setting bool 0 as false
if ($oSettingRef -ne $null) { write-verbose " oSettingRef object Created"} else {write-warning " oSettingRef object Creation failed"; exit}
$oSettingRef.MethodType = [Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ConfigurationItemSettingMethodType]::Value
$oConstValue = New-Object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.ConstantValue( 0,
[Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.DataType]::Int64)
if ($oConstValue -ne $null) { write-verbose " oConstValue object Created"} else {write-warning " oConstValue object Creation failed"; exit}
$oFileCheckOperands = new-object Microsoft.ConfigurationManagement.DesiredConfigurationManagement.CustomCollection``1[[Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.ExpressionBase]]
$oFileCheckOperands.Add($oSettingRef)
$oFileCheckOperands.Add($oConstValue)
$FileCheckExpression = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.Expression(
[Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ExpressionOperators.ExpressionOperator]::NotEquals, $oFileCheckOperands)
$oRule = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.Rule("IsInstalledRule",
[Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.NoncomplianceSeverity]::$NoncomplianceSeverity, $null, $FileCheckExpression)
if ($oRule -ne $null) { write-verbose " rule object Created"} else {write-warning " rule object Creation failed"; exit}
#$oEnhancedDetection.ChangeId()
$oEnhancedDetection.Rule = $oRule
}
"RegistryKey"{
$sourceFix = @"
using Microsoft.ConfigurationManagement.DesiredConfigurationManagement;
using System;
namespace RegistrySettingNamespace
{
public class RegistrySettingFix
{
private RegistrySetting _registrysetting;
public RegistrySettingFix(string str)
{
this._registrysetting = new RegistrySetting(null);
}
public RegistrySetting GetRegistrySetting()
{
return this._registrysetting;
}
}
}
"@
#Hack to bypass bug in Microsoft.ConfigurationManagement.DesiredConfigurationManagement.registrySetting which doesn't allow us to create a enhanced detection method.
Add-Type -ReferencedAssemblies $DcmObjectModelPath -TypeDefinition $sourceFix -Language CSharp
$temp = New-Object RegistrySettingNamespace.RegistrySettingFix ""
$oRegistrySetting = $temp.GetRegistrySetting()
$oEnhancedDetection = New-Object Microsoft.ConfigurationManagement.ApplicationManagement.EnhancedDetectionMethod
write-verbose "--> Creating Enhanced Registry Detection Method"
$oDetectionType = [Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ConfigurationItemPartType]::RegistryKey
if ($oRegistrySetting -ne $null) { write-verbose " oRegistrySetting object Created"} else {write-warning " oRegistrySetting object Creation failed";Break}
switch ($RegistryHyve){
"HKEY_CLASSES_ROOT"{
$oRegistrySetting.RootKey = "ClassesRoot"
Break
}
"HKEY_CURRENT_CONFIG"{
$oRegistrySetting.RootKey = "CurrentConfig"
Break
}
"HKEY_CURRENT_USER"{
$oRegistrySetting.RootKey = "CurrentUser"
Break
}
"HKEY_LOCAL_MACHINE"{
$oRegistrySetting.RootKey = "LocalMachine"
Break
}
"HKEY_USERS"{
$oRegistrySetting.RootKey = "Users"
Break
}
}
$oregistrysetting.Key = $RegistryKey
$oRegistrySetting.ValueName = $RegistryKeyValue
if ($Is64bit){$Is64bits= 1}else{$Is64bits = 0}
$oRegistrySetting.Is64Bit = $Is64bits#$Is64bits
$oRegistrySetting.SettingDataType = [Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.DataType]::String#$RegistryKeyValueDataType
#$oRegistrySetting.ChangeLogicalName()
$oEnhancedDetection.Settings.Add($oRegistrySetting)
#$oFileSetting
write-verbose "Settings Reference"
$oSettingRef = New-Object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.SettingReference(
$App1Deserializedstuff.Scope,
$App1Deserializedstuff.Name,
$oApplicApp1Deserializedstuffation.Version,
$oRegistrySetting.LogicalName,
$oRegistrySetting.SettingDataType,
$oRegistrySetting.SourceType,
[bool]0 )
# setting bool 0 as false
if ($oSettingRef -ne $null) { write-verbose " oSettingRef object Created"} else {write-warning " oSettingRef object Creation failed"; break}
#Registry Setting must satisfy the following rule
$oSettingRef.MethodType = [Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ConfigurationItemSettingMethodType]::Value
$oSettingRef.PropertyPath = "RegistryValueExists"
#$oSettingRef
<#
if (!($CheckForConstant)){
$ConstantValue = $true
$ConstantDataType = "boolean"
}
#>
#$ConstantValue = $true
#$ConstantDataType = "boolean"
$oConstValue = New-Object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.ConstantValue($ConstantValue,
[Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.DataType]::$ConstantDataType)
if ($oConstValue -ne $null) { write-verbose " oConstValue object Created"} else {write-warning " oConstValue object Creation failed";break}
$oRegistrySettingOperands = new-object Microsoft.ConfigurationManagement.DesiredConfigurationManagement.CustomCollection``1[[Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.ExpressionBase]]
$oRegistrySettingOperands.Add($oSettingRef)
$oRegistrySettingOperands.Add($oConstValue)
#$Operator = "IsEquals"
write-verbose "Operator is --> $($Operator)"
$RegistryCheckExpression = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.Expression(
[Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ExpressionOperators.ExpressionOperator]::$Operator, $oRegistrySettingOperands)
#$RegistryCheckExpression = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.Expression("isEquals",$oRegistrySettingOperands)
$oRule = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.Rule("IsInstalledRule",
[Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.NoncomplianceSeverity]::$NoncomplianceSeverity, $null, $RegistryCheckExpression)
if ($oRule -ne $null) { write-verbose " rule object Created"} else {write-warning " rule object Creation failed"; break}
#$oEnhancedDetection.ChangeId()
$oEnhancedDetection.Rule = $oRule
Break}
"Folder"{
Break
}
"MSI"{
Break
}
"Assembly"{
Break
}
"Other"{
Break
}
#Expression, Annotation, Severity and an empty
Default {Throw "DetectionType $($DetectionType) not recognized as a valid detection type"}
}
#$oAppinstaller.EnhancedDetectionMethod = $oEnhancedDetection
return $oEnhancedDetection
}
@JonWalz2
Copy link

`#Requires $ProductCode in the Parameter block of the function

    "MSI"{
        $msiSetting = New-Object Microsoft.ConfigurationManagement.DesiredConfigurationManagement.MSISettingInstance($ProductCode, $null)
        $oEnhancedDetection.Settings.Add($msiSetting)
        $msiDataType = [Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.DataType]::Int64
        $msiConstValue = New-Object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.ConstantValue('0', $msiDataType)

        $msiSettingRef = New-Object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.SettingReference(
            $App1Deserializedstuff.Scope,
            $App1Deserializedstuff.Name,
            $App1Deserializedstuff.Version,
            $msiSetting.LogicalName,
            $msiDataType,
            $msiSetting.SourceType,
            [bool]0
        )

        $msiSettingRef.MethodType = [Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ConfigurationItemSettingMethodType]::Count
        $msiOperands = new-object Microsoft.ConfigurationManagement.DesiredConfigurationManagement.CustomCollection``1[[Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.ExpressionBase]]
        $msiOperands.Add($msiSettingRef);
        $msiOperands.Add($msiConstValue);
        $msiExpression = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.Expression(
            [Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ExpressionOperators.ExpressionOperator]::NotEquals, $msiOperands)

        $oRule = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.Rule("IsInstalledRule", 
        [Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.NoncomplianceSeverity]::$NoncomplianceSeverity, $null, $msiExpression)
            if ($oRule  -ne $null) { write-verbose " rule object Created"} else {write-warning " rule object Creation failed"; exit}

        $oEnhancedDetection.Rule = $oRule 

    }

`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment