如何使用Powershell与FileSystemRights进行比较?

时间:2014-12-17 15:34:15

标签: windows powershell filesystems acl

我想检查给定用户是否可以访问给定文件夹 - 通过检查他们是否有"修改"分配给他们的访问。

我认为那个PS就是:

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

但是最后一部分没有工作 - 我没有结果。但我知道他们有修改权限 - 如果我输入:

(Get-Acl .\myfolder).Access | ?{$_.IdentityReference -eq "BUILTIN\Users"} | select -ExpandProperty filesystemrights
然后我回来了:

Modify, Synchronize
ReadAndExecute, Synchronize

这是因为FileSystemRights属性是枚举吗?如果是这样,我该如何测试呢?

3 个答案:

答案 0 :(得分:4)

这是一个类型问题。 (Get-Acl .\myfolder).Access[].FileSystemRights的类型为System.Security.AccessControl.FileSystemRights。它并没有真正显示字符串。要使其成为字符串,只需使用ToString()方法:

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

或者您可以使用按位比较方法。但是,当您想要使用它时,很容易混淆:

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

当您想要使用它时:

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

他们的意义截然不同。例如,如果您具有完全控制,则前一个测试仍然是正确的。那是你要的吗?或者您想知道FileSystemRights 字面只是Modify的时间?

此外,[System.Security.AccessControl.FileSystemRights]是一个不完整的枚举。在我的环境中,我发现我需要这张表:

+-------------+------------------------------+------------------------------+
|    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                |
+-------------+------------------------------+------------------------------+

比较这些产出很有意思:

[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__)";}

.Net类中没有枚举GENERIC权限,但如果枚举了足够的文件,您将看到该数值。

祝你好运!

答案 1 :(得分:2)

知道了:

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

这是一个按位比较 - 因此你需要使用“-band”。

但是如果在两个枚举中都设置了相同位的任何,则“-band”将返回true。因为即使“读取”设置了几个位(它是100000000010001001) - 其中一些将与“修改”匹配,您还需要将结果与“修改”进行比较,以确保结果实际上是相同的。

(感谢下面的评论让我指出了正确的方向。)

答案 2 :(得分:0)

更新了新版本。

来自Arco评论的澄清版本。

在这个版本中,我们检查是否设置了修改位。

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

value__属性是数字位集版本。