Deploying High Sierra 10.13 with Casper Imaging

reddrop
New Contributor III

Hi All,

I thought i would share with the community my method for deploying High Sierra with Casper Imaging.
The method basically consists for two scripts.

I have tested this with a 10.13.1 Netboot Image created with AutoDMG and AutoCasperNBI

restoreMacOS.sh To deploy the correct image which runs as a "before" script

imagingPostinstall. To run after reboot to run the Sierra Upgrade if needed.

The first script will decide which image to deploy to the Mac based on the currently installed Operating System or File system.

-If it is APFS it will deploy the 10.13.1 APFS image to the APFS container.
-If it is HFS+ it will check the currently installed OS. If the OS is already 10.13 it will image using the 10.13 HFS+ image.
-If the filesystem is HFS+ and the current OS is not 10.13 it will deploy 10.12.6 and then upgrade to 10.13 on next reboot using startOSInstall.

Script 1 RestoreMacOS.sh This replaces your base image in your Casper Admin Config

#!/bin/bash
######################################################################################
#
#   RestoreMacOs.sh - Ashley Stonham <reddrop>
#   Restores either High Sierra or Sierra based on a best guess
#
#   Variables:
#   DP      - Set this to the path that your DP mounts as
#   SIERRA      - Set this to the filename of your Sierra image 
#   HSIERRAAPFS     - Set this to the filename of your HighSierra APFS Image    
#   HSIERRAHFS  - Set this to the filename of your HighSierra HFS Image
#
######################################################################################


## Set these Variables
DP="/Volumes/casperdp"
SIERRA="osx-10.12.6-16G29.hfs.dmg"
HSIERRAAPFS="osx-10.13.1-17B48.apfs.dmg"
HSIERRAHFS="osx-10.13.1-17B48.hfs.dmg"


## No need to change anything below
TARGET="$1"
SOURCE=""

FSTYPE=$( diskutil info "$TARGET" | grep 'Type (Bundle)' | awk '{print $3}' )


## If the filesystem is APFS just restore High Sierra APFS

if [ "$FSTYPE" == "apfs" ]; then
    echo "APFS Detected setting SOURCE to $HSIERRAAPFS"
    SOURCE="$HSIERRAAPFS"
fi


## If the filesystem is HFS check the currently installed OS Version
if [ "$FSTYPE" == "hfs" ]; then
        echo "HFS Detected checking OS Version"
    VERSION=$( defaults read "${TARGET}/System/Library/CoreServices/SystemVersion.plist" ProductVersion )
    echo $VERSION
    if [[ "$VERSION" == *"10.13"* ]]; then
        echo "High Sierra Detected"
        SOURCE="$HSIERRAHFS"
    else
        echo "High Sierra Not Detected"
        SOURCE="$SIERRA"
    fi  
fi


if [ "$SOURCE" == "" ]; then
    echo "ERROR: Unable to determine source"
    exit 1
fi

echo "Running ASR ${DP}/Packages/${SOURCE} to $TARGET"

## If restoring APFS
if [ "$SOURCE" == "$HSIERRAAPFS" ]; then
    echo "Restoring APFS Volume"

    ## Workout APFS Container
    APFSDISK=$( diskutil list "$TARGET" | head -1 | cut -d' ' -f 1 )
    APFSCONTAINER=$( diskutil apfs list "$APFSDISK" | grep 'APFS Physical Store Disk' | cut -d':' -f 2 | tr -d '[:space:]' );

    if [[ "$APFSCONTAINER" == *"disk"* ]]; then
        echo "Restoring ${DP}/Packages/${SOURCE} to /dev/${APFSCONTAINER}"
        asr restore --source "${DP}/Packages/${SOURCE}" --target "/dev/${APFSCONTAINER}" --erase --noprompt 
        diskutil mountDisk "${APFSDISK}"
    else
        echo "Error unable to determine APFS container"
        exit 1;
    fi
else
    echo "Restoring HFS Volume"
    asr restore --source "${DP}/Packages/${SOURCE}" --target "$TARGET" --erase --noprompt --corestorageconvert
    #diskutil cs convert "$TARGET"
fi

exit 0

ImagingPostinstall.sh this scripts runs as an After Reboot and will create a launchDaemon to install HighSierra if the current OS is 10.12

#!/bin/bash

