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

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

我认为那个PS会是:

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

但最后一部分是不行的 – 我没有收到任何结果。 但是我知道他们有修改权限 – 如果我input:

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

然后我回来:

 Modify, Synchronize ReadAndExecute, Synchronize 

这是因为FileSystemRights属性是一个枚举? 如果是这样,我该如何testing它呢?

这是一个类型问题。 (Get-Acl .\myfolder).Access[].FileSystemRightsSystem.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类中枚举,但是如果列举的文件足够多,您将看到该数值。

祝你好运!

得到它了:

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

这是一个按比例的比较 – 因此你需要使用“波段”。

但是,如果在两个枚举中都设置了相同的位,则“带”将返回true。 甚至“读”有几个比特集(它是100000000010001001) – 其中一些将与“修改”相匹配,您还需要将结果与“修改”进行比较,以确保结果实际上是相同的。

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

更新的新版本。

澄清版本来自Arco的评论。

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

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

value__属性是数字位设置版本。