Removing Power Manager
Power Manager comes with a shell script that completely removes both installed and runtime created files.
The script is fairly complex as it deals with all combinations of the Power Manager packages and executables.
The removal script is presented in full below. If you just want to remove Power Manager, stop reading and run the Remove Power Manager… command in the System Preference.
For those wanting to learn more about the specifics of removing Power Manager we will walk through the script in detail.
The script is located deep within the System Preference. It is a shell script and requires root privileges.
| Line | |
|---|---|
| 1 | /Library/PreferencePanes/Power Manager.prefPane/Contents/MacOS/Remove Power Manager.app/Contents/Resources/Remove Power Manager.sh |
Set Up and Presentation
The script sets out the copyright details, then presents feedback to the user informing them of the implications of continuing.
Finally we change to a known directory.
| Line | Remove Power Manager.sh |
|---|---|
| 1 | #!/bin/sh |
| 2 | # Part of DssW Power Manager |
| 3 | # Copyright (c) 2007 Dragon Systems Software Limited |
| 4 | # Support: support@dssw.co.uk |
| 5 | # |
| 6 | # This script completely removes Power Manager from the host Mac. |
| 7 | # A restart is required on completion to tidy up after removing pmauth |
| 8 | # and rights. |
| 9 | |
| 10 | if [[ $EUID -ne 0 ]]; then |
| 11 | echo "You must be a root to run this script" 2>&1 |
| 12 | exit 1 |
| 13 | fi |
| 14 | |
| 15 | echo "Removing DssW Power Manager 3..." |
| 16 | echo "" |
| 17 | |
| 18 | cd / |
| 19 | ## |
Stop the Daemon
The daemon responsible for Power Manager is stopped in two stages.
- The daemon's scheduler is disabled;
- The daemon itself is removed.
Depending on the managing process either launchd needs to have the Power Manager job removed, or the SystemStarter directory needs to be deleted.
| Line | Remove Power Manager.sh |
|---|---|
| 20 | # Disable and stop Power Manager |
| 21 | if [ -e '/usr/local/powermanager/bin/powermanagerctl' ]; then |
| 22 | echo "...turning off Power Manager's schedule" |
| 23 | /usr/local/powermanager/bin/powermanagerctl scheduler.setenabled no |
| 24 | fi |
| 25 | |
| 26 | echo "...stopping Power Manager" |
| 27 | if [ -e "/Library/LaunchDaemons/uk.co.dssw.powermanager.plist" ]; then |
| 28 | # Power Manager 3.5+; launchd managed |
| 29 | # Ask launchctl to stop the daemon |
| 30 | /bin/launchctl unload "/Library/LaunchDaemons/uk.co.dssw.powermanager.plist" |
| 31 | fi |
| 32 | |
| 33 | if [ -e "/Library/StartupItems/PowerManager" ]; then |
| 34 | # Power Manager 3.0 - 3.2.1, and 3.5+ under Mac OS X 10.3.9 |
| 35 | # Send a stop command to the daemon via the StartupItem package |
| 36 | /Library/StartupItems/PowerManager/PowerManager stop |
| 37 | sleep 2 |
| 38 | fi |
| 39 | ## |
Revoking the Security Policy
Various elements within Power Manager use the security policy database to delegate authentication and authorization to Mac OS X. On removal we remove Power Manager's presence from the security policy database.
Each Power Manager tool knows about the security rights it installs; each tool is also responsible for removing its rights.
Mac OS X 10.3.9 asks for an administrator password for each right removed. This behaviour is unfriendly and has caused users to give up part way through the installation process. To avoid this burden, we skip the this step if the Mac is running Mac OS X 10.3.9. This leaves unneeded policies in the database but it is a safe decision.
We recommend removing all uk.co.dssw.powermanager. rights by hand on Mac OS X 10.3.9 to avoid this password burden.
| Line | Remove Power Manager.sh |
|---|---|
| 41 | # Programmatically remove the global login item |
| 42 | if [ -e '/usr/local/powermanager/bin/pmassistant.app/Contents/MacOS/pmassistant' ]; then |
| 43 | echo "...removing assistants" |
| 44 | /usr/local/powermanager/bin/pmassistant.app/Contents/MacOS/pmassistant -r |
| 45 | fi |
| 46 | |
| 47 | # Remove security policy rights |
| 48 | if [ -e '/usr/local/powermanager/bin/powermanagerd' ]; then |
| 49 | # Skip this step on Mac OS X 10.3.9 |
| 50 | OSVERSION=`sw_vers -productVersion` |
| 51 | if [ "$OSVERSION" != "10.3.9" ]; then |
| 52 | echo "...revoking security policy rights" |
| 53 | /usr/local/powermanager/bin/powermanagerd -u |
| 54 | fi |
| 55 | fi |
| 56 | ## |
Remove the Login Window Plugin
The login window security plugin needs to remove its security mechanism before uninstalling. The security removal is performed by a command line tool included within the plugin.
| Line | Remove Power Manager.sh |
|---|---|
| 58 | # Remove the authentication plug-in |
| 59 | if [ -e "/System/Library/CoreServices/SecurityAgentPlugins/pmauth.bundle" ]; then |
| 60 | echo "...disable login window notification" |
| 61 | "/System/Library/CoreServices/SecurityAgentPlugins/pmauth.bundle/Contents/MacOS/pmauthctl" -u |
| 62 | fi |
| 63 | ## |
If the removal fails or is interrupted, the Mac may be left unable to return to the Login Window. This is because the Login Window plug-in pmauth uses the Power Manager framework. If the framework does not exist - or has been removed - the plug-in will not load and will crash the Login Window.
To ensure this does not occur, the following two commands remove specific pmauth lines from the /etc/authorization file.
This in-place perl command provides a 'belt and braces' approach to the problem.
| Line | Remove Power Manager.sh |
|---|---|
| 65 | # Ensure authorization contains no mention of pmauth |
| 66 | sed -E -e '/^[[:space:]]+<string>pmauth:test<\/string>$/d' /etc/authorization > /tmp/authorization.dssw |
| 67 | install -b -B .pm -m 0644 -o root -g wheel -S /tmp/authorization.dssw /etc/authorization |
| 68 | rm /tmp/authorization.dssw |
| 69 | ## |
Remove Supporting Files and Folders
With the daemon stopped and the security rights revoked, the remaining Power Manager files can be removed.
| Line | Remove Power Manager.sh |
|---|---|
| 71 | # Remove our files |
| 72 | REMOVE_FILES=( |
| 73 | '/Library/Application Support/Power Manager' # Preference pane's support files |
| 74 | '/Library/Automator/PMCancelEvents.action' |
| 75 | '/Library/Automator/PMDelayEvents.action' |
| 76 | '/Library/Automator/PMDeleteEvents.action' |
| 77 | '/Library/Automator/PMEvent.definition' |
| 78 | '/Library/Automator/PMEventsToStrings.caction' |
| 79 | '/Library/Automator/PMExportEvents.action' |
| 80 | '/Library/Automator/PMFilterEvents.action' |
| 81 | '/Library/Automator/PMImportEvents.action' |
| 82 | '/Library/Automator/PMListEvents.action' |
| 83 | '/Library/Automator/PMNewEvent.action' |
| 84 | '/Library/Automator/PMNextEvent.action' |
| 85 | '/Library/Automator/PMQuickSchedule.action' |
| 86 | '/Library/Automator/PMToggleScheduler.action' |
| 87 | '/Library/Documentation/Help/Power Manager Help' # Help Book symlink |
| 88 | '/Library/Frameworks/PowerManager.framework' # Shared framework needed to talk to the daemon |
| 89 | '/Library/LaunchDaemons/uk.co.dssw.powermanager.plist' # Launchd job ticket (Mac OS X 10.4+) |
| 90 | '/Library/PreferencePanes/Power Manager.prefPane' # Preference pane |
| 91 | '/Library/StartupItems/PowerManager' # StartupItem (Mac OS X 10.3.9) |
| 92 | '/Library/Widgets/Power Manager.wdgt' # Dashboard widget (Mac OS X 10.4+) |
| 93 | '/System/Library/CoreServices/SecurityAgentPlugins/pmauth.bundle' # loginwindow plugin |
| 94 | '/usr/local/powermanager' # Unix daemon and command line tool |
| 95 | '/var/tmp/uk.co.dssw.powermanager' # Unix socket directory |
| 96 | ); |
| 97 | for (( i = 0 ; i < ${#REMOVE_FILES[@]} ; i++ )) |
| 98 | do |
| 99 | FILEPATH=${REMOVE_FILES[$i]} |
| 100 | if [ -e "$FILEPATH" ]; then |
| 101 | echo "...removing file: ${FILEPATH}" |
| 102 | rm -r "${FILEPATH}" |
| 103 | fi |
| 104 | done |
| 105 | ## |
In Power Manager 3.6.1 we forgot to remove a single Automator action. This mistake caused Automator to crash. In order to prevent this mistake ever happening again, we added an additional check to the removal script with regard to Automator actions.
The additional check looks for any Automator actions that mention DssW in their Info.plist files. If we are mentioned, those actions are removed. The command to do this is fairly complex.
| Line | Remove Power Manager.sh |
|---|---|
| 107 | # Remove Automator actions with our signature (belt and braces) |
| 108 | echo "...removing Automator actions" |
| 109 | find '/Library/Automator' -path '/Library/Automator/PM*/Contents/Info.plist' -type f -print0 | xargs -0 grep -l 'uk.co.dssw.powermanager.' | sed 's/\/Contents\/Info.plist//g' | xargs -n 1 rm -r |
| 110 | ## |
The first part finds all the Automator actions matching our file naming convention. The list of files returned points to each action's Info.plist.
| Line | |
|---|---|
| 1 | find '/Library/Automator' -path '/Library/Automator/PM*/Contents/Info.plist' -type f -print0 |
The next part reduces the returned list to files containing uk.co.dssw.powermanager..
| Line | |
|---|---|
| 1 | xargs -0 grep -l 'uk.co.dssw.powermanager.' |
We now have a list of Info.plist files that need to be removed. In fact, we need to move up two directories; this will leave us with a list of Automator actions, and not a list of Info.plist files within those actions.
The next part uses sed to strip the /Contents/Info.plist suffix from the path.
| Line | |
|---|---|
| 1 | sed 's/\/Contents\/Info.plist//g' |
Finally, we have a list of Automator actions that match our file naming convention, and mention our unique company identifier in their Info.plist file.
The final part of the command uses xargs to translate the list into a series of recursive removal commands.
| Line | |
|---|---|
| 1 | xargs -n 1 sudo rm -r |
Clean Up Processes
Next issue killall commands for each of the processes Power Manager uses. By calling killall with sudo permissions all instances of each process will be killed.
| Line | Remove Power Manager.sh |
|---|---|
| 112 | # Kill still running processes |
| 113 | echo "...stopping user assistants" |
| 114 | KILL_PROCESSES=( |
| 115 | 'powermanagerd' # Unix daemon |
| 116 | 'Power Manager Menu' # Users' menu status bar |
| 117 | 'pmassistant' # User space assistant |
| 118 | 'Power Manager Scripting' # AppleScript support application |
| 119 | 'System Preferences' # Preference pane host application |
| 120 | ); |
| 121 | for (( i = 0 ; i < ${#KILL_PROCESSES[@]} ; i++ )) |
| 122 | do |
| 123 | PROCESS=${KILL_PROCESSES[$i]} |
| 124 | echo " ${PROCESS}" |
| 125 | killall "${PROCESS}" 2>&1 |
| 126 | |
| 127 | # Kill any outstanding process with brute force (needed for powermanagerd) |
| 128 | ps -e -o pid,command | grep "${PROCESS}" | awk '{print$1}' | xargs -n 1 kill -9 |
| 129 | done |
| 130 | ## |
Remove Runtime Created Files
To clean up fully the script must also remove files created at runtime.
The script removes all the installer receipts and shared preferences.
Preferences of individual users are not removed by this script. This was deemed too complex to perform correctly for every situation.
No essential information is stored within individual user's Power Manager related preferences.
It is always safe to remove user's individual preferences beginning with uk.co.dssw.powermanager.
| Line | Remove Power Manager.sh |
|---|---|
| 132 | # Remove the run time created files |
| 133 | echo "...removing preferences and installer receipts" |
| 134 | find '/Library/Receipts' -name 'Power Manager *.pkg' -type d -print0 | xargs -0 rm -r |
| 135 | find '/Library/Preferences' -name 'uk.co.dssw.powermanager.*' -type f -delete |
| 136 | find '/var/root/Library/Preferences' -name 'uk.co.dssw.powermanager.*' -type f -delete |
| 137 | ## |
Finally Restart
After altering the security rights the Mac must be restarted. So we nicely ask the user to perform a restart and exit.
| Line | Remove Power Manager.sh |
|---|---|
| 139 | # Say goodbye |
| 140 | echo "" |
| 141 | echo "...Finished." |
| 142 | echo "" |
| 143 | |
| 144 | |
| 145 | # Ask the user to restart to ensure running processes come down fully |
| 146 | echo "" |
| 147 | echo "Thank you. DssW Power Manager has been removed." |
| 148 | echo "" |
| 149 | echo "Please now restart." |
| 150 | echo "" |
| 151 | echo "*** Success ***" |
- Previous: Logging and Debugging Power Manager
- Next: Network Deployment