Is there a way to reinstall an application in SCCM 2012?

kampi picture kampi · Mar 9, 2015 · Viewed 23k times · Source

In SCCM 2007, there were several "Right Click Tools", and with their help it was possible to "reinstall" a package. In SCCM 2012 I still couldn't find a way, how could I reinstall an application?

Let me explain:
I created an installation package from a software, then distributed it as an "Application". Installation finished successfully. One week later a user calls, he is having trouble with this application. The package I created supports the reinstallation(either by removing the software and installing it again, or with a repair functionality). But, in SCCM I have no option(neither found a right click tool which could do that), to reinstall the package. I have to remove it, and then install it again.

I thought I could write a program to that, and create my own "Right Click Tool", but I can't find any information what exactly should I do?

So my questions are:
- Is there a Right Click Tool which can reinstall an application somehow?
- Is there some documentation, where I could get some information about this issue?

I am sure, many others have the same problem. Or I didn't find a way, because there is none? :(

Thanks in advance!

Answer

Syberdoor picture Syberdoor · Mar 12, 2015

In our company we would also have to liked this and did some basic research but as it seems no one has done it so far (doesn't mean it's impossible). We also talked to two Microsoft SCCM consultants about it and both said there is currently no way.

The thing is applications are all about the detection method. It is the only thing that will trigger the setup. So if you have a software, and you don't want to deploy it as package (this is still possible and they can still be rerun with tools like Roger Zanders client center), what you can do is use a detection method that you can influence. Like a file or reg key, which you can remove remotely. The application deployment evaluation cycle can be triggered remotely just like all other client actions so this would not be a problem.

Sadly this is only a workaround and I would very much like if someone proves me wrong but so far this is the best we could come up with.

Edit: So you motivated me to dig a little deeper and I also got some really good slides from Microsoft and I found some possible approach:

As the application is all about detection all the time my idea is to fake it.

As far as I can tell detection methods are saved in some crazy xml format in the WMI in root\ccm\CIModels in the Class Local_Detect_Synclet. So I wrote a script that goes there and replaces the detection method with an empty detection method that checks for a file. It has no properties so it can never work. After that I call the enforce method on my application using the class CCM_AppDeliveryType in the same namespace. It takes an AppdeliveryTypeID and the current revision but both of those can be seen in CCM_AppDeliveryTypeSynclet. After the enforce reinstalled the program I reset the detection method to the old one and trigger a second enforce which will do nothing but tell the system the app is properly detected. The Vbscript that does all this looks like this:

computername = "WS0000xxxx"

Set wmiCIModels = GetObject("winmgmts:\\" & computername & "\root\ccm\CIModels")
Set wmiAppDeliveryType = GetObject("winmgmts:\\" & computername & "\root\ccm\CIModels:CCM_AppDeliveryType")


deploymentTypeID = "ScopeId_79903130-730F-48B7-8165-6088B83359BE/DeploymentType_68a80836-208e-401b-a69f-ae4c184b9f85"

Set installedDelTypes = wmiCIModels.ExecQuery("select * from Local_Detect_Synclet where AppDeliveryTypeId = '" & deploymentTypeID & "'" )

For Each instDelType In installedDelTypes
    strOldDetectionMethod = instDelType.ExpressionXml
    instDelType.ExpressionXml = "<LocalDetectionMethod><Settings><File></File></Settings><Rule xmlns=""http://schemas.microsoft.com/SystemsCenterConfigurationManager/2009/06/14/Rules""><Expression><Operator>Equals</Operator><Operands><SettingReference AuthoringScopeId="""" DataType=""Version"" SettingLogicalName=""X"" Method=""Value""/><ConstantValue DataType=""Version""/></Operands></Expression></Rule></LocalDetectionMethod>"
    instDelType.Put_ 0

    wmiAppDeliveryType.EnforceApp deploymentTypeID, "4", "", "Install", "", "1"

    instDelType.ExpressionXml = strOldDetectionMethod
    instDelType.Put_ 0

    wmiAppDeliveryType.EnforceApp deploymentTypeID, "4", "", "Install", "", "1" 
Next

The ExpressionXML is horribly long but I deleted everything from it by trial and error that seems possible.

For simplicity I hardcoded the AppdeliveryTypeID and revision but you can get a list of those, including nice names, with the following query:

Set wmiCIModels = GetObject("winmgmts:\\" & computername & "\root\ccm\CIModels")

Set delTypes = wmiCIModels.ExecQuery("select * from CCM_AppDeliveryTypeSynclet" )

For Each delType In delTypes
    WScript.Echo "Deployment Name: " & delType.AppDeliveryTypeName & VbCrLf & "AppdeliveryTypeID: " & delType.AppDeliveryTypeId & VbCrLf & "Revision: " & delType.Revision & VbCrLf
Next

This also presents on of the biggest downsides I found so far. It is only possible to easily get the names of the AppDeliveries. These are not the names the application will show in the Software Center for example. I looked into translating this but the only method I found so far is to query the SCCM DB itself and the query is horribly complicated and needs of course some SCCM admin to execute it.

As with all WMI scripts you can execute it remotely by specifying a computer name or locally if you use '.', so you could use the SCCM Console Extension system and build your own right-click tool based on this.

This will work even on Applications that are not installed similar to the rerun of packages. If you do not want this you can check against CCM_AppDeliveryType to only see the installed applications.