Using ICACLS to set file permission to 'read-only'
Permissions in Unix and Windows work in different ways. In Windows you have inheritance by default and permissions are more granular because you have ACEs (permissions per identity), not just owner/group/other. Permissions for the owner is only given on creation. If you change owner later, you need to manually update ACEs before the owner can modify the file.
Because of this, you need to know who you want to give permissions to. If you want to only give read permission to the user you are logged on with, you can use $env:username
in PowerShell or %USERNAME%
in cmd.
Examples using PowerShell:
$path = ".\test.txt"
#Reset to remove explict permissions
icacls.exe $path /reset
#Give current user explicit read-permission
icacls.exe $path /GRANT:R "$($env:USERNAME):(R)"
#Disable inheritance and remove inherited permissions
icacls.exe $path /inheritance:r
If you want set it equal to chmod 400
, you can check who's the owner and assign permissions to that account. Be aware that this can also be a group like Administrators:
$path = ".\test.txt"
icacls.exe $path /reset
icacls.exe $path /GRANT:R "$((Get-Acl -Path $path).Owner):(R)"
icacls.exe $path /inheritance:r
Or you can use the built-in cmdlets in PowerShell:
$path = ".\test.txt"
#Get current ACL to file/folder
$acl = Get-Acl $path
#Disable inheritance and remove inherited permissions
$acl.SetAccessRuleProtection($true,$false)
#Remove all explict ACEs
$acl.Access | ForEach-Object { $acl.RemoveAccessRule($_) }
#Create ACE for owner with read-access. You can replace $acl.Owner with $env:UserName to give permission to current user
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList $acl.Owner, "Read", "Allow"
$acl.AddAccessRule($ace)
#Save ACL to file/folder
Set-Acl -Path $path -AclObject $acl
Kyle Vassella
Started from the bottom, now we've got an expandable user card.
Updated on June 14, 2022Comments
-
Kyle Vassella almost 2 years
I'm having a heck of a time transferring from the simple, intuitive
chmod 400
to trying to do the same thing in Windows Command Prompt usingICACLS
. Compared to the sleek, octal representation of UNIX/LINUX'schmod
,ICACLS
seems a complex nightmare.I have a SSH .pem key which I'm trying to make read-only. I want to replace the old permissions which are currently on it with this new, read-only permission. The closest I've come to finding an answer is the following:
ICACLS "D:\Folder A\Another Folder\File Name Here.ext" /GRANT:R "DOMAIN\USERNAME":R
(found here: https://www.experts-exchange.com/questions/27624477/What-command-can-give-user-read-only-permission.html)I believe the
:R
at the very end allows me to replace the current permissions, which is what I want. But I don't know what to put for the"DOMAIN\USERNAME"
segment. Any advice? -
Kyle Vassella about 7 yearsI don't think so - I was reading that you're really supposed to use
ICACLS
to change the file permissions and notattrib
- plus I don't think adding the read attribute will remove the write and execute permissions already on the file. Thank you for trying though! -
Joe Berg over 4 yearsThank you. This is still relevant and saved me after quite a bit of searching
-
Dennis almost 4 yearsgreat answer, thanks. Typo in the second example where you are not modifying the owner. Line 3 should be
icacls.exe $path /GRANT:R "$((Get-Acl -Path $path).Owner):(R)"
-
Paul Pritchard almost 2 yearsWorked a treat for me, just typing each command in at the PowerShell prompt. Thank you @frode-f