the sad macs club

an ex-Genius' adventures in IT, code, and the Twin Cities

Today has been a bit long, so I decided to put down into writing how I configured NoMAD to utilize its File Share menu feature because I found their documentation to be distinctly lacking in that space.

First, Some Background

We have been in the process of upgrading our previous SMB file share from a macOS Server running 10.12.5 using Open Directory for access control to a new Windows 2016 server utilizing Active Directory.

Active Directory would allow us to have centralized control for accessing these shares, but with a directory service that was going to continue to be supported for the future. We hadn't been using it before so all accounts are new. I also had no intention of binding our Macs to AD as my prior experiences with that have been... not great.

Since all the accounts were new I would have to either personally sit down with each employee and reset their new AD password or set up NoMAD to facilitate those changes. Because I am lazy efficient, I decided to go with setting up NoMAD so I could turn on the option to change passwords after next login.

I was vaguely aware of the file share capabilities, but I intended to research the share mounting features later since we were on a time crunch.

Our previous method for accessing our file shares on our Macs was a folder dock item that listed out a list of Automator apps that ran an Applescript that would run something similar to the following:

set shareName to "<change-me>"
    
    tell application "Finder"
        if (disk shareName exists) then
            (*Do Nothing*)
        else
            try
                mount volume "smb://serverIP/" & shareName & quote
            on error
                (*Do Nothing*)
            end try
        end if
        do shell script "open \"/Volumes/" & shareName & quote
    end tell

It was a little hacky, but it worked. I decided to replicate it for this file server to make it a seamless transition that hopefully no one really noticed other than the fact that I used a slightly different icon for the dock item.

I got NoMAD working based off their support docs, plugging in our AD info. I was able to login and change my password successfully without issue.

Then I tried to access a file share.

The first thing that I noticed is that my script didn't use Kerberos ticket supplied by NoMAD. The script also worked maybe 50% of the time. My Mac seemed to be passing the Guest account despite me choosing registered user and entering the correct password. The guest account would be rejected due to security, but my AD account would be accepted. My Mac decided to see the first rejection and decide that it didn't work.

I also found out that due to Transparency Consent and Control in macOS, as I upgraded employees to newer versions of macOS they'd have to grant permission to allow the Applescript to run and that wasn't a good solution going forward. Using NoMAD to handle this would resolve that issue without creating a bunch of future work for myself trying to get our current system to work inside TCC.

After many hours of hard work I finally got it working and I wanted to share my process for others to be able to find when they Google, “How to Set Up NoMAD Shares Menu.”

Guide: How to Set Up NoMAD Shares Menu

After a description fit for a recipe blog, here is the process I went through to set it up. This document assumes that NoMAD is already running in your environment. The NoMAD Kbase is a great resource for this.

First thing that isn't mentioned in the documents is to set the key MenuFileServers in the NoMAD preference file. It is described on the NoMAD Kbase article Preferences and What They Do as “Changes the menu text of the File Servers menu.” But what I found is that it was required to actually get the menu item to appear in NoMAD. Your key will be added to your preference file like so:

<key>MenuFileServers</key>
<string>Company File Share</string>

After that the setup becomes more straight forward. To test this quickly, create the file ~/Library/Preferences/menu.nomad.shares.plist in XML format using either the example provided as the base in a text editor or using ProfileCreator to create a configuration profile to test.

As you make changes make sure to run killAll cfprefsd and then quit and relaunch NoMAD to see those reflected. Incidentally, this is also a great way to test if the LaunchAgent is working.

I used a text editor to create mine.

