How to find Settings Preventing Application Deletion in ConfigMgr

Today my co-worker was attempting to delete an old application and got blocked with the following message message and I wanted to document it for future reference.

A Square Dozen Image
Configuration Manager cannot delete this application because other applications or task sequences reference it or it is configured as a deployment.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Configuration Manager cannot delete this application because other applications or task sequences reference it or it is configured as a deployment.

Details:
Number of dependent applications: 0
Number of active deployments: 1
Number of dependent task sequences: 9 
Number of virtual environments:0
Number of settings:1

To view the dependent applications, open the application properties, and then click the References tab.
To view the active deployments, select the application, and then select the Deployments tab in the details pane.
To view the dependent task sequences, select the task sequences in the Operating Systems node, and then select the References tab in the details pane.
To view the virtual environments, open the application properties, and then click the References tab.

Number of Settings = Number of Configuration Items

The first items listed are easy to find and the dialog even provides instructions for finding the blocking references to the application. The last item in the list was the confusing one. Number of settings: 1. There is no information in the dialog to help find out what Settings refers to. To find the answer I opened up smsprov.log from the site server logs to see which query was being run. This is a great technique for finding out where data is coming from within the ConfigMgr console. As you can see in the screenshot, I found the WMI class being queried - SMS_ApplicationLatest.

SMS_ApplicationLatest

A Square Dozen Image

To query this in WMI the query would be:

1
2
3
SELECT * 
FROM SMS_ApplicationLatest 
WHERE ModelName='ScopeId_FC07EA7F-55AD-47CC-90AA-2A3E907188DF/Application_dda94e21-8237-4403-ba24-0f36ce2f9213'

The equivalent query in SQL would use a ConfigMgr SQL function. If you were building a report, you’d want to use the RBAC function fn_rbac_ListLatestApplicationCIs but to keep this simple, we will use the non-RBAC function fn_ListLatestApplicationCIs.

1
2
3
SELECT * 
FROM fn_ListLatestApplicationCIs(1033) 
WHERE modelname = 'ScopeId_FC07EA7F-55AD-47CC-90AA-2A3E907188DF/Application_dda94e21-8237-4403-ba24-0f36ce2f9213'

The result of this query includes the NumberOfSettings column which populates the count for Number of settings: in the error message.

A Square Dozen Image
fn_ListLatestApplicationCIs - NumberOfSettings

Unfortunately, this function only provides the summarized count for this column, we need the underlying table(s) in order to determine the source of this count.

STOP! The following should only be done in your test/lab environment. I do not recommend doing this in production since you could unintentionally break things. I take no responsibility for your actions.

In SSMS, you can right click on the function and open it in the editor to see what queries are being used to generate the output for the function. This was my next step.

A Square Dozen Image

This function is quite complex but searching for NumberOfSettings made it easy to find the source tables in the queries.

A Square Dozen Image

A Square Dozen Image

Within the console there are Configuration Items that go with Configuration Baselines, but within the ConfigMgr backend, Configuration Items can be any object within the database. My next step was to determine what a RelationType of 21 mapped to. I quickly found another view that gave me a full list.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
SELECT * 
FROM v_CIRelationTypes

--Results
RelationType	Description	IsRecursive
1	Bundled	1
2	Required	0
3	Prohibited	0
4	Optional	0
5	Derived	1
6	Superseded	1
7	Self	0
8	Reference	0
9	AppToDTReference	0
10	AppDependence	1
11	Intention	0
12	Platform	0
13	GlobalConditionReference	0
15	ApplicationSuperSeded	1
16	ApplicationType	0
17	ApplicationHost	0
18	ApplicationInstaller	0
19	SupersedOrDependent	1
20	VirtualEnvironmentReference	0
21	AppDCMReference	0
22	DeploymentTypeToPolicyTemplateReference	0
23	CIInheritanceRelation	0

As you can see on line 23, RelationType 21 = AppDCMReference. (Desired Configuration Management) which is part of your Compliance Settings in the for ConfigMgr. You may also notice that RelationType 9 was also used in the query. This was the relationship mapping the Application to the Application Deployment Type. Then the Application Deployment Type was mapped to the Configuration Item.

Building a Query to map Applications to DCM Configuration Items

From there I was able to build a simple query to use to pinpoint the Configuration Item that is preventing the application from being deleted.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
DECLARE @LocaleID int, @ApplicationName nvarchar(500)

SELECT 
	@LocaleID = 1033,
	@ApplicationName = 'MDOP MBAM 2.5 SP1'

SELECT
	lci.DisplayName  AS ApplicationName,
	lci.ci_id as ApplicationCIID,
	loc.DisplayName as CIName
FROM 
	fn_ListLatestApplicationCIs(1033) lci INNER JOIN
	vSMS_CombinedConfigurationItemRelations appToDTRel ON lci.CI_ID = appToDTRel.FromCI_ID
	inner join vSMS_CombinedConfigurationItemRelations cidt on appToDTRel.ToCI_ID=cidt.FromCI_ID and appToDTRel.RelationType=9
	inner join vSMS_CombinedConfigurationItemRelations settingsToDTRel on settingsToDTRel.ToCI_ID = cidt.FromCI_ID 
	inner join v_ConfigurationItems settingsCI on settingsToDTRel.FromCI_ID=settingsCI.CI_ID and settingsToDTRel.RelationType=21 and settingsCI.IsTombstoned=0   
	inner join fn_LocalizedCIProperties(@LocaleID) as loc ON loc.CI_ID = settingsCI.CI_ID
WHERE
	lci.DisplayName = @ApplicationName

In this case, we had to look at the revision history for a CI for another application and delete an older version of the CI where the old application was being referenced. We had created a CI that we used as a template for several others and each time we changed from the template app to the new app, the template app was left in the revision history, making it less than obvious where it was hiding.

Extending the Console

If you want to take it to the next level and add a custom pane to your ConfigMgr console, you can use this WMI query as the starting point then use this great post by Ioan Popovici to build the custom extension https://sccm-zone.com/extend-the-sccm-console-to-show-collection-membership-using-console-builder-c6db52b408d8. More info on the WMI Class SMS_CIRelation_Flat can be found here https://docs.microsoft.com/mem/configmgr/develop/reference/compliance/sms_cirelation_flat-server-wmi-class

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
SELECT DISTINCT settingsCI.*
FROM 
	SMS_ApplicationLatest INNER JOIN
	sms_CIRelation_flat AS appToDTRel ON SMS_ApplicationLatest.CI_ID = appToDTRel.FromCIID INNER JOIN
	sms_CIRelation_flat AS cidt ON appToDTRel.ToCIID = cidt.FromCIID INNER JOIN
	sms_CIRelation_flat AS settingsToDTRel ON settingsToDTRel.ToCIID = cidt.FromCIID INNER JOIN
	SMS_ConfigurationItem AS settingsCI ON settingsToDTRel.FromCIID=settingsCI.CI_ID
WHERE 
	SMS_ApplicationLatest.ModelName='ScopeId_FC07EA7F-55AD-47CC-90AA-2A3E907188DF/Application_dda94e21-8237-4403-ba24-0f36ce2f9213'
	and appToDTRel.RelationType = 9
	and settingsToDTRel.RelationType=21

Summary

Sometimes things within ConfigMgr can be a mystery but with a little bit of digging you can solve the puzzle. If you ever see the message above when deleting an application, just remember that Settings refers to Configuration Items. I hope you found this helpful - if nothing else, I’ve got this documented for the next time I need to deal with it.