Mountain Lion InstallESD?

Matt
Valued Contributor

Hey all what is the recommended way of using the InstallESD (in order to get recovery partition)?

1 ACCEPTED SOLUTION

Matt
Valued Contributor

InstallESD is actually now working for me with 8.62 installed.

View solution in original post

25 REPLIES 25

Matt
Valued Contributor

Let me add, I did a composed OS only and it drops the OS image down but refuses to install the PKG's. I am also getting Nilobject errors frequently from both 10.7 and 10.8 Netboot with just Mountain Lion images. I compiled the entire image in Casper Admin and it works fine. Just seems like a PITA!!!

jwojda
Valued Contributor II

I compiled mine using ML's install ESD & Casper 8.6 w/o any extra apps, just the esd.

Matt
Valued Contributor

I am having all sorts of issues. I can't compile InstallESD and on my netboot servers I keep getting freaking NilObjects errors or just random crashing. This all started as soon as we moved to 8.6.

yr_joelbruner
New Contributor III

Well I can recommend a script I made that will combine the Install OS X (Mountain) Lion.app and the RecoveryHDUpdate from Apple, to make a self contained DMG with a that can then create a Recovery Partition.

It's on this page:
http://www.brunerd.com/blog/software/

The original post detailing it:
http://www.brunerd.com/blog/2012/03/21/update-create-lion-recoveryhd-partition-quickly-without-reins.../

Matt
Valued Contributor

I did the compile InstallESD the same way I did on Lion and it just refuses to work. Frustration.

ryanatkisson
New Contributor

Matt,

Did you ever figure out how to create a working 10.8 installer? I'm in the same boat.

Matt
Valued Contributor

No I had to do a Compile, extract the compiled image, add it to a configuration, and then add a script to add the recovery partition post install.

nkalister
Valued Contributor

here's how i do it:

  1. upload your installESD.dmg file with Casper Admin
  2. tell casper admin to mark the ESD file as an OS installer
  3. add the ESD file to your configuration

That's it. When casper imaging runs the OS installation, it'll run through the recovery HD creation just like normal. All your machines will have a recovery HD with the correct drivers for their hardware.

jhbush
Valued Contributor II

I've also started using FileWave Lightning for this. It's way easier than uploading to your JSS and doing a compile and then doing another add. Here's what I do:
1.Add AppStore Installer for 10.8.x and JAVA to Lightning
2.Don't add an admin account
3.Compile locally and upload to JSS
4.Add to workflow to run before reboot
5.Use DU to erase the drive
6.Erase the drive in CI and run

I get an ASR restore of a perfect clean OS with the RP in place and all of my addon get put in place at the reboot.

Matt
Valued Contributor

InstallESD is actually now working for me with 8.62 installed.

Kevin
Contributor II

OK, tell me what I am doing wrong…

I uploaded the most recent Apple installESD.dmg file with Casper Admin.
I checked the box in casper admin to mark the ESD file as an OS installer.
I added the ESD file to a configuration (where that ESD file is the only item)

When I try to use that configuration in Casper Imaging (netbooted and installing on previously erased hd), the installer appears to run, but the only items placed on the hard drive are two folders: install.1023CiyARi and Library.

The Library folder has a red dash through it to denote no access. Obviously, no OS has been installed on the HD.

Has anybody else seen this behavior?
JSS 8.62
Netboot image OS 10.8.2
Casper Imaging 8.62

Kevin
Contributor II

Jason, I downloaded FileWave to try your method.
I added the 10.8.2 Mountain Lion installer.app file to FileWave, as well as the Java installer.
I did not create any accounts.
I created the image set and uploaded the asr.dmg file to the JSS.
The questions:
How did you run this in Casper Imaging?
What does your configuration look like?
Do you have a script to run this that you would share?

Matt
Valued Contributor

I had that issue when I was using netboot as well. I can't confirm if it works now because we have abandoned netboot and replaced it with USB keys.

easyedc
Valued Contributor II

