<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.7.4">Jekyll</generator><link href="https://gmarnin.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://gmarnin.com/" rel="alternate" type="text/html" /><updated>2019-02-08T08:19:58-05:00</updated><id>https://gmarnin.com/feed.xml</id><title type="html">gmarnin</title><subtitle>Notes from a Macadmin</subtitle><author><name>gmarnin</name><uri>https://gmarnin.com</uri></author><entry><title type="html">My Bootstrappr Workflow</title><link href="https://gmarnin.com/my-bootstrappr-workflow/" rel="alternate" type="text/html" title="My Bootstrappr Workflow" /><published>2018-07-29T00:00:00-04:00</published><updated>2018-07-29T00:00:00-04:00</updated><id>https://gmarnin.com/my-bootstrappr-workflow</id><content type="html" xml:base="https://gmarnin.com/my-bootstrappr-workflow/">&lt;h3 id=&quot;see-ya-netboot&quot;&gt;See Ya NetBoot&lt;/h3&gt;

&lt;p&gt;With Apple’s introduction of the &lt;a href=&quot;https://support.apple.com/en-us/HT208862&quot;&gt;T2&lt;/a&gt; processor, a long standing tool in many MacAdmin’s toolkit has taken a big hit. The T2 introduces &lt;a href=&quot;https://support.apple.com/en-us/HT208330&quot;&gt;Secure Boot&lt;/a&gt; which renders Macs with the chip unable to be NetBoot. Although Secure Boot can be disabled, it is non trivial to do so and clearly non advisable. In summary, Apple considers NetBoot a security risk and NetBoot is no longer a viable option going forward. Apple’s preferred NetBoot replacement is DEP and MDM. For now, my preferred replacement is &lt;a href=&quot;https://github.com/munki/bootstrappr&quot;&gt;Bootstrappr&lt;/a&gt; from &lt;a href=&quot;https://managingosx.wordpress.com&quot;&gt;Greg Neagle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before the T2, I was NetBooting via &lt;a href=&quot;https://github.com/bruienne/bsdpy/tree/windows&quot;&gt;BSDPy&lt;/a&gt; into &lt;a href=&quot;https://github.com/grahamgilbert/imagr&quot;&gt;Imagr&lt;/a&gt;. Imagr was running a simple workflow that took a new Mac, named it and created a new &lt;a href=&quot;https://github.com/munki/munki&quot;&gt;Munki&lt;/a&gt; manifest based off a template using a forked version of a &lt;a href=&quot;https://github.com/gmarnin/munki-enroll&quot;&gt;Munki-Enroll&lt;/a&gt;. Finally, Imagr installed a few setup packages to boot the Mac into Munki’s bootstrap mode and the rest is history. This workflow has served me well for a for a few years.&lt;/p&gt;

&lt;p&gt;Naming the Mac is an important step in our imaging workflow. I know some environments don’t care what the Mac is named, but we do. We have stable hostnames and use the name to key off for many of our other systems. The name codifies the physical location of the Mac on our sprawling campus. We also use it for Active Directory binding, as well as the identifier for the Munki manifest name and other stuff too.&lt;/p&gt;

&lt;h3 id=&quot;why-bootstrappr&quot;&gt;Why Bootstrappr?&lt;/h3&gt;
&lt;p&gt;Bootstrappr is a bare-bones tool to install a set of packages and scripts on a target volume. So why use it over DEP and MDM? In short, because it is quick, easy, non-fragile and it just works. I can still keep the entire imaging process on our internal network which also means I still control the whole process. Bootstrappr can replace NetBoot and my Imagr workflow. I simply feed Bootstrappr the same packages Imagr was using and I’m done. Well, done until it came time to give the Mac its name before the Munki bootstrap mode takes over. Out of the box, Bootstrappr has no support for naming a Mac.&lt;/p&gt;

