Using AppleScript to show an Alert when a specific USB Drive is disconnected

I am putting this here for anyone wanting to do the same thing I needed to do. It looks daunting but it’s actually easy. The steps just make this look long. I’m not a coder and I’ve never used AppleScript or launchd before so this is a cut/paste/modify situation. I apologize if the scripting is bad. Here are my references:

Backstory:
I have two Mac Minis with a Dual Monitor setup. One is my workhorse (Plex Server, Video Editing, Photoshop, etc) and the other is for the family. I have a USB Hub attached to a USB Switch so I can switch my Accessories (Keyboard, USB Drives, Printer, etc) to the computer I’m using. Although it will be rare, I wanted a way for my family to know when the Keyboard, specifically, wasn’t connected to their computer so they know to switch it back. Since my 3TB External HD is on the same Hub, it made sense that trying to detect it was the easiest way for me to accomplish my task.

[Video Example:](USB Drive removed shows an Alert)

PLIST File:
Using Craig’s tutorial I created a PLIST file and placed it in /Users/YOURNAME/Library/LaunchAgents. It is named WatchCB.plist (just like Craigs):

<?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>WatchingVolumesPath</string>
    <key>LowPriorityIO</key>
    <true/>
    <key>Program</key>
    <string>/usr/bin/osascript</string>
    <key>ProgramArguments</key>
    <array>
        <string>osascript</string>
        <string>/Users/YOURNAME/Documents/SWITCH/USBDetect.scpt</string>
    </array>
    <key>ServiceDescription</key>
    <string>Runs Applescript directly when Volumes Path changes</string>
    <key>StandardOutPath</key>
    <string>/Users/YOURNAME/Documents/SWITCH/USBLog.txt</string>
    <key>WatchPaths</key>
    <array>
    <string>/Volumes</string>
    </array>
</dict>
</plist>"

BREAKDOWN:
This section will tell the Launch Agent where my files are located:

        <string>osascript</string>
        <string>/Users/YOURNAME/Documents/SWITCH/USBDetect.scpt</string>

and where to dump logs (USBLog.text) because I guess that’s important, lol! *This file will auto-create; you don’t need to make one.

    <key>ServiceDescription</key>
    <string>Runs Applescript directly when Volumes Path changes</string>
    <key>StandardOutPath</key>
    <string>/Users/YOURNAME/Documents/SWITCH/USBLog.txt</string>

Creating the PLIST file is fairly easy. Use the TextEdit.app. Under the Format Tab, change it to ‘Make Plain Text.’ Copy/Paste my script then Save. In Finder, rename it and add .plist to the end. That’s it!

Load the PLIST:
After placing the WatchCB.plist file in /Users/YOURNAME/Library/LaunchAgents, you need to ‘Load’ it with launchd in Terminal. Obviously, change YOURNAME to whatever your name is in Users.
Open the Terminal.app and type/paste this in:

launchctl load -w /Users/YOURNAME/Library/LaunchAgents/WatchCB.plist

What I find easiest is to use Finder and go to /Users/YOURNAME/Library/LaunchAgents/ and locate the WatchCB.scpt file. Copy/Paste the beginning command:

launchctl load -w

Then drag the WatchCB.scpt file into Terminal and it will fill out the location automatically.

NOTE: Anytime this file is edited, you need to unload and then load it again.
To unload it, type:

launchctl unload -w /Users/YOURNAME/Library/LaunchAgents/WatchCB.plist

AppleScript Files:
Next, I created two AppleScript files: one that watches for when my USB Drive disconnects/connects (USBDetect.scpt), and the other for showing a Popup Alert, aka display alert (MacScript.scpt). I placed these files in a SWITCH folder that’s inside my Documents folder. So, to clarify, here is the location path and what’s inside:
/Users/YOURNAME/Documents/SWITCH/

  • USBlog.txt
  • MacScript.scpt
  • USBDetect.scpt

USBDetect.scpt File:
This is where the script looks for my 3TB External Hard Drive and if it’s disconnected or not. I tried using Craig’s script for this but I kept getting the Popup Alert anytime I’d disconnect or connect. That is when I found StefanK’s post and used his method. Now, the Popup Alert only shows when I disconnect.
Here is what my watcher/detector file looks like:

property flashState : false --Has to be set to false

property flashName : "3TB" --Name of my specific USB Drive

property folderPath : "SSD:Users:YOURNAME:Documents:SWITCH:" --Location of my files

set script2Run to (folderPath) & "MacScript.scpt" --Points to the Location and runs MacScript file

set currentDisks to paragraphs of (do shell script "ls /Volumes") --Scans for Drives Connected/Disconnected

if (flashName is in currentDisks) then --DON'T KNOW WHY

if (flashState is false) then --I NEED THIS SECTION

set flashState to true --BUT IT DOESN'T

end if --WORK WITHOUT IT

else

if flashState is true then --Detects if my USB drive not connected

set flashState to false --Changes is to being connected

run script file script2Run --Runs the MacScript.scpt file

end if

end if

BREAKDOWN:
I don’t know what these are considered but I call them identifiers. Basically, they’re pieces that will be used in the actual script.

property flashState : false --Has to be set to false

property flashName : "3TB" --Name of my specific USB Drive

property folderPath : "SSD:Users:YOURNAME:Documents:SWITCH:" --Location of my files

set script2Run to (folderPath) & "MacScript.scpt" --Points to the Location and runs MacScript file

set currentDisks to paragraphs of (do shell script "ls /Volumes")  --Scans for Drives Connected/Disconnected

NOTE: My main Hard Drive on both machines are labeled SSD. Yours is probably Macintosh HD. I don’t know how to account for the space between ‘Macintosh’ and ‘HD’ in the script. My apologies :pensive:

For this section, I have no idea why it needs to be in here but when I removed it, my script wouldn’t work so I left it in.

if (flashName is in currentDisks) then --DON'T KNOW WHY

if (flashState is false) then --I NEED THIS SECTION

set flashState to true --BUT IT DOESN'T

end if --WORK WITHOUT IT

This section is what calls for my Popup Alert file (MacScript.scpt) to show when the drive is disconnected

else

if flashState is true then --Detects if my USB drive not connected

set flashState to false --Changes it to being connected

run script file script2Run --Runs the MacScript.scpt file

MacScript.scpt:
This is the file that has a Popup Alert in the middle of the screen with an OK button to clear it. You can edit the text to whatever you need:

display alert "‼️KEYBOARD SWITCHED‼️" message "The Keyboard and all other 
USB Accessories have been switched. 
Press OK to Continue"

This is self explanatory ALTHOUGH you can adjust centering by adding spaces.
Screenshot 2024-04-04 at 10.40.06 AM

Conclusion:
After confirming that this worked on one machine, I simply AirDropped the files to the other computer and put everything where it belonged. Remember to ‘load’ your WatchCB.plist file in Terminal.

As a recap, here’s where the files went:
WatchCB.plist - /Users/YOURNAME/Library/LaunchAgents
SWITCH folder - /Users/YOURNAME/Documents
USBlog.txt - /Users/YOURNAME/Documents/SWITCH
MacScript.scpt - /Users/YOURNAME/Documents/SWITCH
USBDetect.scpt - /Users/YOURNAME/Documents/SWITCH

Hope this helps someone and sorry it’s not professional. Just an average guy trying to make life easier on his family!

2 Likes