Balaji RR
Balaji RR

Reputation: 63

Check if a folder is given access

I m new to PS scripting. Just started to write a script to find if a folder is permissionned properly for a user. The folder name and the AD account name is same. Say if the folder name is XX11223, then the user XX11223 should have access to that particular folder. The folders which are not properly permissionned should be printed to file. Someone pls help on this.

$Paths = Get-Content "Path.txt"

#To get the subfolders for which the permissions has to be checked

$Folder = foreach ($Path in $Paths) {
    $Path = $Path | Select-Object -Unique
    Write-Host $Path -ForegroundColor Green
    Get-ChildItem $Path | Where-Object { $_.Attributes -eq 'Directory' } | Select-Object FullName
}

#To get the ACLs for the list of folders from above

$ACLS = Get-Content $Folder

$Out = foreach ($ACL in $ACLS) { 
    Write-Host $ACL -ForegroundColor Cyan
    Get-Acl $ACL | Select-Object AccesstoString
}

I m stuck here and have not a faintest idea how to proceed. :(

Upvotes: 4

Views: 4713

Answers (3)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174545

This all depends on what constitutes "proper permissions", but if you expect the user to have FullControl granted on his folder, you can do the following:

Retrieve the ACL of each folder:

$FolderAcl = Get-Acl $path

Construct an NTAccount object representing the corresponding folder

$Account   = New-Object System.Security.Principal.NTAccount "DOMAIN\user"

And then grab all explicit access rule entries from the ACL granting FullControl to the account in question:

$FullControl = $FolderAcl.GetAccessRules($true,$false,[System.Security.Principal.NTAccount]) | Where-Object {
    $_.FileSystemRights -eq "FullControl" -and 
    $_.AccessControlType -eq "Allow" -and 
    $_.IdentityReference -eq $Account
}

If $FullControl contains $null (ie. no access rules were found) print to file.

if(-not $FullControl){
    $path |Out-File C:\wrongPermissions.txt
}

If you want to find ACE's with Modify rights, including those where Modify is included in another rights (such as FullControl), you can perform a bitwise AND operation against the value of Modify, like so:

$ModifyValue = [System.Security.AccessControl.FileSystemRights]::Modify -as [int]
$ACEswithModify = $FolderAcl.Access |?{ ($_.FileSystemRights -band $ModifyValue) -eq $ModifyValue }

Upvotes: 5

Balaji RR
Balaji RR

Reputation: 63

Thanks @Sodawillow and @Mathias.

I tried to combine both your codes and write a new one to get the desired output. The user should have "Modify" access to the folder. But all paths are getting written to the file. Please check the below code and advise.

$rootList = Get-Content "Path.txt"

$pathList = foreach ($root in $rootList) {
$path = $root | Select-Object -Unique
Write-Host $path -ForegroundColor Green
Get-ChildItem $path -Directory | Select-Object FullName}

foreach ($path in $pathList) {
$path1 = $path | Select-Object -Unique
$folderName = (Get-Item $path1).Name
$FolderAcl = (Get-Acl $path1).Access

$Permission = $FolderAcl | Where-Object {
$_.FileSystemRights -like "*Modify*" -and 
$_.IdentityReference -like "*$folderName*"
}
if(-not $Permission){
$path1 >> wrongPermissions.txt}

}

Upvotes: 0

sodawillow
sodawillow

Reputation: 13176

Here is my attempt at this:

$Paths = Get-Content "Path.txt"

#To get the subfolders for which the permissions has to be checked

$Folder = foreach ($Path in $Paths) {
    $Path = $Path | Select-Object -Unique
    Write-Host $Path -ForegroundColor Green
    Get-ChildItem $Path | Where-Object { $_.Attributes -eq 'Directory' } | Select-Object FullName
}

#To get the ACLs for the list of folders from above

$ACLS = Get-Content $Folder

$Out = foreach ($ACL in $ACLS) {
    $accessOK = $false
    Write-Host $ACL -ForegroundColor Cyan
    $folderName = (Get-Item $ACL).Name
    (Get-Acl $ACL).Access | % {
        if($_.IdentityReference.ToString().Split("\")[1] -match $folderName) {
            if($_.AccessControlType.ToString() -match "Allow") {
                $accessOK = $true
            }
        }
    }
    if(!$accessOK) { $ACL }
}

$Out should contain only paths where user named after the folder does not have access.

Comments: your naming can be misleading. I would not have called $ACL a variable containing a string which is in fact a full path :). That's why I did not modify the rest of the code. I'll try to show you what I mean in a rewrite:

$rootList = Get-Content "Path.txt"

$pathList = foreach ($root in $rootList) {
    $path = $root | Select-Object -Unique
    Write-Host $path -ForegroundColor Green
    #with powershell 3
    Get-ChildItem $path -Directory | Select-Object FullName
}

$Out = foreach ($path in $pathList) {
    $accessOK = $false
    Write-Host $path -ForegroundColor Cyan
    $folderName = (Get-Item $ACL).Name
    (Get-Acl $path).Access | % {
        if($_.IdentityReference.ToString().Split("\")[1] -match $folderName) {
            if($_.AccessControlType.ToString() -match "Allow") {
                $accessOK = $true
            }
        }
    }
    if(!$accessOK) { $path }
}

Upvotes: 0

Related Questions