フォルダーのアクセス許可をExcelで確認するには、Get-Aclで取得したアクセス制御エントリを1行ずつCSVへ出力します。フォルダー単位で権限を1セルに詰め込むより、ユーザー・グループ、許可/拒否、継承の有無で絞り込みやすくなります。以下はWindows PowerShell 5.1以降を想定した、アクセス許可を変更しない棚卸し例です。

CSVに残す項目と対象範囲
対象は指定フォルダー自身と、その配下のフォルダーです。ファイル個別のACLとSMB共有アクセス許可は対象外です。1フォルダーに複数のACEがあれば複数行になります。所有者、主体、権限、Allow/Deny、継承フラグを分けて記録します。
実行前に小さな検証フォルダーを用意し、明示的な許可、拒否、継承された権限をそれぞれ含めて結果を確認してください。監査情報にはアカウント名やフォルダー名が含まれるため、CSVの保存先と共有先も制限します。
ルートを含めてCSV出力するPowerShell
最初の$rootを対象へ変更して実行します。出力は対象フォルダーの外にある一時フォルダーへ日時付きで保存します。ワイルドカードとして解釈させないためLiteralPathを使い、ジャンクションなどの再解析ポイントは記録して追跡しません。新しいモジュールのインストールは不要です。
$root = 'C:\Data'
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss-fff'
$csv = Join-Path $env:TEMP "folder-acl-$stamp.csv"
$log = Join-Path $env:TEMP "folder-acl-errors-$stamp.txt"
$issues = New-Object 'System.Collections.Generic.List[string]'
$queue = New-Object 'System.Collections.Generic.Queue[string]'
$start = Get-Item -LiteralPath $root -ErrorAction Stop
if (-not $start.PSIsContainer) { throw '対象はフォルダーにしてください。' }
if ($start.Attributes -band [IO.FileAttributes]::ReparsePoint) {
throw '開始フォルダーにはリンク先の実体パスを指定してください。'
}
$queue.Enqueue($start.FullName)
$rows = New-Object 'System.Collections.Generic.List[object]'
while ($queue.Count -gt 0) {
$path = $queue.Dequeue()
try {
$acl = Get-Acl -LiteralPath $path -ErrorAction Stop
foreach ($ace in $acl.Access) {
$rows.Add([pscustomobject]@{
Path = $path
Owner = $acl.Owner
Identity = $ace.IdentityReference.Value
Rights = [string]$ace.FileSystemRights
Type = [string]$ace.AccessControlType
Inherited = $ace.IsInherited
InheritanceFlags = [string]$ace.InheritanceFlags
PropagationFlags = [string]$ace.PropagationFlags
})
}
if ($acl.Access.Count -eq 0) {
$issues.Add("ACL要確認(ACEなし): $path")
}
} catch { $issues.Add("ACL取得失敗: $path : $($_.Exception.Message)") }
try {
$children = @(Get-ChildItem -LiteralPath $path -Directory -Force -ErrorAction Stop)
foreach ($dir in $children) {
if ($dir.Attributes -band [IO.FileAttributes]::ReparsePoint) {
$issues.Add("リンク先を除外: $($dir.FullName)")
} else { $queue.Enqueue($dir.FullName) }
}
} catch { $issues.Add("子フォルダー列挙失敗: $path : $($_.Exception.Message)") }
}
$rows | Export-Csv -LiteralPath $csv -NoTypeInformation -Encoding UTF8 -NoClobber -ErrorAction Stop
if ($issues.Count -gt 0) { $issues | Out-File -LiteralPath $log -Encoding utf8 -NoClobber -ErrorAction Stop }
[pscustomobject]@{ Csv=$csv; Rows=$rows.Count; Warnings=$issues.Count; Log=$log }
Warningが1件でもあれば、ログを読んで調査範囲の欠落を確認します。子フォルダーの列挙に失敗した場所では配下を取得できていません。権限を無理に付け替えて収集を続けず、適切な読み取り権限を持つ担当者に確認してください。リンク先を含める必要がある場合は、リンク先の実体を別の対象として調査します。
Excelでは文字列として読み込む
CSVをダブルクリックするより、Excelの「データ」からテキスト/CSVを取り込み、UTF-8と区切り文字を確認します。パスやアカウント名などの列は文字列として扱い、先頭が「=」「+」「-」「@」などの値が数式として評価されないようにします。想定外の数式や外部リンクの実行を許可しないでください。
取り込み後、先頭のルートフォルダーが含まれるか、既知のフォルダーの権限がエクスプローラーの「セキュリティ」→「詳細設定」と一致するかを確認します。CSVの行数はフォルダー数ではなくACE数です。対象範囲、収集時刻、エラーログを一緒に保管すると、後日の比較ができます。
ACL一覧から実効アクセスを断定しない
ACLの一覧は実効アクセス権の計算結果ではありません。グループ所属、拒否ルール、継承、共有経由でのアクセス条件などを追加確認して判断します。Inherited=Trueは継承されたACEであり、「直接設定がないから権限がない」という意味ではありません。
この例は棚卸し用で、Set-Aclなどの書き換え処理を含みません。実行環境のACL構成に対する結果は利用者側で検証が必要です。CSVが生成されたことだけで全件成功とせず、警告数と既知の権限の照合までを完了条件にしてください。
保存失敗と収集警告を分けて確認する
CSVやログの書き込みに失敗した場合は処理を停止するよう、出力コマンドに-ErrorAction Stopを付けています。CSVのパスが表示されたことだけで保存完了と判断せず、実ファイルが存在して読み込めることを確認してください。警告がある場合は、CSVだけでなく対応するログも一緒に保管します。0行の場合は、空の正常な棚卸しと決めつけず、ルートとACL取得エラーを確認します。
Excelで特定の主体や継承設定を調べる
| 確認したいこと | CSVで見る列と操作 |
|---|---|
| 特定のユーザー・グループに直接書かれたACE | Identityを完全一致で絞る。グループ経由の実効権限は別途調べる |
| 継承せず明示的に設定したACE | InheritedをFalseに絞る |
| 拒否の設定 | TypeをDenyに絞り、対象と継承元を確認 |
| ルート配下の収集漏れ | Pathの一覧と警告ログを確認。ACE行数をフォルダー数と数えない |
データ量が大きい場合、この例は結果をメモリへ保持するため負荷が増えます。まず対象を部門やフォルダー単位に分け、小さい範囲で収集時間と出力容量を確認します。ACLを読み取れない範囲を権限変更で無理に埋めず、調査対象外・未取得として記録してください。


コメント