Andrew Ducker
Andrew Ducker

Reputation: 5500

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?

Upvotes: 4

Views: 7557

Answers (3)

Bacon Bits
Bacon Bits

Reputation: 32210

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!

Upvotes: 7

Andrew Ducker
Andrew Ducker

Reputation: 5500

Got it:

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

It's both a bitwise comparison - and therefore you need to use "-band".

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

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

Upvotes: 2

Micky Balladelli
Micky Balladelli

Reputation: 10001

Updated new version.

Clarified version from Arco's comment.

With this version we're checking if the Modify bit is set.

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

The value__ property is the numeric bit set version.

Upvotes: 0

Related Questions