I have had the same issue with the InstallESD installation method as well. Works with no issues when booted off of USB drive, but Netboot fails for various reasons. Working through JAMF and AppleCare for results. So far. Nada. I'd rather not have tons of USB sticks/drives floating around for imaging. Makes me nervous.

acdesigntech
Contributor II

Its for this reason I moved to a thin imaging solution. Works like a charm and preserves the restore partition.

If I need to reimaged I restore an unbooted DMG to the boot partition and do a thin image from there.

pickerin
Contributor II

@acdesigntech, what do you mean by a "thin image"?

I too am unable to Netboot 10.8.3 and create a 10.8.3 image on a new system. Always crashes Casper Imaging with a NilObjectPointer error.

At this point, I think we're just going to abandon Imaging all together, just build "Imaging Packages" and Policies to create everything we want to have done to the systems and lay those down on clean systems. If something really awful happens we'll just Carbon Copy Clone a clean DMG over top of it and start over.

I really wish someone had an answer.

acdesigntech
Contributor II

thin imaging is a method of imaging that leaves the factory installed OS intact, and layers your owns apps and settings on top of it. see here: https://jamfnation.jamfsoftware.com/discussion.html?id=6247 for an example discussion about it.

What I do is this:

  1. netboot a new Mac
  2. automatically runs a script to generate a name for the mac
  3. script installs a launchdaemon onto the new mac boot drive and reboots the mac
  4. launchdaemon installs a quickadd package on startup, and then manually triggers a setup policy in the JSS
  5. policy installs packages and settings, removes the lauchdaemon and restarts the Mac

That's it. If I need to reimage that (or any) mac, my netboot script has a step that requests the action to perform (reimage to 10.8 or do a legacy image to 10.6 using casper imaging). It then does several checks to see if that mac is in the JSS and/or bound to AD. If this is a reimage, it restores an unbooted copy of the boot drive for that mac based on model identifier of that Mac. Then it continues with step 2 - 5 above.

I'm trying to take casper imaging out of the picture. While useful, it adds too much time to the setup process and too many failure points along the way. Thin imaging is an easily repeatable process.

pickerin
Contributor II

@acdesigntech,

Would you be willing to share your launchdaemon from step 2 and then the script you use in the policy for step 5?

This sounds like exactly what I'd like to do, and I'd love to not have to reinvent things. Would be very appreciative.

acdesigntech
Contributor II

Sure. Scripts are at work though, so might be later today.

gachowski
Valued Contributor II

@acdesigntech

Sorry to pile on, but could you share you netboot script too? I am so onboard the the thin image, but couldn't think away around the onsite teams having to re-imaging machines. It sounds like your script will be the answer.

Great idea by the way, none of the people I asked for help had an answer for how to automate re-imaging and thin imaging together!!!

Thank you!!

C

acdesigntech
Contributor II

Sorry this is so late folks, but better late than never I guess. Here it goes (these are still all under testing, btw, so ymmv):

Netboot script:

#!/bin/sh

##  macImage - System Scrubbing and Reimage Tool.  v 5.0
##  Written by AC Andrew Caldwell

#########################################################################
# determine the location of the mac to be partitioned
NETADD=`ifconfig | grep "inet " | grep -v 127.0.0.1 | cut -d  -f2 | awk '{print substr($1,1,6)}'`
case $NETADD in
"@@.@@@"*)
    LOC="SHA"
    SharedVol="Casper Share"
    ;;
"##.###"*)
    LOC="RIP"
    SharedVol="Casper Share"
    ;;
*)
    LOC="CLE"
    SharedVol="CasperShare"
    ;;
esac

