Control tool for Power Manager.
pmctl is a tool for managing DssW Power Manager.
pmctl is used to connect to and control Power Manager.
pmctl is the main command line tool for interacting with local and remote Power Manager instances.
pmctl can send requests to Power Manager. Responses can be displayed in common script friendly formats.
If no URL is provided,
pmctl will connect to the default instance of Power Manager. The default is typically the local instance of Power Manager.
A provided URL must include a
dnssd:// scheme. The file path form is used to connect with older local versions of Power Manager through a UNIX domain socket.
IPv6 shorthand notation is supported. The IPv6 loopback address can be written as
./pmctl ./pmctl -u pm://192.168.1.40:4567 ./pmctl -u pm://localhost:4567 ./pmctl -u pm://[::1]:4567 ./pmctl -u pm:/var/tmp/uk.co.dssw.powermanager/pmd ./pmctl -u dnssd://Mac-Pro ./pmctl -u dnssd://Mac-Pro.local.
A range of URL schemes are supported by
pmctl can connect to Bonjour/ZeroConf advertised Power Manager services. Use the
dnssd:// scheme to provide the service name to resolve and connect to.
By default, Bonjour service name resolution occurs within the
local. domain. Append the domain to the URL
dnssd://Mac-Pro.other-domain. to provide an alternative domain to resolve service names with.
Get the version details of the local Power Manager instance.
Sets of parameters can be associated with a request. A parameter consists of a name and value pair.
Base parameter format.
./pmctl scheduler.setenabled enabled=true
Enable the scheduler with a request and parameter.
Parameters containing spaces must be quoted to avoid the shell splitting the contents:
./pmctl scheduler.remove 'unique ID=Weekend Sleep'
Parameters with spaces must be quoted.
Parameters may be preprocessed using parentheses. Preprocessed parameters expand the range of input
pmctl can use when building a request. They allow for parameters to be read from files, remote resources, and for pass phrases to be securely requested from the command line.
Some complex parameters must be preprocessed. These parameters include those that require structures or arrays.
./pmctl scheduler.set event=(plist:file:///Users/Shared/event.plist)
Set an event using the contents of a local property list file.
Permitted formats include:
A parameter can be fetched from a file path or a URL:
./pmctl eventstore.store events=(plist:https://example.com/events.plist)
Using a remote property list as a parameter.
Alternative parameter formats.
The URL may refer to local or remote resources:
./pmctl scheduler.set event=(plist:file:///Users/Shared/event.plist) ./pmctl scheduler.set event=(plist:http://www.example.com/event.plist) ./pmctl scheduler.set event=(plist:https://www.example.com/event.plist)
A range of URL schemes are supported for getting property lists.
URLs may be escape encoded. Relative file scheme URLs are evaluated using the current working directory as the base location.
A parameter may need to include contents that match
pmctl’s preprocessing format. To avoid preprocessing content, use the raw preprocessor:
Base raw parameter format.
The brackets and prefixed raw will be removed, but the contents will be untouched and passed through as the parameter.
If an event has the unique ID
(plist:file:///tmp/), the following command will issue an appropriate remove request:
./pmctl scheduler.remove 'unique ID=(raw:(plist:file:///tmp/))'
Remove an event with the unique ID:
Multiple requests can be sent by appending the requests to the command. A single connection is created and the requests are issued in the order provided on the command line.
pmctl sends one request at a time.
pmctl may interrupt the requests, if authentication is required by the Scheduler. In this case, the authentication must be completed successfully before the remaining requests are sent.
Responses to multiple requests are grouped and output as a dictionary or an associative array:
./pmctl build.version notifications.warningperiod notifications.notifyperiod
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>build.version</key> <string>uk.co.dssw.powermanager.pmd v5.0.0</string> <key>notifications.notifyperiod</key> <integer>900</integer> <key>notifications.warningperiod</key> <integer>3</integer> </dict> </plist>
Multiple requests are supported. Responses are returned as dictionaries.
All character encoding and input is assumed to be UTF8. Providing input in other encodings may can authentication to fail.
UTF8 encoding is the default for macOS’s Terminal.app application.
Parameters need to passed to Power Manager in specific formats. All parameters provided directly from command line arguments are strings; in many cases strings are not the appropriate format.
Type coercion is limited in the possible conversions that can be performed. Where a conversion is not possible, the original parameter is left untouched. In this situation the request is expected to fail with an error message explaining which parameter is invalid.
pmctl can coerce parameters manually by extending the request format.
./pmctl scheduler.setenabled enabled:boolean=true
Coerce the parameter
enabled from a string to a boolean.
To coerce a parameter, insert a final parameter type into the request before the equals symbol. Supported types include:
0 if a connection is established.
EXIT_FAILURE is returned if no connection could be established, or authentication failed.
The return value can be used to test if Power Manager is available locally, or at a specified address.
#!/bin/sh `./pmctl` if [ "$?" -ne "0" ]; then echo "Power Manager is not available" else echo "Power Manager is available" fi
Shell script to test
pmctl’s return value.
#!/bin/sh `./pmctl -u pm://192.168.1.1:1234` && ( echo "Power Manager is available" ) || ( echo "Power Manager is not available" )
One line shell script to test
pmctl’s return value.
pmctl’s return value can not be used to determine the success or failure of a request. The success or failure of a request can be determined by the response returned.
Authentication and Authorisation
Authorisation is required for Power Manager requests that access privileged information or make device wide changes. By default, only device administrators can make these restricted requests.
Authentication determines who is making the request. Authorisation determines who can make the request.
By default, the authentication process delegated to the device’s Pluggable Authentication Module (PAM) implementation. Prompts and messages from PAM are passed to the client for interactive responses.
Avoiding Interactive Authentication
When writing scripts or tools that use
pmctl as a client, being able to avoid an interactive prompt is often essential.
Power Manager and
pmctl support multiple methods of authentication.
pmctl can use a
netrc file to provide credentials. A netrc file is a specially formatted text file containing device credentials that are used for login and password based PAM requests.
netrc file contains a single login (
hello) and password (
default login hello password world
Sample netrc file format.
To use a netrc file with
pmctl, use the
-netrc flag and pass the path to the netrc file:
./pmctl -netrc ~/netrc.txt
Pass a netrc file to pmctl.
To use a netrc file when disabling the scheduler, the
pmctl command becomes:
./pmctl -verbose -netrc ~/netrc.txt scheduler.setenabled enabled:boolean=false
Pass a netrc file to pmctl command to disable the scheduler.
netrc approach works for authentication prompts that include
password: prompts. If the device uses a non-standard or multilingual prompt, the netrc approach will not be able to respond appropriately.
Client Side Certificates
Power Manager supports client side Transport Layer Security (TLS) certificates for authentication.
A certificate can be associated with a specific user. When the certificate is used to connect to Power Manager, the associated user will be considered to be making the requests with no additional authentication.
This approach allows a certificate to avoid storing plain text credentials and is the preferred method of non-interactive authentication.
Creating a Client Certificate
To associate a certificate with a user, a TLS certificate pair is required.
The certificate pair can be created using a wide range of tools. Power Manager will evaluate the certificate but does not enforce hostname validity; this allows self-signed certificates to be used.
To create a certificate pair using the widely available
openssl, issue the command:
/usr/bin/openssl req -new -utf8 -x509 -days 3650 -newkey rsa:2048 -sha256 -nodes -keyout 'key.pem' -out 'certificate.pem'
When prompted, providing
* for the
Common Name and leaving all other fields blank,
., will result in a well-formed self-signed certificate.
openssl command above will create two files:
Both files need to be passed to
pmctl to authenticate the connection using a client side certificate.
Associating a Client Certificate
To associate a certificate pair with a user, issue this command to
./pmctl -verbose -authenticate-on-connect -client-certificate certificate.pem -client-key key.pem
Associate a client certificate with a user.
pmctl will prompt for to authentication the first time an unseen client certificate is used. If the authentication is successful, the certificate will be associated with that user.
Both the certificate and key must be passed by the
-client-key flags with every connection.
The certificate pair remains associated with the user indefinitely and can be used to avoid interactive authentication.
To use a client certificate when disabling the scheduler, the
pmctl command becomes:
./pmctl -verbose -client-certificate certificate.pem -client-key key.pem scheduler.setenabled enabled:boolean=false
Use a client certificate with pmctl to disable the scheduler.
Certificate pairs can be copied to other devices and used by multiple scripts without needing to disclose authentication credentials. This approach can be useful for administrators wishing to provide non-administrators with access to Power Manager, but without involving the non-administrator user with the client certificate process.