NetNXT Logo

Mac – Generic DMG Installer – JumpCloud

This guide shows how to deploy macOS applications packaged as DMG files using a single generic shell script in JumpCloud Commands. You’ll set the download URL, scope to devices or groups, and handle mounting, copying to /Applications, and cleanup.

November 13, 2025
5 min read
ByNetNXT
On this page
Share this article

Purpose

Install macOS applications distributed as .dmg files using a single reusable script executed from JumpCloud → Commands. This is ideal for Chrome, Firefox, Slack, and similar DMG-based apps.

Prerequisites

  • Admin access to the JumpCloud Admin Portal
  • Target macOS devices enrolled in JumpCloud
  • A direct DMG download URL or a URL that redirects to a DMG (validated via headers)
  • Network egress allowed to the app vendor’s CDN

Tip: If you’re setting up new Macs, see our SOP on Automated macOS Device Enrollment via JumpCloud MDM (ADE + ABM + ZTE)

to make this part of your zero-touch flow.

Step-by-Step Instructions

Step 1 — Create the command

  1. Log in to JumpCloud Admin Portal.
  2. Go to Devices → Commands.
  3. Click + to add a new command.
  4. Select macOS (Shell).
  5. Give the command a clear name (for example, Install – Chrome (DMG)).

Step 2 — Configure the script

  • In the script, set DownloadUrl="DOWNLOAD_URL" to the app’s DMG link.
  • The URL must either:
  • End with .dmg, or
  • Return a Location header that points to a DMG (the script checks this).

You can quickly verify with:

curl -s --head "<your URL>"

Look for a Location header ending in .dmg.

Step 3 — Scope and run

  1. Assign the command to the target device(s) or device group.
  2. Click Save, then Run (or schedule as needed).
  3. Monitor the command logs for “Copied … to /Applications” and cleanup messages.

Command (use as-is; set the DownloadUrl)

#!/bin/bash
# *** USAGE *** Version: 1.2
# NOTE: Designed for DMG files only (not .pkg, .zip, or DMGs containing .pkg).
# Set the DMG download URL below.

DownloadUrl="DOWNLOAD_URL"

