Over the years I've posted a number of atricles related to using PowerShell with SCCM. The most read of these was about creating SCCM Applications with Enhanced Detection methods - specifically for File Based Detection. A number of people have asked for an example of the same script using Registry based detection for installed applications.
Not to go over old ground - the earlier blogs that may be of interest are found here:
Creating SCCM Applications with Powershell,
Constructing SCCM Rules with Powershell,
Scripting SCCM Application Dependencies,
Creating SCCM Global Conditions
The script below uses the presence of a registry key to indicate that an application is installed.
#####################################################
# Add Required Type Libraries
Add-Type -Path "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.dll"
Add-Type -Path "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.MsiInstaller.dll"
Add-Type -Path "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ManagementProvider.dll"
Add-Type -Path "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.Extender.dll"
#used for creating rules
Add-Type -Path "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\DcmObjectModel.dll"
#WQL Connection to Server
Add-Type -Path "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\AdminUI.WqlQueryEngine.dll"
#Application Wrapper and Factory
Add-Type -Path "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\AdminUI.AppManFoundation.dll"
#####################################################
# Core Application Details
[string]$sPackageDirectory ="\\sccmserver\d$\Applications\7Zip_09.20_64a"
[string]$sApplicationName = "7Zip_09.20_64a"
[string]$sApplicationDestription = "Example Application"
[string]$sApplicationVersion = "02.00"
[string]$sApplicationPublisher = "Vendor A"
[string]$ApplicationOwner = ""
[string]$sSCCMServerName = "mySCCMServer"
[string]$sSCCMUsername = "myusername"
[string]$sSCCMPassword = "mypassword"
#####################################################
# Functions
# WQLConnect
# Purpose: To create a WQL query connection to an SCCM Server
# This will utilise credentials if script isn't being run on the server itself
#
function WQLConnect($Server, $User, $Password) {
$namedValues = New-Object Microsoft.ConfigurationManagement.ManagementProvider.SmsNamedValuesDictionary
if ($namedValues -ne $null) { write-host " namedValues object Created"} else {write-host " namedValues object Creation failed"; exit}
$connection = New-Object Microsoft.ConfigurationManagement.ManagementProvider.WqlQueryEngine.WqlConnectionManager
if ($connection -ne $null) { write-host " connection object Created"} else {write-host " connection object Creation failed"; exit}
# Connect with credentials if not running on the server itself
if ($env:computername.ToUpper() -eq $Server.ToUpper()){
write-host "Local WQL Connection Made"
[void]$connection.Connect($Server)
}
else
{
write-host "Remote WQL Connection Made: " + $sSCCMServerName
[void]$connection.Connect($Server, $User, $Password)
}
return $connection
}
# Store
# Purpose: To commit the completed application to SCCM
#
function store ($Application){
# Set the application into the provider object.
$oAppManWrapper.InnerAppManObject = $Application
# "Initializing the SMS_Application object with the model."
$oApplicationFactory.PrepareResultObject($oAppManWrapper);
# Save to the database.
$oAppManWrapper.InnerResultObject.Put();
}
#####################################################
# Main
#create connection to SCCMServer (not used until the end of the script)
$oServerConnection = WQLConnect $sSCCMServerName $sSCCMUsername $sSCCMPassword
$oApplicationFactory = New-Object Microsoft.ConfigurationManagement.AdminConsole.AppManFoundation.ApplicationFactory
$oAppManWrapper = [Microsoft.ConfigurationManagement.AdminConsole.AppManFoundation.AppManWrapper]::Create( $oServerConnection , $oApplicationFactory)
write-output "Creating Application Object"
$oApplication = New-Object Microsoft.ConfigurationManagement.ApplicationManagement.Application
if ($oApplication -ne $null) { write-output " oApplication object Created"} else {write-output " oApplication object Creation failed"; exit}
$oApplication.Title = $sApplicationName
$oApplication.SoftwareVersion = $sApplicationVersion
$oApplication.Publisher = $sApplicationPublisher
$oApplication.DisplayInfo.DefaultLanguage = "en-US"
write-output "Creating Application Display Info"
$oApplicationDisplayInfo = New-Object Microsoft.ConfigurationManagement.ApplicationManagement.AppDisplayInfo
if ($oApplicationDisplayInfo -ne $null) { write-output " oApplicationDisplayInfo object Created"} else {write-output " oApplicationDisplayInfoo object Creation failed"; exit}
$oApplicationDisplayInfo.Title = $sApplicationName
$oApplicationDisplayInfo.Description = $sApplicationDestription
$oApplicationDisplayInfo.Language = "en-US"
$oApplication.DisplayInfo.DefaultLanguage = "en-US"
$oApplication.DisplayInfo.Add($oApplicationDisplayInfo)
$oAppinstaller = New-Object Microsoft.ConfigurationManagement.ApplicationManagement.ScriptInstaller
if ($oAppinstaller -ne $null) { write-output " oAppinstaller object Created"} else {write-output " oAppinstaller object Creation failed"; exit}
#Note that this example hardcodes install and remove syntax by using
#a launcher for all applications
$oAppinstaller.InstallCommandLine = '"Launcher.exe"'
$oAppinstaller.UninstallCommandLine = '"Launcher.exe" /Remove'
#####################################################
# Upload File Content to Server
write-output "Upload Content"
$oContent = [Microsoft.ConfigurationManagement.ApplicationManagement.ContentImporter]::CreateContentFromFolder($sPackageDirectory)
$oContent.OnSlowNetwork = "Download"
$oAppinstaller.Contents.Add($oContent)
#####################################################
# Main Creating Enhanced File Detection Method (file based)
# This uses a standard Package signature file under c:\windows\logs
# to determine if the package is installed
#write-output "Enabling Enhanced File Detection"
$oAppinstaller.DetectionMethod = [Microsoft.ConfigurationManagement.ApplicationManagement.DetectionMethod]::Enhanced
$oEnhancedDetection = New-Object Microsoft.ConfigurationManagement.ApplicationManagement.EnhancedDetectionMethod
if ($oEnhancedDetection -ne $null) { write-output " oEnhancedDetection object Created"} else {write-output " oEnhancedDetection object Creation failed"; exit}
$oDetectionType = [Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ConfigurationItemPartType]::RegistryKey
#$oFileSetting = New-Object Microsoft.ConfigurationManagement.DesiredConfigurationManagement.FileOrFolder( $oDetectionType , $null)
# if ($oFileSetting -ne $null) { write-output " oFileSetting object Created"} else {write-output " oFileSetting object Creation failed"; exit}
#$oFileSetting.FileOrFolderName = $sApplicationName + ".sig"
#$oFileSetting.Path = "%Windir%\Logs"
#$oFileSetting.Is64Bit = 1
#$oFileSetting.SettingDataType = [Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.DataType]::Int64
#$oEnhancedDetection.Settings.Add($oFileSetting)
# Registry Setting
$oRegSetting = new-object Microsoft.ConfigurationManagement.DesiredConfigurationManagement.RegistrySetting(@($null))
$oRegSetting.Name
$oRegSetting.RootKey = "LocalMachine"
$oRegSetting.Key = "Software\7-Zip"
$oRegSetting.Is64Bit = $true
$oRegSetting.ValueName = "path"
$oRegSetting.CreateMissingPath = $false
$oRegSetting.SettingDataType = [Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.DataType]::String #Int64/String/?
$oEnhancedDetection = New-Object Microsoft.ConfigurationManagement.ApplicationManagement.EnhancedDetectionMethod
$oEnhancedDetection.Settings.Add($oRegSetting)
write-output "Settings Reference"
$oSettingRef = New-Object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.SettingReference(
$oApplication.Scope,
$oApplication.Name,
$oApplication.Version,
$oRegSetting.LogicalName,
$oRegSetting.SettingDataType,
$oRegSetting.SourceType,
[bool]0 )
# setting bool 0 as false
if ($oSettingRef -ne $null) { write-output " oSettingRef object Created"} else {write-output " oSettingRef object Creation failed"; exit}
$oSettingRef.MethodType = [Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ConfigurationItemSettingMethodType]::Value
$oConstValue = New-Object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.ConstantValue("MY VALUE",$oRegSetting.SettingDataType)
if ($oConstValue -ne $null) { write-output " oConstValue object Created"} else {write-output " oConstValue object Creation failed"; exit}
$oCheckOperands = new-object Microsoft.ConfigurationManagement.DesiredConfigurationManagement.CustomCollection``1[[Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.ExpressionBase]]
$oCheckOperands.Add($oSettingRef)
$oCheckOperands.Add($oConstValue)
$oExpression = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.Expression(
[Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ExpressionOperators.ExpressionOperator]::IsEquals, $oCheckOperands)
$oRule = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.Rule("IsInstalledRule",
[Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.NoncomplianceSeverity]::None, $null,$oExpression)
if ($oRule -ne $null) { write-output " rule object Created"} else {write-output " rule object Creation failed"; exit}
$oEnhancedDetection.Rule = $oRule
$oAppinstaller.EnhancedDetectionMethod = $oEnhancedDetection
#####################################################
# Add Deployment Type to Application
write-output "Adding Deployment Type"
$oApplicationDeploymentType = new-object Microsoft.ConfigurationManagement.ApplicationManagement.DeploymentType($oAppinstaller,
[Microsoft.ConfigurationManagement.ApplicationManagement.ScriptInstaller]::TechnologyId,
[Microsoft.ConfigurationManagement.ApplicationManagement.NativeHostingTechnology]::TechnologyId)
if ($oApplicationDeploymentType -ne $null) { write-output " NewApplicationDeploymentType object Created"} else {write-output " NewApplicationDeploymentType object Creation failed"; exit}
$oApplicationDeploymentType.Title = $oApplication.Title
#####################################################
write-output "Limiting Collections to 64bit workstations"
$oOperands = new-object "Microsoft.ConfigurationManagement.DesiredConfigurationManagement.CustomCollection``1[[Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.RuleExpression]]"
####if ($oOperands -ne $null) { write-output " oOperands object Created"} else {write-output " oOperands object Creation failed"; exit}
# Its possible to limit the deployment of application to specific operating systems
# A current list of possible values may be found t:
# http://www.laurierhodes.info/?q=node/60
$oOperands.Add("Windows/All_x64_Windows_XP_Professional")
$oOperands.Add("Windows/All_x64_Windows_7_Client")
$oOperands.Add("Windows/All_x64_Windows_8_Client")
$oOperands.Add("Windows/All_x64_Windows_8.1_Client")
$oOSExpression = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Expressions.OperatingSystemExpression -ArgumentList ([Microsoft.ConfigurationManagement.DesiredConfigurationManagement.ExpressionOperators.ExpressionOperator]::OneOf), $oOperands
$oAnnotation = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.Annotation
$oAnnotation.DisplayName = new-object Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.LocalizableString -ArgumentList "DisplayName", "Operating system One of {All x86 Windows XP (64bit)}", $null
$oDTRule = new-object "Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.Rule" -ArgumentList `
("Rule_" + [Guid]::NewGuid().ToString()),
([Microsoft.SystemsManagementServer.DesiredConfigurationManagement.Rules.NoncomplianceSeverity]::None),
$oAnnotation,
$oOSExpression
write-output "Adding Deployment Type rule to Application"
$oApplicationDeploymentType.Requirements.Add($oDTRule)
############################################
# Finish
# Add Deployment Type to Application
$oApplication.DeploymentTypes.Add($oApplicationDeploymentType)
# Verify the Application structure
write-output "Verifying Application Object"
$oApplication.Validate
#Add Application to SCCM
write-output "Loading SCCM Application"
Store $oApplication
- Log in to post comments