はじめに
※あくまで個人的備忘録です※ 運用チームのお手伝いで、エンジニア人生5年目で初めて実用的なスクリプト作成にトライしました。 内容は「バックアップされたファイル、フォルダを目視確認している。この手間を省くため、確認作業の自動化をしてほしい。」というお話からでした。 当時、構築案件が落ち着いていたこともあり、私が対応することになりました。 要件は明確ですが、スクリプトなんてまともなものを作ったことがないため、1からググることを始めました。スクリプトの仕様について
始める前に、以下の流れで取り組み、イメージを可視化しました。 ①フローチャート図を作成し、大まかな処理の流れを書き出す(実際の確認処理は処理A,処理Bとaboutに表現) ②処理A、Bと表現した処理について、要件から必要な処理ごとに分ける ③処理に必要と思われるコマンドを調べ、イメージと合致するものをピックアップしていく◆要件の整理◆
パターン | 確認方法 | 補足 |
---|---|---|
A | YYYY-MM-DD hh.mm.ss表記のフォルダが作成されている | |
B | 更新日時が前日日付のファイルがある | |
C | UDPコンソールを起動しイベントログからステータス確認 | バックアップサーバにRDP接続する |
D | .binファイルの更新日付が確認日の2:00になっている | |
E | YYYY.MM.DD,YYYY.MM.DD-1,YYYY.MM.DD-2のフォルダが存在すること |
◆コマンドのピックアップ◆
forコマンド
for /f "skip=1 tokens=1-3 delims=," %%a in ( ****.csv ) do ( )
rem カンマ(,)区切りのCSVを変数に読み込む
dirコマンド
dir /b /ad %FILEPATH%
rem FILEPATHに存在するフォルダ一覧のみ表示
dir /a-d %FILEPATH%
rem FILEPATHに存在するファイルを一覧表示(更新日付含む)
findstrコマンド
dir /b /ad %FILEPATH% | findstr "test"
rem dirコマンドで取得した値から、文字列「test」を含むものだけ抽出
実際に作ってみた
以下のファイル構成で準備しました。
分割したのは汎用性を高めるためです。(改修や別スクリプトへの流用)
情報ファイル(hostlist.csv)を事前に準備します。
内容例は以下になります。
ホスト名 | パターン情報 | 確認先フォルダ |
---|---|---|
HOST-A | A | H:\Backup\HOST-A |
HOST-B | B | H:\Backup\HOST-B |
HOST-C | C | H:\Backup\HOST-C |
・・・ | ・・・ | ・・・ |
main.bat
@echo off
setlocal EnableDelayedExpansion
rem *-------------------------------*
rem
rem バックアップ確認 自動化
rem
rem *-------------------------------*
rem
rem YYYY.MM.DD :新規作成
rem サブスクリプト一覧(subscript配下)
rem today.bat :当日日付情報取得
rem yesterday.bat :昨日日付情報取得
rem 2days_ago.bat :一昨日日付情報を取得
rem PatternA.bat :パターンAの処理用
rem PatternB.bat :パターンBの処理用
rem PatternC.bat :パターンCの処理用
rem PatternD.bat :パターンDの処理用
rem PatternE.bat :パターンEの処理用
rem 変数一覧
rem TODAY1 :yyyy-mm-dd表記の当日日付
rem TODAY2 :yyyy/mm/dd表記の当日日付
rem TODAY3 :yyyymmdd表記の当日日付
rem YESTERDAY1 :yyyy-mm-dd表記の昨日日付
rem YESTERDAY2 :yyyy/mm/dd表記の昨日日付
rem YESTERDAY3 :yyyymmdd表記の昨日日付
rem TWODAYS_AGO :yyyymmdd表記の一昨日日付
rem CSVHOSTNAME :CSV一覧に記載されている確認対象ホスト名
rem CSVPATH :CSV一覧に記載されている確認先パス情報
rem HANTEI :分岐処理の判定結果(○/△)
rem LOGFILE :検査結果の出力先
rem 日付情報の取得
call subscript\today.bat
call subscript\yesterday.bat
call subscript\2days_ago.bat
set LOGFILE=C:\TEMP\Script\%TODAY1%_backup-autocheck.csv
rem 対象ホスト,パターン,確認先フォルダ情報元の指定
set LISTFILE = hostlist.csv
for /f "skip=1 tokens=1-3 delims=," %%a in ( %LISTFILE% ) do (
rem ホスト名,パターン情報,確認先を変数に代入
set CSVHOSTNAME=%%a
set CSVPATH=%%c
set HANTEI=N/A
rem パターンごとに処理を分岐
if %%b == A (
call subscript\PaternA.bat %%c
) else if %%b == B (
call subscript\PaternB.bat %%c
) else if %%b == C (
call subscript\PaternC.bat %%c
) else if %%b == D (
call subscript\PaternD.bat %%c
) else if %%b == E (
call subscript\PaternE.bat %%c
) else (
set HANTEI=Error:該当パターン無
)
rem ホスト名と判定結果をCSV出力
echo !CSVHOSTNAME!,!HANTEI! >> %LOGFILE%
)
endlocal
today.bat
@echo off
rem 時刻表記がYYYY-MM-DD
set TODAY1=%DATE:~0,4%-%DATE:~5,2%-%DATE:~8,2%
rem 時刻表記がYYYY/MM/DD
set TODAY2=%DATE:~0,4%/%DATE:~5,2%/%DATE:~8,2%
rem 時刻表記がYYYY.MM.DD
set TODAY3=%DATE:~0,4%.%DATE:~5,2%.%DATE:~8,2%
yesterday.bat
@echo off
rem 時刻表記がYYYY-MM-DD
rem 前日日付
FOR /F "usebackq" %%a IN (`powershell -command [DateTime]::Today.AddDays"("-1")".ToString"("'yyyy-MM-dd'")"`) DO SET yesterday1=%%a
rem 時刻表記がYYYY/MM/DD
rem 前日日付
FOR /F "usebackq" %%a IN (`powershell -command [DateTime]::Today.AddDays"("-1")".ToString"("'yyyy/MM/dd'")"`) DO SET yesterday2=%%a
rem 時刻表記がYYYY.MM.DD
rem 前日日付
FOR /F "usebackq" %%a IN (`powershell -command [DateTime]::Today.AddDays"("-1")".ToString"("'yyyy.MM.dd'")"`) DO SET yesterday3=%%a
2days_ago.bat
@echo off
rem 時刻表記がYYYY.MM.DD
rem 前々日日付
FOR /F "usebackq" %%a IN (`powershell [DateTime]::Today.AddDays"("-2")".ToString"("'yyyy.MM.dd'")"`) DO SET TWODAYS_AGO=%%a
PatternA.bat
@echo off
set CSVPATH=%1
rem 取得した日付と同じ日付のフォルダ名を検索
dir /b /ad %CSVPATH% | findstr "%YESTERDAY1%" >nul
if %errorlevel% == 0 (
set HANTEI=○
) else (
set HANTEI=△
)
PatternB.bat
@echo off
set CSVPATH=%1
rem 取得した日付と同じ更新日付のファイルを検索
dir /a-d %CSVPATH% | findstr "%YESTERDAY2%" > nul
if %errorlevel% == 0 (
set HANTEI=○
) else (
set HANTEI=△
)
Patternc.bat
@echo off
set HANTEI=自動化対象外
PatternD.bat
@echo off
set CSVPATH=%1
rem 更新時刻情報を取得
set UPDATE-TIME=02:00
rem 対象ファイル1を指定
set FILE1=test1.bin
rem 指定された日付,時刻のファイル名を検索
dir /a-d %CSVPATH% | findstr "%TODAY2%" | findstr "%UPDATE-TIME%" | findstr "%FILE1%" > nul
if %errorlevel% == 0 (
goto :GOOD-END
)
rem 対象ファイル2を指定
set FILE2=test2.bin
rem 指定された日付,時刻のファイル名を検索
dir /a-d %CSVPATH% | findstr "%TODAY2%" | findstr "%UPDATE-TIME%" | findstr "%FILE2%" > nul
if %errorlevel% == 0 (
goto :GOOD-END
)
set HANTEI=△
exit /b
:GOOD-END
set HANTEI=○
PatternE.bat
@echo off
set CSVPATH=%1
rem 2日前の日付フォルダ名を検索
dir /b /ad %CSVPATH% | findstr "%TWODAYS_AGO%" >nul
if %errorlevel% neq 0 (
goto :NG-END
)
rem 昨日の日付フォルダ名を検索
dir /b /ad %CSVPATH% | findstr "%YESTERDAY3%" >nul
if %errorlevel% neq 0 (
goto :NG-END
)
rem 当日の日付フォルダ名を検索
dir /b /ad %CSVPATH% | findstr "%TODAY3%" >nul
if %errorlevel% neq 0 (
goto :NG-END
)
set HANTEI=○
exit /b
:NG-END
set HANTEI=△
おわりに
完璧なものを手今日することができなかったのは悔しいですが、最低限必要な機能を実装はできました。 「PatternC」についてもイメージはあったんですが、下記の理由で断念しました。 ①バックアップシステム本体は直接触れない ②自動化はしてほしいがあまり時間をかけないでほしい(ベストエフォート) ※「確認対象は1つ2つ程度だったこともあり、自動化するほどではない。」と無理矢理納得してもらいました。。。。ただ、個人的には「自分の力でスクリプトを作成することができる」ことがわかったので、これからちょくちょくやっていこうと思います。