知識は未だ霧の中

スパコン眼鏡NET。HPCのことはあまり書かない。

Powershellでアクセス権限を確認する方法

目的

PowerShellでアクセス権限をかっこよく確認したい。

プログラムを書いていて、事前にファイルを変更するアクセス権限があるか確認したいなぁと思いました。
とりあえず、書き込いてみてエラーをハンドリングするというのも手なのですが、アクセス権限だけを確認したいときはスマートではないと感じます。(感じてください)

ということで作成しました。

環境

PowerShell 5.1 で動作確認。(ほかのバージョンも動くと思うんですが、保証はしません)

中身

function Test-Permission() {
    param(
        [string][parameter(mandatory)] $Path,
        [string][parameter(mandatory)] $User,
        [System.Security.AccessControl.FileSystemRights][parameter(mandatory)] $Right
    )
    $acl = (Get-ACL $Path).Access;
    $allow = $acl | Where-Object {$_.IdentityReference -match $User -and $_.AccessControlType -match "Allow"}  | ForEach-Object {$t = $False} {$t = (($_.FileSystemRights -band $Right) -eq $Right) -or $t} {$t}
    $deny =  $acl | Where-Object {$_.IdentityReference -match $User -and $_.AccessControlType -match "Deny"}  | ForEach-Object {$t = $False} {$t = (($_.FileSystemRights -band $Right) -eq $Right) -or $t} {$t}
    return $allow -and -not $deny    
}

使い方

C:\hogeフォルダのmynameユーザーに変更権限があるかどうか確認したい時は、

Test-Permission "C:\hoge" "myname" Modify

みたいな感じです。
3つ目の変数はSystem.Security.AccessControl.FileSystemRights列挙体の変数を取ります。ReadとかWriteとかModifyとか…。詳しくはこちら

解説

Get-ACLで対象のオブジェクトのアクセスコントロールリストを取得し、該当ユーザーに関する許可リストと拒否リストをそれぞれ抽出し、該当する権限がそれぞれに載っているかを確認し、集約してます。
(ちなみにFileSystemRightsはビットフィールドで管理されています。へー。)
許可リストに載っていて、拒否リストに載っていなかったらTrueを、それ以外はFalseを返します。