fImageChoice2 ()
{
## Set a variable to keep track of the model type entered
ModelTypeCorrect="no"

## Set up a loop to keep asking for a model type until the person enters some form of DT or LT
while [ "$ModelTypeCorrect" == "no" ]; do
    echo "Enter DT if this is a desktop or LT if this is a laptop."
    read modeltype
    echo "$modeltype" > /Library/.modeltype.txt
    ConvertedType=$(tr "[:upper:]" "[:lower:]" < /Library/.modeltype.txt)
    ## check value of $modeltype - desktop or laptop?
    if [ "$ConvertedType" = "lt" ]; then
        ASSETPREFIX=$LOC"ML-"
        ModelTypeCorrect="yes"
    elif [ "$ConvertedType" = "dt" ]; then
        ASSETPREFIX=$LOC"MD-"
        ModelTypeCorrect="yes"
    else
        echo "Incorrect type."
    fi
done


echo "Now running GetNextMacName.app to get the next available Mac Name…" 
open /Applications/GetNextMacName.app
echo "Enter the Next Available Name here: "
read tagnum


# Partition the drive and format based on processor architecture

echo "Creating two partitions: XXXX and Work"
    /usr/sbin/diskUtil partitionDisk disk0 2 GPTFormat HFS+ XXXX 100G HFS+ Work 0b
    echo "Partitioning With GPT Format Complete."
    echo ""
    ## Wait for disks to stop being busy
    sleep 10

# Restore the current Work drive image
 echo "Loading Work Image." 
    sudo asr restore -source /Volumes/CasperShare/DiskImages/WorkFY12MacDAC_20110420.dmg -target /Volumes/Work -noprompt -verbose -erase -format HFS+

 echo "Complete."
 echo ""
    ## Wait for disks to stop being busy again
    sleep 10
    ##  Enables Journaling.
    /usr/sbin/diskUtil enableJournal /Volumes/AGXXXX
   ## rename AGXXXX to $ASSETPREFIX$5
    /usr/sbin/diskutil rename /Volumes/AGXXXX $ASSETPREFIX$tagnum
    ##/usr/sbin/diskutil rename /Volumes/WorkFY12MacDAC_20110420 Work
    /usr/sbin/diskUtil enableJournal /Volumes/Work

echo "Complete. Opening Casper Imaging to finish reimage process."
sleep 2

sudo diskUtil unmount /Volumes/Documentation

open /Applications/Casper Suite 8.6/Casper Imaging 8.6.app
open /Applications/Casper Suite 8.62/Casper Imaging 8.62.app
open /Applications/Casper Suite/Casper Imaging.app

sleep 2

exit 0

}

