Author: ctangora

A good guy.

Serial Numbers Reprise (this time for hard drives)

Having to hack away at a strange request, getting the serial numbers for the hard drives installed on a system.

First, for the shell script for the Macs (tested on 10.8 and 10.9).
ioreg -c IOAHCIBlockStorageDevice | grep "Device Characteristics" | awk -F "Serial Number\"" '{print $2}' | awk -F "\"" '{print $2}'

Next for you windows folks, a quick one-two in the powershell.
wmic path win32_diskdrive get SerialNumber

’till next time.

Clearing Font Caches

Wrote up a handy script to clear all the font caches for the Mac OS, Adobe, MIcrosoft Office and Apple iWorks.

I am using this in Casper, so I have it running as root and having a reboot happen after.  If you are going to run this on your own, you may want to put a root check in there and make sure to reboot after.

#!/bin/bash
## Author: C. Tangora
## Purpose: Remove Font Cache from Adobe, Microsoft, iWork and Mac OS.
## If run outside of Casper, be sure to be root & reboot after.

## Adobe Font Caches are stored in the User's Libraries, and will have "Fnt" in the name and end in ".lst".
echo "Removing Adobe Font Caches (Lists)"
find -x /Users -mindepth 5 -type f -iname *Fnt*.lst -delete
sleep 1

## Next it will remove the font caches from Microsoft Office.
echo "Removing Office Font Caches"
find -x /Users -mindepth 7 -type f -name *Office\ Font\ Cache* -delete
sleep 1

## iWorks is next on the chopping block
echo "Removing iWork Font Caches"
find -x /Users -type f -name com.apple.iwork.fonts -delete
sleep 1

## Next we will restart the Apple Type Server.
# This is the one we want to make sure we reboot (or at least logout) to restart.
echo "Removing OS Font Caches"
atsutil databases -remove
sleep 1

echo "Restarting Apple Type Service Server"
atsutil server -shutdown
atsutil server -ping
sleep 1
echo "Completed Font Clearing."
echo "Please restart ASAP."

exit 0
’till next time

Fastest ways to get a Mac’s serial number from the command line

Getting a Mac’s serial number is often a task that is prelude to other work in a shell script. I was toying around with a script and noticed that it was taking longer than I liked on the client machines, but really fast on my machine. Looking around the web I found a great page that listed the times it took another person to query for the Serial Number, on jaharmi.com. It made me stop and do some time test for myself.

I started timing each component to track down the culprit. Turns out the serial number logic was taking over  a second to run to run the first time it was called, but then was dropping dramatically on consecutive calls. I decided to do some time test myself, first to see if Jaharmi’s post was still relevant (it was from 2008) and second to see if I couldn’t tweak it further to gain a few more fractions of a second improvement.

First was what the script had at first, using system_profile. When I tested just using system_profile I found that the first run of the script would take over 1 second on my Mid-2010 MacBook Pro. The next few times I ran it the time dropped from 1.722 seconds down to as low as 0.226 seconds.  The trimmed mean for running it five times was 0.227 seconds.

system_profiler SPHardwareDataType | grep "Serial Number" | awk '{ print $4; }'

Next I took the ioreg approach, first off what Jaharmi had posted…

ioreg -l | awk '/IOPlatformSerialNumber/ { split($0, line, "\""); printf("%s\n", line[4]); }'

But this took even longer!  The trimmed mean time for this was 0.470 seconds.  That would definitely not do.  However, I still felt that ioreg should return a better time than system_profiler, something in my gut told me that.  So I took a closer look at the script and modified it to return a smaller data set before sorting it.

ioreg -c IOPlatformExpertDevice -d 2 | awk '/IOPlatformSerialNumber/ { split($0, line, "\""); printf("%s\n", line[4]); }'

Now we’re cooking.  This returned a trimmed mean time of 0.007 seconds. I tried tweaking it a bit more with a different sorting logic to see if this could be dropped even further. But alas, it didn’t really make much of a difference when dealing with thousandth’s of a second. I ended up using this code…

ioreg -c IOPlatformExpertDevice -d 2 | grep SerialNumber | awk -F "\"" '{print $4}'

… as it required less code to get the same speed result. I’m now adding this to my useful unix file for future reference.

’till next time

Can a Mac run 10.9 or 10.8

Casper Extension Attributes (BASH Shell Scripts) to know if a Mac can be downgraded.

