Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I compare against FileSystemRights using Powershell?

I want to check whether a given user has access to a given folder - by checking if they have "Modify" access assigned to them.

I thought that the PS for that would be:

(Get-Acl .\myfolder).Access | ?{$_.IdentityReference -eq "BUILTIN\Users"} |?{$_.filesystemrights.value -contains "Modify"} 

But the final part of that isn't working - I get back no result. But I know that they have Modify access - if I put in:

(Get-Acl .\myfolder).Access | ?{$_.IdentityReference -eq "BUILTIN\Users"} | select -ExpandProperty filesystemrights

then I get back:

Modify, Synchronize
ReadAndExecute, Synchronize

Is this because the FileSystemRights property is an enumeration? And if so, how do I test against it?

like image 406
Andrew Ducker Avatar asked Feb 12 '23 08:02

Andrew Ducker


1 Answers

It's a type problem. (Get-Acl .\myfolder).Access[].FileSystemRights is of type System.Security.AccessControl.FileSystemRights. It's not really displaying a string. To make it a string, just use the ToString() method:

(Get-Acl .\myfolder).Access | ?{$_.IdentityReference -eq "BUILTIN\Users"} |?{$_.filesystemrights.ToString() -contains "Modify"} 

Or you can use the bitwise comparison method. However, it's very easy to confuse when you want to use this:

($_.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::Modify) -eq [System.Security.AccessControl.FileSystemRights]::Modify

With when you want to use this:

($_.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::Modify) -eq $_.FileSystemRights

They have very different meanings. For example, if you have Full Control, the former test is still true. Is that what you want? Or do you want to know when the FileSystemRights are literally just Modify?

Also, [System.Security.AccessControl.FileSystemRights] is an incomplete enumeration. In my environment, I found I needed this table:

+-------------+------------------------------+------------------------------+
|    Value    |             Name             |            Alias             |
+-------------+------------------------------+------------------------------+
| -2147483648 | GENERIC_READ                 | GENERIC_READ                 |
|           1 | ReadData                     | ListDirectory                |
|           1 | ReadData                     | ReadData                     |
|           2 | CreateFiles                  | CreateFiles                  |
|           2 | CreateFiles                  | WriteData                    |
|           4 | AppendData                   | AppendData                   |
|           4 | AppendData                   | CreateDirectories            |
|           8 | ReadExtendedAttributes       | ReadExtendedAttributes       |
|          16 | WriteExtendedAttributes      | WriteExtendedAttributes      |
|          32 | ExecuteFile                  | ExecuteFile                  |
|          32 | ExecuteFile                  | Traverse                     |
|          64 | DeleteSubdirectoriesAndFiles | DeleteSubdirectoriesAndFiles |
|         128 | ReadAttributes               | ReadAttributes               |
|         256 | WriteAttributes              | WriteAttributes              |
|         278 | Write                        | Write                        |
|       65536 | Delete                       | Delete                       |
|      131072 | ReadPermissions              | ReadPermissions              |
|      131209 | Read                         | Read                         |
|      131241 | ReadAndExecute               | ReadAndExecute               |
|      197055 | Modify                       | Modify                       |
|      262144 | ChangePermissions            | ChangePermissions            |
|      524288 | TakeOwnership                | TakeOwnership                |
|     1048576 | Synchronize                  | Synchronize                  |
|     2032127 | FullControl                  | FullControl                  |
|   268435456 | GENERIC_ALL                  | GENERIC_ALL                  |
|   536870912 | GENERIC_EXECUTE              | GENERIC_EXECUTE              |
|  1073741824 | GENERIC_WRITE                | GENERIC_WRITE                |
+-------------+------------------------------+------------------------------+

It's interesting to compare the output of these:

[System.Enum]::GetNames([System.Security.AccessControl.FileSystemRights]);
[System.Enum]::GetNames([System.Security.AccessControl.FileSystemRights]) | % { "$($_.ToString())`t`t$([System.Security.AccessControl.FileSystemRights]$_.ToString())`t`t$(([System.Security.AccessControl.FileSystemRights]$_).value__)";}
[System.Enum]::GetValues([System.Security.AccessControl.FileSystemRights]) | % { "$($_.ToString())`t`t$(($_).value__)";}

The GENERIC rights are not enumerated in the .Net class, but you will see that numeric value if you enumerate enough files.

Good luck!

like image 174
Bacon Bits Avatar answered Mar 27 '23 23:03

Bacon Bits