【Power Shell】タスクスケジューラでバックアップ用のスクリプト動かす


作業を行っている最中に間違えてファイル消す事故があった為に、バックアップを1日1回取る事にしました。
最近はPowerShell触るのが楽しいので、PowerShellでバックアップ用のスクリプトを作成　→　タスクスケジューラに登録しようと思います。

※今回はCopy-Itemコマンドで作成を行っておりますが、ログをちゃんと残したい/タイムスタンプ等の細かな情報を保持したままコピーしたいのであればRoboCopyコマンドをお勧めします。今回はとりあえずファイル/フォルダのコピーが出来ればよいので、Copy-Itemコマンド使います。

とりあえず、何かしら異常があった場合にエラーを吐くように $ErrorActionPreference にStopを設定します。コマンド(cdなど)によっては、処理を停止せずに続きの処理を行ってしまうのをこれで防げます。
スクリプトの一行目に記載しています。

4行目でConfを定義
7行目でスクリプト実行時の日付取得と書式の設定を行っています。

今回はログも残しておきたいので

・10行目でログを保存するフォルダの定義
・13～14行目でログ/エラーログのファイル名
・16～17行目でログ/エラーログのファイルパス

を定義しています。

```:
$ErrorActionPreference = "Stop"

#Conf定義
$Conf = "C:\Folder_Backup.conf"

#日付定義
$Date = Get-Date -Format "yyyyMMdd"

#LogFolder定義
$Log_Folder = "C:\Log"

#ログ/エラーログファイル名定義
$Log_Name = $Date + "_Folder_Backup.log"
$Error_Log_Name = $Date + "_Folder_Backup_Error.log"

#ログのファイルパス作成
$Log_File = Join-Path $Log_Folder $Log_Name
$Error_Log_File = Join-Path $Log_Folder $Error_Log_Name
```

4行目で定義しているConfを作成します。
Copy-Itemコマンドに引数を渡す為のConfとなります。　2行目の","の左部分がコピー元　/　右部分がコピー先　となります。


```:Folder_Backup.conf
#Copy-itemの引数(コピー元,コピー先)
C:\Source,C:\Target
```

上記で、定義は行えました。
お次は、メイン処理を記載していきます。
try~Catchでエラーが出た場合は17行目の　\\$Error[0]  > \\$Error_Log_File　を実施しています。

5~7行目は、Get-Contentでファイルを読み込み/文字列の検索/置換/配列化　を行っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/015aa288-c065-f773-ae47-9c68a9afbaa2.png)

9行目のCopy-Itemコマンドでバックアップを行います。
-Recurseで再帰的なコピーを指定。-forceでコピー先に同名ファイル等が存在する場合でも上書きするように指定。
10行目は　$Log_File　にコピーの結果を出力しています。

これで、スクリプトの作成は終了です。

```:
try{

    if((Test-Path $Conf) -and ((Get-Content $Conf).Length -eq 2)){

        $Conf_Read = Get-Content  $Conf -Encoding "UTF8" | Select-String -NotMatch "#"
        $Conf_Read =  $Conf_Read -replace "`n",""
        $Copy_Item_Args = $Conf_Read.split(",")

        Copy-Item $Copy_Item_Args[0] $Copy_Item_Args[1] -Recurse -Force
        "以下引数でバックアップを行っております。`n"  + $Copy_Item_Args | Out-File $Log_File
    }

}

Catch{
    
    $Error[0]  > $Error_Log_File
}

```

★スクリプト_完成系★
※上記で解説したコマンド等を合わせただけです。

```:Folder_Backup.ps1
$ErrorActionPreference = "Stop"

#Conf定義
$Conf = "C:\Folder_Backup.conf"

#日付定義
$Date = Get-Date -Format "yyyyMMdd"

#LogFolder定義
$Log_Folder = "C:\Log"

#ログ/エラーログファイル名定義
$Log_Name = $Date + "_Folder_Backup.log"
$Error_Log_Name = $Date + "_Folder_Backup_Error.log"

#ログのファイルパス作成
$Log_File = Join-Path $Log_Folder $Log_Name
$Error_Log_File = Join-Path $Log_Folder $Error_Log_Name

try{

    if((Test-Path $Conf) -and ((Get-Content $Conf).Length -eq 2)){

        $Conf_Read = Get-Content  $Conf -Encoding "UTF8" | Select-String -NotMatch "#"
        $Conf_Read =  $Conf_Read -replace "`n",""
        $Copy_Item_Args = $Conf_Read.split(",")

        Copy-Item $Copy_Item_Args[0] $Copy_Item_Args[1] -Recurse -Force
        "以下引数でバックアップを行っております。`n"  + $Copy_Item_Args | Out-File $Log_File
    }

}

Catch{
    
    $Error[0]  > $Error_Log_File
}

```


作成したスクリプトをタスクスケジューラに登録します。
タスクスケジューラを開き、右のメニューから
　
　「タスクスケジューラ ライブラリ　▼」
　　┗「タスクの作成」を選択し、押下します。

全般タブのセキュリティオプションの設定を行います。
「ユーザーがログオンしているどうかにかかわらず実行する」、「最上位の特権で実行する」にチェックを入れます。
名前などは適当にお願いします。

お次はトリガータブです。

今回は、設定を毎日に間隔を1日にしました。以下のような設定で毎日0時にスクリプトが動作します。
有効にチェックも忘れずに、、(無効にすると、動きません。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/3c0c18c7-53e5-e245-de1e-acc0b096ff89.png)

最後に操作タブです。

「プログラム/スクリプト」にPowershell.exeを指定します。
私の環境では、C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe　でした。
そして、引数の追加に今回作成したスクリプトのフルパスを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/2607145f-a0b7-eb5b-3817-cde17837a4c1.png)


簡易的ではありますが、以上で設定は終わりです。
条件タブと設定タブはいつもデフォルトのままにしています。必要に応じて弄りましょう。

テストがてらに動かしてみてください。(実行ポリシーで動かない等があるかも)
ちゃんと動けば、スクリプト内で定義したログフォルダにログが吐かれるはずです。
Confで指定したパスに誤りがなければ、コピーが成功していると思います。

以上、何かしらの参考になれば幸いです。