&lt;h3 id=&quot;my-workflow&quot;&gt;My Workflow&lt;/h3&gt;
&lt;p&gt;Bootstrappr is a simple bash script because it is made to run in Recovery mode where a lot of other scripting languages and binaries are not available. With an idea I got from &lt;a href=&quot;http://www.vaughnemiller.com&quot;&gt;Vaughn Miller&lt;/a&gt; at the hallway track at &lt;a href=&quot;https://macadmins.psu.edu&quot;&gt;PSU MacAdmins Conference&lt;/a&gt;, I could modify the bootstrappr.sh script to ask for the computer name and write it to a file on the boot drive. For me, that addition looks like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Name the Mac. Works in conjunction with the 1_bootstrappr_macname_munki_enroll-1.0.pkg to set the name and generate a munki manifest before munki runs. 
echo
echo &quot;Please give the Mac a name:&quot;
read computer_name
/usr/bin/touch &quot;/Volumes/${SELECTEDVOLUME}&quot;/Users/Shared/computer_name.txt
echo $computer_name &amp;gt; &quot;/Volumes/${SELECTEDVOLUME}&quot;/Users/Shared/computer_name.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Vaughn was using &lt;a href=&quot;https://github.com/chilcote/outset&quot;&gt;Outset&lt;/a&gt; to run a script on first boot to read the file that Bootstrappr set. While I love me some Outset, I didn’t want it as dependency in this workflow. I was looking to replace my Imagr workflow all within my Bootstrappr workflow. With a hat tip to &lt;a href=&quot;https://twitter.com/mikeymikey&quot;&gt;Mike Lynn&lt;/a&gt;, I started looking at &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/sbin/chroot&lt;/code&gt; to allow me to run &lt;code class=&quot;highlighter-rouge&quot;&gt;scutil&lt;/code&gt; on the Macintosh HD volume from Recovery mode.&lt;/p&gt;

&lt;p&gt;I created a package named &lt;code class=&quot;highlighter-rouge&quot;&gt;1_bootstrappr_macname_munki_enroll-1.0.pkg&lt;/code&gt; which Bootstrappr &lt;a href=&quot;https://github.com/munki/bootstrappr#order&quot;&gt;runs first&lt;/a&gt;. The payload drops &lt;code class=&quot;highlighter-rouge&quot;&gt;bootstrappr_macname_munki_enroll.sh&lt;/code&gt; in &lt;code class=&quot;highlighter-rouge&quot;&gt;/Users/Shared/&lt;/code&gt; and a &lt;code class=&quot;highlighter-rouge&quot;&gt;postinstall&lt;/code&gt; which executes it.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bootstrappr_macname_munki_enroll.sh&lt;/code&gt; reads the &lt;code class=&quot;highlighter-rouge&quot;&gt;computer_name.txt&lt;/code&gt; file which contains the name, sets the name and generates the Munki manifest using &lt;code class=&quot;highlighter-rouge&quot;&gt;Munki-Enroll&lt;/code&gt;. A perfect hat trick!&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/Users/Shared/bootstrappr_macname_munki_enroll.sh&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# This script is part of our bootstrappr workflow. It sets the Mac name, and gens a munki manifest based on munki-enroll.&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;ComputerName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /Volumes/Macintosh&lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;HD/Users/Shared/computer_name.txt&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;Serial&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;/usr/sbin/ioreg &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;IOPlatformSerialNumber | cut &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'&quot;'&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f4&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ComputerName is &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ComputerName&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Serial is &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Serial&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Name the Mac &lt;/span&gt;
/usr/sbin/scutil &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; ComputerName &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ComputerName&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
/usr/sbin/scutil &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; HostName &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ComputerName&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
/usr/sbin/scutil &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; LocalHostName &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ComputerName&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;The Mac has been named to &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ComputerName&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# mDNSResponder is not available in the chroot'ed environment and so all DNS lookups will fail. Using the ip address as workaround.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Using -k option, (--insecure) because ssl cert is based on the DNS name. Doesn't work without -k&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;SUBMITURL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://ip.address/munki/munki-enroll/enroll.php&quot;&lt;/span&gt;

	/usr/bin/curl &lt;span class=&quot;nt&quot;&gt;-vv&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-k&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Authorization:Basic KeyGoesHere'&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--max-time&lt;/span&gt; 5 &lt;span class=&quot;nt&quot;&gt;--silent&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--get&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;computername&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ComputerName&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;serial&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Serial&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
	&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SUBMITURL&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;postinstall&lt;/code&gt; script uses &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/sbin/chroot&lt;/code&gt; and cleans up:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Macintosh HD is hard coded because new Macs have shipped with that HD name since forever&lt;/span&gt;
