diff --git a/backup.sh b/backup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d8a3ad96055dd9d887f32e29f8d398efbe59d554
--- /dev/null
+++ b/backup.sh
@@ -0,0 +1,178 @@
+#!/bin/bash
+snipeitDirectory="/var/www/html/snipeit"
+backupDirectory="$snipeitDirectory/storage/app/backups"
+dbDumpFile="$snipeitDirectory/vendor/spatie/db-dumper/src/Databases/MySql.php"
+destinationDir="/export/home/snipeit/backups"
+
+#/ Usage: backup.sh [-dbmof]
+#/
+#/ Create an incremental backup of a snipeit-instance
+#/
+#/ OPTIONS:
+#/   -d | --snipeit-directory          Set the directory of the instance to be backed up
+#/   -b | --backup-directory           Set the directory where SnipeIT places the internal backups
+#/   -m | --mysql-dump-settings        Set the location of the database dump settings file
+#/   -o | --output-directory           Set the output directory for where to place the backups
+#/   -f | --full-backup                Make a new, full, backup instead of an incremental one
+#/   -h | --help                       Show this message.
+
+print_usage () {
+  grep '^#/' <"$0" | cut -c 4-
+  exit 1
+}
+
+#Parse arguments
+while [[ $# > 0 ]]; do
+  case "$1" in
+    -d|--snipeit-directory)
+      shift
+      if test $# -gt 0; then
+        snipeitDirectory=$(echo "$1" | sed "s,/$,,")
+      else
+        echo "No SnipeIT directory specified"
+        exit 1
+      fi
+      shift
+      ;;
+    -b|--backup-directory)
+      shift
+      if test $# -gt 0; then
+        backupDirectory=$(echo "$1" | sed "s,/$,,")
+      else
+        echo "No backup directory specified"
+        exit 1
+      fi
+      shift
+      ;;
+    -m|--mysql-dump-settings)
+      if test $# -gt 0; then
+        dbDumpFile=$1
+      else
+        echo "No database dump settings specified"
+        exit 1
+      fi
+      shift
+      ;;
+    -o|--output-directory)
+      if test $# -gt 0; then
+        destinationDir=$(echo "$1" | sed "s,/$,,")
+      else
+        echo "No output directory specified"
+        exit 1
+      fi
+      shift
+      ;;
+    -f|--full-backup)
+      echo "Creating full backup"
+      mkdir "$destinationDir/$(date +%s)"
+      shift
+      ;;
+    -h|--help)
+      print_usage
+      exit 1
+      ;;
+    -*)
+      echo "Error: invalid argument: '$1'" 1>&2
+      print_usage
+      exit 1
+      ;;
+  esac
+done
+
+if ! [ -d "$destinationDir/" ]; then
+    echo "Output directory not found: $destinationDir"
+    exit 0
+fi
+
+if ! [ -d "$snipeitDirectory/" ]; then
+    echo "SnipeIT directory not found: $snipeitDirectory"
+    exit 0
+fi
+
+if ! [ -d "$backupDirectory/" ]; then
+    echo "Backup directory not found: $backupDirectory"
+    exit 0
+fi
+
+if ! [ -f "$dbDumpFile" ]; then
+    echo "Database dump settings file not found: $dbDumpFile"
+    exit 0
+fi
+
+#Update value in config file to get correct format
+sed -i 's/protected $useExtendedInserts = true;/protected $useExtendedInserts = false;/' $dbDumpFile
+
+#Generate the internal backup
+cd $snipeitDirectory
+php artisan backup:run
+backupFile=$(ls -lt $backupDirectory | head -3 | tail -1 | awk '{print $9}')
+extractDir=$(echo $backupFile | cut -f 1 -d '.')
+echo "Current backup: $extractDir"
+
+#Create the workdir and copy all the important files to it
+workdir=$(mktemp -d)
+cd $workdir
+echo "Tmp dir: $workdir"
+mkdir new
+unzip -qq "$backupDirectory/$backupFile" -d "./$extractDir" > /dev/null 2>&1
+cd $extractDir
+echo "Copied:"
+find . -path ".$snipeitDirectory/public/uploads/barcodes" -prune -o -print| egrep '(*\.png|*\.jpg|*\.webp|*\.gif|*\.svg|\.env)$' | cpio -pdmu ../new/
+cd ../
+cp -r $extractDir/db-dumps new/
+
+now=$(date +%s)
+
+#If there are no previous full backups, then create one
+if [ -z "$(ls -A "$destinationDir/")" ]; then
+    mkdir "$destinationDir/$now"
+fi
+
+lastBackup=$(ls -lt $destinationDir | head -2 | tail -1 | awk '{print $9}')
+
+#If there are no patches, create a folder for them
+if ! [ -d "$destinationDir/$lastBackup/patches" ]; then
+    mkdir "$destinationDir/$lastBackup/patches"
+fi
+
+#Check and copy all files (images, .env) that are either new or changed.
+cd new
+files=$(find ".$snipeitDirectory" -type f)
+echo "Files to check:"
+echo "$files"
+echo "Trying to copy:"
+
+while IFS= read -r file; do
+    if ! [ -f "$destinationDir/$lastBackup/$(echo $file | cut -c 3-)" ] || [ "$destinationDir/$lastBackup/$(echo $file | cut -c 3-)" -ot "$file" ]; then
+        cp -u --parents "$file" "$destinationDir/$lastBackup/"
+        echo "Copied $file $destinationDir/$lastBackup/$(echo $file | cut -c 3-)"
+    else
+        echo "File already exists: $destinationDir/$lastBackup/$(echo $file | cut -c 3-)"
+    fi
+done <<< "$files"
+
+#Try to make a patch of the database dump
+file="db-dumps/mysql-snipeit.sql"
+if [ -z "$(ls -A "$destinationDir/$lastBackup/patches")" ]; then
+    diff -urN null $file > patch.patch
+    cp "patch.patch" "$destinationDir/$lastBackup/patches/$now.patch"
+    echo "Copied patch to $destinationDir/$lastBackup/patches/$now.patch"
+else
+    for p in "$destinationDir/$lastBackup/patches/*.patch"; do
+        (patch --quiet -p1) < $p
+    done
+    
+    result=$(diff "mysql-snipeit.sql" "$file" > "$now.patch" && echo $? || echo $?)
+    
+    #Only save non-empty patches
+    if [ $result != 0 -a $result != 1 ]; then
+        echo "Nothing to patch"
+        exit 1
+    fi
+    if [ -s "$now.patch" ]; then
+        cp "$now.patch" "$destinationDir/$lastBackup/patches/"
+        echo "Copied patch to $destinationDir/$lastBackup/patches/$now.patch"
+    else
+        echo "Nothing to patch"
+    fi
+fi