Public/Get-ACLInfo.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
function Get-ACLInfo {
  <#
      .SYNOPSIS
      Get a summary of a folder ACL

      .DESCRIPTION
      This command will examine the ACL of a given folder and create a custom object.
      The object will include a count of access rules based on the identity
      reference. Any ACL that belongs to a builtin or system account, or Everyone and
      Creator Owner, will be counted as a SystemACL. Everything else will be counted
      as a UserACL. You might use this information to identify folders or files where
      ACLS aren't what you expect.

      The custom object also contains an AccessRules property which will be a
      collection of the access rules for that object.

      SystemACL : 7
      Owner : BUILTIN\Administrators
      UserACL : 1
      AccessRules : {System.Security.AccessControl.FileSystemAccessRule,
                        System.Security.AccessControl.FileSystemAccessRule,
                        System.Security.AccessControl.FileSystemAccessRule,
                        System.Security.AccessControl.FileSystemAccessRule...}
      Path : C:\work
      TotalACL : 8

      It is assumed you will use this with the FileSystem provider.

      This version of the command uses a format file which is loaded "on the fly" so by default,
      information is presented as a nicely formatted table without the AccessRules property.

      .PARAMETER Path
      The path of the folder to analyze. The default is the current directory.

      .EXAMPLE
      PS C:\> Get-ACLInfo D:\Files
      Get acl data on the Files folder.

      .EXAMPLE
      PS C:\> Get-ChildItem e:\groups\data -Recurse | Where-Object {$_.PSIsContainer} | Get-ACLInfo
      Get acl information for every folder under e:\groups\data.

      .NOTES
      NAME : Get-ACLInfo
      VERSION : 0.9
      LAST UPDATED: 6/21/2012
      AUTHOR : Jeffery Hicks (http://jdhitsolutions.com/blog)

      .LINK
      Get-ACL

      .INPUTS
      Strings

      .OUTPUTS
      Custom object
  #>

  Param(
    [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
    [ValidateScript({Test-Path -Path $_ -PathType Container})]
    [string[]]$Path = $PWD.Path
  )
  Begin {
    Write-Verbose -Message ('Starting {0}' -f $MyInvocation.MyCommand)
    $Xml = @'
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
    <ViewDefinitions>
        <View>
            <Name>JDH.ACLInfo</Name>
            <ViewSelectedBy>
                <TypeName>JDH.ACLInfo</TypeName>
            </ViewSelectedBy>
            <TableControl>
                <TableHeaders/>
                <TableRowEntries>
                    <TableRowEntry>
                        <TableColumnItems>
                            <TableColumnItem>
                                <PropertyName>Path</PropertyName>
                            </TableColumnItem>
                            <TableColumnItem>
                                <PropertyName>Owner</PropertyName>
                            </TableColumnItem>
                            <TableColumnItem>
                                <PropertyName>TotalACL</PropertyName>
                            </TableColumnItem>
                            <TableColumnItem>
                                <Propertyname>SystemACL</Propertyname>
                            </TableColumnItem>
                            <TableColumnItem>
                                <Propertyname>UserACL</Propertyname>
                            </TableColumnItem>
                        </TableColumnItems>
                    </TableRowEntry>
                </TableRowEntries>
            </TableControl>
        </View>
    </ViewDefinitions>
</Configuration>
'@

    $TempFile = [System.IO.Path]::GetTempFileName() + '.ps1xml'
    Write-Verbose -Message ('Creating {0}' -f $TempFile)
    $Xml | Out-File -FilePath $TempFile
    Write-Verbose -Message 'Updating Format Data'
    Update-FormatData -AppendPath $TempFile -ErrorAction SilentlyContinue
  }
  Process {
    Foreach ($Folder in $Path) {
      Write-Verbose -Message ('Getting ACL for {0}' -f $Folder)
      $ACL = Get-ACL -Path $Folder
      [regex]$Regex = '\w:\\\S+'
      $FolderPath = $Regex.Match($ACL.Path).Value
      $Access = $ACL.Access
      $SysACL= $Access | Where-Object {$_.IdentityReference -match 'BUILTIN|NT AUTHORITY|EVERYONE|CREATOR OWNER'}
      $NonSysACL = $Access | Where-Object {$_.IdentityReference -notmatch 'BUILTIN|NT AUTHORITY|EVERYONE|CREATOR OWNER'}
      $Obj = [PSCustomObject] @{
        Path = $FolderPath
        Owner = $ACL.Owner
        TotalACL = $Access.Count
        SystemACL = ($SysACL | Measure-Object).Count
        UserACL = ($NonSysACL | Measure-Object).Count
        AccessRules = $Access
      }
      $Obj.PSObject.TypeNames.Insert(0,'JDH.ACLInfo')
      $Obj
    }
  }
  End {
    if (Test-Path -Path $TempFile) {
      Write-Verbose -Message ('Deleting {0}' -f $TempFile)
      Remove-Item -Path $TempFile
    }
  }
}