/usr/sbin/chroot /Volumes/Macintosh&lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;HD /Users/Shared/bootstrappr_macname_munki_enroll.sh

/bin/sleep 10

&lt;span class=&quot;c&quot;&gt;# Clean up&lt;/span&gt;
/bin/rm /Volumes/Macintosh&lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;HD/Users/Shared/computer_name.txt
/bin/rm /Volumes/Macintosh&lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;HD/Users/Shared/bootstrappr_macname_munki_enroll.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In testing, I found this works well in 10.13 and on 10.14 beta 4. In 10.12, &lt;code class=&quot;highlighter-rouge&quot;&gt;curl&lt;/code&gt; throws an error that I didn’t investigate. 10.12 isn’t really a concern for me because Apple isn’t shipping anymore 10.12 Macs except for maybe the Mac Mini.&lt;/p&gt;

&lt;p&gt;The other packages Bootstrappr installs are (in order):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1_bootstrappr_macname_munki_enroll-1.0.pkg
2_create_local_admin-1.1.pkg
3_munki-config-1.1.pkg
4_munkitools-3.3.1.3537.pkg
5_munki-bootstrap-1.0.pkg
6_SuppressSetupAssistant-1.0.pkg
7_disable-login-popups-1.3.pkg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;update&quot;&gt;Update&lt;/h3&gt;

&lt;p&gt;After imaging several dozen Macs using Bootstrappr with the chroot method described above, I ultimately found the chroot method of naming the Mac unreliable. 
I haven’t been able to pin down why some Macs get named and some don’t. I needed a more consistent workflow and so I changed things up again. I’m still having Bootstrappr
ask for and write the computer name to &lt;code class=&quot;highlighter-rouge&quot;&gt;/Users/Shared/computer_name.txt&lt;/code&gt; because that always works. I stopped using &lt;code class=&quot;highlighter-rouge&quot;&gt;chroot&lt;/code&gt; and moved the naming of the Mac to
to Munki, using a &lt;code class=&quot;highlighter-rouge&quot;&gt;postinstall_script&lt;/code&gt; in a &lt;code class=&quot;highlighter-rouge&quot;&gt;nopkg&lt;/code&gt; that is in my &lt;code class=&quot;highlighter-rouge&quot;&gt;site_default&lt;/code&gt; manifest:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &amp;lt;key&amp;gt;installcheck_script&amp;lt;/key&amp;gt;
    &amp;lt;string&amp;gt;#!/bin/sh

# Check if computer_name file exists. Abort if it doesn't exist. 

if [ ! -f /Users/Shared/computer_name.txt ]; then
    echo &quot;/Users/Shared/computer_name.txt not found!&quot;
    exit 1
fi

    &amp;lt;/string&amp;gt;
    &amp;lt;key&amp;gt;postinstall_script&amp;lt;/key&amp;gt;
	&amp;lt;string&amp;gt;#!/bin/bash

# This script is part of our bootstrappr workflow. It sets the Mac name, and gens a munki manifest based on munki-enroll.

