How to Get the Full Access Control List (ACL) of a File in Batch Script
Security administration in Windows revolves heavily around NTFS permissions. Knowing exactly who has what type of access to a crucial server file or sensitive directory is essential for audits and troubleshooting "Access Denied" errors. The lists defining these permissions are called Access Control Lists (ACLs).
In this guide, we will explore the best tools for extracting the full Access Control List of files and folders using Batch scripting. We will focus primarily on icacls, the modern standard built into Windows.
The icacls Command
icacls is the built-in command-line utility for displaying or modifying Access Control Lists (ACLs) for files and folders. It replaced the older cacls command.
Viewing Basic Permissions
To view the ACL for a specific file, simply provide the path to icacls.
icacls "C:\SensitiveData\Payroll.xlsx"
Typical Output:
C:\SensitiveData\Payroll.xlsx NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
DOMAIN\FinanceGroup:(I)(RX)
DOMAIN\JaneDoe:(I)(M)
Successfully processed 1 files; Failed processing 0 files
Understanding the Output
The output format looks cryptic. It lists the User/Group followed by their specific permission abbreviations in parentheses.
- (F) - Full Control: Can read, write, modify, execute, change permissions, and take ownership.
- (M) - Modify: Can read, write, change, and execute files.
- (RX) - Read and Execute: Can view lists of files, read files, and run applications.
- (R) - Read: Can view lists of files and read file contents.
- (W) - Write: Can write to a file but cannot modify existing contents (append only) unless combined with other rights.
- (I) - Inherited: This means the permission was inherited from the parent folder rather than explicitly set on this specific file.
For example, DOMAIN\FinanceGroup:(I)(RX) means the Finance Group inherited Read & Execute permissions from the folder above Payroll.xlsx.
Saving ACLs for Auditing or Backup
If you are performing an audit or preparing to make massive changes to a directory structure, backing up the current ACLs is critical. You can save the entire ACL structure of a directory tree to a text file using /save.
Scripting an ACL Backup
Here is a Batch script that accepts a folder path and saves all its ACLs into a timestamped file.
@echo off
setlocal
set "TARGET_DIR=C:\Shared\Marketing"
set "BACKUP_DIR=C:\AclBackups"
set "BACKUP_FILE=%BACKUP_DIR%\Marketing_ACLs.txt"
set "LOG_FILE=%BACKUP_DIR%\Marketing_ACLs_Log.txt"
REM -------------------------------
REM Verify the target directory exists
REM -------------------------------
if not exist "%TARGET_DIR%" (
echo [ERROR] Target directory does not exist: "%TARGET_DIR%"
pause
exit /b 1
)
REM -------------------------------
REM Ensure the backup directory exists
REM -------------------------------
if not exist "%BACKUP_DIR%" (
mkdir "%BACKUP_DIR%"
if errorlevel 1 (
echo [ERROR] Failed to create backup directory: "%BACKUP_DIR%"
pause
exit /b 1
)
)
REM -------------------------------
REM Backup ACLs recursively
REM -------------------------------
echo Saving ACLs...
REM Remove /q so output is visible
icacls "%TARGET_DIR%" /save "%BACKUP_FILE%" /t /c > "%LOG_FILE%" 2>&1
REM -------------------------------
REM Check for success
REM -------------------------------
if %ERRORLEVEL% equ 0 (
echo [SUCCESS] Access Control Lists saved to "%BACKUP_FILE%"
echo Log of the operation saved to "%LOG_FILE%"
) else (
echo [WARNING] Backup finished, but some files produced errors.
echo See "%LOG_FILE%" for details.
)
echo ------------------------------------------
echo Done.
endlocal
Why Use /save Instead of Piping?
While you could use icacls "C:\folder" > output.txt, the /save parameter creates a specially formatted, Unicode text file that icacls can later read using the /restore command. It is much safer for recreating lost permissions.
Restoring an ACL Backup:
icacls "C:\Shared\Marketing" /restore "C:\AclBackups\Marketing_ACLs.txt"
Finding the File Owner
Sometimes you don't need the full ACL; you just need to know who owns the file. An even simpler built-in tool exists just for identifying owners: dir /q.
Script: Find Owner Using DIR
The dir /q command displays the owner of a file in the column just before the file name.
dir /q "C:\SensitiveData\Payroll.xlsx"
Output:
05/10/2026 09:00 AM 145,200 BUILTIN\Administrators Payroll.xlsx
Advanced ACL Extraction with PowerShell
While icacls is excellent, parsing its bracketed output programmatically in a Batch script is extremely messy and difficult if you are trying to find "Does User X have Write access?".
If you need programmatic analysis of an ACL within a batch script, wrapping a PowerShell command is far superior.
Hybrid Script: Clean ACL Export
@echo off
setlocal
set "TARGET_FILE=C:\SensitiveData\Payroll.xlsx"
if not exist "%TARGET_FILE%" (
echo [ERROR] File not found: %TARGET_FILE%
pause
exit /b 1
)
echo Getting clean ACL format using PowerShell...
echo.
powershell -NoProfile -Command ^
"try {" ^
"$acl = Get-Acl -LiteralPath '%TARGET_FILE%' -ErrorAction Stop;" ^
"$acl.Access | Format-Table IdentityReference, FileSystemRights, AccessControlType -AutoSize" ^
"} catch {" ^
"Write-Host ('[ERROR] ' + $_.Exception.Message)" ^
"}"
echo.
endlocal
pause
Output:
IdentityReference FileSystemRights AccessControlType
----------------- ---------------- -----------------
NT AUTHORITY\SYSTEM FullControl Allow
BUILTIN\Administrators FullControl Allow
DOMAIN\FinanceGroup ReadAndExecute Allow
DOMAIN\JaneDoe Modify Allow
This output is infinitely more readable than icacls for human auditors because it spells out the rights explicitly.
Conclusion
The icacls command is the definitive tool in Batch scripting for getting the full Access Control List of files and directories. Utilizing the /save switch is the proper way to backup permissions, while hybrid PowerShell scripts offer a cleaner, more human-readable display of complex NTFS rights. Always remember that reading ACLs for sensitive files requires that your script runs with Administrative or Backup Operator privileges.