Here is an example file (NOTE: My environment doesn't utilize the AD home folders so I don't have a mention of that, but based on the documentation, it's pretty similar.):

<?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>Shares</key>
        <array>
            <dict>
                <key>AutoMount</key>
                <false/>
                <key>ConnectedOnly</key>
                <true/>
                <key>Groups</key>
                <array/>
                <key>Name</key>
                <string>File Share</string>
                <key>Options</key>
                <array/>
                <key>URL</key>
                <string>smb://server.domain/fileshare</string>
            </dict>
        </array>
        <key>Version</key>
        <string>1</string>
    </dict>
</plist>

In our environment it makes more sense for the time being to not auto-mount the drives so I set that to false. One thing to note is these drives do appear for everyone and you must make references to each share that's on your network. My XML file contains roughly 24 different shares.

Groups don't need to be declared unless you plan to use AutoMount. So even if AutoMount is set to true it won't mount unless there is also a list of groups who may AutoMount the drive and the user is in said group. This is also true of the ConnectedOnly key, it's set to true, but requires the groups to be declared to be used. I kept this as true because if we do move to AutoMount in the future, I don't want NoMAD to attempt this if someone isn't connected to the network.

Also note that if you have nested groups in your AD that have access to shares you will also need to add the key RecursiveGroupLookup as true to your NoMAD preferences as well.

For me it looks like this:

<key>RecursiveGroupLookup</key>
<string>1</string>

Depending on the size of your Active Directory, this can require a lot more processing power to use, but because the app runs constantly, it shouldn't generally be noticeable.

But that's really all there is to it! You should have a working file share menu in your NoMAD. I distributed the plist as a configuration profile in Jamf that using Custom Settings, effecting the Preference Domain menu.nomad.shares.

I hope this guide was helpful, if you have feedback you can find me on the MacAdmins Slack as @PaperFixie.

A Simple Python Script for Naming Macs

I recently have been working at my new job to learn as many ways as possible to automate our current setup.

One thing that I took a day or so to work on was finding a way to automate our naming conventions.

The following script is still in development, hasn't been tested on any machines other than verifying that the output worked as intended. It is intended to be run by JAMF, so it will run as root.

import subprocess
import sys
import os
from SystemConfiguration import SCDynamicStoreCopyConsoleUser

# dictionary matching our model naming schemes for Macs to their model identifiers

model_id_dict = {'15MBP': ['MacBookPro15,1', 'MacBookPro14,3', 'MacBookPro13,3',
                          'MacBookPro11,4', 'MacBookPro11,5', 'MacBookPro11,2', 
                          'MacBookPro11,3', 'MacBookPro10,1', 'MacBookPro9,1'],
                '13MBP': ['MacBookPro15,2', 'MacBookPro14,2', 'MacBookPro14,1',
                          'MacBookPro13,2', 'MacBookPro13,1', 'MacBookPro12,1',
                          'MacBookPro11,1', 'MacBookPro10,2', 'MacBookPro9,2'],
                '27iMac': ['iMac18,3', 'iMac15,1', 'iMac17,1', 'iMac15,1', 
                           'iMac14,2', 'iMac13,2', 'iMac12,2', 'iMac11,3'],
                '21iMac': ['iMac18,1', 'iMac18,2', 'iMac16,1', 'iMac16,2',
                           'iMac14,4', 'iMac14,1', 'iMac13,1', 'iMac12,1',
                           'iMac11,2']}

# variable for to store results of model id bash command
fetch_model_id = subprocess.check_output(['sysctl','hw.model'])
search_model_id = fetch_model_id.strip('hw.model:').strip('\n').strip()
model_name = ''

# reverse dictionary lookup to set model name based on model id
for name, model_id in model_id_dict.items():
    if search_model_id in model_id:
        model_name = name
        break
    else:
        model_name = 'Mini'

def get_console_user():
    '''Uses Apple's SystemConfiguration framework to get the current
    console user'''
    cfuser = SCDynamicStoreCopyConsoleUser(None, None, None)
    return cfuser[0]


console_user = get_console_user()
user_real_name = subprocess.check_output(['id','-F', console_user])
computer_name = ''.join(user_real_name.split()) + '-' + model_name


def set_computer_name(cname):
    '''function to set hostname, localhost, and computer name
    to the same value and flush the cache'''
    commands = ['HostName', 'LocalHostName', 'ComputerName']
    for name_type in commands:
        subprocess.call(['scutil', '--set', name_type, cname])
    subprocess.call(['dscacheutil', '-flushcache'])


if user_real_name == 'Local Administrator':
    sys.exit(0)
else:
    set_computer_name(computer_name)

check_computer_name = subprocess.check_output(['scutil', '--get', 'ComputerName'])
if check_computer_name == computer_name:
    sys.exit(0)

Our naming scheme prior to this script has been a manual affair: modify the Mac's name on JAMF Pro to fit the format of {Firstname}{Lastname}-{Model} This is not something that's easily automated since the abbreviated model names weren't something used by Apple.

What I had to do was go to Apple's website and manually transcribe the model identifiers into a dictionary in Python. I used subprocess.check_output() to generate a string and save it to a variable to compare to the dictionary and perform a reverse lookup.

After that lookup it assigns the key as the model_name variable. Then it's cleaned up by stripping out the "hw.model: " string from the output.

To lookup the user who this will be named after, I originally just had it run id -F to find the Full Name attribute of the user, but without realizing that would look up the user running the script.

To resolve that issue, it is possible to run the command with an argument of the username.

id -F [username]

I was referred by another Mac Admin to a function on the Munki GitHub repository that uses Apple's SystemConfiguration framework to get the current console user.

I adapted it into my code, moving the dependencies up to the import lines and renaming the function to follow my naming conventions. The function is used to save the username to a variable. Then it's used by the subprocess.check_output() method to run id -F [username], which then saves a string with the Full Name attribute.

The final name is created by cleaning up the output and appending the hyphen and model name to it:

computer_name = ''.join(user_real_name.split()) + '-' + model_name

I then check to make sure that the logged in user isn't our “Local Administrator” account to prevent improper naming and exit the script. If the logged in user is the end user, it then sets the computer's HostName, LocalHostName, and ComputerName to match the output and flushes the caches.

I'll go through a full test of this soon, but for right now, this was really an exercise in if I could do this with Python and to set the framework for the future.

I hope you enjoyed this little explanation. Follow the development of this script on GitHub if you're interested and feel free to comment if you have ideas on how to improve it.

Cheers!

❤️ -Vince

Greetings from the Twin Cities!

I have started my new job in Minneapolis and I'm adjusting to the time zone changes. But otherwise, I'm doing well!

Once I have a better grip as to what I'll be doing at my new job and getting a feel for it. I'll continue to blog.

For now I'll say this:

Don't change extension attributes on the production server without first knowing what they'll do to your fleet.

Whoops!

-Vince

I'm moving to Minneapolis!

After a long and very emotionally draining search, I have found a new job and will be moving to Minneapolis on September 5th! I'll be working for a small company called Tenenz, Inc. in Bloomington, MN.

I'm really excited for the growth that this will bring, as I will be able to have agency over our infrastructure choices, and help improve processes all around.

I will post progress and new things learned to this blog. I'm excited to check out a new city as well. If you're a friend from Portland, please keep in touch via the Mac Admins Slack, Mastodon (@paperfixie@elekk.xyz), and Instagram (@paperfixie).

If you're in MSP and want to hang out, feel free to contact me as well! I'll be lonely for a couple months while I search for a house and live alone, so I'll be needing to find new peoples.

Nothing new to write about tech wise this week, it's been really busy at home. I'll try to update later this week when it's a little less stressful.

Cheers! -Vince

The Beginnings of a Conference Talk

I am not one to generally want to get up and speak in front of others. Claiming to be an expert on something is hard for me, as I have a background in the arts.

Being an artist, you tend to worry deeply that people are going to see your work, not like it and see you for the fraud you really are. I know imposter syndrome exists in all walks of life, but I feel like it's especially a pervasive sentiment in the arts. We want to show things off that we're proud of, but if you're too loud, you'll get called out for being full of yourself, bragging, or whatever negative name you're thinking in your head whenever you press send on that post.

I'll leave imposter syndrome for another post for now, but just know I'm not one to generally say, “Yes, I would like to talk to people about a focused subject for 75 minutes!” But that was about to change when I went to Seattle for a Mac Admins meet up. I was speaking to another admin, a very nice metalhead named Jesse (as an aside I've never met a metalhead dude who wasn't the sweetest teddy bear person in the world) and we got to talking after a few drinks about subjects for Mac Admins conferences.

I mentioned how I would never be able to give a talk like the ones he's working on. I'm not a highly technical person. I like to think of myself as smart, but at the end of the day, I'm still just a guy who got the smartest job at an Apple Retail store who couldn't sling two lines of code together into something useful.

Jesse brought up that he would much rather listen to a talk about developing “soft skills” like the ones I learned at Apple. He encouraged me to put together a talk. I've been mulling it over ever since. After learning a bit more about the process from another admin on Slack, I'm jumping in!

First, some background about me to fill in why I think I can put together an insightful talk on applying Genius skills to the world of IT support. I started working for Apple as a Specialist (retail sales associate) in 2009 a few months after graduating college. During that time I did sales, but also learned how to teach training sessions for teaching how to use Macs or various iLife and iWork apps. After the launch of the iPhone 4, I transitioned to what was then called Family Room Specialist (what is now known more simply as Technical Specialist), which shifted my focus from sales to mobile device support (iPhone, iPod, and, later, iPad after it launched) as well as continuing to do training sessions. After around three years in that role I was promoted to Genius where I became Mac certified and stayed in that role for 4 years until I left for another company to do IT support.

The idea her is that I'll use the blog to throw down some ideas or enumerate on one of the subjects I'll cover in the talk

Today I'll talk about:

Empathy

Empathy and sympathy are often confused. And while there is definitely some overlap, the main tenet of empathy is feeling what a person is feeling whereas sympathy is more akin to acknowledging how someone feels, but not necessarily feeling it at the same time.

Conveying empathy is important to have a good relationship with your customers, be they part of your company or external. Which can in-turn, foster a good relationship with their technology. When they aren't scared to ask questions, they aren't scared of their machines anymore and may even be able to support themselves more one day. On top of that, if your reputation is good, it helps with vertical advancement as well.

What we tried to always convey at Apple was feeling empathetic to the situation. That's a really hard skill to make someone feel like not only do you understand their situation, but that you're walking with them to the solution.

Now truly to get through your day at a retail store, you can't go just feeling all the things that another person is feeling, and true empathy in those situations is impossible, but what Apple is getting at here is validation.

I want you to know that I have understanding of the situation you're in when you come to me for help. I want you to know that it's okay to feel the frustration, anxiety, sadness, or anger you're feeling. I want you to know that I'm here to help and not to be a blocker to overcoming those raw emotions.

More often than not at the Genius Bar, you're not just fixing a person's tech, you're fixing them a little too. I have had to more than once (probably a hundred times after seven plus years) had to tell a person that their hard drive data is gone without a backup. Donezo. Finito. It has become an ex-parrot. This includes, wedding photos, photos of your dead grandmother, photos of your first child, the dissertation you've been writing for two hard fought years, any number of impossible to recreate moments or pieces of information.

It's one of the hardest things to teach, and, really I don't know if it can be truly taught. I and many other Genii have said, I can teach anyone to fix a computer, I can't teach you how to fix a person. But I'll do my best to break it down using the tools Apple gave me, and add in as best I can my take from actually doing this for many years.

Apple's toolbox for empathy is referred to as the Three A's:

  • Acknowledge: Recognize the issue, but not just to yourself but stating it back to your customer (I use customer her because it's easier to slip back into Apple mode that way, also Thomas Limoncelli calls them that in his books, so I feel justified). Do your best to think about a time that you were in a similar situation, this will help feed into the next part as well.

As an example:

“I see that you're having an issue with your hard drive, I'm sorry to see that.”

Be careful as that sometimes reads as sympathy, keep track of your tone as best you can.

  • Align: Alignment is a bit weird, but really comes down to making sure that the customer sees you as being on their side while also validating their feelings. It helps to sit or stand next to them and not across from them or with a barrier between the two of you.

To further our example:

“I see you're having an issue with your hard drive, I'm sorry to see that. I know if must be frustrating to have to deal with this kind of issue with a device we rely on.”

I will mention, it's hard to come up with these on the fly while typing and I'm using muscle memory to write them. I'll solicit feedback from other ex-Genii to get a better example. Either way, monitor your tone to make sure you aren't slipping into a pattern of speech, this can read as insincerity.

  • Assure: Assurance is really just that, letting your customer know that they are going to be taken care of. This also helps you further ingratiate yourself as being on the same team against this issue, rather than you standing as a blocker between the customer and their work.

And finally to complete the example:

“I see you're having an issue with your hard drive, I'm sorry to see that. I know if must be frustrating to have to deal with this kind of issue with a device we rely on. If it's okay with you, I'm going to run some tests and I'm sure we can find out what's going on and how we can fix it.”

It's important to bring the customer along with you on this journey using inclusive pronouns like “we” as well as to always talk about the device having the issue, and make sure that the user doesn't see it as something they did.

This is just a start to any number of techniques for empathy to be conveyed, but this is just a start for this talk and I will dive into more depth when I've had some more time to sit and think about this.

But I hope this at least gets you started in your journey towards a more welcoming IT team.

Later!

-Vince

Welcome to The Sad Macs Club.

The club has one member, me. My name is Vince. I like to fix Macs and play with technology I don't understand. I also play games and sometimes draw.

This blog is going to be for ramblings on Mac IT, learning to code, and showcase some DIY electronics projects. I've been playing around with open source hardware in an effort to find a creative outlet that has a technical side to it.

This is mostly an initial post to get things started beyond a blank page, so keep an eye out for more!

print('Hello world!')