?
Solved

Need a PowerShell Script to list ACLS on Folders VIA UNC Path

Posted on 2011-03-17
12
Medium Priority
?
4,023 Views
Last Modified: 2012-05-11
In dire need for a quick and dirty powershell scrip that can do the following:

All computers here are Windows 2003 AD members.

- Scan NTFS permissions on a list of folders that I provide the UNC path too
- Report back those NTFS permissions
- If there are AD groups defined in the NTFS permissions to enumerate the AD groups and show all group members of those groups
- Spit out the results to a txt or CSV file

Can anyone help?  I am a novice to powershell.
0
Comment
Question by:Mark Roddy
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
12 Comments
 
LVL 5

Expert Comment

by:daveTechSearch
ID: 35160316
Give this a try... uses the Quest AD snap-in...
the source file that I use contains the full UNC to REMOTE systems...

i am also filtering the output for ONLY Domain objects
Add-PSSnapin Quest.ActiveRoles.ADManagement -errorAction silentlyContinue
$domain = "ENTERYOURDOMAINHERE"
$queryList = get-content c:\temp\queryList.txt

@(foreach($path in $queryList){
$identQuery = (get-acl $path).access | where {$_.IdentityReference -match $domain} | ft -auto -hideTableHeaders IdentityReference | out-file c:\temp\identQuery.log
$identList = (get-content c:\temp\identQuery.log) -replace ' {2,}','' | where {$_ -ne ""}
$identListString = $identList | out-string
@(foreach($ident in $identList){get-qadgroupmember $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append c:\temp\groupExpand.log
$groupExpand = (get-content c:\temp\groupExpand.log) -replace ' {2,}','' | where {$_ -ne ""} |out-string
 
    $path | select @{name='Path';expression={$path}},@{name='Access';expression={($identListString)}},@{name="GroupsExpanded";expression={$groupExpand}}
    remove-item c:\temp\groupExpand.log
}) | export-csv -notype c:\temp\ACL.csv

Open in new window

0
 

Author Comment

by:Mark Roddy
ID: 35192461
Give me a few days on this one.  I haven't forgotten you just really busy with a company rebranding.

Thank you so much...I will get back to you in a couple of days!
0
 

Author Comment

by:Mark Roddy
ID: 35192626
I had a quick chance to try it out after all....does the query list need to be computer objects or can I use a UNC to a share and then subfolders of that root share?

I have the qwest tools installed.  I use it weekly enumerating the domain with Get-QADComputer commands.  The domain in the code below was changed from my actual domain to "domain".  Error below and modified code attached.

Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
 
Get-QADGroupMember : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Supply an argument that is not null or empty and then try the command
 again.
At D:\Script_Testing\Finance_Permissions.ps1:9 char:51
+ @(foreach($ident in $identList){get-qadgroupmember <<<<  $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\grou
pExpand.log
    + CategoryInfo          : InvalidData: (:) [Get-QADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
Add-PSSnapin Quest.ActiveRoles.ADManagement -errorAction silentlyContinue
$domain = "domain"
$queryList = get-content D:\Finance_Permissions\querylist.txt

@(foreach($path in $queryList){
$identQuery = (get-acl $path).access | where {$_.IdentityReference -match $domain} | ft -auto -hideTableHeaders IdentityReference | out-file D:\Finance_Permissions\identQuery.log
$identList = (get-content D:\Finance_Permissions\identQuery.log) -replace ' {2,}','' | where {$_ -ne ""}
$identListString = $identList | out-string
@(foreach($ident in $identList){get-qadgroupmember $ident -errorAction silentlyContinue | ft -hideTableHeaders Name}) |out-file -append D:\Finance_Permissions\groupExpand.log
$groupExpand = (get-content D:\Finance_Permissions\groupExpand.log) -replace ' {2,}','' | where {$_ -ne ""} |out-string
 
    $path | select @{name='Path';expression={$path}},@{name='Access';expression={($identListString)}},@{name="GroupsExpanded";expression={$groupExpand}}
    remove-item D:\Finance_Permissions\groupExpand.log
}) | export-csv -notype D:\Finance_Permissions\ACL.csv

Open in new window

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 5

Expert Comment

by:daveTechSearch
ID: 35192690
Yes... for my test I just used the administrative share and a folder on a couple boxes:

\\server\c$\folder\

I suspect that this is a result of peforming the get-qadgroupmember against individual users.... if this is the case we would just need to add a filter to process ONLY if the object is a 'group' versus an 'individual'.

Do you actually have any content in the CSV file?

0
 

Author Comment

by:Mark Roddy
ID: 35193115
The UNC path seems to be working now.  I was using FQDN for the domain before..duh.

I think you are right about the user and group thing.  I am getting this multiple times in the results when testing:

Get-QADGroupMember : Target object is of invalid type: 'user'. 'group' expected.

The CSV is showing data but looks a little weird on the format.  The user \ group filter might help there as well.  The script is exporting the enumeration of the user list for each group but is not defining which group the user was a memember of nor what rights (user and/or group) it has....

So maybe columns like these:

Path, Groups and Users with Access to the Path, NTFS Access Rights of the Users and Groups, and  Members of those Groups with the exception of Domain Users and Authenticated users if it is listed as a group with access to the path...I don't need enumerate all users in the domain

I am running this on a list of about 15 shared folders.
0
 
LVL 5

Expert Comment

by:daveTechSearch
ID: 35193188
Right now you should see:
Path - in the PATH column
All users and Groups with access - in the ACCESS column.
All users that are contained in any of the Groups - In the GROUPSEXPANDED column.

... also, remember that this is a CSV... you will need to adjust the column/cell hight/width in order to see all of the contents.

not really clear on what you mean by this:
"and  Members of those Groups with the exception of Domain Users and Authenticated users if it is listed as a group with access to the path"

You don't need to know which Domain Users are members of the groups?... are you using Local Groups and Users on each box?  The way the script works right now is it ONLY looks at Domain users/groups... using a filter...
0
 

Author Comment

by:Mark Roddy
ID: 35193423
The "Domain Users" group is defined as having access to list contents on some of these shares.  Since it contains all users of the Domain I don't need to see the users in these groups.

So I am looking for a report with the following:

Path - Groups and Users with Access to Path -  NTFS Permission Assigned to Individual Groups or Users - List of Individual Users in a Individual Group  

Showing me what users and groups have access to the share is a start.  I just need to be able to define what rights the users and groups have to the path and what users are in each one of those groups (with the exception of the "Domain Users" groups which I know contains all AD users)
0
 
LVL 71

Accepted Solution

by:
Chris Dent earned 2000 total points
ID: 35230393

So it's kind of complex. You'll need PowerShell 2 for this, I can't test it under PowerShell 1 so I won't be writing it for that. If you don't have it already you can find it here: http://support.microsoft.com/kb/968930.

The script expects you to be executing it on a member of the domain, with sufficient rights to query AD (read-only) and the file system.
Function Get-AclDetail {
  Param(
    [Parameter(ValueFromPipeline = $True)]
    [ValidateScript( { Test-Path $_ } )]
    [String]$Path = ".",

    [Switch]$ExpandGroups
  )

  Process {

    # Get access list, change any domain

    $Access = (Get-Acl $Path).Access |
      Select-Object @{n='Path';e={ $Path }}, *,
        @{n='ADObject';e={ 
          If ($_.IdentityReference -NotMatch "^(NT AUTH|BUILTIN|$($Env:ComputerName))") {
            $Searcher = [ADSISearcher]"(sAMAccountName=$($_.IdentityReference -Replace '^.+\\'))"
            $Searcher.PropertiesToLoad.AddRange(@("name", "distinguishedName", "objectClass"))
            $Searcher.FindOne()
        } }} |
      Select-Object *, @{n='Name';e={ $_.ADObject.Properties['name'][0] }},
        @{n='DN';e={ $_.ADObject.Properties['distinguishedname'][0] }},
        @{n='Class';e={ ([String[]]$_.ADObject.Properties['objectclass'])[-1] }} -Exclude ADObject

    If ($ExpandGroup) {

      # If expansion of groups to objects is required, replace the group entry with an entry for each member

      $Access | ForEach-Object {
        $Entry = $_
        If ($Entry.Class -eq 'group') {
          $Searcher = [ADSISearcher]"(memberOf:1.2.840.113556.1.4.1941:=$($Entry.DN))"
          $Searcher.PageSize = 1000
          $Searcher.PropertiesToLoad.AddRange(@("name", "distinguishedName", "objectClass"))
          $Searcher.FindAll() | ForEach-Object {
            $ADObject = $_
            $Entry | Select-Object *, @{n='Name';e={ $ADObject.Properties['name'][0] }},
              @{n='DN';e={ $ADObject.Properties['distinguishedname'][0] }},
              @{n='Class';e={ ([String[]]$ADObject.Properties['objectclass'])[-1] }} -Exclude Name, DN, Class
          }
        } Else {
          $Entry
        }
      }
    } Else {

      # If expansion is not required return the original access list

      $Access
    }
  }
}

Open in new window

And some usage examples:
# Currentfolder
Get-AclDetail

# Current folder, expanding groups
Get-AclDetail -ExpandGroups

# Alternate folder
Get-AclDetail "\\someserver\someshare"

# A static list of folders
"\\server\share", "c:\windows" | Get-AclDetail

# From a file
Get-Content FolderList.txt | Get-AclDetail -ExpandGroups

Open in new window

And a warning. If a remote ACL uses Local Users (on that remote machine) you'll get a SID back, not the object name as Get-Acl cannot resolve SIDs to remote user names (beyond the scope of the CmdLet).

Chris
0
 

Author Comment

by:Mark Roddy
ID: 35302390
Chris...I will test this next week and get back to you.  Thank you for your help.

0
 

Author Closing Comment

by:Mark Roddy
ID: 35491841
Thank you so much for your help.  Great script and did what I needed it to do.
0

Featured Post

Bringing Advanced Authentication to the SMB Market

WatchGuard announces the acquisition of advanced authentication provider, Datablink, with one mission – to bring secure authentication to SMB, mid-market, and distributed enterprises with a cloud-based solution, ideal for resale via their established channel & MSSP community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The Nano Server Image Builder helps you create a custom Nano Server image and bootable USB media with the aid of a graphical interface. Based on the inputs you provide, it generates images for deployment and creates reusable PowerShell scripts that …
Recently we ran in to an issue while running some SQL jobs where we were trying to process the cubes.  We got an error saying failure stating 'NT SERVICE\SQLSERVERAGENT does not have access to Analysis Services. So this is a way to automate that wit…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…
Suggested Courses

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question