## Check OS Version if 10.12 Upgrade to HighSierra


OSVERSION=$( defaults read /System/Library/CoreServices/SystemVersion.plist ProductVersion )
if [[ "$OSVERSION" != *"10.12"* ]]; then

    ## Do nothing and exit
    echo "OS is not 10.12"
    exit 0;
fi


/bin/mkdir /usr/local/scripts


cat <<"EOF" > "/usr/local/scripts/NextBoot.sh"
#!/bin/bash
OSVERSION=$( defaults read /System/Library/CoreServices/SystemVersion.plist ProductVersion )

## If already on 10.13 remove the scripts.
if [[ "$OSVERSION" == *"10.13"* ]]; then
        ## Remove LaunchDaemon
        /bin/rm -f /Library/LaunchDaemons/com.scripts.NextBoot.plist

        ## Remove Script
        /bin/rm -fdr /usr/local/scripts

        launchctl remove com.scripts.NextBoot
        exit 0
fi

## Sleep for 30s to give the mac a chance to connect to network
sleep 30

## Update Device Inventory
/usr/local/jamf/bin/jamf recon

## Run HighSierra Upgrade
/usr/local/jamf/bin/jamf policy -event highSierraUpgrade 

exit 0

EOF


/usr/sbin/chown root:admin /usr/local/scripts/NextBoot.sh
/bin/chmod 755 /usr/local/scripts/NextBoot.sh

## Install the launchdaemon
    cat << EOF > /Library/LaunchDaemons/com.scripts.NextBoot.plist
<?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>Label</key>
    <string>com.scripts.NextBoot</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>-c</string>
        <string>/usr/local/scripts/NextBoot.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
EOF

##Set the permission on the file just made.
/usr/sbin/chown root:wheel /Library/LaunchDaemons/com.scripts.NextBoot.plist
/bin/chmod 644 /Library/LaunchDaemons/com.scripts.NextBoot.plist


exit 0
1 ACCEPTED SOLUTION

reddrop
New Contributor III

ReconOnReboot.sh:
This was extracted from the SierraUpgrade script. I just cut it down i use it quite often for software updates etc.

#!/bin/bash
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# CREATE FIRST BOOT SCRIPT
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

/bin/mkdir /usr/local/jamfps

/bin/echo "#!/bin/bash
## First Run Script to remove the installer.

## Update Device Inventory
/usr/local/jamf/bin/jamf recon

## Remove LaunchDaemon
/bin/rm -f /Library/LaunchDaemons/com.jamfps.reconNextBoot.plist

## Remove Script
/bin/rm -fdr /usr/local/jamfps
exit 0" > /usr/local/jamfps/recon.sh

/usr/sbin/chown root:admin /usr/local/jamfps/recon.sh
/bin/chmod 755 /usr/local/jamfps/recon.sh

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# LAUNCH DAEMON
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

cat << EOF > /Library/LaunchDaemons/com.jamfps.reconNextBoot.plist
<?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>Label</key>
    <string>com.jamfps.reconNextBoot</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>-c</string>
        <string>/usr/local/jamfps/recon.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
EOF

##Set the permission on the file just made.
/usr/sbin/chown root:wheel /Library/LaunchDaemons/com.jamfps.reconNextBoot.plist
/bin/chmod 644 /Library/LaunchDaemons/com.jamfps.reconNextBoot.plist

RestoreMacOS.sh
Updated with a few tweaks and bug fixes to handle filesystems that don't have CoreStorage enabled.

#!/bin/bash
######################################################################################
#
#   RestoreMacOs.sh - Ashley Stonham <reddrop>
#   Restores either High Sierra or Sierra based on a best guess
#
#   Variables:
#   DP      - Set this to the path that your DP mounts as
#   SIERRA      - Set this to the filename of your Sierra image 
#   HSIERRAAPFS     - Set this to the filename of your HighSierra APFS Image    
#   HSIERRAHFS  - Set this to the filename of your HighSierra HFS Image
#
######################################################################################


## Set these Variables
DP="/Volumes/casperdp"
SIERRA="osx-10.12.6-16G29.hfs.dmg"
HSIERRAAPFS="osx-10.13.2-17C88.apfs.dmg"
HSIERRAHFS="osx-10.13.2-17C88.hfs.dmg"


## No need to change anything below
TARGET="$1"
SOURCE=""



