Windows Server の管理共有を含めた共有フォルダーの権限一覧を表示する方法
更新履歴
2017/10/25 スクリプト修正
多数のWindows Serverの管理を行い、それぞれのサーバーで共有フォルダーを作成していると、それぞれのアクセス権の設定の理が煩雑となってきます。
本来であれば、運用を見据えて各共有フォルダーのアクセス権設定を管理すべきなのですが(Windowsがそんな管理コンソールを用意してくれれば良いのですが・・・)、管理せずに共有フォルダーを作成したり、各部署が勝手に共有フォルダーを作成している場合、アクセス権設定が正しく設定されていないがために、重要なファイルが漏洩したり、誤って削除される可能性があります。
そんな状況を何とか脱するために、まずは各サーバーに設定されている共有フォルダーと、アクセス権設定一覧を出力する必要があります。
いちいちGUIで確認するのは面倒ですので、下記のPowershellスクリプト(.ps1)を使ってサクッとテキストに落としてみます。
なお、このスクリプトはWindows 8.1以降または、Windows Server 2012 R2以降でのみ有効です。
## 変数設定
# ログファイルを出力するUNCパスを記載します。
# 今回は、\\kaga\testを共有し、共有名を「test$」、NTFSおよびファイル共有の # パーミッションはEveryone フルコントロールとしています。
$mount_point="\\kaga\test$"
# 上記で設定したUNCパスをZドライブとしてマウントします。
$mount_device="Z"
# 出力するログをフルパスで指定するようにしています。
# 今回はZドライブ(\\kaga\test$)にスクリプトを実行した端末名.txtというファイルを指定しています。
$log_dir=$mount_device + ":\" + $Env:COMPUTERNAME + ".txt"
# 先ほど変数で定義したログファイルを出力するUNCパスをZドライブとしてマウントします
New-PSDrive -Name $mount_device -PSProvider FileSystem -Root
$mount_point
# Get-SmbShareコマンドレットの実行結果を$SmbShare_result変数に代入します。
$SmbShare_result = Get-SmbShare
# Write-Outputコマンドレットを利用して、「I am <スクリプトを実行した端末名」という文字列を、ログファイルへ書き込みます。
# なお、Write-Outputコマンドレットは出力した文字列をパイプで渡すもので、Write-Hostコマンドレットを使用した場合、パイプで
# 渡せません。そのためWrite-Outputコマンドレットを利用しています。
Write-Output "I am $Env:COMPUTERNAME" | Out-File -Append -FilePath $log_dir
# $SmbShare_resultに代入されたGet-SmbShareの実行結果から、Nameオブジェクトを抜き出し、パイプでforeach処理部に渡します。
#foreach処理部では、抜き出したNameオブジェクトを1つずつ処理していきます。
# 今回は、共有名が$で終わる管理共有は対象外と想定しているため、$_(foreachに渡されたNameオブジェクトの中身)を
# if文のlikeを使って、$で終わる物を引っかけます。引っかかった物は何の処理もされずに次のNameオブジェクトを取り出して
# 処理するようにしています。共有名が$で終わらなかった物はelse句に周り、Get-SmbShareAccessコマンドレットに
# $_(foreachに渡されたNameオブジェクトの中身)を渡して、そのアクセス権のリストを$Resultsの中に代入します。
# そして最後に再びWrite-Outputコマンドレットを利用して、$Resultsに格納されたアクセス権一覧を、ログファイルに出力しています。
$SmbShare_result.Name |
foreach{
if($_ -like "*`$"){
}
else{
$Results=Get-SmbShareAccess $_
Write-Output $Results | Out-File -Append -FilePath $log_dir
}
}
# 最後に、冒頭でマウントしたzドライブをアンマウントします。
Remove-PSDrive -Name $mount_device
実行例
I am KAGA Name ScopeName AccountName AccessControlType AccessRight ---- --------- ----------- ----------------- ----------- shares * BUILTINAdministrators Allow Read shares * KAGAadmiral Allow Read shares * SYOBONmanager Allow Read
管理共有も含めた結果を得たい場合は、下記のPowershellスクリプト(.ps1)を実行してあげればOKです。
$mount_point="\kagatest$"
$mount_device="Z"
$log_dir=$mount_device + ":" + $Env:COMPUTERNAME + ".txt"
New-PSDrive -Name $mount_device -PSProvider FileSystem -Root $mount_point
$Result = Get-SmbShare
Write-Output "I am $Env:COMPUTERNAME" | Out-File -Append -FilePath $log_dir
$Result.Name |
foreach{
$Results=Get-SmbShareAccess $_
Write-Output $Results | Out-File -Append -FilePath $log_dir
}
Remove-PSDrive -Name $mount_device
実行例
I am KAGA Name ScopeName AccountName AccessControlType AccessRight ---- --------- ----------- ----------------- ----------- ADMIN$ * BUILTINAdministrators Allow Full ADMIN$ * BUILTINBackup Operators Allow Full ADMIN$ * NT AUTHORITYINTERACTIVE Allow Full C$ * BUILTINAdministrators Allow Full C$ * BUILTINBackup Operators Allow Full C$ * NT AUTHORITYINTERACTIVE Allow Full IPC$ * BUILTINAdministrators Allow Full IPC$ * BUILTINBackup Operators Allow Full IPC$ * NT AUTHORITYINTERACTIVE Allow Full
なお、複数サーバーが存在する場合は、このPowershellスクリプトを、C:WindowsTempあたりに配布して、PsExecを利用することで管理用端末から当該サーバ群の共有フォルダー一覧と、パーミッション設定一覧を取得することが出来ます。
まとめ
本来であればPsExecを利用せずに、Get-SmbShare、Get-SmbShareAccesアプレットに、別コンピュータで実行できるオプションがあれば良いのですが、残念ながらこのサーブレットには、別コンピュータで実行するオプションが用意されていないので、psexecを活用するしかなさそうです・・・
ただし、別コンピュータで実行する場合は、そのスクリプトに署名するか、対象コンピュータのPowerShellから「Set-ExecutionPolicy Unrestricted」または「Set-ExecutionPolicy Bypass」を実行してPowerShellスクリプトの実行ポリシーを変更する必要があるのでご注意ください。