├── Get-NonGroupPermissions.ps1
├── README.md
├── gitattributes
└── gitignore
/Get-NonGroupPermissions.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .Synopsis
3 | Gets a list of folders within a share that have individual user permissions set, rather than the approved role groups from within AD
4 | .EXAMPLE
5 | .\Get-NonGroupPermissions.ps1 -Path '\\server\share\path' -Domain acmecorp -OutputFilepath C:\Temp\Test.csv -Email -To reciever@acme.com -From sender@acme.com -SmtpServer smtp.acme.com -Subject 'Test email' -Verbose -Recurse
6 | .NOTES
7 | Author - Robert Ainsworth - https://ainsey11.com
8 | Contributor - Shawn Esterman - https://github.com/ShawnEsterman
9 | #>
10 |
11 | function Get-NonGroupPermissions{
12 |
13 | [CmdletBinding()]
14 | Param (
15 | [Parameter(Mandatory = $true,
16 | ValueFromPipeline = $true,
17 | ValueFromPipelineByPropertyName = $true)]
18 | [ValidateScript({ $_ | ForEach-Object -Process { Test-Path -Path $_ } })]
19 | [String[]]
20 | $Path,
21 | [Parameter(Mandatory = $true)]
22 | [String]
23 | $Domain = "acme.com",
24 | [switch]
25 | $Recurse,
26 | [String]
27 | $OutputFilepath = "C:\Support\FoldersWithIndividualAccess.csv",
28 | [Parameter(Mandatory = $true,
29 | ParameterSetName = 'Email')]
30 | [Switch]
31 | $Email,
32 | [Parameter(ParameterSetName = 'Email')]
33 | [ValidateScript({ $_ | ForEach-Object -Process { try { New-Object System.Net.Mail.MailAddress($_) } catch { return $false } }; return $true })]
34 | [String[]]
35 | $To = 'defaultto@acme.com',
36 | [Parameter(ParameterSetName = 'Email')]
37 | [ValidateScript({ try { New-Object System.Net.Mail.MailAddress($_); return $true } catch { return $false } })]
38 | [String]
39 | $From = 'defaultfrom@acme.com',
40 | [Parameter(ParameterSetName = 'Email')]
41 | $SmtpServer = 'defaultsmtp.acme.com',
42 | [Parameter(ParameterSetName = 'Email')]
43 | $Subject = "Files and Folders found with individual permissions assigned"
44 | )
45 |
46 | $PreContent = @"
47 |
48 |
49 |
50 |
78 |
79 |
80 | "@
81 |
82 | $PostContent = @"
83 |
84 |
85 | "@
86 |
87 | $Body = $PreContent
88 | $Body += "$Subject
"
89 |
90 | $Data = @()
91 |
92 | if ($Recurse)
93 | {
94 | $Folderlist = get-ChildItem $Path -recurse | ?{ $_.PSIsContainer }
95 | foreach ( $p in $Folderlist ) {
96 | Write-Verbose "Checking path $P"
97 | $Data += (Get-ChildItem $Path -Recurse |Get-Acl).Access.Where{ $_.IdentityReference -like "$domain\*.*" } |
98 | Select-Object -Property FileSystemRights,IdentityReference,Isinherited |
99 | ForEach-Object -Process {
100 | Write-Verbose "Found $($_.FileSystemRights) on path $("$path\$Folderlist") for $($_.IdentityReference)"
101 | [pscustomobject] @{
102 | Path = "$path\$p"
103 | FileSystemRights = $_.FileSystemRights
104 | IdentityReference = $_.IdentityReference
105 | IsInherited = $_.IsInherited
106 | }
107 | }
108 | }
109 | }
110 |
111 | else {
112 |
113 | foreach ( $P in $Path ) {
114 | Write-Verbose "Checking path $P"
115 | $Data += (Get-Acl -LiteralPath $Path).Access.Where{ $_.IdentityReference -like "$domain\*.*" } |
116 | Select-Object -Property FileSystemRights,IdentityReference,Isinherited |
117 | ForEach-Object -Process {
118 | Write-Verbose "Found $($_.FileSystemRights) on path $($P) for $($_.IdentityReference)"
119 | [pscustomobject] @{
120 | Path = $P
121 | FileSystemRights = $_.FileSystemRights
122 | IdentityReference = $_.IdentityReference
123 | IsInherited = $_.IsInherited
124 | }
125 | }
126 | }
127 |
128 | }
129 |
130 | if ( $Data ) {
131 |
132 | if ( $OutputFilepath ) {
133 | Write-Verbose "Outputting data to $OutputFilePath"
134 | $Data | Export-Csv -LiteralPath $OutputFilepath -NoTypeInformation
135 | }
136 |
137 | if ( $Email ) {
138 |
139 | $Body += $Data | ConvertTo-Html -Fragment
140 | $Body += $PostContent
141 |
142 | $Params = @{
143 | To = $To
144 | From = $From
145 | SmtpServer = $SmtpServer
146 | Subject = $Subject
147 | Priority = 'High'
148 | Body = $Body
149 | BodyAsHtml = $true
150 | }
151 | Send-MailMessage @Params
152 | }
153 |
154 | }
155 | }
156 |
157 | Get-NonGroupPermissions -Path '\\timicogroup.local\dfs01' -Domain timicogroup.local -OutputFilepath C:\Temp\Test.csv -Email -To rob@timico.co.uk -From sender@timico.co.uk -SmtpServer mail.timicogroup.local -Subject 'Test email' -Verbose -Recurse
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ainsey11's Powershell NTFS Individual User Permissions Report
2 | This bit of code scans over a folder set in a variable, then e-mails a set address if there are permissions for individual users.
3 |
4 | ### Installation Instructions :
5 | Place in any dir, then execute with the relevant arguments.
6 |
7 | ### Example :
8 | .\Get-NonGroupPermissions.ps1 -Path '\\server\share\path' -Domain acmecorp -OutputFilepath C:\Temp\Test.csv -Email -To reciever@acme.com -From sender@acme.com -SmtpServer smtp.acme.com -Subject 'Test email' -Verbose -Recurse
9 |
10 | ##### Improvement Plan:
11 | - Look into making a seperate script that writes to a database for logging and a scaled solutuion for large file servers.
--------------------------------------------------------------------------------
/gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # Windows shortcuts
18 | *.lnk
19 |
20 | # =========================
21 | # Operating System Files
22 | # =========================
23 |
24 | # OSX
25 | # =========================
26 |
27 | .DS_Store
28 | .AppleDouble
29 | .LSOverride
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear in the root of a volume
35 | .DocumentRevisions-V100
36 | .fseventsd
37 | .Spotlight-V100
38 | .TemporaryItems
39 | .Trashes
40 | .VolumeIcon.icns
41 |
42 | # Directories potentially created on remote AFP share
43 | .AppleDB
44 | .AppleDesktop
45 | Network Trash Folder
46 | Temporary Items
47 | .apdisk
48 |
--------------------------------------------------------------------------------