Search code examples
powershellacl

Execute icacls command on remote servers


Below is code I have which is executing perfectly when ran for individual servers


$Hostname = $env:COMPUTERNAME
$CsvData = Import-Csv -Path "C:\Ansible\status_report_2021.csv" | Where-Object{$_.ServerName -eq $Hostname} | Select-Object SystemFolderPath

foreach($path in $CsvData)
{

$path = $path.SystemFolderPath
$path = $path.trim('\')

# break inheritance on the folder and copy ACEs as uninherited
icacls $path /inheritance:d

#remove all BUILTIN\Users granted ACEs
icacls $path /remove:g BUILTIN\Users

#grant only BUILTIN\Users Read&Execute. avoid using (S,GE,GR) = RX.
#(S,GE,GR) is a specific right and icacls would create 2 ACEs.
#same meaning but if we can avoid it's better
icacls $path /grant:r "BUILTIN\Users:(OI)(CI)RX"

#remove SYSTEM
icacls $path /remove:g "NT AUTHORITY\SYSTEM"

#grant SYSTEM as Full control on "this folder, subfolder and files"
icacls $path /grant:r "NT AUTHORITY\SYSTEM:(OI)(CI)F"

icacls $path

}

Please let me know how to execute these icacls commands for remote servers.


Solution

  • I guess you can use a combination of Group-Object to group all server names and their SystemFolderPath entries in the csv together and loop over these groups.

    Inside the loop use Invoke-Command to have the icacls commands perform on each server.

    Something like

    Import-Csv -Path "C:\Ansible\status_report_2021.csv" | Group-Object ServerName | ForEach-Object {
        $server = $_.Name
        foreach ($path in ($_.Group.SystemFolderPath | Select-Object -Unique)) {
            Invoke-Command -ComputerName $server -ScriptBlock {
                param ([string]$path)
                # break inheritance on the folder and copy ACEs as uninherited
                icacls $path /inheritance:d
    
                # remove all BUILTIN\Users granted ACEs
                icacls $path /remove:g BUILTIN\Users
    
                # grant only BUILTIN\Users Read&Execute. avoid using (S,GE,GR) = RX.
                # (S,GE,GR) is a specific right and icacls would create 2 ACEs.
                # same meaning but if we can avoid it's better
                icacls $path /grant:r "BUILTIN\Users:(OI)(CI)RX"
    
                # remove SYSTEM
                icacls $path /remove:g "NT AUTHORITY\SYSTEM"
    
                # grant SYSTEM as Full control on "this folder, subfolder and files"
                icacls $path /grant:r "NT AUTHORITY\SYSTEM:(OI)(CI)F"
    
                icacls $path
            } -ArgumentList $path.Trim('\')
        }
    }