fImageChoice1 ()
{
########## Get the group membership for the client #####################
## Get MAC Address using networksetup
MAC=$( networksetup -getmacaddress en0 | awk '{ print $3 }' | sed 's/:/./g' )

## Use the JSS API to see if the Mac is in JAMF. A return of "<p>The server has not found anything matching the request URI</p>" means the
## Mac is NOT in the database and can be safely reimaged. 
IsInJSS=$( curl -s -u APIUsername:"APIpassword" https://<casper server>:8443/JSSResource/computers/macaddress/$MAC | grep "<name>")

ComputerName=`diskutil list | grep "2:" | awk '{print $3}'`
## Find if the computer is already in Active Directory. If it is, exit. We need to remove it from AD
IsInAD=$(dscl /Active Directory/All Domains/ -read /Computers/$ComputerName$ | grep UniqueID)

if [ "$IsInJSS" != "" -o "$IsInAD" != "" ]; then
    echo "This Mac is still in the JSS! You must remove it from the database before reimaging! Exiting program."
    exit 1
else
mkdir -p -m 777 /Volumes/Documentation
sleep 2
echo "Mounting Documentation. Please wait..."
mount_afp afp://username:password@<casper server>/Documentation /Volumes/Documentation

## Get the model type of the Mac to determine naming scheme
echo "Now getting the computer model type to determine name. "
ModelType=`system_profiler SPHardwareDataType | grep -e "Model Identifier" | awk '{print substr($3,1,4)}'`
if [ "$ModelType" != "MacB" ]; then
    ASSETPREFIX=$LOC"MD-A0"
elif [ "$ModelType" == "MacB" ]; then
    ASSETPREFIX=$LOC"ML-A0"
else
    echo "Unknown computer model type. Aborting re-image."
    exit 1
fi

####### Get Next Mac Name #############
## Read the RefreshMacNames.txt file, get the last entry. This entry is just incremental integers
lastName=`grep . /Volumes/Documentation/RefreshMacNames.txt | tail -1`

## Increment the name by one
nextName=$(($lastName+1))

## Append the new name to the RefreshMacNames.txt file
echo "$nextName" >> /Volumes/Documentation/RefreshMacNames.txt
########## End get Next Mac Name ###############
sleep 1
sudo diskUtil unmount /Volumes/Documentation

######### Restore boot drive to factory defaults using /Volumes/CasperShare/DiskImages/ASR_Only/ ########
## Erase the current boot volume. DO NOT repartition since we want to preserve the restore partition
sudo diskutil eraseVolume HFS+ "Macintosh HD" /dev/disk0s2
sleep 5

  sudo asr restore -source /Volumes/CasperShare/DiskImages/ASR_Only/iMac13_2.dmg -target /dev/disk0s2 -noprompt -verbose -erase -format HFS+

## Write the name to a hidden file at the root of Macintosh HD. This file will be used to rename the computer upon restart
echo "$ASSETPREFIX$nextName" > /Volumes/Macintosh HD/.MacName.txt
## This is a reimage of an existing Mac without touching the user data, so add a blank file 
## to the boot drive to let our automations know NOT to try to partition it
echo "Reimage boot drive ONLY" > /Volumes/Macintosh HD/.OSXReimage.txt

## Wait for disks to stop being busy again
echo "Enabling journaling"
##  Enables Journaling.
/usr/sbin/diskUtil enableJournal /Volumes/Macintosh HD

echo "Journaling complete."
echo "------------------"
echo ""

/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog msgbox --title "Next Available Name" --text "This Mac will be named: $ASSETPREFIX$nextName" --button1 "OK"

echo "Now installing QuickAdd launchdaemon to Macintosh HD and rebooting."
rsync -avE /Volumes/"$SharedVol"/Packages/JAMFEnroll-HardwareRefresh_testreimage.pkg /
sleep 2
installer -pkg /JAMFEnroll-HardwareRefresh_testreimage.pkg -target /Volumes/Macintosh HD/

reboot
fi
}

################################ 3/20/2013 #################################
#### Create a selection menu for 10.8.2 restore OR classic imaging only ####
############################################################################
ImageChoice="0"
while [ "$ImageChoice" == "0" ]; do
    echo "#####################################################"
    echo "Please select from the following two imaging choices:"
    echo "1: Restore a 10.8 disk image to factory defaults and reimage automatically - TESTING ONLY"
    echo "2: Image a 10.6 Mac using Casper Imaging."
    echo "Enter a choice (1 or 2):"
    read ImageChoice
    if [ "$ImageChoice" == "1" ]; then
         ImageChoice=1
         fImageChoice1
    elif [ "$ImageChoice" == "2" ]; then
        ImageChoice=2
        fImageChoice2
    else
        echo "You can only choose 1 or 2. Try again."
        echo "-----------"
        echo ""
    fi
done

acdesigntech
Contributor II

The jamfEnroll-HardwareRefresh package consists of a launch Daemon:

<?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>Disabled</key>
    <false/>
    <key>Label</key>
    <string>com.mycompany.jamfenroll</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Library/Scripts/jamfenroll.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

A payloadless quickadd package:

#!/bin/sh

####################################################
## Create the configuration file at:
## /Library/Preferences/com.jamfsoftware.jamf.plist
####################################################
/usr/sbin/jamf createConf -url 'https://<Casper Server>:8443/' -k

####################################################
## Turn on SSH
####################################################
/usr/sbin/jamf startSSH

####################################################
## Run enroll
####################################################
/usr/sbin/jamf enroll -invitation <invitation generated from JSS>

enrolled=$?


############################################################
## Run the FY14Refresh autosetup policy based on location ##
############################################################
NETADD=`ifconfig | grep "inet " | grep -v 127.0.0.1 | cut -d  -f2 | awk '{print substr($1,1,6)}'`
case $NETADD in
"11.111"*)
    CasperTrigger="FY14Refresh1"
    ;;
