Clean up shell scripts in BBEdit

Continuing on the topic of using Text Filters in BBEdit as discussed in Clean Up XML Formatting in BBEdit, this hint shows you how to clean up shell scripts.

First download bashbeautify.py from the linked github project.

Create a simple bash script that calls the bashbeautify.py file. The following script uses the --tab-str option to set the default tab character from the script’s default of two spaces to the actual tab character. The --tab-size option sets how many --tab-strs per tab.  The trailing - says to act on stdin which is what the open BBEdit file is. Save the Text Filter script to ​~/Library/Application Support/BBEdit/Text Filters/bashbeautify.sh to make it available to BBEdit

bashbeautify.sh

#!/bin/bash
python ~/Applications/bin/bashbeautify.py --tab-str ' ' --tab-size 1 -

Now open a poorly formatted shell script. You may want to remove all indentations first to have a baseline of no indents. You can accomplish this by selecting all (Command-a) and using Command-[ until all text has shifted left.  Then use the menu Text > Apply Text Filter > bashbeautify.

Example: This hard to read script

Screenshot 2018-03-15 23.10.38

turns into this

Screenshot 2018-03-15 23.10.57

Tagged , , , , , ,

Clean Up XML Formatting in BBEdit

If you work with XML or .plist files you’ve most likely run into a file that is proper XML but is not human readable due to its formatting.  That usually means running it thru an xml format cleanup process to make it human readable. If you work with those files in BBEdit like I do, there is a feature called Text Filters that allows scripts to be run on the file you’re working on.

Create a simple bash script and save it to ​~/Library/Application Support/BBEdit/Text Filters/plist_format.sh:

#!/bin/bash
plutil -convert xml1 -o - -- -

Now if you have a file open that has no line breaks or indentation like this:

<?xml version="1.0encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0">...

Access the script in BBEdit in Text->Apply Text Filter->plist_format and it will format the output in-app.

<?xml version="1.0encoding="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>distribution_style</key>
    <false/>
    <key>identifier</key>
    <string>com.github.munki.pkg.isIllustrator18Installed</string>
    <key>install_location</key>
    <array>
        <string>/</string>
    </array>
    <key>name</key>
    <string>isIllustrator18Installed-${version}.pkg</string>
    <key>ownership</key>
    <string>recommended</string>
    <key>postinstall_action</key>
    <string>none</string>
    <key>suppress_bundle_relocation</key>
    <true/>
    <key>version</key>
    <string>1.0</string>
</dict>
</plist>

 

Tagged , , , , , ,

Add `product id` to a distribution pkg with Packages.app

Packages is a great GUI tool for creating distribution and flat .pkg installers for various needs in your environment.  Version 1.2.2 of Packages added the ability to add a product id to the pkg .dist file at build time.

Documented at https://managingosx.wordpress.com/2017/11/17/customized-high-sierra-install-issues-and-workarounds/ distribution-style packages need to have a unique product IDs included in the distribution file for it to work with startosinstall‘s --installpackage option. Without a product id the package is not included in the output of that tool.

To add a product id to a Packages project do the following:

  1. In the “Packages->Preferences…->Advanced” settings tick the box to “Show Advanced User Options” advanced-preferences.png
  2. Create a new Distribution Project. Access the “Project” listing on the left and in the “Settings” tab you’ll see “Advanced Options”. Scroll to the “product id”.project-settings.png
  3. Once you build the pkg, the distribution file in the package will contain a product idpkg-distribution.png

 

Configuring System Integrity Protection in a NetBoot environment

System Integrity Protection (SIP) can be enabled and disabled using csrutil from OS X Recovery per Apple’s documentation.  However, booting to Recovery is a local-only procedure and allows no remote access capabilities. I work remotely so it interests me to have capabilities to remotely change SIP status instead of walking a user thru the Recovery process which is daunting over the phone. We currently have NetBoot with Apple Remote Desktop (ARD) access in all offices and that can be leveraged for our needs.

The NetBoot environment by default doesn’t allow for csrutil access to enable or disable SIP: original-netboot-no-csrutil-access.png

However, if we copy boot.efi from a Recovery partition and use it to replace the i386/booter file in the NetBoot NBI the NetBoot environment can adjust SIP’s status:adjusted-netboot-csrutil-access.png

To extract the boot.efi first we have to determine which partition the Recovery OS is on and mount it. In this example the Recovery OS is on /dev/disk1s3 and is on an APFS formatted disk.  Use mount -t apfs /dev/disk1s3 /path/to/mountpoint to mount it to a mount point and copy the boot.efi file off:mount-recoveryhd.pngNow copy the boot.efi in the NBI’s i386/ directory, name it booter and give it 664 root:admin permissions:copy-boot.efi-to-booter-in-NBI.png

Now when I NetBoot to that NBI I can gain access with ARD and adjust SIP status with csrutil.

Tagged , , , , , ,

APFS Disk Roles

APFS is Apple’s new file system coming sometime in 2017. In 10.12.x the disk management command line tools have been updated to recognize commands relating to APFS. diskutil has some APFS options, one of which being changeVolumeRole . In that verb there is a reference as to how to set the different roles the volume can be

From the manpage of diskutil:

changeVolumeRole | chrole volumeDevice roles
Change the role metadata flag bits of an existing
APFS Volume.

The roles should be any combination of one or more
of the characters busrvBUSRV in much the same man-
ner as diskutil apfs addVolume above, in which
unspecified flags are left alone, use of lower-case
causes flags to be cleared, and use of upper-case
causes flags to be set. Alternatively, clear will
remove all flags, or 0 can be used as a no-op for
scripting convenience. You should not make any
assumptions about the usage or legal combinations
of role bits.

Ownership of the affected disks is required.

But no where does it state what the roles BUSRV are.

The role of the disk can be observed by running diskutil apfs list

APFS Container (1 found)
|
+-- Container disk2 9C36DEF6-B883-462B-A227-84F8A60E3551
    ====================================================
    APFS Container Reference: disk2
    Capacity Ceiling (Size): 255883108352 B (255.9 GB)
    Capacity In Use By Volumes: 138276864 B (138.3 MB) (0.1% used)
    Capacity Available: 255744831488 B (255.7 GB) (99.9% free)
    |
    +-< Physical Store disk0s4 13E393EF-C27E-44EC-B238-A7CA8A842F50     | -----------------------------------------------------------     | APFS Physical Store Disk: disk0s4     | Size: 255883108352 B (255.9 GB)     |     +-> Volume disk2s1 CC9D66C2-345C-4415-92E4-8CDE3A396180
        ---------------------------------------------------
        APFS Volume Disk (Role): disk2s1 (No specific role)
        Name: apfTest
        Mount Point: /Volumes/apfTest
        Capacity Consumed: 24576 B (24.6 KB)
        Capacity Reserve: None
        Capacity Quota: None
        Cryptographic Security: None

Iterating thru the roles they translate to:

B = "Preboot"
U = "User"
S = "System"
R = "Recovery"
V = "VM"

A volume can be set with any combination of roles according to diskutil.

A volume with all roles set shows

APFS Volume Disk (Role):  disk2s1 (Preboot, User, System, Recovery, VM)

Tagged , , , , , , ,

What’s New? New “What’s New” Office 2016 Suppression Key

Updated:
• Notification that one setting can suppress What’s New for the entire Office suite
• Changed to reflect new 15.34 key to suppress What’s New dialogs by a boolean
• Update to OneNote now using the same OUIWhatsNewShonItemIds key instead of its own ONWhatsNewShownItemIds key

My previous post, Not much, what’s new with you?, showed how to suppress the “What’s New” banners on updated software versions of the Office 2016 Suite.  While it worked, it _was_ work to get the specific preference key value to block the latest banner from appearing.  Due to the nature of how the values were dynamically created at build time it wasn’t known what those values were until the software was downloaded, installed, launched, then examine the preference file for the new value of OUIWhatsNewLastShownLink.  Blah.

Our good friends at Microsoft recognized the madness and worked on a way to make the suppression easier and more predictable for us admins.  As of version 15.32 there is a new key that takes an array of ints that can be added to the mobileconfig profile —  OUIWhatsNewShownItemIds.  The previous key OUIWhatsNewLastShownLink is still needed to suppress the What’s New dialogs prior to 15.32.

Good News, Bad News, Better News, Best News, and Bestest News

The Good News is that the values of OUIWhatsNewShownItemIds are predictable. It starts at 1 and increases by 1 for every new feature that is to be listed in a What’s New dialog box.  The Bad News is that each application can have its own number of new features to display, so knowing how many values isn’t known ahead of time. The Better News is that there is a bug (VSO #1476177 – Give admins a better way to turn off the What’s New dialog for O365 users) reported by our same Microsoft friends to recognize a boolean to “Don’t show me any more What’s New dialogs for any new versions ever.”  The Bestest News is that the new boolean value coming in version 15.34 can be set in the key ShowWhatsNewOnLaunch to be -bool false in the com.microsoft.office domain for the entire suite.  No need for individual application domain settings to suppress What’s New dialogs. That feature is on track to be part of the 15.34 release on May 16th.

So, until May 16th, you can add a list of values to the OUIWhatsNewShownItemIds key to suppress dialogs until the boolean value is respected.  The array must be a complete list meaning you can’t just add a value of 10 and have that mean block all values 1-10.

Each application domain (com.microsoft.Excel, com.microsoft.onenote.mac, com.microsoft.Outlook, com.microsoft.Powerpoint, and com.microsoft.Word) will need the values added for OUIWhatsNewShownItemIds. The easiest way would be to add these values to the existing mobileconfig profiles from Not much, what’s new with you? and modify it like this example for Word. But come version 15.34 just use the new key in the com.microsoft.office domain and call it a night.

Tagged , , , ,

Office 2016 Preference Management Changes

Starting with Office version 15.33 you’ll have the ability to manage some suite-wide preferences via profile management. Previously, these settings were configurable via defaults commands but weren’t CFPrefs enabled to allow for profile management of the settings. Thanks to the hard work of Paul Bowden and Erik Schwiebert at Microsoft, along with the collaboration and feedback of Mac admins in the macadmins.org slack instance, this request of preference management has been made possible. And this is just the beginning. Now with the foundation for preference management in code this will allow for more management options in future versions.

When an Office 15.33 app is launched for the first time, the existing preferences in ~/Library/Group Containers/UBF8T346G9.Office/com.microsoft.officeprefs.plist will be migrated over to the new preference domain automatically. At that time a key will be set signaling that the migration has occurred.

Paul has put together a new site (http://www.office4mac.com) that showcases a video course educating users and admins of the management changes. Look for more videos to come. This video shows examples of the preference changes, how to manage them, and implementing them through a management system. It’s definitely worth the watch.

For me, the meat and potatoes of these changes are the keys and values that are manageable in the com.microsoft.office domain. Here is an example management profile of all the keys that can be managed.

suite-wide preferences.png

OfficeActivationEmailAddress adds a “Belongs to” value in the About box to list who owns the software.

DefaultsToLocalOpenSave – by default Office offers to open and save documents to OneDrive, however due to data security policies that may not be acceptable and confuse users. This key will set the default open and save dialog boxes of all Office apps to the standard System views.

VisualBasicMacroExecutionState has 3 values that relate to the “GUI settings” in Preferences->Security & Privacty in app:

DisabledWithWarnings – “Disable all macros with notification” (Default)

DisableWithoutWarnings – “Disable all macros without notification”

EnabledWithoutWarnings – “Enable all macros (not recommended; potentially dangerous code can run)”

I don’t recommend managing the HaveMergedOldPrefs key as that is set organically. If you set it to TRUE then the old pref won’t be migrated automatically on first run. If you manage it as FALSE then it will try and migrate on every launch.

The two debug keys msoridEnableLogging and msoridDefaultMinimumSeverity should only be set when debugging an issue and I don’t see a need to manage them centrally. Leaving them enabled isn’t recommended.

Seeing these preference options move to a manageable location is a big plus for us admins, not only for the specifics of these settings, but also in the willingness of Microsoft to make these changes based on admin feedback. This can only mean more good things in the future.

Tagged , , , , ,

How to remove accounts cleanly

When you want to get rid of an account that’s not being used on a computer anymore, how do you do that pragmatically?  Visiting the computer and going thru the System Preferences’ Users & Groups options is time consuming, inconvenient, and sometimes physically not possible.

Previously I’d say use dscl to remove the cached account credentials and rm -r /Users/username to remove the home folder.  However, that leaves behind pieces that has caused some issues.

Enter sysadminctl

This removes any running processes by that user, the home folder, the public share, the cached credentials, and disabling Back To My Mac for that user if set.

Example:

bash-3.2# ls /var/db/dslocal/nodes/Default/sharepoints/
Tester's Public Folder.plist eholtam's Public Folder.plist admin's Public Folder.plist

bash-3.2# sysadminctl -deleteUser tester
2017-03-14 21:28:05.241 sysadminctl[2093:60392] Killing all processes for UID 503
2017-03-14 21:28:05.242 sysadminctl[2093:60392] Removing tester's home at /Users/tester
2017-03-14 21:28:05.877 sysadminctl[2093:60392] Deleting Public share point for tester
2017-03-14 21:28:05.903 sysadminctl[2093:60392] Deleting record for tester
2017-03-14 21:28:05.930 sysadminctl[2093:60392] AOSKit INFO: Disabling BTMM for user, no zone found for uid=503, usersToZones: {
 502 = "1234567.members.btmm.icloud.com.";
}

bash-3.2# ls
eholtam's Public Folder.plist admin's Public Folder.plist

Future me will be using sysadminctl for all account deletion needs.

Tagged , , , , ,

Sierra’s Built-in Storage Management Utility

New with Sierra there is a built-in utility to help keep disk storage space available.  The function is part of the System Information.app and is accessed a few ways:

  1.  => About This Mac => Storage => Manage…
  2. (Hold the option key down)  => System Information… => Window => Storage Mangement (Cmd-U)
  3. /Applications/Utilities/System Information.app => Window => Storage Mangement (Cmd-U)

Once launched it will proceed to gather data sizes of categories of interest. The available and total disk space will be listed in the window’s name.

main-overview

First you’ll see some recommendations of ways to keep disk space available.  Each has its own set of gotchas so be sure to make note of the implications:

Store in iCloud

store-in-icloud-options

There has been some interesting discoveries in the behavior surrounding iCloud Desktop and Documents.  See iCloud Desktop and Documents in macOS Sierra – The Good, The Bad and the Ugly for a full rundown. Even though these checkboxes are checked by default, that doesn’t represent the actual state of the setting.  On my machine I have Desktop and Documents turned off in the iCloud preference pane yet this box shows as checked.

Optimize Storage —

optimize-storage-options

Empty Trash Automatically —

empty-trash-automatically

If you’re one of those that can’t commit to deleting things once put in the Trash, let the OS handle it for you.

Reduce Clutter —

This option opens the Documents listing.

Along the left are categories and the amount of space each is taking up.  Accessing those brings up a list sorted by largest on top.  If you want to remove an individual listing, right click and select Delete. Even though Applications are listed, non-admins can’t remove applications without admin credentials.

Thanks to @adamcodega for pointing this tool out.

Tagged , , , , , , ,