How to Grant Read-Only Access to a File in Batch Script
Securing configuration files, legal documents, or baseline templates against accidental modification is a critical administrative task. While users may need to view the contents of a file, granting them the ability to save changes or delete the file introduces risk.
In this guide, we will explore how to grant strictly Read-Only access to a file using Batch scripting. We will look at both the simple "Read-Only attribute" method and the much more secure NTFS permission method using icacls.
Method 1: Setting the Read-Only Attribute (Simple but Weak)
The oldest and simplest way to make a file read-only in DOS and Windows Batch is using the attrib command.
Syntax
attrib +r "C:\Path\To\File.txt"
+r: Adds the Read-Only attribute.-r: Removes the Read-Only attribute.
Basic Script Example
@echo off
setlocal
set "TEMPLATE_FILE=C:\Shared\CompanyLetterhead.docx"
if not exist "%TEMPLATE_FILE%" (
echo [ERROR] File not found: %TEMPLATE_FILE%
pause
exit /b 1
)
echo Locking the template file...
attrib +r "%TEMPLATE_FILE%"
if %ERRORLEVEL% equ 0 (
echo [SUCCESS] File is now marked Read-Only.
) else (
echo [ERROR] Failed to set Read-Only attribute on %TEMPLATE_FILE%.
)
endlocal
pause
The Problem with attrib
The attrib +r command is technically a suggestion to the operating system and applications. It prevents accidental saves (e.g., Word will prompt "This file is read-only. Save as...").
However, it is not a security boundary. Any user with standard Modify folder permissions can simply open properties, uncheck the "Read-only" box (or run attrib -r), and overwrite the file. It protects against accidents, not malicious intent.
Method 2: Granting Read-Only NTFS Permissions (Strong security)
If you want absolute certainty that a specific user or group cannot alter a file, regardless of attributes, you must modify the Access Control List (ACL) using the icacls command.
NTFS permissions enforce security at the file-system level.
Understanding the Read Permission
In icacls, the flag for Read access is (R). However, often users need to open and run files (like PDFs or scripts), so Read & Execute (RX) is frequently used.
- (R) - Read: Can view the file contents and its properties.
- (RX) - Read & Execute: Can view contents and run the file if it is an executable/script.
Robust Security Script
Let's assume "Interns" currently have "Modify" access to a folder, but we have one specific file (Archive.zip) that they should absolutely not be able to delete or alter. We will change their explicit permission to Read-Only.
@echo off
setlocal
set "SECURE_FILE=C:\Finance\Q1_Archive.zip"
set "TARGET_GROUP=DOMAIN\Interns"
if not exist "%SECURE_FILE%" (
echo [ERROR] File not found: %SECURE_FILE%
pause
exit /b 1
)
echo Establishing strict Read-Only access for %TARGET_GROUP% on %SECURE_FILE%...
REM The /grant:r switch REPLACES existing explicit permissions for that group.
REM If they previously had (M) Modify, it is overwritten with (R) Read.
icacls "%SECURE_FILE%" /grant:r "%TARGET_GROUP%:(R)"
if %ERRORLEVEL% equ 0 (
echo [SUCCESS] %TARGET_GROUP% can now only read the file. Modification is blocked.
) else (
echo [ERROR] Failed to set permissions. Run script as Administrator.
)
endlocal
pause
Dealing with Inheritance (The "Access Denied" Loophole)
If you run the script above and find the Interns still have "Modify" access, they are likely receiving that permission through Inheritance from the parent folder (e.g., the C:\Finance folder grants them Modify).
An explicit /grant does not automatically override an inherited capability if both exist. If a folder says "Modify" and the file explicitly says "Read", they retain "Modify".
To fix this, you have two choices:
- Break Inheritance (
/inheritance:d): Copy the parent limits, then downgrade the Interns to Read. - Explicit Deny (The sledgehammer): Deny them Write access explicitly.
The Explicit Deny Fix
An explicit Deny overriding everything else is exactly what you need to guarantee Read-Only status against inherited broader rights.
@echo off
setlocal
set "SECURE_FILE=C:\Finance\Q1_Archive.zip"
set "TARGET_GROUP=DOMAIN\Interns"
if not exist "%SECURE_FILE%" (
echo [ERROR] File not found: %SECURE_FILE%
pause
exit /b 1
)
echo Forcing Read-Only by explicitly blocking Write and Delete access...
REM Deny Write (W) and Delete (D) for the target group.
REM They will still be able to use their inherited Read (R) rights.
icacls "%SECURE_FILE%" /deny "%TARGET_GROUP%:(W,D)"
if %ERRORLEVEL% equ 0 (
echo [SUCCESS] %TARGET_GROUP% can read but cannot write or delete %SECURE_FILE%.
) else (
echo [ERROR] Failed to apply Deny rule. Ensure you run this as Administrator.
)
endlocal
pause
(W) denies writing and appending data, (D) denies deletion.
Summary
When writing Batch scripts to enforce Read-Only access:
- Use
attrib +rif you just want to protect a template from clumsy users accidentally hitting Ctrl+S. It's fast and easy. - Use
icacls ... /grant:r "User:(R)"(combined with blocking Write inheritance via/deny (W,D)if necessary) when you need mathematically sound, system-level security guaranteeing the file's integrity against deliberate modification.