"22.222"*)
    CasperTrigger="FY14Refresh2"
    ;;
*)
    CasperTrigger="FY14Refresh3"
    ;;
esac
/usr/sbin/jamf policy -trigger "$CasperTrigger"
exit $enrolled

and a script, called by the LaunchDaemon:

#!/bin/sh

## Create gat user and enable SSH & ARD
        dscl . -create /Users/localadmin
        dscl . -create /Users/localadmin UserShell /bin/bash
        dscl . -create /Users/localadmin RealName "localadmin"
        dscl . -create /Users/localadmin UniqueID 501
        dscl . -create /Users/localadmin PrimaryGroupID 80
        dscl . -create /Users/localadmin NFSHomeDirectory /Users/localadmin
        dscl . -create /Users/localadmin Picture "/Library/User Pictures/Flowers/Red Rose.tif"
        dscl . -passwd /Users/localadmin "password"
        dscl . -append /Groups/admin GroupMembership localadmin

## Kickstart ARD for localadmin
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -access -on -users localadmin -privs -all -restart -agent -menu
## Start SSH for gat
dseditgroup -o create -a localadmin -t user -q com.apple.access_ssh

# split the drive and resize
echo "Splitting and resizing Macintosh HD: Macintosh HD and Work"
    sudo diskutil resizeVolume /Volumes/Macintosh HD 100g HFS+ Work 0b
    echo "Split Complete."
    echo ""
    ## Wait for disks to stop being busy
    sleep 10

sleep 5
installer -pkg /Library/QuickAdd.pkg -target /

sleep 5
  1. Netboot the Mac
  2. Choose whether to do a legacy 10.6 image via Casper Remote or a shiny new thin image via script
  3. If thin imaging, the boot drive ONLY is restored to factory defaults, based on model identifier (we only have one model right now, so no logic statements here yet to choose which dmg to restore), then the launchDaemon package is installed to the boot drive, and the computer restarted
  4. on restart, launchdaemon runs a script to create the initial admin user account, kickstart ard and ssh, and install the quickadd package
  5. quick add package immediately enrolls the Mac and triggers our setup policy
  6. the very last step in our setup is to remove the launchdaemon, script, quickadd package, and reboot

acdesigntech
Contributor II

GetNextMacName is an Applescript applet I wrote to make a friendly gui way of getting the next available name for a Mac. As you can I'm doing away with that in favor of a more streamlined imaging scheme.

-- add parsing for "a0, b0, stuff like that. Have to check if applescript drops leading zeros, if so must account for that

-- variable initialization
set nextName to 0 as integer
set nameRange to 0 as integer

-- mount the server that contains the mac names file
try
    mount volume "afp://<CasperServer>/Documentation"
    delay 1
on error
    try
        mount volume "afp://<Casperserver>/Documentation"
        delay 1
    on error
        display dialog "There was an error mounting the server <CasperServer>. The server may be unavailable at this time. Please inform the Network Administrator if this problem continues." buttons {"Ok"} default button 1 giving up after 10
        error number -124
    end try
end try

-- specify the file that contains mac names
set theFile to "Volumes:Documentation:MacNames-New.txt"

-- Applescript locks the file when it opens, so there is no danger of another process editing the file while running this script. Likewise, Applescript cannot edit the file if another process has it locked, so there is no danger of Applescript editing it while another program has it open..
try
    set refNumber to (open for access file theFile with write permission)
on error
    try
        set refNumber to (open for access file theFile with write permission)
    on error
        display dialog "The file MacNames-New.txt cannot be opened for write access by this script. The file may already be opened by another program. Please inform the ISD Desktop team if this problem continues." buttons {"Ok"} default button 1 giving up after 10
        error number -61
    end try
end try