FSTYPE=$( diskutil info "$TARGET" | grep 'Type (Bundle)' | awk '{print $3}' )


## If the filesystem is APFS just restore High Sierra APFS

if [ "$FSTYPE" == "apfs" ]; then
    echo "APFS Detected setting SOURCE to $HSIERRAAPFS"
    SOURCE="$HSIERRAAPFS"
fi


## If the filesystem is HFS check the currently installed OS Version
if [ "$FSTYPE" == "hfs" ]; then
        echo "HFS Detected checking OS Version"
    VERSION=$( defaults read "${TARGET}/System/Library/CoreServices/SystemVersion.plist" ProductVersion )
    echo $VERSION
    if [[ "$VERSION" == *"10.13"* ]]; then
        echo "High Sierra Detected"
        SOURCE="$HSIERRAHFS"
    else
        echo "High Sierra Not Detected"
        SOURCE="$SIERRA"
    fi  
fi


if [ "$SOURCE" == "" ]; then
    echo "ERROR: Unable to determine source"
    exit 1
fi

echo "Running ASR ${DP}/Packages/${SOURCE} to $TARGET"

## If restoring APFS
if [ "$SOURCE" == "$HSIERRAAPFS" ]; then
    echo "Restoring APFS Volume"

    ## Workout APFS Container
    APFSDISK=$( diskutil list "$TARGET" | head -1 | cut -d' ' -f 1 )
    APFSCONTAINER=$( diskutil apfs list "$APFSDISK" | grep 'APFS Physical Store Disk' | cut -d':' -f 2 | tr -d '[:space:]' );

    if [[ "$APFSCONTAINER" == *"disk"* ]]; then
        echo "Restoring ${DP}/Packages/${SOURCE} to /dev/${APFSCONTAINER}"
        asr restore --source "${DP}/Packages/${SOURCE}" --target "/dev/${APFSCONTAINER}" --erase --noprompt 
        diskutil mountDisk "${APFSDISK}"
    else
        echo "Error unable to determine APFS container"
        exit 1;
    fi
else
    echo "Restoring HFS Volume"
    diskutil cs convert "$TARGET"
    diskutil cs resizeVolume "$TARGET" 0
    asr restore --source "${DP}/Packages/${SOURCE}" --target "$TARGET" --erase --noprompt --corestorageconvert

    #diskutil cs convert "$TARGET"
fi

NEWNAME=$( echo "$TARGET" | cut -d'/' -f3 )
diskutil rename /Volumes/Macintosh HD "$NEWNAME"

exit 0

ImagingPostInstall.sh

#!/bin/bash

## Check OS Version if 10.12 Upgrade to HighSierra


OSVERSION=$( defaults read /System/Library/CoreServices/SystemVersion.plist ProductVersion )
if [[ "$OSVERSION" != *"10.12"* ]]; then

    ## Do nothing and exit
    echo "OS is not 10.12"
    exit 0;
fi


/bin/mkdir /usr/local/scripts


cat <<"EOF" > "/usr/local/scripts/NextBoot.sh"
#!/bin/bash
OSVERSION=$( defaults read /System/Library/CoreServices/SystemVersion.plist ProductVersion )

## If already on 10.13 remove the scripts.
if [[ "$OSVERSION" == *"10.13"* ]]; then
        ## Remove LaunchDaemon
        /bin/rm -f /Library/LaunchDaemons/com.scripts.NextBoot.plist

        ## Remove Script
        /bin/rm -f /usr/local/scripts/NextBoot.sh

        launchctl remove com.scripts.NextBoot
        exit 0
fi

## Sleep for 30s to give the mac a chance to connect to network
sleep 30

## Update Device Inventory
/usr/local/jamf/bin/jamf recon

## Run HighSierra Upgrade
/usr/local/jamf/bin/jamf policy -event highSierraUpgrade 

exit 0

EOF


/usr/sbin/chown root:admin /usr/local/scripts/NextBoot.sh
/bin/chmod 755 /usr/local/scripts/NextBoot.sh

## Install the launchdaemon
    cat << EOF > /Library/LaunchDaemons/com.scripts.NextBoot.plist
<?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>Label</key>
    <string>com.scripts.NextBoot</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>-c</string>
        <string>/usr/local/scripts/NextBoot.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
EOF

