Set Folders as Read Only using Powershell

Awhile back, I had to create a script that set permissions on a folder to Read Only on a Windows Server. Trying this as a batch file was more difficult than with Powershell.

The script will read a CSV file, which will contain the username and folder that you want to set as read only. The child folders will inherit the Read Only permission from the folder it sets as Read Only for that user.

This will run in a loop and output information in a text file as a log. Pretty handy to see if it set it correctly or not. I do notice one issue which is that if you have a ton of files in the directory, it will log that in the log file. In the future, I might create separate log files per user folder to lessen the amount of data in the one log file.

This script has been tested on Server 2008/R2 and Server 2012/R2. Make sure the execution policy for Powershell is set as Unrestricted while running this script and then turning it back on to Restricted.

Here is the two files as shown below:
ReadOnlyFolders.ps1

#############################
# ReadOnlyFolders.ps1
# Version 1.1
#
# Created by: Infinite Technica
# www.infinitetechnica.com
# Date: 2016/04/04
# 
# Licensed under Creative Commons Zero
# https://creativecommons.org/publicdomain/zero/1.0/
#############################


# Variables
# Change D:\ to any Drive letter you will put your CSV file at
$csv = Import-Csv 'D:\Set Read Only\ReadOnly.csv'
$currentDate = get-date -format yyyyMMdd
$currentRDate = get-date -format yyyy/MM/dd
$currentTime = get-date -format hh:mm:sstt
$outputName = "ReadOnlyLog-" + $currentDate + ".txt"
#############################
# Change the Drive Path; Make sure you change D:\ if you don't want it at that path
$outputPath = "D:/$outputName" 
#############################


# Creating Initial Log File
echo "Output log for Read Only Permissions Script" > $outputPath
echo "Date Ran: $currentRDate" >> $outputPath
echo "Time Ran: $currentTime" >> $outputPath
echo "================================================" >> $outputPath

# For Loop
foreach ($line in $csv) {
    # Variables
    $User = $line.Users
    
    #############################
    # CHANGE THIS TO YOUR DOMAIN
    $Domain = "YOUR DOMAIN" 
    #############################

    $DomainUser = $Domain + "/" + $User
    $GrantVar = ":(OI)(CI)RX"
    $RemoveVar = "g,d"
    $Directory = $line.Directory
    $GrantUser = $User + $GrantVar
    $Verify = ""
    $VerifyUser = $Domain + "\" + $User
    $VerifyPermission = ""

    # Adding Information to Log File
    echo "User: $User" >> $outputPath
    echo "Starting Directory: $Directory" >> $outputPath
    echo " " >> $outputPath

    # Removing Permissions
    echo "Removing Permissions" >> $outputPath
    icacls ($Directory) /inheritance:d /remove:$RemoveVar ($User) >> $outputPath
    
    
    # Adding Read-Only Permissions
    echo " " >> $outputPath
    echo "Changed to Read-Only" >> $outputPath
    icacls ($Directory) /grant:r $GrantUser /t >> $outputPath
    

    # Verifying Read-Only has been set
    echo " " >> $outputPath
    $VerifyPermission = (get-acl $Directory).Access | Where-Object {$_.IdentityReference -eq "$VerifyUser" -and $_.FileSystemRights -eq "ReadAndExecute, Synchronize"}
    if ($VerifyPermission.FileSystemRights -eq "ReadAndExecute, Synchronize") {
        $verify = "Yes"
    }
    else
    {
        $verify = "No"
    }

    echo "Verified Read-Only: $Verify" >> $outputPath
    echo "" >> $outputPath
    echo "-------------------------------" >> $outputPath
}


ReadOnly.csv

Users,Directory
user1,D:\user\testuser1
user2,D:\user\testuser2\files

With my code, I try to license it as Creative Commons Zero because code can be written several different ways. Feel free to modify it however you want!