6 min read

Automating USB Data Backup: How I Built a Silent USB Copier

How I built a silent USB auto-backup system using Python to detect devices, copy files safely, track processed drives, and log every action for reliable, hands-free backups.

I often found myself in a frustrating situation: I’d insert a USB drive, but forget to back up important files. The manual copying process is tedious, prone to errors, and easy to overlook especially when you’re in a rush. So, I decided to automate the backup process with a simple script.

The Goal

The idea was straightforward:

  • Track USB devices as they’re plugged in.
  • Automatically copy all their data to a local backup folder.
  • Generate logs of what happened, without requiring any manual steps.

But there was a challenge: How do I build a seamless, automated backup system that quietly detects USB devices, copies their contents, and logs everything — without needing constant supervision?

⚡ The First Breakthrough: Building the Script

The first step was clear: I needed a script that would handle the entire backup process from start to finish. This meant detecting USB devices, copying files, and logging everything — all automatically.

Why This Approach?

  • No manual interruption: I didn’t want to open folders or copy files every time I plugged in a USB.
  • Complete logging: I needed detailed logs that documented everything — what files were copied, when it happened, and if any errors occurred.
  • Flexibility: The script needed to handle any USB device, no matter the name, size, or type of content.
  • Seamless Automation: Ideally, I wanted this process to run in the background without requiring me to think about it.

With that in mind, the project was born: Auto-copying data from USB drives.

🛠️ The Challenges

While the idea was simple, turning it into a working system came with a few challenges:

  1. Detecting Devices: How do I automatically detect when a USB drive is inserted, and uniquely identify it?
  2. Copying Files: How can I ensure that all files — regardless of type, size, or structure — are copied to a pre-defined backup folder?
  3. Logging Everything: How can I capture detailed logs without making them overwhelming or redundant?
  4. Error Handling: What happens if a USB drive can’t be accessed or a file fails to copy?

I needed to find tailored solutions to these problems to ensure everything worked seamlessly.

🔑 The Solution: Building the System

The core of this system was a Python script designed to monitor USB devices, copy their contents, and log each step of the process.

1. Detecting USB Devices

The first step was detecting when a USB device was inserted into the system. I used the psutil library to check the system’s mounted drives. This method works across platforms, detecting USB drives on both Windows and other systems.

def get\_mounted\_drives():  
    system = platform.system()  
    drives = \[\]  
    if system == "Windows":  
        for letter in string.ascii\_uppercase:  
            path = f"{letter}:/"  
            if os.path.exists(path):  
                drives.append(path)  
    else:  
        for part in psutil.disk\_partitions(all=False):  
            if 'media' in part.mountpoint or 'Volumes' in part.mountpoint:  
                drives.append(part.mountpoint)  
    return drives

This code checks potential drive letters (on Windows) or partitions (on other systems) and returns a list of the currently mounted drives.

2. Copying Files

Once a USB device is detected, the next task was to copy its contents to a backup folder. For this, I used shutil.copytree(), which allows me to copy entire directories, including all subdirectories and files.

def copy\_from\_usb(usb\_path, drive\_id):  
timestamp = datetime.now().strftime("%Y-%m-%d\_%H-%M-%S")  
drive\_letter = usb\_path\[0\].upper()  
folder\_name = f"{drive\_letter}\_{timestamp}"  
dest\_subfolder = DEST\_FOLDER / folder\_name  
try:  
    logging.info(f"Copying files from {usb\_path} to {dest\_subfolder}")  
    shutil.copytree(usb\_path, dest\_subfolder, dirs\_exist\_ok=True)  
    copied\_devices\[drive\_id\] = timestamp  
    save\_tracker()  
    logging.info(f"Successfully copied from {usb\_path} to {dest\_subfolder}")  
except Exception as e:  
    logging.error(f"Error copying from {usb\_path}: {e}")

Here, every time a USB drive is inserted, its contents are copied into a subfolder named after the drive letter and timestamp, ensuring that no files are overwritten.

3. Tracking Devices

To prevent copying the same USB multiple times, I added a device tracker. This tracker records the unique identifier of each USB device once it’s been processed.

copied\_devices = {}  
def save\_tracker():  
    with open(DEVICE\_TRACKER, "w") as f:  
        json.dump(copied\_devices, f, indent=2)

Once the device is copied, its ID is saved, so it’s not processed again the next time it’s plugged in.

4. Logging Everything

Logging is essential for tracking every action. I used Python’s built-in logging module to record every step, from detecting a USB drive to copying files and catching errors.

logging.basicConfig(  
    filename=LOG\_FILE,  
    level=logging.INFO,  
    format="%(asctime)s - %(levelname)s - %(message)s"  
)  
logging.info("USB AutoCopy started.")

This setup captures all the actions, allowing me to review exactly what happened if something goes wrong.

5. Continuous Monitoring

To ensure the system runs continuously in the background, I needed the script to check for new drives every 5 seconds. If a new drive is detected, the script automatically triggers the backup process.

def main():  
    logging.info("Monitoring USB devices...")  
    previous\_drives = set(get\_mounted\_drives())  
    while True:  
            time.sleep(5)  
            current\_drives = set(get\_mounted\_drives())  
            new\_drives = current\_drives - previous\_drives  
            for drive in new\_drives:  
                drive\_id = get\_drive\_id(drive)  
                if drive\_id:  
                    if drive\_id not in copied\_devices:  
                        logging.info(f"New USB detected: {drive} (ID: {drive\_id})")  
                        copy\_from\_usb(drive, drive\_id)  
                    else:  
                        logging.info(f"USB {drive} already copied this session. Skipping.")  
            previous\_drives = current\_drives

The main() function continuously monitors for new USB devices and starts the backup process as soon as a new device is detected.

6. Running It Silently in the Background

To make the system user-friendly, I converted the script into a GUI-less executable that runs silently in the background. Using PyInstaller, I created a standalone executable that doesn’t open a terminal window.

pyinstaller --onefile --noconsole usb\_autocopy.py

This creates a single executable file that runs silently in the background. I then set the script to start automatically every time the computer boots.

🚀 The Final System

After following these steps, I now have a fully automated, silent backup system that:

  • Detects USB devices as soon as they are plugged in.
  • Automatically copies files from the USB to a local backup folder.
  • Generates detailed logs of every action.

The best part? It runs in the background without any intervention, ensuring that I never forget to back up my files again.

🔧 Customization & Extensions

This basic system can easily be customized to suit different needs. For instance, you could:

  • Add filters to back up only specific types of files.
  • Implement encryption to protect sensitive data during the backup process.
  • Set up cloud backups to sync data online for added redundancy.

The possibilities for enhancing this system are endless!

It’s important to remember that consent is key. Before backing up any data, make sure you have clear permission from the owner of the files. Unauthorized copying of data could violate local laws or company policies.

If you plan to use this system in a workplace environment, be sure to get approval from IT, legal, and security teams.

✨ Final Thoughts

Building this script wasn’t just about automating a small task. It was about creating a seamless, efficient backup solution that operates in the background, without requiring constant attention.

Key takeaways from the project:

  • Automatic USB detection.
  • Silent, error-free backups.
  • Comprehensive logging for transparency.
  • Continuous monitoring for new devices.
  • Error handling to ensure smooth operation.

What started as a small idea has evolved into a fully automated solution that saves time and ensures data safety.

Feel free to try the system out! Here’s the full code:

GitHub Repository — USB AutoCopy

Let me know if you have questions or ideas for extending this system!

Related Articles