Ransomware in Schools: Why Your Offline Backups Are Your Only Hope

Your edutech ransomware protection strategy starts and ends with one uncomfortable truth: when ransomware hits at 6 AM on a Monday and your entire student information system is encrypted, your endpoint agent is not going to save you.

Neither is your cloud-sync folder  because ransomware actors specifically target mapped drives and cloud sync clients in the first 60 seconds of execution. The only thing standing between your district and a six-figure ransom note is whether you have a clean, offline, air-gapped backup that the malware never touched.

Most schools are running a patchwork of aging hardware, a stretched two-person IT team, and security software that hasn’t been audited since the last superintendent. The attackers know this.

School districts were the most targeted public sector vertical for ransomware for the third consecutive year. This guide cuts through the vendor noise and gives you the exact implementation you need  PowerShell scripts, air-gap logic, and the gotchas that will burn you if you skip them.

The Quick Fix: Your Air-Gap Backup Script (Deploy Today)

Drop this on your backup server. It mounts an offline USB target only during the backup window, runs the job, then unmounts and power-cycles the drive via a managed USB hub. The drive is electronically invisible to the network the other 23 hours of the day.

Schedule this via Task Scheduler under a dedicated local service account with no network rights and no domain membership. If ransomware has your domain, it cannot touch what it cannot authenticate to.

Why the Standard Advice Fails in a School Environment

Microsoft’s own backup documentation points you toward Azure Backup or Windows Server Backup to a network share. In a district with a properly-segmented network and a dedicated security team, that’s fine. In a school with one IT admin, flat VLANs, and a $0 security budget, it is a liability.

Here is exactly why the generic approach collapses:

  • Cloud sync targets are not backups. OneDrive, Google Drive, and Dropbox sync deletions and encryption nearly in real time. Ransomware encrypted a 2022 district’s SIS and the “backup” folder was fully re-synced with encrypted files within 8 minutes.
  • NAS targets on the domain are reachable. If your NAS is domain-joined or has a mapped drive letter visible from any workstation, ransomware with lateral movement capability will find it. SMB shares are a primary target.
  • Backup software agents get killed first. Modern ransomware families specifically terminate common backup agent processes (Veeam, Acronis, ShadowProtect) before beginning encryption. Relying on the agent alone is not a recovery strategy.
  • VSS snapshots get deleted. Ransomware routinely calls `vssadmin delete shadows /all /quiet` as one of its first actions. If your only local snapshots are VSS, assume they are gone.

Step-by-Step Implementation: The Air-Gap Backup Stack

Hardware you need (total cost: ~$300-$600):

  • 3x external USB 3.0 drives (4TB minimum — rotate on a Mon/Wed/Fri schedule). Keep one offsite at all times.
  • 1x USB relay/hub controller (Denkovi DA-Base8, ICStation, or a smart PDU with USB port control). This is what the script toggles — drives power OFF between jobs.
  • 1x dedicated backup server (even a $150 refurb OptiPlex works). It must not be domain-joined.

Phase 1: Harden the Backup Host

  • Remove from the domain. Local accounts only. No domain admin credentials should ever touch this machine.
  • Enable Windows Defender Application Control (WDAC) or Software Restriction Policies. Only robocopy.exe, powershell.exe, and your backup script are allowed to execute.
  • Disable RDP. Manage via direct KVM or a physically isolated management VLAN with MFA.
  • Block all outbound internet at the firewall for this host’s IP. It has one job

Phase 2: Set Up the Rotation Schedule

The 3-2-1-1 rule for schools with no budget: 3 copies, 2 media types, 1 offsite, 1 air-gapped offline.

# Drive rotation logic — add to Invoke-AirGapBackup.ps1

# Label drives AIRGAP_A, AIRGAP_B, AIRGAP_C

 

$DayMap = @{

“Monday”    = “AIRGAP_A”

“Wednesday” = “AIRGAP_B”

“Friday”    = “AIRGAP_C”

}

 

$TodayLabel = $DayMap[(Get-Date).DayOfWeek.ToString()]

 

if (-not $TodayLabel) {

Write-Log “No backup scheduled today. Exiting cleanly.”

exit 0

}

 

# Swap $Drive lookup to use $TodayLabel instead of wildcard

$Drive = Get-WmiObject Win32_LogicalDisk |

Where-Object { $_.VolumeName -eq $TodayLabel } |

Select-Object -First 1

 

Phase 3: Verify Your Backups Actually Work