-- read the last line of the file. This is the last mac name used. This line will be incremented by 1 to give the next name
try
    set lastName to last paragraph of (read refNumber)
on error
    try
        set lastName to last paragraph of (read refNumber)
    on error
        display dialog "Could not get the last item in the file MacNames-New.txt. The file may be busy. Please contact ISD Desktop support if this problem continues." buttons {"Ok"} default button 1 giving up after 10
        --  error number -1702
    end try
end try

-- do you want the next available name or a range of available names (e.g.: Mac DAC)? 
display dialog "" buttons {"Get next Mac name", "Get a range of Mac names"}
set opMode to button returned of result

-- file write operations depend on how many names are being requested
if (opMode = "Get next Mac name") then
    -- if we are only interested in the next available name, increment the last name by one, write it to the EOF, and display the available name
    set lastNameLetter to do shell script "echo " & lastName & " | cut -d 0 -f1 | awk '{print $1}'"
    set lastNameNum to do shell script "echo " & lastName & " | cut -d 0 -f2,3,4 | awk '{print $1}'" --this drops the leading zero, so make sure to add it back below
    set nextNameNum to lastNameNum + 1
    set nextName to lastNameLetter & "0" & nextNameNum
    try
        write return & nextName to refNumber
    on error
        display dialog "Could not write to the file. The file may be locked by another program. MacNames.txt is unchanged. Please contact the ISD Desktop team if this problem continues." buttons {"Ok"} default button 1 giving up after 10
        --  error number -61
    end try
    display alert "Next available name: " & nextName
else
    -- if we want a range of names, set up a repeat loop for the number of names we want (use a second repeat loop to make sure we get valid input), write them to the file, then output them as a list that can be copy/pasted.
    set gotRange to false
    -- Start a repeat loop to keep asking the user for a range until a positive integer value is entered
    repeat until gotRange is true
        display dialog "Please enter a positive, non-zero integer for how many names you want:" default answer ""
        try
            set nameRange to text returned of result as integer
            if (nameRange ? 0) then
                display dialog "Integers less than 1 are invalid." buttons {"Ok"} default button 1 giving up after 10
            else
                set gotRange to true
            end if
        on error
            display dialog "Invalid input. Enter positive integers only." buttons {"Ok"} default button 1 giving up after 5
        end try
    end repeat

    -- set up a blank list to write each available name to
    set nameList to {}
    repeat nameRange times
        set lastNameLetter to do shell script "echo " & lastName & " | cut -d 0 -f1 | awk '{print $1}'"
        set lastNameNum to do shell script "echo " & lastName & " | cut -d 0 -f2,3,4 | awk '{print $1}'" --this drops the leading zero, so make sure to add it back below
        set nextNameNum to lastNameNum + 1
        set nextName to lastNameLetter & "0" & nextNameNum
        -- append the nextName to the end of the list of available names
        try
            write return & nextName to refNumber
        on error
            display dialog "Could not write to the file. The file may be locked by another program. MacNames-New.txt is unchanged. Please contact the ISD Desktop team if this problem continues." buttons {"Ok"} default button 1 giving up after 10
            --  error number -61
        end try
        set nameList to nameList & nextName & return
        -- an EOF error is generated if we try to read from the file a second time, but since we are incrementing the list by one each time for a specified number of times, we can simply advance the file by 1 using only varialbes. We are not required to read the file each time.
        set lastName to nextName
    end repeat
    display dialog "Next " & nameRange & " names: " & return default answer "" & nameList buttons {"OK"} default button 1
end if

-- close access to the file
close access refNumber

acdesigntech
Contributor II

just found this out: you need to add the -k option in the curl statement above if booted from a partition that does not have the casper server certificate. -k allows curl to not verify the web server cert.

so ```
IsInJSS=$( curl -ks -u APIUsername:"APIpassword" https://<casper server>:8443/JSSResource/computers/macaddress/$MAC | grep "<name>")
```

gachowski
Valued Contributor II

Andrew,

Thank you very very much, that is more than enough to get me started!!!!!!!

C