スクリプト作成_権限強制リセット


はじめに

※あくまで個人的備忘録です※
VDI環境の増築対応で、移動ユーザプロファイルの削除が必要でした。
しかし、この時に手順を誤ったことでプロファイル領域を削除することができませんでした。
この結果、個人ユーザ以外アクセス権がないファイル・フォルダが大量に残ってしまいました。
通常、ユーザプロファイルに対して管理者のみアクセス権を付与しておきますが、今回対応した環境ではそれが実施されていません。

今後、自分以外の人間が同じことをする可能性もあるので、大量のデータに対してACLの書き換えを行うスクリプトを作っておこうと思いました。

スクリプトの仕様について

◆フローチャート図◆
ちょっと手を抜きました。。。
あくまで概要なのでざっくりしたイメージ図として進めます。

概要

◆コマンドのピックアップ◆

takeownコマンド
rem ファイル(フォルダ)の所有者をAdministratorsに変更する
takeown /F %FOLDER% /A 
icaclsコマンド
rem ファイル(フォルダ)のNTFS権限をリセットし継承しているACEだけに変更する
icacls %FOLDER% /reset 
dirコマンド
rem 指定フォルダ配下のフォルダ名のみ表示
dir /a-d /s /b %FOLDER% 
rem 指定フォルダ配下のファイル名のみ表示
dir /a:h /s /b %FOLDER%
rem 指定フォルダ配下の隠しファイル名のみ表示
dir /ad /s /b %FOLDER%

実際に作ってみた

main.bat
@echo off
setlocal EnableDelayedExpansion

rem ------------------------------------------
rem     ファイル一括削除スクリプト
rem     (所有者,権限リセットスクリプト)
rem ------------------------------------------

rem ------------------------------------------
rem YYYY.MM.DD  新規作成
rem ------------------------------------------

rem ログ出力
set TODAY=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%
set LOG=H:\tmp\%TODAY%_LOG.log

rem rootディレクトリ
set ROOT=H:\Profile\test01.V6

rem 一時ファイル作成
set TMP_FILE=H:\tmp\tmp_file.txt
set TMP_HIDE=H:\tmp\tmp_hide.txt
set TMP_DIR=H:\tmp\tmp_dir.txt
set CUR_DIR=H:\tmp\cur_dir.txt

rem rootディレクトリの所有権,権限リセット
takeown /F %ROOT% /A >> %LOG% 2>&1
icacls %ROOT% /reset >> %LOG% 2>&1

rem ファイル,フォルダ,隠しファイル情報の一覧取得
dir /a-d /s /b %ROOT% > %TMP_FILE%
dir /a:h /s /b %ROOT% > %TMP_HIDE%
dir /ad /s /b %ROOT% > %TMP_DIR%

rem ファイル,フォルダの権限リセット(ループ処理)
:ACLLOOP
set TMP1=0
set TMP2=0
set TMP3=0
set TMP4=0
set CNT=0
type nul > %CUR_DIR%

rem カレントディレクトリ行数のカウント
for /f "delims=" %%a in ( %TMP_DIR% ) do (
    set /a CNT=CNT+1
)

rem ファイル権限リセット
for /f "delims=" %%a in ( %TMP_FILE% ) do (
    set TMP1=%%a
    takeown /F "!TMP1!" /A >> %LOG% 2>&1
    icacls "!TMP1!" /reset >> %LOG% 2>&1
)
rem 隠しファイル権限リセット
for /f "delims=" %%a in ( %TMP_HIDE% ) do (
    set TMP2=%%a
    takeown /F "!TMP2!" /A >> %LOG% 2>&1
    icacls "!TMP2!" /reset >> %LOG% 2>&1
)
rem フォルダ権限リセット
for /f "delims=" %%a in ( %TMP_DIR% ) do (
    set TMP3=%%a
    takeown /F "!TMP3!" /A >> %LOG% 2>&1
    icacls "!TMP3!" /reset /t>> %LOG% 2>&1
)

rem 一時ファイルの初期化
type %TMP_DIR% > %CUR_DIR%
type nul > %TMP_FILE%
type nul > %TMP_HIDE%
type nul > %TMP_DIR% 

if %CNT% neq 0 (
    for /f "delims=" %%a in ( %CUR_DIR% ) do (
        set TMP4=%%a
        dir /a-d /s /b !TMP4! >> %TMP_FILE%
        dir /a:h /s /b !TMP4! >> %TMP_HIDE%
        dir /ad /s /b !TMP4! >> %TMP_DIR%   
    )
    goto ACLLOOP
) 

rem 警告メッセージ
echo ----- WARNING -----
echo ----- WARNING -----
echo ----- WARNING -----

rem 領域の削除
rd /s /q %ROOT%
del %TMP_FILE%
del %TMP_HIDE%
del %TMP_DIR% 
del %CUR_DIR% 

endlocal

おわりに

反省点として
・下の階層に潜っていく仕様をイメージしたが、隠しファイル設定に対してうまく機能しなかった
→スクリプトを再実行すると、最下層までリセットが適用されるので一旦OK
・一時ファイル、隠しファイル、フォルダのピックアップがあまりよろしくない
→センスと経験の問題なのでこれから頑張ります