ComputerName=`cat /Volumes/Macintosh\ HD/Users/Shared/computer_name.txt`
Serial=`/usr/sbin/ioreg -l | grep IOPlatformSerialNumber | cut -d'&quot;' -f4

# Name the Mac
/usr/sbin/scutil --set ComputerName &quot;$ComputerName&quot;
/usr/sbin/scutil --set HostName &quot;$ComputerName&quot;
/usr/sbin/scutil --set LocalHostName &quot;$ComputerName&quot;

SUBMITURL=&quot;https://ip.address/munki/munki-enroll/enroll.php&quot;

	/usr/bin/curl -vv -k -H 'Authorization:Basic KeyGoesHere' --max-time 5 --silent --get \
	-d computername=&quot;$ComputerName&quot; \
	-d serial=&quot;$Serial&quot; \
	&quot;$SUBMITURL&quot;

# Remove the file computer_name.txt bootstrappr file
/bin/rm /Users/Shared/computer_name.txt

exit 0
    &amp;lt;/string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I hope you find this workflow useful or at least gives you an idea of what Bootstrappr can do. If you have a similar workflow that improves on mine, please let me know.&lt;/p&gt;

&lt;p&gt;Happy imaging!&lt;/p&gt;</content><author><name>gmarnin</name></author><category term="bootstrappr" /><category term="imaging" /><category term="munki" /><category term="netboot" /><summary type="html">I found a use for chroot</summary></entry><entry><title type="html">Schedule Restart Configuration Profile</title><link href="https://gmarnin.com/restart-config-profile/" rel="alternate" type="text/html" title="Schedule Restart Configuration Profile" /><published>2017-03-28T00:00:00-04:00</published><updated>2017-03-28T00:00:00-04:00</updated><id>https://gmarnin.com/restart-config-profile</id><content type="html" xml:base="https://gmarnin.com/restart-config-profile/">&lt;p&gt;I had a need to reboot a small lab of student use iMacs every night. My first thought was to use a configuration profile as I try to use them whenever I need to manage a setting. This is the preferred Apple way®️ of managing macOS settings. I don’t have an MDM in production and I don’t manually create configuration profiles by hand. Instead, I run Apple’s Profile Manager inside a VM. I fire it up whenever I need to generate a profile as it does most of the work for me. I then download the profile, run &lt;code class=&quot;highlighter-rouge&quot;&gt;plutil -convert xml1 /path/to/foo.mobileconfig&lt;/code&gt; to fix the formatting and make minor edits in my text editor if needed. I use &lt;a href=&quot;https://github.com/munki/munki/wiki/Managing-Configuration-Profiles&quot;&gt;Munki&lt;/a&gt; to install the profile.&lt;/p&gt;

&lt;p&gt;So in Profiler Manager Server 5.1.5, I went looking for the setting to schedule reboot. To my surprise, I didn’t find it anywhere. In the Energy Saver section, I have the option to sleep or shutdown the Mac on a schedule but no option to restart. In the Energy Saver preference pane in macOS there is a option to restart on a schedule but the option to do so is missing from Profile Manager. It didn’t make sense to me why the restart option was missing from Profile Manager.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://gmarnin.com/images/profile_manager_no_restart_option.png&quot; alt=&quot;No restart option in Profile Manager&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To work around this limitation, and because I only had a small lab of iMacs that needed this setting, I could of manually configured each Mac by hand. But I know that won’t scale should my need to schedule restart on more Macs grow.&lt;/p&gt;

&lt;p&gt;My solution was to configure one Mac with the restart settings that I needed and then, in a moment of #macadminshame, copy off the &lt;code class=&quot;highlighter-rouge&quot;&gt;/Library/Preferences/SystemConfiguration/com.apple.AutoWake.plist&lt;/code&gt; the Mac created and use &lt;a href=&quot;https://github.com/munki/munki-pkg&quot;&gt;munki-pkg&lt;/a&gt; to package up the file for Munki to install.&lt;/p&gt;

&lt;p&gt;I also filed radar 26844969 requesting that the Profile Manager Energy Saver section match what is available on the Mac. Specifically, I requested the ability to create a restart configuration profile to match the settings that are available in macOS.&lt;/p&gt;

&lt;p&gt;Six months later, Apple responded to my radar and asked me to test the latest beta of Server. I cloned my non production Profiler Manager Server VM, updated it to the latest Server beta 5.2, and retested. I’m happy to say that Apple added the ability to create a scheduled restart configuration profile.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://gmarnin.com/images/profile_manager_restart_option.png&quot; alt=&quot;Restart option in Profile Manager&quot; /&gt;&lt;/p&gt;

&lt;p&gt;My take away here is simple: If you think filing radars is a waste of time you’re wrong. It really works. It may not be a quick process and you may not always get the answer you want but Apple hears you. I encourage you to file early and often.&lt;/p&gt;

&lt;p&gt;Sample configuration profile to automatically restart a Mac every weekday at 2am:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;plist&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;version=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadContent&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;array&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadDisplayName&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Energy Saver&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadEnabled&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadIdentifier&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;com.apple.mdm.domain.edu.339b00a0-162b-0134-2637-000c29bcc5f4.alacarte.energysaver.0fc3fd60-162d-0134-2638-000c29bcc5f4&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadType&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;com.apple.MCX&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadUUID&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;0fc3fd60-162d-0134-2638-000c29bcc5f4&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadVersion&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;integer&amp;gt;&lt;/span&gt;1&lt;span class=&quot;nt&quot;&gt;&amp;lt;/integer&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;com.apple.EnergySaver.desktop.Schedule&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
				&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;RepeatingPowerOff&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
				&lt;span class=&quot;nt&quot;&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
					&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;eventtype&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
					&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;restart&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
					&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;time&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
					&lt;span class=&quot;nt&quot;&gt;&amp;lt;integer&amp;gt;&lt;/span&gt;120&lt;span class=&quot;nt&quot;&gt;&amp;lt;/integer&amp;gt;&lt;/span&gt;
					&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;weekdays&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
					&lt;span class=&quot;nt&quot;&gt;&amp;lt;integer&amp;gt;&lt;/span&gt;127&lt;span class=&quot;nt&quot;&gt;&amp;lt;/integer&amp;gt;&lt;/span&gt;
				&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/array&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadDisplayName&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Schedule Restart Overnight&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadIdentifier&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;com.apple.mdm.domain.edu.339b00a0-162b-0134-2637-000c29bcc5f4.alacarte&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadOrganization&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;ITS&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadRemovalDisallowed&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;false/&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadScope&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;System&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadType&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Configuration&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadUUID&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;339b00a0-162b-0134-2637-000c29bcc5f4&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadVersion&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;integer&amp;gt;&lt;/span&gt;1&lt;span class=&quot;nt&quot;&gt;&amp;lt;/integer&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>gmarnin</name></author><category term="Profile Manager" /><category term="Configuration Profile" /><summary type="html">radar or it never happened</summary></entry><entry><title type="html">Querying CDP from a Mac</title><link href="https://gmarnin.com/network-cdp/" rel="alternate" type="text/html" title="Querying CDP from a Mac" /><published>2016-12-16T00:00:00-05:00</published><updated>2016-12-16T00:00:00-05:00</updated><id>https://gmarnin.com/network-cdp</id><content type="html" xml:base="https://gmarnin.com/network-cdp/">&lt;p&gt;As part of our network security plan, we manage all the ethernet ports in the spaces that we support. We have some long-standing policies around ethernet ports such as only allowing managed desktops access, binding the MAC address to the port and disabling ports not in use. These policies address various issues such as only allowing authorized devices on our network, preventing desktops from being moving around and preventing unauthorized devices from being connected on our network. Desktops have their Wi-Fi interface &lt;a href=&quot;https://github.com/gmarnin/Profiles/blob/master/Disable-Wifi-1.0.mobileconfig&quot;&gt;disabled via a configuration profile&lt;/a&gt; installed via a &lt;a href=&quot;https://github.com/munki/munki/wiki/Conditional-Items&quot;&gt;Munki Conditional Item&lt;/a&gt;. Mobile devices can remote into our network via vpn but ethernet is off limits.&lt;/p&gt;

&lt;p&gt;The practical impact of these policies is that everytime we setup a new desktop or move devices around we have to configure or reconfigure the ethernet ports too. We have several expensive &lt;a href=&quot;http://www.flukenetworks.com&quot;&gt;Fluke&lt;/a&gt; devices to query our Cisco switches for &lt;a href=&quot;http://www.cisco.com/c/en/us/td/docs/ios/12_2/configfun/configuration/guide/ffun_c/fcf015.html&quot;&gt;Cisco Discovery Protocol aka CDP&lt;/a&gt;
which provides the info needed by the networking team. Using the Fluke method works well but has some annoying downsides. Namely, you have to remember to take the Fluke with you when doing fieldwork. We support offices all over town and if you forget the Fluke while across town the job is over before it begins. Worse, sometimes the Flukes don’t get returned to their shelf when not in use, get left on desk in someone’s office or are all in use when I need one. Dead batteries happen too. These are all are common scenarios that are very inconvenient when work has to get done.&lt;/p&gt;

&lt;p&gt;Of course, using the Fluke isn’t the only way to query Cisco switches for the relevant information. While researching alternate methods, I found &lt;a href=&quot;http://www.computernetworkbasics.com/whichswitch/&quot;&gt;whichSwitch&lt;/a&gt; which is an gui application that displays CDP information. It works great but has to be installed on every Mac and only runs via the gui. whichSwitch uses &lt;a href=&quot;https://www.wireshark.org/docs/man-pages/tshark.html&quot;&gt;tshark&lt;/a&gt;, a terminal based version of Wireshark, to grab CDP.  &lt;a href=&quot;https://wiki.wireshark.org/CDP&quot;&gt;tshark can be used&lt;/a&gt; without whichSwitch but it’s a dependency that I don’t want to manage. The installations can all be automated but is not ideal for my use case. Too much work.&lt;/p&gt;

&lt;p&gt;There is a better way. We can capture CDP information without a Fluke, gui app or third party dependencies. I’m not the first person on to post this command but I sure do use it enough to warrant posting it again. A carefully crafted tcpdump command can do it:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/sbin/tcpdump -nn -v -i en0 -s 1500 -c 1 'ether[20:2] == 0x2000'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To understand what’s going on with all those switches:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;tcpdump&lt;/code&gt; - Dump the traffic on a network&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-nn&lt;/code&gt;- Don’t convert any addresses&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-v&lt;/code&gt; - Verbose output&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-i&lt;/code&gt; - Interface name&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-s&lt;/code&gt; - Capture 1500 bytes of data from each packet rather than the default of 65535 bytes. Less data = faster run.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-c&lt;/code&gt; - Count 1 packet (in this case) and exit&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ether[20:2] == 0x2000&lt;/code&gt; Check bytes 20 and 21 from the start of the ethernet header for a value of 2000 (hex)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have posted my &lt;a href=&quot;https://github.com/gmarnin/Mac-Scripts/blob/master/switch_script.sh&quot;&gt;CDP switch script&lt;/a&gt; for all to use. Along with the above tcpdump command, the script also finds the MAC, IP and link speed for the active ethernet interface. CDP can show some interesting information not easily natively obtainable from the Mac which could come in handy when troubleshooting or documenting your network setup. Examples are which switch port the Mac is plugged into and the vlan the Mac is on. The name of the switch, ip address and physical location are also available. The switch model and duplex setting are returned but are not shown in my script output. I simply don’t need that information. To view the raw CDP information returned run &lt;code class=&quot;highlighter-rouge&quot;&gt;cat /tmp/network.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sample output from the script:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ sudo /Library/ITS/switch_script.sh
Password:

If the Ethernet interface is active, this script can take up to 30 seconds to run.
Still beats using a Fluke in the field. Please be patient.

tcpdump: listening on en0, link-type EN10MB (Ethernet), capture size 1500 bytes
1 packet captured
1495 packets received by filter
0 packets dropped by kernel

Mac Results:
Computer Name: mac02.domain.com
Mac IP (en0) = 172.X.X.X
Mac, MAC Address = 68:5b:35:XX:XX:XX
Link Speed: 1000baseT

Switch Results:
Switch Port = GigabitEthernet1/0/32
Vlan = 120
Switch Location = Basement-Building-3
Switch Name = b01-foo-bar
Switch IP = 172.X.X.X
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The main advantage is I never forget the script. I always know where it is. If I need to run the script again, I don’t have to visit the port in question. I can remote into the Mac and run it. I can then copy the results and send it off to networking. Bonus points for not having any hardware or software dependencies.&lt;/p&gt;

&lt;p&gt;In some cases, usually to further network security, CDP might be turned off on the port you are querying. An indication of this is if the script doesn’t return any results after 60 seconds.&lt;/p&gt;

&lt;p&gt;I hope our Flukes don’t get offended.&lt;/p&gt;</content><author><name>gmarnin</name></author><category term="cisco" /><category term="cdp" /><category term="network" /><summary type="html">I have a Fluke but</summary></entry><entry><title type="html">When AutoPkg Meets a Munki Catalog Error</title><link href="https://gmarnin.com/autopkg-munki-import-error/" rel="alternate" type="text/html" title="When AutoPkg Meets a Munki Catalog Error" /><published>2016-12-06T00:00:00-05:00</published><updated>2016-12-06T00:00:00-05:00</updated><id>https://gmarnin.com/autopkg-munki-import-error</id><content type="html" xml:base="https://gmarnin.com/autopkg-munki-import-error/">&lt;p&gt;I auto run a list of 25 or so &lt;a href=&quot;https://github.com/autopkg/autopkg&quot;&gt;AutoPkg&lt;/a&gt; recipes twice a day and, if the run finds an update or throws any errors, I have the results emailed to me for review.&lt;/p&gt;

&lt;p&gt;I recently updated to AutoPkg 1.0.0. The major feature of 1.0.0 is the &lt;a href=&quot;https://github.com/autopkg/autopkg/wiki/AutoPkg-and-recipe-parent-trust-info&quot;&gt;Parent Trust Info&lt;/a&gt;  which alerts you to changes made in a parent recipes. I set this up by running &lt;code class=&quot;highlighter-rouge&quot;&gt;autopkg update-trust-info&lt;/code&gt; against all my recipe overrides. Then I checked all the recipe overrides with &lt;code class=&quot;highlighter-rouge&quot;&gt;autopkg verify-trust-info&lt;/code&gt; which came back with &lt;code class=&quot;highlighter-rouge&quot;&gt;OK&lt;/code&gt; for each override. I then ran my recipe list and I got this error for every recipe:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Error Domain=NSCocoaErrorDomain Code=3840 &quot;Encountered unexpected EOF&quot; UserInfo={NSDebugDescription=Encountered unexpected EOF,
kCFPropertyListOldStyleParsingError=Error Domain=NSCocoaErrorDomain Code=3840 &quot;Malformed data byte group at line 1; invalid hex&quot;
UserInfo={NSDebugDescription=Malformed data byte group at line 1; invalid hex}}
Failed.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;At first I thought I had an AutoPkg trust error because that is all that changed in AutoPkg. To rule out AutoPkg 1.0.0, I downgraded to AutoPkg 0.6.1 and ran my recipe list again. Same error.&lt;/p&gt;

&lt;p&gt;I then tested a recipe I never used before: Zoom.munki. I made an override for it, like I do with all my recipes but sans the parent trust info, and ran it:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;The following recipes failed:
    Zoom.munki
        Error in local.munki.Zoom: Processor: MunkiImporter: Error: Error Domain=NSCocoaErrorDomain Code=3840 &quot;Encountered unexpected EOF&quot; UserInfo={NSDebugDescription=Encountered unexpected EOF, kCFPropertyListOldStyleParsingError=Error Domain=NSCocoaErrorDomain Code=3840 &quot;Malformed data byte group at line 1; invalid hex&quot; UserInfo={NSDebugDescription=Malformed data byte group at line 1; invalid hex}}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Not exactly the same error as before. After closer inspection, it’s the MunkiImporter Processor that’s at fault. I haven’t made any recent changes that would cause MunkiImporter Processor to balk so what is going here? I wasn’t sure so I asked &lt;a href=&quot;https://twitter.com/gregneagle&quot;&gt;Greg&lt;/a&gt; who suspected that I have an invalid plist somewhere in my munki repo. He was right:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;plutil -lint /Volumes/server/munki/catalogs/*&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/Volumes/macupdates/munki/catalogs/all: Encountered unexpected EOF&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That surprised me. Not sure how that happen but the fix is an easy one: Run &lt;code class=&quot;highlighter-rouge&quot;&gt;makecatalogs&lt;/code&gt; which came back clean. I ran my recipe list again and everything was normal.&lt;/p&gt;

&lt;p&gt;Curious, I checked for client errors in &lt;a href=&quot;https://github.com/munkireport/munkireport-php&quot;&gt;munkireport-php&lt;/a&gt; to see how many of my Macs where failing because of this catalog error. Zero. Why? Clients don’t use the &lt;code class=&quot;highlighter-rouge&quot;&gt;all&lt;/code&gt; catalog as &lt;a href=&quot;https://github.com/munki/munki/wiki/Using-Munki-Catalogs#catalog-naming&quot;&gt;documented on the Munki wiki&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lesson learned.&lt;/p&gt;</content><author><name>gmarnin</name></author><category term="munki" /><category term="autopkg" /><summary type="html">Munki catalog error caused autopkg munkimport processor error</summary></entry><entry><title type="html">Welcome to gmarnin’s Blog</title><link href="https://gmarnin.com/hello/" rel="alternate" type="text/html" title="Welcome to gmarnin's Blog" /><published>2016-12-05T00:00:00-05:00</published><updated>2016-12-05T00:00:00-05:00</updated><id>https://gmarnin.com/hello</id><content type="html" xml:base="https://gmarnin.com/hello/">&lt;p&gt;Hello World!&lt;/p&gt;</content><author><name>gmarnin</name></author><category term="general" /><summary type="html">Hello, hi and wecome.</summary></entry></feed>