Solved

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

Posted on 2011-03-17
12
3,741 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
  • 6
  • 3
12 Comments
 
LVL 5

Expert Comment

by:daveTechSearch
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 5

Expert Comment

by:daveTechSearch
Comment Utility
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
Comment Utility
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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 5

Expert Comment

by:daveTechSearch
Comment Utility
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
Comment Utility
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 70

Accepted Solution

by:
Chris Dent earned 500 total points
Comment Utility

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
Comment Utility
Chris...I will test this next week and get back to you.  Thank you for your help.

0
 

Author Closing Comment

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

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

This is a PowerShell web interface I use to manage some task as a network administrator. Clicking an action button on the left frame will display a form in the middle frame to input some data in textboxes, process this data in PowerShell and display…
"Migrate" an SMTP relay receive connector to a new server using info from an old server.
Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

762 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now