A macOS Bash script for forensic data collection. It creates a local Time Machine snapshot, mounts it read-only, and copies all data into a self-sizing container (APFS sparse image by default). This can be on an mounted external or internal drive.
| Requirement | Details |
|---|---|
| macOS | 10.14 (Mojave) or later |
| Shell | Bash (built-in) |
| Privileges | Must be run as root (sudo) |
| Full Disk Access | Terminal.app must have Full Disk Access enabled in System Settings → Privacy & Security → Full Disk Access |
| Time Machine | Local snapshots must be enabled and supported on the system volume |
Note: ASR (Apple Software Restore) can be used as an alternative if SIP is disabled.
A simple point-and-click front-end is included so you don't need to use the terminal.
Additional requirement: Python 3 (ships with macOS — no install needed)
Launch:
python3 MacGrabGUI.pyFeatures:
- Browse button to pick the target directory
- sudo Password field (required — the script runs as root)
- Run / Stop button to start or cancel the collection
- Live colour-coded log — errors in red, success in green, warnings in yellow
- Status bar showing current state
Both
MacGrabGUI.pyandMacGrab.shmust be in the same folder.
- Creates a local Time Machine snapshot of the root volume using
tmutil localsnapshot - Mounts the snapshot read-only at
/tmp/tm_snapshotusingmount_apfs - Calculates required storage by checking the snapshot's current disk usage and adding a 40-unit buffer
- Creates a sparse APFS image (
.sparseimage) at your specified target location, sized dynamically to fit the data - Copies all snapshot data into the mounted sparse image using
rsyncwith full attribute preservation - Logs the transfer to a
.rsync.logfile alongside the sparse image - Cleans up by unmounting both the snapshot and the sparse image when complete
sudo sh ./MacGrab.sh <target_directory>| Parameter | Required | Description |
|---|---|---|
<target_directory> |
✅ Yes | Path where the sparse image and log file will be written (e.g. /Volumes/ExternalDrive) |
-h |
No | Display usage help and exit |
Example:
sudo sh ./MacGrab.sh /Volumes/ExternalDrive| File | Location |
|---|---|
| Sparse image | <target_directory>/<hostname>-targetcontainer.sparseimage |
| rsync log | <target_directory>/<hostname>-targetcontainer.sparseimage.rsync.log |
| Data mount point | /Volumes/TargetFolder (mounted during transfer, unmounted on completion) |
A few variables at the top of the script can be adjusted to suit your environment:
| Variable | Default | Description |
|---|---|---|
OUT_DIR |
/Volumes/TargetFolder |
Mount point for the sparse image during transfer |
mount_point |
/tmp/tm_snapshot |
Temporary mount point for the Time Machine snapshot |
TARGET_CONTAINER |
<hostname>-targetcontainer.sparseimage |
Name of the output sparse image |
The script includes a commented-out section to run UAC (Unix Artifact Collector) directly against the mounted snapshot. To enable it, uncomment and update the path in the script:
cd /<path_to_uac>/uac-2.9.1/
./uac -p full -a \!live_response/\* /tmp --mount-point /tmp/tm_snapshot --operating-system macos- "This script must be run as root" → Run with
sudo - "Failed to create Time Machine snapshot" → Ensure local snapshots are not disabled (
tmutil disablelocal) - "Failed to mount snapshot" → Verify Terminal has Full Disk Access in System Settings
- Sparse image already exists → The script will automatically delete and recreate it
| Version | Date | Notes |
|---|---|---|
| v1.1 | March 2026 | Added MacGrabGUI.py — Python/Tkinter point-and-click front-end |
| v1.0 | March 2025 | Initial release — snapshot creation, sparse image, rsync collection, UAC hook |
MIT License © 2024 EasyMetaData
