Restores access to external drives whose files are owned by SIDs from a machine that no longer exists — the "Access Denied on every folder" job that lands on a repair bench when a customer's PC dies and their drive gets plugged into another one.
Built to be non-destructive by default, and verifiable before you point it at a client's drive.
.\Fix-DriveAccess.ps1 -Mode SelfTest # prove the safeguards work, on a throwaway folder
.\Fix-DriveAccess.ps1 -Path E:\ # read-only assessment
.\Fix-DriveAccess.ps1 -Path E:\ -Mode Rescue -Destination F:\RecoveredBecause it destroys data you cannot get back.
Almost every guide online recommends:
takeown /F E:\ /R /D Y
icacls E:\ /grant Administrators:F /T
Microsoft's own takeown documentation
defines /D Y as:
"Take ownership of the directory. The directory permissions are replaced with permission granting the user full control only."
On every directory where you lack List/Read — precisely the directories you are
trying to repair — the existing ACL is wiped and replaced. And because those
directories were unreadable, an icacls /save backup taken beforehand could
not record them either. The damage is unrecoverable.
This script takes ownership one directory at a time with takeown /F "<dir>" /A
— no /R, no /D. Per the same documentation /D is only valid alongside
/R, so no ACL-replacement path is reachable. Only the owner field changes.
Once we own a directory we implicitly hold READ_CONTROL and WRITE_DAC, so
the ACL can then be read, recorded, and added to with icacls /grant.
| Mode | Writes to the source? | Use when |
|---|---|---|
SelfTest |
No — only %TEMP% |
Always, before trusting the script |
Report (default) |
No | Read-only assessment |
Rescue |
No | Recommended for client data. Copy it off and stop. |
Repair |
Yes | Only when the original drive itself must work |
Restore |
Yes | Undo a repair's permission changes |
-Mode Rescue uses robocopy /B (backup mode). Microsoft
documents
that in backup mode robocopy "overrides file and folder permission settings
(ACLs), which might otherwise block access" — it reads straight through the
dead machine's SIDs without altering a single permission on the source.
For a data-recovery job this is the correct first move: get the data off, verify it, and only then decide whether the original drive needs fixing.
Rescue re-reads the source afterwards and diffs it, to prove nothing changed.
- No file content is ever read, written, deleted, moved, or renamed
- No filesystem repair — no
chkdsk, nodiskpart, no partition writes icacls /grantis used without:r, which the documentation confirms adds to existing permissions rather than replacing them/reset,/remove,/denyand/setintegritylevelare never used/MIR,/PURGE,/MOV,/MOVE— robocopy's deleting switches — appear nowhere in the script- Refuses to run on the system drive
- Every ACL is exported before modification; every owner change is recorded
- Path, owner, full SDDL and attributes are captured before and after any
procedure, with a
CHANGE-REPORT.txtdiffing them - File count and byte total compared before/after; a decrease is a failure
-DryRunprints every command and executes nothing
icacls /saveand/restorehandle DACLs only. Ownership is not restored byRestore. The owner manifest is a record, not a one-click undo.- An
OWNER RIGHTSACE (S-1-3-4) can revoke the owner's implicitREAD_CONTROL/WRITE_DAC, defeating this approach. Detected and reported. - Many USB enclosures do not pass SMART through. Absent data is reported as unknown, never as healthy.
- Paths over 260 characters may be skipped by
icacls/takeown. Counted and listed rather than silently ignored. - No software-only method is literally zero-write. Attaching an NTFS volume lets Windows replay the journal. For forensic preservation, use a hardware write blocker and image the drive.
Accounts with SeBackupPrivilege enabled — common on recovery and
technician builds — can read files regardless of their ACLs. On such a session:
-Mode Reportwill report a client drive clean that the customer cannot read.
The script probes for this before every scan and prints a full-width warning,
explicitly stating the drive has not been cleared. SelfTest detects it too,
and will temporarily drop the privilege (for its own process only, reversibly)
so the test can still run.
Never clear a drive as healthy from such a session. Rescue from it is fine — arguably ideal, since it reads straight through everything.
This tool ships with docs/VERIFICATION.md: a record of
every behavioural claim, the Microsoft documentation it was checked against, and
every defect found during development — including the ones I got wrong and
had to withdraw.
Fourteen defects were found. Two came from reading documentation; ten came
from actually running it. Several were critical, including two separate
versions of "the scanner reports a locked drive as clean" and one destructive
takeown call.
Current status: 12/12 self-test checks passing on Windows 11 / PowerShell 5.1.
Run the gate yourself before trusting it:
.\Fix-DriveAccess.ps1 -Mode SelfTestIt builds a disposable folder in %TEMP%, locks it behind a fabricated
dead-machine SID, and asserts twelve properties including SHA-256 file
integrity, that pre-existing ACEs survive, and that the backup genuinely
restores. Anything less than 12/12 means don't use it. SKIP is not PASS.
- Windows PowerShell 5.1 or later
- Run elevated
- NTFS source volume (other filesystems have no ACLs to repair; Rescue still works as a copy tool)
Unblock-File .\Fix-DriveAccess.ps1
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force-Scope Process affects only that window and reverts when you close it.
# 1. Verify the tool (once per machine, or after any update)
.\Fix-DriveAccess.ps1 -Mode SelfTest
# 2. Read-only look at the drive
.\Fix-DriveAccess.ps1 -Path E:\
# 3. Get the data off without touching the source
.\Fix-DriveAccess.ps1 -Path E:\ -Mode Rescue -Destination F:\Recovered\Client -DryRun
.\Fix-DriveAccess.ps1 -Path E:\ -Mode Rescue -Destination F:\Recovered\Client
# 4. Only if the original drive itself must work — after step 3 succeeded
.\Fix-DriveAccess.ps1 -Path E:\ -Mode Repair -DryRun
.\Fix-DriveAccess.ps1 -Path E:\ -Mode Repair
# Undo a repair
.\Fix-DriveAccess.ps1 -Path E:\ -Mode Restore -RestoreFrom <permissions.acl>For most jobs you stop at step 3. The customer's data is recovered and their drive is bit-for-bit as it arrived.
Stop and image the drive (ddrescue, HDDSuperClone) if it clicks, stalls,
drops out mid-copy, or reports repeated read failures. Permissions are the least
of the problem on a dying disk, and the health gate cannot see SMART through
most USB enclosures.
Each run writes to <Desktop>\DriveAccessBackups\<label>_<timestamp>\:
| File | What it is |
|---|---|
run.log |
Full transcript |
permissions.acl |
icacls /save export — the undo source |
permissions-BEFORE.csv / -AFTER.csv |
Path, owner, SDDL, attributes |
CHANGE-REPORT.txt |
Human-readable diff. Keep this. |
owner-changes.csv |
Pre-change owner and SDDL of anything re-owned |
Keep the folder until the customer confirms everything is fine. If they ever
ask what was done to their drive, CHANGE-REPORT.txt is the answer.
If you change behaviour, -Mode SelfTest must still pass 12/12, and the change
belongs in docs/VERIFICATION.md with the source you checked it against.
The history of this tool is that plausible reasoning produced confident, wrong answers repeatedly, and only running it settled anything. Please hold new changes to that standard.
MIT — see LICENSE.
This software is provided without warranty. It is intended for data recovery on
drives you are authorised to work on. Always have a verified copy of
irreplaceable data before running anything in Repair mode — including this.