How can I compare to FileSystemRights using Powershell?

I want to check if a given user has access to a given folder by checking to see if they have Edit access assigned to them.

I thought the PS for this would be:

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

      

But the last part of it doesn't work - I get no result. But I know they have Modify access - if I added:

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

      

then I will return:

Modify, Synchronize
ReadAndExecute, Synchronize

      

Is it because the FileSystemRights property is an enumeration? And if so, how should I try it out?

+3


source to share


3 answers


This is a type problem. (Get-Acl .\myfolder).Access[].FileSystemRights

has a type System.Security.AccessControl.FileSystemRights

. It doesn't show the line. To make it a string, just use the method ToString()

:

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

      

Or you can use the bitwise comparison method. However, it is very easy to get confused when you want to use this:

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

      

If you want to use this:

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

      

They have very different meanings. For example, if you have complete control, the previous test is still valid. Is this what you want? Or do you want to know when FileSystemRights

literally simple Modify

?



It is also [System.Security.AccessControl.FileSystemRights]

an incomplete listing. In my environment, I found that 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 is interesting to compare the result:

[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 permissions are GENERIC

not listed in the .Net class, but you will see this numeric value if you list enough files.

Good luck!

+3


source


Got this:

(get-acl .\myfolder).Access | ?{$_.IdentityReference -eq "BUILTIN\Users"} | ?{($_.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::Modify) -eq [System.Security.AccessControl.FileSystemRights]::Modify}

      

It's also a bitwise comparison - and that's why you need to use "-band".



But "-band" will return true if any of the same bits are set in both enumerations. And since even Read has several bits (100000000010001001), some of which will correspond to Modify, you also need to compare the result with Modify to make sure the result is actually the same.

(Thanks for the comments below to get me pointed in the right direction.)

+2


source


New version updated.

Adjusted version from Arco's comment.

In this version, we check if the modification bit is set.

(Get-Acl .\myfolder).Access | ?{$_.IdentityReference -eq "BUILTIN\Users"} |?{ $_.FileSystemRights -band [Security.AccessControl.FileSystemRights]::Modify}

      

Value__ is the numeric bit version.

0


source







All Articles