This is something that came up when we were forced to do downgrades to Macs coming in the Mavericks, since the 10.9 image wasn’t officially tested yet we could not release it to the wild. Some machines were okay, some were not. While the immediate need for this has passed, I did write this up so I could modify it for the next OS. These are not 100% accurate, as Apple changes the contents of a model and will not increment the model number (they did this with Mavericks and the MBP’s recently).

But this gives us a starting point.  Both for finding out what machines can run the OS, and for what machines can not.

To update the list (for 10.10 or X2 or 11.00) you will have to use MacTracker or something similar to find the minimal specs for the OS, then get the model number for each, replacing the minimum value in each.  I then took the a look through each model and found the model number that shipped with 10.9 and marked the one under that as the last version of the model that would run the older OS.

Extension Attribute to Check for Mavericks (10.9) Compatibility

#!/bin/bash

## Checks to see if Machine is compatible with Mac OS 10.9

hw_model=`sysctl hw.model | awk '{ print $2 }'`

mod_name=`echo $hw_model | tr -cd [[:alpha:]]`
mod_majver=`echo $hw_model | awk -F "," '{ print $1 }' | tr -cd [[:digit:]]`
mod_minver=`echo $hw_model | awk -F "," '{ print $2 }'`


## Find Machine And Report Back

case "$mod_name" in 
 iMac* )
 if [[ $mod_majver -ge 7 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 MacBookPro* )
 if [[ $mod_majver -ge 5 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 Xserve* )
 if [[ $mod_majver -ge 3 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 MacBookAir* )
 if [[ $mod_majver -ge 2 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 Macmini* )
 if [[ $mod_majver -ge 3 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 MacPro* )
 if [[ $mod_majver -ge 3 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 MacBook* )
 if [[ $mod_majver -ge 5 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 * )
 echo "<result>Error</result>"
 ;;
esac

exit 0

Extension Attribute for testing Mt. Lion (10.8) compatibility.

#!/bin/bash

## Checks to see if Machine is compatible with Mac OS 10.8
hw_model=`sysctl hw.model | awk '{ print $2 }'`

mod_name=`echo $hw_model | tr -cd [[:alpha:]]`
mod_majver=`echo $hw_model | awk -F "," '{ print $1 }' | tr -cd [[:digit:]]`
mod_minver=`echo $hw_model | awk -F "," '{ print $2 }'`

## Find Machine And Report Back
case "$mod_name" in 
 iMac* )
 echo "iMac"
 if [[ $mod_majver -ge 7 ]] && [[ $mod_majver -lt 15 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 MacBookPro* )
 echo "MBP"
 if [[ $mod_majver -ge 5 ]] && [[ $mod_majver -lt 11 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 Xserve* )
 echo "XS"
 if [[ $mod_majver -ge 3 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 MacBookAir* )
 echo "MBA"
 if [[ $mod_majver -ge 2 ]] && [[ $mod_majver -lt 7 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 Macmini* )
 echo "Mm"
 if [[ $mod_majver -ge 3 ]] && [[ $mod_majver -lt 7 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 MacPro* )
 echo "MP"
 if [[ $mod_majver -ge 3 ]] && [[ $mod_majver -lt 6 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi
 ;;
 MacBook* )
 echo "MB"
 if [[ $mod_majver -ge 5 ]]; then
 echo "<result>Compatible</result>"
 else
 echo "<result>Not Compatible</result>"
 fi

 ;;
 * )
 echo "<result>Error</result>"
 ;;
esac
exit 0

’till next time.

Turn off Wi-Fi via shell script

Need to send a Shell Script to disable the wi-fi network?  No problem!  Have multiple types of machines that may have different device ID’s for the wi-fi?  No problem!

#!/bin/bash

# By Chris
## This will send a power-down to the Wi-Fi Device.
## Tested on 10.8.2 with single Wi-Fi device/hardware.

## First we get the Wi-Fi device name.  We are not assuming it is en1.
# We do this by listing all the hardware on the device, then only showing the line of and immediately following "Wi-Fi".
# Then do a quick second grep to only show the line of the Wi-Fi setting with the "Device" tag.
# We then cut out the first part of the entries and keep with is on the right side (of the ":".
# And finaly we strip out the extra space (to be neat).

WiFiDev="`networksetup -listallhardwareports | grep -A 1 "Wi-Fi" | grep -C 0 "Device" | cut -d ":" -f 2 | tr -d " "`"

# echo $WiFiDev

## Now turn it off.

networksetup -setairportpower $WiFiDev off

echo "Turning off the port at $WiFiDev"

exit 0
till next time

Set Proxy on all available network services

When you want to set the proxy on all available network services (say with JAMF’s Casper Suite at imaging time?)

#!/bin/bash

## A few variables we'll need for later

ProxyURL=http\:\/\/foo\/bar\.pac
declare -a NetServs

# Dealing with IFS as we need to alter it to avoid space issues.
OrigIFS=$IFS
IFS=$'\n'

#Define what Network Services are available.
NetServs=( `networksetup -listallnetworkservices | cut -d "." -f 2-` )

# Go through each network service and set the autoproxy.

for NetServ in ${NetServs[*]}; do
networksetup -setautoproxyurl "$NetServ" $ProxyURL
echo "$NetServ" is now set to use the proxy at $ProxyURL
done

exit 0

Enjoy.

till next time

Googled in any search engine

We all get cold sales calls. I just got one for a ‘major’ networking opportunity. I was willing to listen and go along with their sales pitch until this line…

"You will be able to be Googled in any major search engine."

If you are going to be calling up a techie, you should be a bit more aware of what you are saying. Yes, she most likely meant searched in any major search engine. But that’s not what she said. It was at that point that I knew I was not going to be giving that company any of my money.

It’s Friday, let us go rejoice.

Till next time.

What version is my Mac OS X installer?

One of the things that I do for Mac imaging is use InstaDMG to make my master image.  Part of the InstaDMG imaging process requires the build version of the installer OS to match a specified key in the catalog.  I figured out where this was, months ago, but as time has passed I forgot it.

Luckily, I didn’t need to use it for a while.  But now I do.  We’re having to go to Lion for a few months to get the Mac Book Airs out the door.  I can’t put an unsupported OS on a production machine.  So, we’ll brave new waters for a few months and try to keep that momentum up for a quick adoption to Mountain Lion.

Anyways!  Back to the point of this post!!!!

To find out what version of Lion your installer is (for use with InstaDMG), simply mount the InstallESD.dmg, and open

MacOSXInstallESD/System/Library/CoreServices/SystemVersion.plist.

Now look at the value for ProductBuildVersion.  That is your version number.

I’m posting this, so if I ever need it again, I know where to look.  Thanks to Allister on AFP548.com’s InstaDMG forum for pointing this one out!

Till next time.
Printers are from hell

Setting Default Printer in Windows 7 with GPO (and a VB Script)

Printers are from hell

Sometimes Printers Just Print What They Want, Where They Want, When They Want

Previously I mentioned using the “Deployed Printers” of GPO’s to push printers to lab machines.  This works great so far but doesn’t solve one problem, the default printer.

While there are lots of options for how to set a default printer, we have the AD architecture to be able to have each lab/area have a specific GPO.   We also have a GPO that covers all the areas.  The higher GPO installs a script (I called it AssignDefaultPrinter-Arguement.vbs) into our standard script location.  This script can be called upon to set a printer as default dynamically.  Here’s the script, before we discuss more.

'  Script to set default printer via passed argument.
'
'  Taken from http://www.computerperformance.co.uk/ezine/ezine17.htm
'  Modified by C. Tangora to have a printer passed as an argument.
' 

Option Explicit
Dim objPrinter
Dim objArgs

WScript.Sleep 1000

Set objArgs = Wscript.Arguments
Set objPrinter = CreateObject("WScript.Network")
objPrinter.SetDefaultPrinter objArgs(0)
WScript.Quit

The script can then be called on individual logon scripts (administered by the GPO for the specific area), without the need to specialize each script.  Since the script is in the same location for all machines, you just call the script and pass the printer you want to have as the default as the argument.  I would suggest using the quotation marks around the argument, as the arguments are separated by spaces.

A test run of this would be for a printer that was setup via the deployed printers, //printserver/LAB100A Color is the server and name of the printer.  To get it to be the default we run ….

AssignDefaultPrinter-Argument.vbs "//printserver/LAB100A Color"

… and in a few seconds (I built in some time to wait for printers to get in place in case they aren’t), the default printer gets assigned.

There may be other ways to skin this cat, and the code could be a bit cleaner, but I am not a big VBScripter, I’m a BASH kind of guy.  If I decided to forgo my UNiX love and dive deeper into Microsoft scripting, I promise to come back and make this cleaner.

Till next time.