### Modify below this line at your own risk!
# Locate DMG Download Link From URL
regex='^https.*.dmg
if [[ $DownloadUrl =~ $regex ]]; then echo "URL points to direct DMG download" validLink="True" else echo "Searching headers for download links" urlHead=$(curl -s --head "$DownloadUrl") locationSearch=$(echo "$urlHead" | grep https:) if [ -n "$locationSearch" ]; then locationRaw=$(echo "$locationSearch" | awk '{print $2}') locationFormatted="$(echo "${locationRaw}" | tr -d '[:space:]')" regex='^https.*' if [[ $locationFormatted =~ $regex ]]; then echo "Download link found" DownloadUrl="$locationFormatted" else echo "No https location download link found in headers" exit 1 fi else echo "No location download link found in headers" exit 1 fi fi # Create Temp Folder DATE=$(date '+%Y-%m-%d-%H-%M-%S') TempFolder="Download-$DATE" mkdir -p "/tmp/$TempFolder" # Navigate to Temp Folder cd "/tmp/$TempFolder" || exit # Download File into Temp Folder curl -s -O "$DownloadUrl" # Capture name of Download File DownloadFile="$(ls)" echo "Downloaded $DownloadFile to /tmp/$TempFolder" # Verify DMG File regex='\.dmg
if [[ $DownloadFile =~ $regex ]]; then DMGFile="$DownloadFile" echo "DMG File Found: $DMGFile" else echo "File: $DownloadFile is not a DMG" rm -r "/tmp/$TempFolder" echo "Deleted /tmp/$TempFolder" exit 1 fi # Mount DMG File (-nobrowse prevents the volume from popping up in Finder) hdiutilAttach=$(hdiutil attach "/tmp/$TempFolder/$DMGFile" -nobrowse) echo "Used hdiutil to mount $DMGFile" err=$? if [ ${err} -ne 0 ]; then echo "Could not mount $DMGFile Error: ${err}" rm -r "/tmp/$TempFolder" echo "Deleted /tmp/$TempFolder" exit 1 fi regex='\/Volumes\/.*' if [[ $hdiutilAttach =~ $regex ]]; then DMGVolume="${BASH_REMATCH[0]}" echo "Located DMG Volume: $DMGVolume" else echo "DMG Volume not found" rm -r "/tmp/$TempFolder" echo "Deleted /tmp/$TempFolder" exit 1 fi # Identify the mount point for the DMG file DMGMountPoint=$(hdiutil info | grep "$DMGVolume" | awk '{ print $1 }') echo "Located DMG Mount Point: $DMGMountPoint" # Capture name of App file cd "$DMGVolume" || exit AppName=$(ls | grep '.app') cd ~ || exit echo "Located App: $AppName" # Test to ensure App is not already installed ExistingSearch=$(find "/Applications/" -name "$AppName" -depth 1) if [ -n "$ExistingSearch" ]; then echo "$AppName already present in /Applications folder" hdiutil detach "$DMGMountPoint" echo "Used hdiutil to detach $DMGFile from $DMGMountPoint" rm -r "/tmp/$TempFolder" echo "Deleted /tmp/$TempFolder" exit 1 else echo "$AppName not present in /Applications folder" fi DMGAppPath=$(find "$DMGVolume" -name "*.app" -depth 1) # Copy the contents of the DMG file to /Applications/ # Preserves all file attributes and ACLs cp -pPR "$DMGAppPath" /Applications/ err=$? if [ ${err} -ne 0 ]; then echo "Could not copy $DMGAppPath Error: ${err}" hdiutil detach "$DMGMountPoint" echo "Used hdiutil to detach $DMGFile from $DMGMountPoint" rm -r "/tmp/$TempFolder" echo "Deleted /tmp/$TempFolder" exit 1 fi echo "Copied $DMGAppPath to /Applications" # Unmount the DMG file hdiutil detach "$DMGMountPoint" echo "Used hdiutil to detach $DMGFile from $DMGMountPoint" err=$? if [ ${err} -ne 0 ]; then echo "Could not detach DMG: $DMGMountPoint Error: ${err}" fi # Remove Temp Folder and download rm -r "/tmp/$TempFolder" echo "Deleted /tmp/$TempFolder"

Validated DMG download URLs (examples)

  1. https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg
  2. https://download.mozilla.org/?product=firefox-latest-ssl&os=osx&lang=en-US
  3. https://go.microsoft.com/fwlink/p/?linkid=525133
  4. https://slack.com/ssb/download-osx

Note: Some vendor links redirect; the script resolves the final DMG URL automatically.

Expected result / validation

  • Command output shows URL detection, DMG mount, copy to /Applications, detach, and temp cleanup.
  • The application appears in /Applications on target Macs and is ready to launch.
  • Re-running the command will safely exit if the app already exists.

FAQs

1) Does this support .pkg or .zip?

No. This template is DMG-only. For PKG deployments, use a dedicated PKG installer workflow in JumpCloud.

2) How do I ensure the URL is correct?

Run:

curl -s --head "<URL>"

Confirm the Location header ends in .dmg, or the original URL ends with .dmg.

3) What if the DMG contains a .pkg instead of an .app?

This script expects a top-level .app. If the DMG contains a .pkg, use a PKG install command.

4) Can I scope this per team or department?

Yes. Assign the command to specific device groups to align with your app catalog strategy.

Need help securing your environment?

Talk to a NetNXT security expert
Was this article helpful?

Stay ahead of the next vulnerability

New KB guides, threat advisories and hardening playbooks from NetNXT's security team — straight to your inbox.

NetNXT will handle your data pursuant to its Privacy Policy.

Like this guide? Join our team.

NetNXT builds security for how modern enterprises actually run.

View open roles

Have a question about this guide?

Our security engineers read every message.

Contact us