简体   繁体   中英

PS1 uninstallation script in SCCM

I'm a nub scripter and am trying to write a really simple script to taskkill 2 programs and then uninstall 1 of them.

I wrote it in Powershell and stuck it in SCCM for deployment...however every time I deploy it, it's not running the last line to uninstall the program.

Here's the code:

 # Closing Outlook instance # taskkill /IM outlook.exe /F # # Closing Linkpoint instance # taskkill /IM LinkPointAssist.exe /F # # Uninstalling Linkpoint via uninstall string if in Program Files # MsiExec.exe /X {DECDCD14-DEF6-49ED-9440-CC5E562FDC41} /qn # # Uninstalling Linkpoint via WmiObject if installed manually in AppData Get-WmiObject -class win32_product -Filter "Name like '%Linkpoint%'" | ForEach-Object { $_.Uninstall()} # Exit 

Can someone help? SCCM says the script completes with no error and I know it's able to execute it since the taskkills work...but it's not uninstalling the program.

Thanks in advance for any input.

I see a lot of these kinds of questions come through on SO and SF: Someone struggling with unexpected behavior of an application, script, or ConfigMgr and very little information about the assumptions I can make about their environment. At that stage, it would typically be days of interaction to narrow the problem to a point where a solution is possible.

I'm hoping this answer can serve as a reference for future such questions. The first question to OP should be "Which of these 9 principles are you violating?" You could think of it as a sort of Joel Test for ConfigMgr application packaging.


Nine Steps to Better ConfigMgr Application Packages

I have found that installing and uninstalling applications reliably using ConfigMgr requires carefully sticking to a bunch of principles. I learned these principles the hard way. If you're struggling to figure out why an application is not working right under ConfigMgr, odds are that you will answer "no" to one of the following questions.

1. Are you testing the entire lifecycle?

In order to have any hope of reliably managing an application you need to test the entire lifecycle of an application. This is the sequence I test:

  • Detect: make sure the detection script result is negative
  • Install: install the application using your installation script
  • Detect: make sure the detection script result is positive when run
  • Uninstall: uninstall using your uninstallation script

I run this sequence repeatedly making tweaks to each step until the whole sequence is working.

2. Are you testing independently of ConfigMgr first?

Using ConfigMgr to test your application's lifecycle is slow and has its own ways of failing that can mask problems with your application package. The goal, then, is to be able to test an application's installation, detection, and uninstallation separate from but equivalent to the ConfigMgr client. In order to achieve that goal you end up with three separate scripts for each application:

  • Install-Application.bat - the entry point for your installation script
  • Detect-Application.ps1 - the script that detects whether the application is install
  • Uninstall-Application.bat - the entry point for your uninstallation script

Each of these three scripts can be invoked directly by either you or the ConfigMgr client. For applications installed as system you need to use psexec -s to invoke scripts in the same context as ConfigMgr ( caveat ).

3. Are you aware of context?

Installers can behave rather differently depending on the context they are invoked in. You need to consider whether an application is installed for a user or the system. If it is installed for the system, when you test independently of ConfigMgr, use psexec -s to invoke your script.

4. Are you aware of user interaction?

An installer can also behave rather differently depending on whether a user can interact with it . To test a script as system with user interaction, use psexec -i -s .

5. Did you match ConfigMgr to the tested context and user interaction?

Once you have the full lifecycle working, make sure you select the correct corresponding options for context (installed for user vs. system) and interaction (user can interact with application, or not). If you don't do this, the ConfigMgr client will be installing the application different from the way you tested, so you really can't expect success.

6. Are you aware of the possibility of application detection context mismatch?

The context that detection scripts run in depends on whether the application is deployed to users or systems. This means that in some cases the installation and detection contexts won't matched . Keep this in mind when you write your detection scripts.

7. Have you structured your scripts so that exit codes work?

ConfigMgr needs to see exit codes from your installation and uninstallation scripts in order to do the right thing. Installers signal failure or the need to reboot using exit codes. In order for exit codes to get to the ConfigMgr client you need to ensure that your install and uninstall scripts are structured correctly.

8. Are you using PowerShell scripts for detection?

ConfigMgr has a nice user interface for checking things like the presence of files, registry keys, etc as a proxy for whether an application is installed. The problem with that scheme is that there is no way to test application detection separately from and equivalent to the ConfigMgr client. If you want to test the application lifecycle independent of the ConfigMgr client (trust me, you want that), all your detection must occur using PowerShell scripts.

9. Have you structured your PowerShell detection scripts correctly?

The rules ConfigMgr uses to interpret the output of a PowerShell detection script are arcane. Thankfully, they are documented .

So, SCCM is running this script, and nothing in the script is going to throw an error.

If you want to throw an error which SCCM can return to know how the deployment went, you need to add an extra step.

 $result = Get-WmiObject -class win32_product -Filter "Name like '%Linkpoint%'" | ForEach-Object { $_.Uninstall()} if ($result.ReturnValue -ne 0){ [System.Environment]::Exit(1603) }else { [System.Environment]::Exit(0) } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM