コンテンツへスキップ

アクセス権を維持したままフォルダコピーしたい。が、無理っぽいので【アクセス権が設定されたルートのフォルダが分かる一覧】をCSV に出力する話。

サーバーを新しく刷新するとき、データの移行時にフォルダについているアクセス権の設定で設定の情報が残ってなくて、フォルダ数もかなりの量なので、、、困った。

コピー元のサーバーでアクセス権限があるアカウントを使ってバックアップを取ると、バックアップ先でアクセス権がすべてデフォルトに変更されてしまう?

で、思いついたのが、Robocopy の「/SEC」アクセス権限情報もそのままコピーできないだろうかという事でしたが、結局あっちのサーバーのユーザーとこっちのサーバーのユーザーがが置き換わるわけでもないので、あきらめた。(※「アクセス権ごとバックアップを取りたい」参照。)

次にアクセス権の一覧を作成することにして、方法はすぐに見つかったのですが(powershell )、デフォルト以外のユーザーのアクセス権だけを確認するのも難しいし、何よりどこのフォルダでアクセス権が設定されて、どこからが継承されてアクセス権なのか区別がつかない。(※「アクセス権の一覧作成」参照。)

「継承」のプロパティが「false」になっている、
アクセス権とユーザーを特定できるようなリストにしたい。着地

特定のユーザーへのアクセス権が設定されたルートのフォルダを一覧で作成したい

アクセス権のルートと継承の見分け方について

任意のアクセス権が設定されたフォルダと、そのアクセス権の継承されたフォルダの見分け方をどうしようと調べていたところ、任意のアクセス権が設定されたフォルダでは、そのアクセス権の「継承元」は「なし」になる、というのを見つけた。確認してみると確かにそうなる。

フォルダに新しく追加したアクセス権は「継承元」が「なし」だから、
「継承元」のステータスを一覧に含めて「なし」になっている奴だけ抜き出したら良いのでは。

アクセス権を設定する。

継承元が「なし」になっている。

この画面で追加しても継承元は「なし」になる。

「継承元」情報の取得

継承元の情報は(Get-ACL).access を使うと取得できた。

参考:Powershellでフォルダアクセス権を手軽に確認する – Qiita

PS C:\Users\unimoni\Downloads\VMCapture> (get-acl).access


FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : NT AUTHORITY\SYSTEM
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : DESKTOP-V66DLU2\unimoni
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None



PS C:\Users\unimoni\Downloads\VMCapture>

じゃあ、こんな感じにかけば、

Get-ChildItem -Directory | ForEach-Object { echo $_.FullName, (Get-Acl $_).Access }

フルパスと、アクセス権の詳細になると。
このフォルダ内で作成したアクセス権の「継承元(IsInherited )が「False」になっているのも確認。

サブフォルダでも、継承元の値を確認してみる。

Get-ChildItem -Directory -Recurse | ForEach-Object {echo $_.FullName,(Get-Acl $_.FullName).Access}

サブフォルダを調べると、拒否アクセスの継承元がTrue なのが分かる。
フォルダを移動で作っても、新規で作っても継承されることも確認。

後は、CSV にいい感じに出力して、エクセルでピポッドテーブルとかでサクッと把握できるようにしたいけど、、、
この出力形式だと、ちょっと難しい。

結果、こうなりました。

いろいろ試した結果、配列に入れることにした。
下記のコードをPowershell に貼り付けして定義してから、test ファンクションを実行すると、CSV が作成されます。
例として「カンマ」区切りでファイル出力するようにしていますが、「FileSystemRights」が複数ある場合、カンマ区切りで出力されるため、開くときにセルが増えてきます。

フォルダ内のみ(1レベル)のバージョン

function test {
$all=@()
Get-ChildItem -Directory | ForEach-Object {
	$a=$_.FullName;
	$b=(Get-Acl $a);
	$b.Access | ForEach-Object { 
  $array=@()
		$array+=$a
		$array+=$_.IdentityReference;
		$array+=$_.IsInherited; 
  $array+=$_.AccessControlType;
  $array+=$_.FileSystemRights;
    $all += $array -join "," }
}
$all | Out-File -FilePath "output.csv" -Encoding utf8
}

アクセス権(FileSystemRights)は複数ある場合にカンマ区切りで表示される為、列がズレたりするので一番後ろにした。join の区切り文字をカンマ以外にを変更するのもありですね。
また、フォルダ名にカンマとか%などの記号を使う人もいますので、「?」とかカンマ以外のフォルダ名に使えないような記号で区切った方がいいと思います。

カンマ以外を使う場合、エクセルで直接開くと自動でカンマ区切りされてしまうので、
いったん新規ファイルを作ってから読み込みし、読み込みオプションで区切り文字を指定します。

サブフォルダを含むバージョン

こうすると、サブフォルダも検索する。
フォルダのアクセス権毎に一行作成するので、フォルダの数が多いとめっちゃ時間かかります。
不安になるので、進捗が分かるようにecho を入れてます。
場合によっては、出力自体を「継承元:なし」の行に絞りこむような構成にした方がいいかもです。
結構時間かかりますし、メモリも使うようです。ファイルサイズもそこそこあります。
参考までに、スペックによりけり(特に時間は)ですが、約6万フォルダでメモリ消費1.5GB 程度、5時間くらいかかって74MB弱のファイルサイズになりました。

Get-ChildItem -Directory -Recurse

