【问题标题】:How can I compare against FileSystemRights using Powershell?如何使用 Powershell 与 FileSystemRights 进行比较?
【发布时间】:2014-12-17 15:34:14
【问题描述】:

我想检查给定用户是否有权访问给定文件夹 - 通过检查他们是否分配了“修改”访问权限。

我认为 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 属性是一个枚举吗?如果是这样,我该如何对其进行测试?

【问题讨论】:

    标签: windows powershell filesystems acl


    【解决方案1】:

    这是一个类型问题。 (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__)";}
    

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

    祝你好运!

    【讨论】:

    • 请注意,如果您在 ACL 上获得同一用户帐户的两个条目,则表明存在 GENERIC_ 标志。例如,给定两个分别为ReadAndExecute-1610612736 的ACE,后者将转换为GENERIC_READ | GENERIC_EXECUTE
    【解决方案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) - 其中一些将与“修改”匹配,您还需要将结果与“修改”进行比较,以确保结果实际上是相同的。

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

    【讨论】:

      【解决方案3】:

      更新了新版本。

      来自 Arco 评论的澄清版本。

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

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

      value__ 属性是数字位集版本。

      【讨论】:

      • 这个版本怎么样?
      • 这几乎行得通——你给了我足够的努力。因为“读取”和“修改”共享 一些 位,所以 -band 在比较它们时会返回“真实”答案。因此,您需要将 -band 的结果与“Modify”进行比较,以确保它实际上是 Modify。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-01
      • 2018-07-02
      • 1970-01-01
      • 2019-04-06
      • 1970-01-01
      相关资源
      最近更新 更多