##Set the permission on the file just made.
/usr/sbin/chown root:wheel /Library/LaunchDaemons/com.scripts.NextBoot.plist
/bin/chmod 644 /Library/LaunchDaemons/com.scripts.NextBoot.plist


exit 0

View solution in original post

86 REPLIES 86

EdenJAMFAdmin
New Contributor

I'm having a problem with running the RestoreMacOS.sh script.
I've created the 10.13 APFS and HFS dmg files, the 12.6 HFS dmg is one that I built last year. All were built using AutoDMG.
As you can see at the bottom, it's coming up as not being able to validate the dmg of the OS installer.

If I manually mount the Distribution point using go->connect to server, and enter the name of the DP as shown in Casper Imaging, followed up with the ASR command translated for the variables, the installation works, so the DMG does work.
asr restore --source "${DP}/Packages/${SOURCE}" --target "$TARGET" --erase --noprompt --corestorageconvert

I've also copied the RestoreMacOS.sh script to the local machine I was trying to image and ran it in Terminal ./RestoreMacOS.sh "Volumes/Macintosh HD", it worked there. So it's only failing when run in Casper Imaging.

I'm going to try to create an updated 12.6 dmg, maybe that will help?

Any other ideas?

Additionally, where do I integrate the ReconOnReboot into the configuration and at what priority, before, after or on reboot?

Result of running RestoreMacOS.sh was: HFS Detected checking OS Version
10.12.6
High Sierra Not Detected
Running ASR /Volumes/jamf/Packages/osx_updated_170721-10.12.6-16G29.hfs.dmg to /Volumes/Macintosh HD
Restoring HFS Volume using /Volumes/jamf/Packages/osx_updated_170721-10.12.6-16G29.hfs.dmg to /Volumes/Macintosh HD
Error converting disk to CoreStorage: Stacked Core Storage Sets are not supported (-69754)
The Core Storage Logical Volume UUID is 475BB6F4-1B40-4AC2-8631-4FA3F6CBB2AD
Started CoreStorage operation
Verifying file system
Volume was successfully unmounted
Performing fsck_hfs -fn -x /dev/rdisk1
Checking Journaled HFS Plus volume
Checking extents overflow file
Checking catalog file
Checking multi-linked files
Checking catalog hierarchy
Checking extended attributes file
Checking volume bitmap
Checking volume information
The volume Macintosh HD appears to be OK
File system check exit code is 0
Restoring the original state found as mounted
Growing Logical Volume
Resizing Core Storage Logical Volume structures
Resized Core Storage Logical Volume to 498,761,564,160 bytes
Growing file system
Finished CoreStorage operation
Validating target...done
Validating source...
Could not recognize "/Volumes/jamf/Packages/osx_updated_170721-10.12.6-16G29.hfs.dmg" as an image file
Could not validate source - Invalid argument
Volume on disk1 renamed to Macintosh HD

EdenJAMFAdmin
New Contributor

Figured out that one problem. In casper imaging, the distribution point was listed as server/sharepoint$/mac/jamf. If I use go connect to server to connect to that path, the volume is mounted as jamf. Looks like casper imaging doesn't mount the path as the final folder name, but as the name of the sharepoint itself, so sharepoint$. Updating the DP variable to /Volumes/sharepoint$ resolved the invalid argument error.

EdenJAMFAdmin
New Contributor

I believe I have a new issue with the scripting, whether I manually reboot after running Casper imaging, or allow Casper Imaging to reboot after completion, it's rebooting into I believe the recovery partition. I need to change the startup disk to get it to boot the Macintosh HD and run the first run scripts.

Nix4Life
Valued Contributor

You may need to bless the new system. I looked at the script and do not see where the restored system is blessed. I use a different restore method and always bless the new drive after restore

lockwojo
New Contributor III

Some comments for what their worth.

It is possible as referred to in this thread to extract the High Sierra firmware installer packages from the High Sierra installer, there is a link earlier in the thread to a script to do this.

We have upgraded a large number of existing MacBook Pros to High Sierra, most already as shipped had High Sierra and APFS compatible firmware. When I say compatible this does not mean that they definitely had the very latest firmware but they did image and boot successfully and the users have reported no problems. Newly purchased Macs will by now all come with compatible firmware.