function test {
$header=@("path","IdentityReference","IsInherited","AccessControlType","FileSystemRights")
$all=@()
$all += $header -join ","
Get-ChildItem -Directory -Recurse | ForEach-Object {
	$a=$_.FullName;
	$b=(Get-Acl -literalPath $a);
	$b.Access | ForEach-Object { 
  $array=@()
		echo "--> " $a 
		$array+=$a
		$array+=$_.IdentityReference;
		$array+=$_.IsInherited; 
		$array+=$_.AccessControlType;
		$array+=$_.FileSystemRights;
    $all += $array -join "," }
}
$all | Out-File -FilePath "output.csv" -Encoding utf8
}

状況に合わせて区切り文字を変更してください。

これなら、追加したACLの起点になるフォルダを見つけられるね。

備考

PowerShell 角括弧[] が含まれたファイル名をリネームする場合は-LiteralPath パラメータが必要

正規表現と解釈されるらしい。
「-literalPath」パラメーターで解決できるという事でコードに追加。

判定はtrue になる? falseになる? →true になる。

親オブジェクトって何? →調査中

継承が true / false になるのは、アクセス権の話。

セキュリティ >詳細設定

共有からアクセス許可を付けた場合。

共有 >詳細な共有

アクセス許可には入ってこない。

共有タブに追加されている

アクセス許可は未設定の状態と思われる。

エクスプローラー右クリックメニューから共有設定してみる。

設定方法の違いというわけでもない。

参考

アクセス権の一覧作成

取り会えず全体の作業量を見据えてから手動とかバッチ処理とか考えるとして、
まずはフォルダアクセス権の一覧を作ろうと思う。

PowerShellでフォルダアクセス権をCSVに出力する

抜粋。

Get-ChildItem -Recurse | where-object {$_.mode -match "d"} | Get-Acl | Select-object Path,PSChildName,AccessToString |Export-Csv C:\list.csv -encoding Default

function testacl{ 
	Get-ChildItem -Recurse | 
	where-object{$_.mode -match"d" } | 
	Get-Acl | 
	Select-Object PSParentPath,PSChildName,Path,Owner,AccessToString | 
	Export-Csv list.csv -encoding Default }

プロパティの一覧

PS C:\Users\unimoni\Downloads\VMCapture> Get-Acl |Format-List *


PSPath                  : Microsoft.PowerShell.Core\FileSystem::C:\Users\unimoni\Downloads\VMCapture
PSParentPath            : Microsoft.PowerShell.Core\FileSystem::C:\Users\unimoni\Downloads
PSChildName             : VMCapture
PSDrive                 : C
PSProvider              : Microsoft.PowerShell.Core\FileSystem
CentralAccessPolicyId   :
CentralAccessPolicyName :
Path                    : Microsoft.PowerShell.Core\FileSystem::C:\Users\unimoni\Downloads\VMCapture
Owner                   : DESKTOP-V66DLU2\unimoni
Group                   : DESKTOP-V66DLU2\なし
Access                  : {System.Security.AccessControl.FileSystemAccessRule, System.Security.AccessControl.Fil
                          eSystemAccessRule, System.Security.AccessControl.FileSystemAccessRule}
Sddl                    : O:S-1-5-21-1084536475-3524646309-189933008-1001G:S-1-5-21-1084536475-3524646309-189933
                          008-513D:(A;OICIID;FA;;;SY)(A;OICIID;FA;;;BA)(A;OICIID;FA;;;S-1-5-21-1084536475-352464
                          6309-189933008-1001)
AccessToString          : NT AUTHORITY\SYSTEM Allow  FullControl
                          BUILTIN\Administrators Allow  FullControl
                          DESKTOP-V66DLU2\unimoni Allow  FullControl
AuditToString           :
AccessRightType         : System.Security.AccessControl.FileSystemRights
AccessRuleType          : System.Security.AccessControl.FileSystemAccessRule
AuditRuleType           : System.Security.AccessControl.FileSystemAuditRule
AreAccessRulesProtected : False
AreAuditRulesProtected  : False
AreAccessRulesCanonical : True
AreAuditRulesCanonical  : True



PS C:\Users\unimoni\Downloads\VMCapture>

一覧になったけど、このリストだと対象が見つけにくいし、ピボットテーブルで処理しにくい。
(とても参考にはなりました^^)

アクセス権ごとバックアップを取りたい

思いついたのは、Robocopy のオプションにそういうの無いかなと。
「セキュリティ情報のコピー」がそれっぽい。バックアップモードもアクセス権付でコピーできるかなーとか。

/Bオプションを指定する。

いきなりエラーが発生してコピーできなかった。どうもコピー元のサーバーのユーザー(アクセス権あり。)と同じアカウント名になっていないといけないらしい。

SeBackupPrivilege の確認

whoami /all を実行して、権限など確認。

SeBackupPrivilege の特権はない。

あるけど、無効になってる。

でも、/b オプション実行できた。

アクセス権とかは無視されている感じ?

/SEC オプションを指定する。

/sec も実行できた。

不明なアカウントは、コピー元のサーバーのadministrator

アクティブディレクトリとかならいいんかな。
サーバー名を同じにして、ユーザー名も同じにしたらSID が一致するのか?

やっぱり、手動で設定が堅実か。
→ 作業量にもよる。
→ こういうタイミングで整理するのもいいかもしれない。

参考

今回あんまり関係ないけど、将来的には使うのかもしれない情報(と思われるもの^^)。

DirectorySecurity クラス

ファイルとフォルダーをコピーおよび移動するときにアクセス許可を処理する方法

以上です。

(Visited 30 times, 1 visits today)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です