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.

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 ***"