Albert Widjaja
asked on
PowerShell script to list which specific folder a user does not have access to?
People,
I need some help in modifying the below PowerShell script so that it can be used to check which folder, the specified user account does not have access to.
The above script will be only dumping the list of Shared Folder only to .CSV
I wanted to get to know which user DOMAIN\John.Smith does not have access under the Shared Folder \\FileServer\HomeDrives$ then export it as .CSV
Any other solution outside of the PowerShell script will also be appreciated.
Thanks,
I need some help in modifying the below PowerShell script so that it can be used to check which folder, the specified user account does not have access to.
Get-ServerShares -ServerName PRDFS01-VM -Type NTFS
<#
.SYNOPSIS
get-servershares generates a report an individual or all servers in AD and its shares access permissions or a shares NTFS permissions of its local path
using WMI instead of relying on WinRM access.
.DESCRIPTION
Get-SharePerm will either query a singular server or all windows servers in Active Directory, and all local shares presented. This does not include
admin or remote shares (aka C$, D$ etc...) It will include SYSVOL shares. if you are using a windows server as a print server, it will exclude all
shares that include -ptr- You are welcome to change this. A CSV will be created in C:\ called Shares_Share_Permissionscsv or Shares_NTFS_Permissions.
.PARAMETER UserName
ServerName
Defines the server that will queried.
If blank, every windows server on the domain will be queried.
Type
This defines the type of permissions being queried.
Share
will generate all access given at the share level
NTFS
will give all NTFS permissions against the local path of a share.
.EXAMPLE
get-servershares -ComputerName Example-FP -Type Share
This will generate a report in C:\ that contains all share level accesses for the particular server defined
If you re-run as with a different server name, the report will compund on the exsisting document. Makes reporting specific servers easier.
.EXAMPLE
get-servershares -ComputerName Example-FP -Type NTFS
This will generate a report in C:\ that contains all NTFS level accesses for the particular server defined
If you re-run as with a different server name, the report will compund on the exsisting document. Makes reporting specific servers easier.
.EXAMPLE
get-servershares -Type Share
This will generate a report in C:\ that contains all share level accesses for the particular for every windows server reachable on the domain
.EXAMPLE
get-servershares -Type NTFS
This will generate a report in C:\ that contains all NTFS level accesses for the particular for every windows server reachable on the domain
.NOTES
Created by: David Dubuque
Date: 27-Sep-2016
Works with: Windows Server 2008R and 2012R
#>
function get-servershares
{
Param (
[string]$ServerName,
[string]$Type
)
if ($ServerName -eq "")
{
write-host "Server not defined gathering server list"
write-host ""
$Servers = Get-ADComputer -Filter { operatingsystem -like "*server*" } | Select-Object Name | Sort-Object Name
if ($Type -eq "NTFS")
{
$csvexport = "C:\Shares_$($Type)_Permissions.csv"
foreach ($server in $Servers)
{
$serverName = $server.Name
$shares = Get-WmiObject Win32_Share -ComputerName "$serverName" | Where-Object{ $_.Name -notlike "*$" -AND $_.Name -notlike "*-ptr-*" } | Select-Object PSComputerName, Name, Path
foreach ($item in $shares)
{
$Path = $item.Path
$RawPath = $item.Path
$Server = $item.PSComputerName
$ShareName = $item.Name
$Path = $Path -replace ":", "$"
$LocalPath = "\\$Server\$Path"
$ACLS = Get-ACL "$LocalPath" | ForEach-Object { $_.Access }
foreach ($ACL in $ACLS)
{
$hash = @{
"Server" = $Server
"ShareName" = $ShareName
"LocalPath" = $RawPath
"Permissions" = $ACL.FileSystemRights
"AccessControlType" = $ACL.AccessControlType
"IdentityReference" = $ACL.IdentityReference
"Inheritance" = $ACL.IsInherited
"InheritanceFlags" = $ACL.InheritanceFlags
"PropagationFlags" = $ACL.PropagationFlags
}
$newRow = New-Object PsObject -Property $hash
$InheritFlag = $newRow | Select-Object InheritanceFlags
$PropFlag = $newRow | Select-Object PropagationFlags
if ($PropFlag.PropagationFlags -like "none" -AND $InheritFlag.InheritanceFlags -eq "none")
{
$AppliesToValue = "folder only"
}
elseif ($PropFlag.PropagationFlags -eq "none" -AND $InheritFlag.InheritanceFlags -eq "ContainerInherit, ObjectInherit")
{
$AppliesToValue = "folder, sub-folders and files"
}
elseif ($PropFlag.PropagationFlags -eq "none" -AND $InheritFlag.InheritanceFlags -eq "ContainerInherit")
{
$AppliesToValue = "folder and sub-folders"
}
elseif ($PropFlag.PropagationFlags -eq "none" -AND $InheritFlag.InheritanceFlags -eq "ObjectInherit")
{
$AppliesToValue = "folder and files"
}
elseif ($PropFlag.PropagationFlags -eq "InheritOnly" -AND $InheritFlag.InheritanceFlags -eq "ContainerInherit, ObjectInherit")
{
$AppliesToValue = "sub-folders and files"
}
elseif ($PropFlag.PropagationFlags -eq "InheritOnly" -AND $InheritFlag.InheritanceFlags -eq "ContainerInherit")
{
$AppliesToValue = "sub-folders"
}
elseif ($PropFlag.PropagationFlags -eq "InheritOnly" -AND $InheritFlag.InheritanceFlags -eq "ObjectInherit")
{
$AppliesToValue = "files"
}
else
{
$AppliesToValue = "Cannot determine"
}
$newhash = @{ "AppliesTo" = $AppliesToValue }
$newRow2 = New-Object PsObject -Property $newhash
$output = [pscustomobject] @{
Server = $newRow.Server
ShareName = $newRow.ShareName
LocalPath = $newRow.LocalPath
Permissions = $newRow.Permissions
AccessControlType = $newRow.AccessControlType
IdentityReference = $newRow.IdentityReference
Inheritance = $newRow.Inheritance
InheritanceFlags = $newRow.InheritanceFlags
PropagationFlags = $newRow.PropagationFlags
AppliesTo = $newRow2.AppliesTo
}
write-host " Server: $serverName | Share: $ShareName "
Export-Csv $csvexport -inputobject $output -append -Force -NoTypeInformation
}
}
}
}
Elseif ($Type -eq "Share")
{
foreach ($server in $Servers)
{
$serverName = $server.Name
$csvexport = "C:\Shares_$($Type)_Permissions.csv"
$shares = Get-WmiObject win32_LogicalShareSecuritySetting -ComputerName "$serverName" | Where-Object{ $_.Name -notlike "*$" -AND $_.Name -notlike "*-ptr-*" }
foreach ($share in $shares)
{
$ACLs = $share.GetSecurityDescriptor().Descriptor.DACL
foreach ($ACL in $ACLs)
{
$Name = $ACL.Trustee.Name
$Perm = $null
switch ($ACL.AccessMask)
{
268435456 { $Perm = "FullControl (Sub Only)" }
2032127 { $Perm = "Full Control" }
1245631 { $Perm = "Change" }
1180095 { $Perm = "ReadAndExecute, Write" }
1180063 { $Perm = "Read, Write" }
1179817 { $Perm = "Read" }
1179817 { $Perm = "ReadAndExecute" }
1179785 { $Perm = "Read" }
-1610612736 { $Perm = "ReadAndExecuteExtended" }
default { $Perm = $ACL.AccessMask }
}
$ACL | Select-Object -Property @{ n = 'Server'; e = { $serverName } },
@{ n = 'Name'; e = { $Share.Name } },
@{ n = 'Principal'; e = { $Name } },
@{ n = 'Permission'; e = { $Perm } } |
Export-Csv -Path $csvexport -NoTypeInformation -Append
$ACL | Select-Object -Property @{ n = 'Server'; e = { $serverName } },
@{ n = 'Name'; e = { $Share.Name } },
@{ n = 'Principal'; e = { $Name } },
@{ n = 'Permission'; e = { $Perm } }
}
}
Switch ($DACL.AccessMask)
{
2032127 { $AccessMask = "FullControl" }
1179785 { $AccessMask = "Read" }
1180063 { $AccessMask = "Read, Write" }
1179817 { $AccessMask = "ReadAndExecute" }
-1610612736 { $AccessMask = "ReadAndExecuteExtended" }
1245631 { $AccessMask = "ReadAndExecute, Modify, Write" }
1180095 { $AccessMask = "ReadAndExecute, Write" }
268435456 { $AccessMask = "FullControl (Sub Only)" }
default { $AccessMask = $DACL.AccessMask }
}
Switch ($DACL.AceType)
{
0 { $AceType = "Allow" }
1 { $AceType = "Deny" }
2 { $AceType = "Audit" }
}
}
}
Else
{
Write-Host "You did not define the type paramater. Please type Share or NTFS" -BackgroundColor Red -ForegroundColor White
Write-Host""
Write-Host "Use -Type Share or -Type NTFS. Also include -ServerName if you want to query a specific server" -BackgroundColor Red -ForegroundColor White
Write-Host""
}
}
else
{
$Servers = $ServerName
if ($Type -eq "NTFS")
{
$csvexport = "C:\Shares_$($Type)_Permissions.csv"
foreach ($server in $Servers)
{
$shares = Get-WmiObject Win32_Share -ComputerName "$serverName" | Where-Object{ $_.Name -notlike "*$" -AND $_.Name -notlike "*-ptr-*" } | Select-Object PSComputerName, Name, Path
foreach ($item in $shares)
{
$Path = $item.Path
$RawPath = $item.Path
$Server = $item.PSComputerName
$ShareName = $item.Name
$Path = $Path -replace ":", "$"
$LocalPath = "\\$Server\$Path"
$ACLS = Get-ACL "$LocalPath" | ForEach-Object { $_.Access }
foreach ($ACL in $ACLS)
{
$hash = @{
"Server" = $Server
"ShareName" = $ShareName
"LocalPath" = $RawPath
"Permissions" = $ACL.FileSystemRights
"AccessControlType" = $ACL.AccessControlType
"IdentityReference" = $ACL.IdentityReference
"Inheritance" = $ACL.IsInherited
"InheritanceFlags" = $ACL.InheritanceFlags
"PropagationFlags" = $ACL.PropagationFlags
}
$newRow = New-Object PsObject -Property $hash
$InheritFlag = $newRow | Select-Object InheritanceFlags
$PropFlag = $newRow | Select-Object PropagationFlags
if ($PropFlag.PropagationFlags -like "none" -AND $InheritFlag.InheritanceFlags -eq "none")
{
$AppliesToValue = "folder only"
}
elseif ($PropFlag.PropagationFlags -eq "none" -AND $InheritFlag.InheritanceFlags -eq "ContainerInherit, ObjectInherit")
{
$AppliesToValue = "folder, sub-folders and files"
}
elseif ($PropFlag.PropagationFlags -eq "none" -AND $InheritFlag.InheritanceFlags -eq "ContainerInherit")
{
$AppliesToValue = "folder and sub-folders"
}
elseif ($PropFlag.PropagationFlags -eq "none" -AND $InheritFlag.InheritanceFlags -eq "ObjectInherit")
{
$AppliesToValue = "folder and files"
}
elseif ($PropFlag.PropagationFlags -eq "InheritOnly" -AND $InheritFlag.InheritanceFlags -eq "ContainerInherit, ObjectInherit")
{
$AppliesToValue = "sub-folders and files"
}
elseif ($PropFlag.PropagationFlags -eq "InheritOnly" -AND $InheritFlag.InheritanceFlags -eq "ContainerInherit")
{
$AppliesToValue = "sub-folders"
}
elseif ($PropFlag.PropagationFlags -eq "InheritOnly" -AND $InheritFlag.InheritanceFlags -eq "ObjectInherit")
{
$AppliesToValue = "files"
}
else
{
$AppliesToValue = "Cannot determine"
}
$newhash = @{ "AppliesTo" = $AppliesToValue }
$newRow2 = New-Object PsObject -Property $newhash
$output = [pscustomobject] @{
Server = $newRow.Server
ShareName = $newRow.ShareName
LocalPath = $newRow.LocalPath
Permissions = $newRow.Permissions
AccessControlType = $newRow.AccessControlType
IdentityReference = $newRow.IdentityReference
Inheritance = $newRow.Inheritance
InheritanceFlags = $newRow.InheritanceFlags
PropagationFlags = $newRow.PropagationFlags
AppliesTo = $newRow2.AppliesTo
}
write-host " Server: $serverName | Share: $ShareName "
Export-Csv $csvexport -inputobject $output -append -Force -NoTypeInformation
}
}
}
}
Elseif ($Type -eq "Share")
{
foreach ($server in $Servers)
{
if ($ServerName -eq "")
{
$serverName = $server.Name
$serverName
}
else
{
$serverName = $server
$serverName
}
$csvexport = "C:\Shares_$($Type)_Permissions.csv"
$shares = Get-WmiObject win32_LogicalShareSecuritySetting -ComputerName "$serverName" | Where-Object{ $_.Name -notlike "*$" -AND $_.Name -notlike "*-ptr-*" }
foreach ($share in $shares)
{
$ACLs = $share.GetSecurityDescriptor().Descriptor.DACL
foreach ($ACL in $ACLs)
{
$Name = $ACL.Trustee.Name
$Perm = $null
switch ($ACL.AccessMask)
{
268435456 { $Perm = "FullControl (Sub Only)" }
2032127 { $Perm = "Full Control" }
1245631 { $Perm = "Change" }
1180095 { $Perm = "ReadAndExecute, Write" }
1180063 { $Perm = "Read, Write" }
1179817 { $Perm = "Read" }
1179817 { $Perm = "ReadAndExecute" }
1179785 { $Perm = "Read" }
-1610612736 { $Perm = "ReadAndExecuteExtended" }
default { $Perm = $ACL.AccessMask }
}
$ACL | Select-Object -Property @{ n = 'Server'; e = { $serverName } },
@{ n = 'Name'; e = { $Share.Name } },
@{ n = 'Principal'; e = { $Name } },
@{ n = 'Permission'; e = { $Perm } } |
Export-Csv -Path $csvexport -NoTypeInformation -Append
$ACL | Select-Object -Property @{ n = 'Server'; e = { $serverName } },
@{ n = 'Name'; e = { $Share.Name } },
@{ n = 'Principal'; e = { $Name } },
@{ n = 'Permission'; e = { $Perm } }
}
}
Switch ($DACL.AccessMask)
{
2032127 { $AccessMask = "FullControl" }
1179785 { $AccessMask = "Read" }
1180063 { $AccessMask = "Read, Write" }
1179817 { $AccessMask = "ReadAndExecute" }
-1610612736 { $AccessMask = "ReadAndExecuteExtended" }
1245631 { $AccessMask = "ReadAndExecute, Modify, Write" }
1180095 { $AccessMask = "ReadAndExecute, Write" }
268435456 { $AccessMask = "FullControl (Sub Only)" }
default { $AccessMask = $DACL.AccessMask }
}
Switch ($DACL.AceType)
{
0 { $AceType = "Allow" }
1 { $AceType = "Deny" }
2 { $AceType = "Audit" }
}
}
}
Else
{
Write-Host "You did not define the type paramater. Please type Share or NTFS" -BackgroundColor Red -ForegroundColor White
Write-Host""
Write-Host "Use -Type Share or -Type NTFS. Also include -ServerName if you want to query a specific server" -BackgroundColor Red -ForegroundColor White
Write-Host""
}
}
}
The above script will be only dumping the list of Shared Folder only to .CSV
I wanted to get to know which user DOMAIN\John.Smith does not have access under the Shared Folder \\FileServer\HomeDrives$ then export it as .CSV
Any other solution outside of the PowerShell script will also be appreciated.
Thanks,
You asked, "PowerShell script to list which specific folder a user does not have access to?"
There is no way to do this.
If a specific user is denied access to a folder, they won't be able to list it's contents.
This is by design.
Maybe you're asking something else. Add a clarifying comment about what you're trying to accomplish.
There is no way to do this.
If a specific user is denied access to a folder, they won't be able to list it's contents.
This is by design.
Maybe you're asking something else. Add a clarifying comment about what you're trying to accomplish.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Back to the original topic, checking if a user has access is more difficult than it sounds.
As stated above, the checking account needs to have enough privilieges to check permissions.
Then you need to check which groups the user is in - and as groups can be nested, this is a recursive/iterative task.
Only then you can check the ACLs for that particular user.
As stated above, the checking account needs to have enough privilieges to check permissions.
Then you need to check which groups the user is in - and as groups can be nested, this is a recursive/iterative task.
Only then you can check the ACLs for that particular user.
ASKER
Qlemo,
thanks for the update in this thread. yes, that does make sense.
@Fibertron, yes, but it requires some amount of fee to generate the report.
thanks for the update in this thread. yes, that does make sense.
@Fibertron, yes, but it requires some amount of fee to generate the report.
ASKER
thanks guys !
https://www.netwrix.com/netwrix_effective_permissions_reporting_tool.html
AccessEnum also audits access but isn't quite as eloquent as the Netwrix tool:
https://docs.microsoft.com/en-us/sysinternals/downloads/accessenum
Hope that helps!