Author: ab
On Internet Shortcut Files
If you are managing Macs and PCs, then you will frequently connect to other computers or virtual machines through screen sharing, secure shell or other means. Here is a simple trick to make those connections easier:
Open your favored UI text editor (Text Edit will do) and type
vnc://<username>@<hostname>
Replace <username>
and <hostname>
with your username and hostname for a Mac you frequently share the screen with.
Then select the entire text and drag it to the desktop. It will create a file with “@” sign on the icon. When you double click this file, Screen Sharing opens and asks for the password (unless it is stored in the Keychain) and connects the remote session.
Now rename this file to VNC <hostname>
. Then activate Spotlight (cmd-space) and start typing “VNC” and the hostname. After a few characters the VNC link file should be the top result. Hit return and the session starts.
As an extra bonus you can put these files in a folder in your cloud file system of choice (iCloud Drive, Dropbox, Google Drive, Box, etc.) and they will sync to all your Macs.
Other Protocols
You can do the same with any URI scheme:
ssh://<username>@<hostname>:<port>
afp://<username>@<hostname>/<share>
smb://<username>@<hostname>/<share>
http://<hostname/<path>
Microsoft Remote Desktop/RDP
The new Microsoft Remote Desktop application available in the Mac App Store also supports rdp
URI schemes, however the syntax is a bit odd. To connect to a remote host you have to use:
rdp://full%20address=s:<hostname>&username=s:<username>
You can find more options for this URI scheme in this technote. One I have found useful is screen mode id
where a value of 1
means to open the remote screen in a window a value of 2
means full screen mode.
Looking into the files
If inspect the file generated by dragging, you can see that it is a property list file with a single key URL
and a string value containing the link.
Files for a vnc
URI get the .vncloc
extension, http[s]
URIs get the .webloc
extension, ftp
URIs get the .ftploc
extension and everything else seems to get .inetloc
extensions. (There may be more, let me know if you find any.)
This makes it easy to write a short script that simplifies the creation of these internet location files:
Sample use:
./create_netloc.py vnc://user@host.example.com
will create VNC host.vncloc
./create_netloc.py http://munki.example.com/munkireport-php/ Munkireport
will create Munkireport.webloc
./create_netloc.py "rdp://full%20address=s:host.example.com&username=s:name&screen%20mode%20id=i:1"
will create RDP host.inetloc
Note on
rdp
links: since the ‘&’ is special in shell commands you need to quote the uri if any are present.
Fun with find
and git
find ~ -type d -name .git -exec dirname {} \;
will show you all folders in your home directory which have a .git
subfolder — i.e. they are git repositories.
This is useful, but can be extended to:
find ~ -type d -name .git -exec dirname {} \; | tr '\n' '\000' | xargs -0 -n1 -I % git -C "%" status
to show the git status
output of all your git repositories.
Time to clean up!
Useful AutoPkg bash functions
Note: the version of these functions I posted originally were not safe for paths with spaces in them. I have updated them and now the should be.
I have added these functions to my .bash_profile
and thought they might be useful for others as well.
alias reveal="open -R"
function recipe-open() { open "$(autopkg info $@ | grep 'Recipe file path' | cut -c 22-)"; }
function recipe-edit() { bbedit "$(autopkg info $@ | grep 'Recipe file path' | cut -c 22-)"; }
function recipe-reveal() { reveal "$(autopkg info $@ | grep 'Recipe file path' | cut -c 22-)"; }
Use them like this
recipe-open RecipeName.munki
recipe-open com.github.recipe.id
recipe-open
will grab the path to the recipe file and use open
to open it with its default application. I have PlistEdit Pro assigned to open .recipe
file extensions.
recipe-edit
will open the recipe file in BBEdit, which doesn’t suck.
recipe-reveal
will open the recipe in the Finder. The bash alias reveal
for open -R
is quite useful independent of autopkg
.
Adapt for your own choice of editors.
Free/Cheap Mac Sysadmin Tools You Might Like
Free tools for the budget-minded Mac admin
Munki 2.2 Official Release
Yay! Munki 2.2 is officially released!
Connect to Active Directory with a Profile
In OS X 10.9 Mavericks Apple added the option to connect a Mac client to Active Directory with a configuration profile. In previous OS versions admins have to script AD connection with the dsconfigad
CLI tool.
Many of the configuration options for this profile are described here. By default the client Mac’s hostname
will be used as the machine record name to connect to AD. However, you can provide a ClientID
key to override the default. There are also placeholders you can provide for this filed as described here. In our setup we use the ComputerName
(as defined in Sharing preference pane or with scutil --set ComputerName
) instead, since the hostname of a given MacBook may change depending on which Thunderbolt ethernet adaptor is used.
The easiest way to create an Active Directory Profile is to use Profile Manager on OS X Server to create one with the settings you want, then download the profile and further edit in a text editor. You can also use this generic Active Directory configuration profile as a starting point.
Building a Cocoa-AppleScript (AppleScriptObjC) Automator Action
This TechNote has been updated for Yosemite. Maybe it is time to update some of my ancient actions, too…
Technical Note TN2322: Building a Cocoa-AppleScript (AppleScriptObjC) Automator Action.
Push Settings with Munki’s new Profile support
Note: please consider supporting supporting this webpage by purchasing one of my books! Thank you!
The combination of AutoPkg and Munki (or another package distribution system) is very powerful. You can use AutoPkg to automatically download, package and import software from the vendor’s site and then use Munki manifests to choose where and how to deploy. With the Managed Software Center interface, you can give users an App Store like interface to choose from software your insitution provides.
This is all wonderful until the user gets to the “Please Enter Your License Number!” dialog. Installing the software is just the first part of software management. You also need to manage configuration.
Since we do not want to mess around with websites to publish the serial numbers, we need another means of pushing configuration settings with Munki.
Note: your institution’s license agreement with a software vendor may or may not allow distribution of the serial number in this way. Some software may not work this way at all. Please check with the license manager/lawyer at your institution and/or the software vendor before you do this.
Which settings to manage?
My example will be the application Fetch. FetchSoftworks is very gracious as it provides free licences to educational and charitable institutions and it also stores the licensing information in a standard preferences file, which makes it perfect for this example.
You can find a Fetch recipe here. To run it in autopkg do:
autopkg repo-add jleggat-recipes
autopkg run Fetch.munki
And add it to the managed installs or optional installs section for your test client(s).
On a test client, install Fetch and open it. Before you enter any licensing info. Open the ~/Library/Preferences
folder in list view and sort the contents by date modified, so the newest changes come first. Quit Fetch again, without entering anything and wait for the Fetch preference file to appear at the top of the list. Note its name (com.fetchsoftworks.Fetch.plist
). You can select the file and hit the space bar to see the contents in QuickView.
Note: It may take a few seconds after quitting the application for the plist file to appear. This is because preference management is handled thorugh a system daemon
cfprefs
which will hold values in memory and wait for an “opportune moment” to actually write new and changed values to disk. Keep this in mind when fiddling with preference files.
The safest way to get an up-to-date view of preferences is using thedefaults
command in Terminal:defaults read com.fetchsoftworks.Fetch
Then start Fetch again and enter your licensing information. Once you have successfully licensed Fetch, quit it again. Wait for the list of files in the Preferences folder to update. We see that Fetch has created or updated three plist files. com.fetchsoftworks.Fetch.plist
, com.fetchsoftworks.Fetch.License.plist
and com.fetchsoftworks.Fetch.Shortcuts.plist
. It is pretty obvious which one we are interested in and looking at the contents confirms that the Fetch.License file contains the licensing info. We can verify once more on the Terminal with:
defaults read com.fetchsoftworks.Fetch.License
Note: the
com.fetchsoftworks.Fetch
domain also contains redundant license information, you could manage it either way. Most applications do not split information this way.
Creating the Profile
There are a few approaches to pushing this plist file to a client machine. You could build an installer package that places this file in a specific user’s home directory, but that would fail if the user name varies from client to client. You could write a postinstall script that moves the file to the current user’s Preferences folder, but that would only work for the current user, not other users and especially not users that may log in the future. There are work arounds for all of these problems, and we may need them for other software. But if we want to control preferences in plist files in either ~/Library/Preferences
or /Library/Preferences
then the best solution are Configuration Profiles.
Configuration Profiles are also property list files, but use a different schema because they contain more metadata around the settings. Tim Sutton has written a wonderful tool to convert ‘normal’ preference plist files to conifguration profiles: mcxToProfile.
You run mcxToProfile
like this:
./mcxToProfile.py --plist ~/Library/Preferences com.fetchsoftworks.Fetch.License.plist --identifier FetchLicense --manage Once
The --manage Once
option sets up the profile, so that it sets the preference keys in it once per user and then stops enforcing them. This is usually the safest and least intrusive choice for management, since it allows the application or the user to override or change settings.
Another option for the --manage
setting are Often
, which will reset the value on every user login. If you do not specify the --manage
switch, then the preference keys in the profile will be always enforced and cannot be changed by the user or the application. This might be very useful in a scrictly controlled environment. Some third party applications may only work with one of the possible --manage
options. Experiment to find out which.
The command above will generate a file called FetchLicense.mobileconfig
open it in a text or property list editor. At the top there is a PayloadContent area where you can find the preference keys from the Fetch.License file nested inside. You can delete any keys and values you do not want to set on the clients.
Further down there are a few top level keys that you will want to modify:
PayloadDisplayName
: this is the ‘Name’ of the config that will be displayed to the User in System Preferences. You will want to change this from the default supplied bymcxToProfile
. You can also use the--displayname
option to provide that during profile generation.PayloadOrganization
: Your institution’s name. You can also provide this during profile generation with the--organization
key.PayloadDescription
: a description of what the profile does.
When you later import the profile into Munki it will use these values to fill the pkginfo file.
Testing the Profile
Now quit Fetch and delete all the preferences it may have set. Use the defaults
command rather than just deleting the files to make sure cfprefsd
is not still caching values:
defaults delete com.fetchsoftworks.Fetch
defaults delete com.fetchsoftworks.Fetch.License
defaults delete com.fetchsoftworks.Fetch.Shortcuts
Then double-click the configuration profile we just created in the Finder. System Preferences should open and prompt to install the profile. Click on “Show Profile” to view the contents, note where and how the data we entered earlier appears. You can also see the keys and settings.
Click “Continue” and confirm again to actually install the profile. You can still inspect the profile in the “Profiles” pane of System Preferences. Remember this for future debugging.
Now launch Fetch again and it should not prompt you for a license. If you can try again with a different user and/or on a different computer/virtual machine.
Importing the Profile into Munki
Once you have confirmed that the profile works as expected. You can import it into Munki. With version 2.2 and higher Munki recognizes files with the .mobileconfig
extension as profiles and know how to install, update and un-install them.
To add a configuration profile, you use munkiimport
munkiimport Profile.mobileconfig
As usual munkiimport
will interactively confirm extra metadata. It will parse most of the metadata from the profile and use it where appropriate. Then you can use the profile like any other item in munki as a managed install, managed un-install, optional install or update.
In our case we want to deploy the FetchLicense profile whenever the Fetch software is installed. In Munki terminology it is an update-for
.
munkiimport FetchLicense.mobileconfig --update-for Fetch
Answer the prompts for the remaining metadata inputs. As an update, this profile does not have to be added to a manifest. As soon as the Fetch package itself is installed on a client, Munki will install the FetchLicense.mobileconfig
.
To test, use Managed Software Center to add Fetch or run managedsoftwareupdate
if Fetch is a managed install. You should also see the FetchLicense.mobileprofile appear as a required install. Once the install is done, check the Profiles pane in System Preferences to see if the profile is installed. Then open Terminal and run:
defaults read com.fetchsoftworks.Fetch.License
Finally launch Fetch and it should not ask for the license.
Obviously you can use this method to control other settings in Fetch and other applications as well.