PowerShellでAclを一括取得してcsv出力する

# はじめに

本記事は [repacls: NTFSセキュリティ情報の確認・操作](https://qiita.com/k2ok/items/4d014b0211aef28dae13) のつづきです。

# 目的（再掲）

WindowsのNTFSファイルシステムで、フォルダ権限設定の不備に起因する障害発生。
他部門から引き継いだもので、どういう経緯か分からないが「継承の無効化」を設定し個人のローカルアカウントの権限付与したフォルダがあった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50759/2f4486a4-fe43-e6a1-6c61-7606b1da6fb1.png)

そんなこととはつゆ知らず、システムを引き継いだ我々は、諸事情アプリ実行アカウントを変更することとなり、上位フォルダに権限付与した。
フォルダ権限はサブフォルダへ継承されると考えていたが、このフォルダへ継承されなかったので当該アカウントからの書き込みができなかったことに初回稼働まで気づかず。

予防策として、下位フォルダの権限について、継承設定も含めて事前確認することとした。

なので、フォルダ権限を抽出できるようなツールが欲しい。


# 前記事の状況おさらい

いちおうCSV出力できるんだけど、出力形式がいけてなかった。

CSV加工すること、あるいは[repacls]のソースコードをforkしてレポート機能を独自に実装することも考えたけど、ちょっと見た感じではだいぶきつそうだった。。

[repacls]:<https://github.com/NoMoreFood/Repacls>


# あらためて調査

こんな記事にあたった。意外とある。。

https://blog.netwrix.com/2021/01/13/ntfs-permissions-tools/

レポートとして残したいので、GUI操作しかないのはちょっと辛い。

また、予算確保で苦しむのは論外なので、有償のものもパス。

[SolarWindsのPermissions Analyzer](https://www.solarwinds.com/free-tools/permissions-analyzer-for-active-directory)なんか、よさそうなんだけどね。。

結果。PowerShell最強ということのようです。
元ネタは以下らしいけど、記事のほうにちゃんと動くコードと使用例が載ってるので、そちらを参考に。

https://community.spiceworks.com/scripts/show/1070-export-folder-permissions-to-csv-file


# 動かしてみる

```Aclを一括取得してcsv出力する.ps1
# 元記事から一部改変してます

Set-StrictMode -Version 2.0

cd $PSScriptRoot

$me = Get-Item $PSCommandPath

# 任意のパスを指定したい場合、ここを修正する
$RootPath = $env:USERPROFILE
#$RootPath = 'C:\'

# $OutFile = "C:Temppermissions.csv"
$Header = "Folder Path,IdentityReference,AccessControlType,IsInherited,InheritanceFlags,PropagationFlags"
# Del $OutFile
$OutFile = $me.BaseName + (Get-Date -UFormat '%Y%m%d_%H%M%S') + '.csv'
Add-Content -Value $Header -Path $OutFile

$Folders = dir $RootPath -recurse | where {$_.psiscontainer -eq $true}

foreach ($Folder in $Folders){
$ACLs = get-acl $Folder.fullname | ForEach-Object { $_.Access }
Foreach ($ACL in $ACLs){
$OutInfo = $Folder.Fullname + "," + $ACL.IdentityReference + "," + $ACL.AccessControlType + "," + $ACL.IsInherited + "," + $ACL.InheritanceFlags + "," + $ACL.PropagationFlags
Add-Content -Value $OutInfo -Path $OutFile
}}

#EOF: このファイルはここで終了
```

```出力例
C:\Users\Owner\.android,NT AUTHORITY\SYSTEM,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.android,BUILTIN\Administrators,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.android,MYHOST\k2ok,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.android,S-1-5-21-xxx,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.AndroidStudio3.2,NT AUTHORITY\SYSTEM,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.AndroidStudio3.2,BUILTIN\Administrators,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.AndroidStudio3.2,MYHOST\k2ok,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.AndroidStudio3.2,S-1-5-21-xxx,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.AndroidStudio3.4,NT AUTHORITY\SYSTEM,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.AndroidStudio3.4,BUILTIN\Administrators,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.AndroidStudio3.4,MYHOST\k2ok,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.AndroidStudio3.4,S-1-5-21-xxx,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.ApacheDirectoryStudio,NT AUTHORITY\SYSTEM,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.ApacheDirectoryStudio,BUILTIN\Administrators,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.ApacheDirectoryStudio,MYHOST\k2ok,Allow,True,ContainerInherit, ObjectInherit,None
C:\Users\Owner\.ApacheDirectoryStudio,S-1-5-21-xxx,Allow,True,ContainerInherit, ObjectInherit,None
```

冗長な出力が出ますね。（元記事のとおり）

# コマンドレット：Get-Acl

使用例を確認する。

http://go.microsoft.com/fwlink/?LinkId=821710

```
PS C:\Users\Owner> $rv = Get-Acl .
PS C:\Users\Owner> $rv.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    DirectorySecurity                        System.Security.AccessControl.FileSystemSecurity
```

なんと[Security.AccessControl.FileSystemSecurity]だそうです。

[Security.AccessControl.FileSystemSecurity]:<https://learn.microsoft.com/ja-jp/dotnet/api/system.security.accesscontrol.filesystemsecurity?view=net-7.0>

この先は、困ったらdotnet関連の資料あたればいけそう。


# 出力内容を加工する

フィルタしたらいいと思います。
（時間切れです、詳細略）


# おまけ：所有者の表示

これも元記事で紹介されているが、記事中のスクリプトは壊れているようだが。。

元ネタを参照。

https://www.netwrix.com/how_to_monitor_excessive_permissions_in_everyone_group_on_windows_file_servers.html?itm_source=blog&itm_medium=context&itm_campaign=permissions&itm_content=none&cID=70170000000kgEZ

```所有者を表示.ps1
dir -Recurse | where { $_.PsIsContainer } | % { $path1 = $_.fullname; Get-Acl $_.Fullname | % { $_.access | where { $_.IdentityReference -like "everyone" } | Add-Member -MemberType NoteProperty -name "Network File Share Path" -Value $path1 -passthru }} | export-csv ".csv File Name And Path”
```

実際に動かせてはいないです。
時間ないので、あとは業務で調べよう。。