When we find a Mac fails during imaging because it had too old firmware we boot it from Sierra and run the extracted firmware installer package manually. We can then re-run the High Sierra APFS imaging process and it will then succeed.

It does not seem possible to automate running the extracted firmware installer since the process to update firmware requires in many cases holding down buttons to boot in to the special firmware update process.

Some Macs even those already updated for High Sierra will need even newer firmware for Mojave, so we will be back to the same situation except worse.

It would be a big help if it was possible to construct say an extension attribute that did not merely show what firmware a Mac has (this is any case a built-in attribute) but rather was able to lookup what the latest firmware for a Mac is and see if it matches. The nearest thing I have found to this is EFIgy. See https://github.com/duo-labs/EFIgy

If someone could create a script to use this and then return the result as an Extension Attribute this could be used to create a smart group which lists Macs needing firmware updates. It maybe that using OSQuery another open source tool which integrates with EFIgy might make this easier. See https://github.com/trailofbits/osquery-extensions/tree/master/efigy

EdenJAMFAdmin
New Contributor

@Nix4Life What bless command are you using.

Still have the issue with bless. Attaching full log here, I added my own bless command

bless -mount "/Volumes/$NEWNAME" -setBoot

within the Restore OS script, and you can see that Casper Imaging is putting it's own bless at the end. Mine is failing and I expect the same, though unreported, is happening to it's bless since it is still rebooting into System Restore.

Initializing
Imaging Process...
Mounting smb://e175file1/sdp$/mac/jamf...
Downloading RestoreMacOS.sh...
Running RestoreMacOS.sh...
Result of running RestoreMacOS.sh was: HFS Detected checking OS Version
10.13.5
High Sierra Detected
Running ASR /Volumes/sdp$/Packages/osx_updated_180606-10.13.5-17F77.hfs.dmg to /Volumes/Macintosh HD
Restoring HFS Volume using /Volumes/sdp$/Packages/osx_updated_180606-10.13.5-17F77.hfs.dmg to /Volumes/Macintosh HD
Error converting disk to CoreStorage: Stacked Core Storage Sets are not supported (-69754)
The Core Storage Logical Volume UUID is CDDE44D0-943F-42C3-8919-5A72B0085FAE
Started CoreStorage operation
Verifying file system
Volume was successfully unmounted
Performing fsck_hfs -fn -x /dev/rdisk1
Checking Journaled HFS Plus volume
Checking extents overflow file
Checking catalog file
Checking multi-linked files
Checking catalog hierarchy
Checking extended attributes file
Checking volume bitmap
Checking volume information
The volume Macintosh HD appears to be OK
File system check exit code is 0
Restoring the original state found as mounted
Growing Logical Volume
Resizing Core Storage Logical Volume structures
Resized Core Storage Logical Volume to 498,761,564,160 bytes
Growing file system
Finished CoreStorage operation
Checking Access to Sharepoint
2018-06-13 11:02
Finished Checking Access to Sharepoint
Validating target...done
Validating source...done
Retrieving scan information...done
Validating sizes...done
Restoring ....10....20....30....40....50....60....70....80....90....100
Verifying ....10....20....30....40....50....60....70....80....90....100
Restoring ....10....20....30....40....50....60....70....80....90....100
Verifying ....10....20....30....40....50....60....70....80....90....100
Remounting target volume...done
Volume on disk1 renamed to Macintosh HD
Setting boot drive /Volumes/Macintosh HD
Could not set boot device property: 0xe00002bc
Setting computer name to "JAMF-TST-EEIL"...
Creating /private/etc/jamf.conf...
Creating /usr/local/bin/jamf...
Creating jamfHelper...
Ensuring Apple's Setup Assistant does not appear...
Creating First Run Enroll Script...
Adding line for binding EdenAD...
Creating First Run Post Install Script...
Adding line to Fix ByHost Files...
Adding line to run ImagingPostInstall.sh...
Adding line to run ReconOnReboot.sh...
Copying script ReconOnReboot.sh...
Downloading ImagingPostInstall.sh...
Copying script ImagingPostInstall.sh...
Downloading ReconOnReboot.sh...
Ensuring system files are hidden...
Unmounting Distribution Point...
Blessing System...

Nix4Life
Valued Contributor

@EdenJAMFAdmin yes that is the command, however as I mentioned I am not using Casper imaging, just a straight APFS restore over http