An untested backup is not a backup. Run a restore drill every quarter. Pull a drive, mount it on an isolated VM, and restore one full application. Document the RTO (Recovery Time Objective) and present it to administration. When a ransomware attack happens — and it will — you want that number on paper so the board understands why you’re asking for 48 hours, not 4.

# Invoke-BackupVerify.ps1

# Run monthly on an isolated, non-domain VM

 

param([string]$BackupRoot = “D:\Backups”)

 

# Get the most recent backup folder

$Latest = Get-ChildItem $BackupRoot -Directory |

Sort-Object CreationTime -Descending |

Select-Object -First 1

 

if (-not $Latest) { Write-Error “No backup folders found.”; exit 1 }

 

Write-Host “Verifying: $($Latest.FullName)”

 

# Hash-check 50 random files to confirm integrity (not full scan — too slow)

$Files = Get-ChildItem $Latest.FullName -Recurse -File |

Get-Random -Count 50

 

$BadFiles = 0

foreach ($f in $Files) {

try {

$hash = Get-FileHash $f.FullName -Algorithm SHA256

# In production: compare against a hash manifest generated at backup time

Write-Host “OK  $($hash.Hash.Substring(0,8))…  $($f.Name)”

} catch {

Write-Warning “FAIL: $($f.FullName)”

$BadFiles++

}

}

 

if ($BadFiles -gt 0) {

Write-Error “$BadFiles file(s) failed integrity check. Investigate immediately.”

} else {

Write-Host “Verification passed. $($Files.Count) files sampled clean.”

}

Gotcha #1: The USB Hub Relay Script Fails Silently.

 

If Toggle-USBHub.ps1 throws an exception (wrong COM port, vendor driver update, hub firmware change), the script catches it in the finally block and tries to power OFF anyway. But if the hub never powered ON, the drive was never mounted, and robocopy ran against a null path — and you get no backup and no alert.

Fix: Add an explicit drive-presence check with email/Teams alerting before robocopy starts. If $Drive is null after a 30-second spin-up wait, send an alert via Send-MailMessage or a webhook and exit 1. Do not let silent failures accumulate.

Gotcha #2: Robocopy /B (Backup Mode) Requires SeBackupPrivilege

Running this under a standard local service account will cause robocopy to fail on locked database files with Access is Denied errors — exactly the files you most need. The account running the script needs the SeBackupPrivilege right, which is not automatically granted even to local admins.

# Add SeBackupPrivilege to your backup service account via Local Security Policy

# Or via PowerShell (requires local admin on the backup host):

 

# Install the Carbon module (no internet? Copy the .nupkg manually)

Install-Module -Name Carbon -Force -Scope AllUsers

 

Import-Module Carbon

Grant-CPrivilege -Identity “BACKUPSRV\svc_backup” -Privilege SeBackupPrivilege

Grant-CPrivilege -Identity “BACKUPSRV\svc_backup” -Privilege SeRestorePrivilege

 

# Verify

Get-CPrivilege -Identity “BACKUPSRV\svc_backup”

 

Gotcha #3: The SIS Database Files Are Always Open

Student Information Systems (PowerSchool, Skyward, Infinite Campus) hold their database files in an exclusive lock 24/7. Robocopy in backup mode handles most of this, but if you’re backing up a local SQL Server instance, you need a pre-backup SQL dump, not a raw file copy.

# Add this BEFORE the robocopy call for SQL-backed SIS systems

 

$SQLInstance = “SIS-SERVER\SQLEXPRESS”

$DBName      = “PowerSchool”

$DumpPath    = “C:\Temp\sis_dump_$Timestamp.bak”

 

Write-Log “Dumping SQL database to staging path…”

Invoke-Sqlcmd -ServerInstance $SQLInstance -Query @”

BACKUP DATABASE [$DBName]

TO DISK = N’$DumpPath’

WITH COMPRESSION, STATS = 10;

“@

 

# Now add $DumpPath to your robocopy source, then clean it up afterward

# The dump is a consistent snapshot; the .mdf file copy is not.

 

What to Automate Next

An air-gapped, rotation-scheduled, verified offline backup is your non-negotiable floor — ship this script this week, label three drives, plug in a USB relay, and schedule the task. Once that’s running and you’ve done one restore drill, the next move is automating your network segmentation audit so that when ransomware lands on a student Chromebook, it physically cannot reach your SIS server in the first place.

Your backups buy you recovery. Your segmentation buys you containment. Together, they mean the next ransom note goes straight in the bin.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top