セーブデータを自動的にバックアップ
このスクリプトの特徴
- 7-Zip を使用して、PPSSPP のセーブデータをバックアップする PowerShell スクリプトです。
- Windows タスクスケジューラを使用することで、PPSSPP のセーブデータを自動的にバックアップできます。
- ダウンロードコンテンツやメディアインストール用のフォルダは、正規表現を使用して除外できます。
- 実行時にエラーが発生した場合は、同一フォルダ内にログファイル(
savedata-backup.log
)が作成されます。
注意:動作は保証しません。使用は自己責任でお願いします。
必要なもの
- Windows 10 64bit
- Powershell:以下のいずれかが必要になります。
- Windows PowerShell v5.1 (x64):Windows 10 64bit にはデフォルトでインストールされています。
- PowerShell Core:手動でインストールする必要があります。
- 7-Zip x64
- テキストエディタ(Notepad++やVS Codeなど)
導入手順
1. PowerShell の実行ポリシーを変更する
PowerShell はセキュリティ上の理由から、スクリプトファイルの実行が既定では許可されていません。このため、手動で設定を変更する必要があります。既に変更している場合はスキップしてください。
1-1. 【管理者権限不要】PowerShell から変更する
- Windows スタートボタンを右クリックして「Windows PowerShell」をクリック
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
をコピペしてEnter
- 警告が表示されるので、
y
を入力してEnter
実行ポリシーを既定に戻したい場合
- Windows スタートボタンを右クリックして「Windows PowerShell」をクリック
Set-ExecutionPolicy -Scope CurrentUser Restricted
をコピペしてEnter
- 警告が表示されるので、
y
を入力してEnter
Get-ExecutionPolicy -List
を実行すれば、現在の実行ポリシーをリスト形式で確認できます。項目の詳細については、Windows で PowerShell スクリプトの実行セキュリティポリシーを変更する:Tech TIPS | @ITを参照してください。
2. スクリプトをエディタにコピペする
Notepad++やVS Codeなどに、以下のスクリプトをコピペする。Windows 10 付属のメモ帳でも構いません。
Set-StrictMode -Version 3.0
Function isPowerShellCore() {
return $PSVersionTable.PSVersion.Major -gt 5
}
Function isValidPath([String]$path) {
return [boolean]$path -and (Test-Path $path)
}
Function createLog([String]$msg) {
[String]$scriptName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.ScriptName)
if (isPowerShellCore) {
Add-Content -LiteralPath "$PSScriptRoot\$scriptName.log" -Encoding utf8NoBOM -Value ((Get-Date -Format G) + ",$msg")
}
else {
(Get-Date -Format G) + ",$msg" |
Out-String |
ForEach-Object { [Text.Encoding]::UTF8.GetBytes($_) } |
Add-Content -LiteralPath "$PSScriptRoot\$scriptName.log" -Encoding Byte
}
Write-Error($msg)
}
Set-Variable -Name 'SEVENZ_PATH' -Option ReadOnly -Value "$Env:PROGRAMFILES\7-Zip\7z.exe"
[String]$backupName = (Get-Date -Format 'yyyy-MM-dd') + '.7z'
[String]$dstPath = ''
[int]$maxBackup = 7
[Regex]$notBackup = 'DAT$|QST$|DLC'
if (-not (isValidPath($SEVENZ_PATH))) {
createLog('7-Zip not found')
exit
}
if (-not $PSScriptRoot.EndsWith('memstick\PSP\SAVEDATA')) {
createLog('Invalid script location')
exit
}
Push-Location -Path $PSScriptRoot
# $dstPathに文字列が代入されていて、かつその文字列が無効なパスな場合
if ([boolean]$dstPath -and -not (Test-Path($dstPath))) {
createLog('Invalid $dstPath')
exit
}
if ($maxBackup -lt 0) {
createLog('Invalid negative $maxBackup')
exit
}
[Array]$savedataList = Get-ChildItem -Directory -Name |
Where-Object { $_ -NotMatch $notBackup }
if ($null -ne $savedataList) {
if (isValidPath($dstPath)) {
&($SEVENZ_PATH) a -t7z (Join-Path $dstPath $backupName) $savedataList
}
else {
&($SEVENZ_PATH) a -t7z $backupName $savedataList
}
}
else {
createLog('No directories to be backed up')
}
if (isValidPath($dstPath)) {
Push-Location -Path $dstPath
}
# WARNING: 明示的な型宣言が無く、かつ変数内のオブジェクトが一つだけのとき、Length取得時にString型へ暗黙の型変換が行われる
[Array]$backupList = Get-ChildItem -File -Filter ????-??-??.7z -Name
if ($backupList.Length -gt $maxBackup) {
for ([int]$i = $backupList.Length - $maxBackup; $i; --$i) {
Remove-Item $backupList[$i - 1]
}
}
Pop-Location
Pop-Location
変更履歴
- 2021-02-12:
$backupCount
を削除。$backupPath
が正しくないときエラー表示を追加。 - 2021-04-10:大規模なリファクタリング。エラー時のログ出力を追加。
- 2021-04-13:出力されるログの文字コードを
UTF-8 BOM無し
で統一。 - 2021-05-10:フォルダの移動を
Set-Location
からPush-Location/Pop-Location
に変更。$directoriesList
を$savedataList
にリネーム。 - 2021-05-11:
$SEVENZ_PATH
を読み込み専用に変更。ログファイルが実行元のカレントディレクトリに作成されてしまう問題を修正。Windows PowerShell でログファイルが改行されない問題を修正。$backupPath
が無効なパスのとき終了するように変更。$maxBackup
が負の値のとき終了するように変更。
2-1. バックアップ先のフォルダを変更する
既定では、「SAVEDATA」フォルダ内にバックアップファイルを作成します。他のフォルダや外部ドライブに保存したい場合は以下の手順で変更できます。
`ある
[String]$backupPath = ''`の行に移動''
の間に、バックアップ先のパスをコピペ
注意:無効なパスが代入された場合は、バックアップの作成と超過分のバックアップの削除は行われません。
- 絶対パス:
[String]$backupPath = 'd:\backup'
- 相対パス:
[String]$backupPath = '..\backup'
- 環境変数入りパス:
[String]$backupPath = "$Env:HOMEPATH\backup"
注意:環境変数をパスに含める場合は、'
の代わりに"
でパス全体を囲んでください。
2-2. 最大バックアップ数を変更する
既定では、最大 7 個のバックアップファイルを保持します。この数値を超えると、バックアップファイルが古い順から自動的に削除されます。
`にある
[int]$maxBackup = 7`の行に移動7
を削除して、バックアップしたい最大数を半角数字で入力
注意:負の値が代入された場合は、バックアップの作成と超過分のバックアップの削除は行われません。
[int]$maxBackup = 3
[int]$maxBackup = 14
2-3. ダウンロードコンテンツやメディアインストール用のフォルダを除外する
「SAVEDATA」フォルダ内にはゲームのセーブデータだけでなく、ゲームによって作成されたメディアインストールデータや、ダウンロードコンテンツが保存されていることがあります。これらフォルダもバックアップ対象にしてしまうと、圧縮処理に時間がかかるだけでなく、作成されたバックアップファイルが無駄に肥大化していまいます。そこで正規表現を利用してこれらのフォルダを除外して、セーブデータのみをバックアップ対象にします。
既定では、MHP2G/MHP3 と MGSPW の該当フォルダを除外しています。その他のゲームは管理人が持っていないため、自分で正規表現に追加してください。正規表現の書き方についてはページ下部の参考リンクを参照するか、ググってください。
`にある
[Regex]$notBackup = 'DAT$|QST$|DLC'`の行に移動'DAT$|QST$|DLC'
に|
を挟んで正規表現を追加していく
注意:正規表現が正しく動作するかはスクリプト側でチェックしていません。実行する前に、必ず下記のサイトなどでテストしてください。
- エクスプローラーを開き、「SAVEDATA」フォルダまで移動
- アドレスバーをクリック > 右クリック > コピー
- Windows スタートボタンを右クリックして「Windows PowerShell」をクリック
cd
に続き半角空白を入力したあと、上記のパスをペーストしてEnter
Get-ChildItem -Directory -Name | Set-Clipboard
をコピペしてEnter
- 上記のサイトの下の欄に貼り付け
- 右上の「Flags」をクリックして、「multiline」を有効化
- 納得のいく正規表現ができるまで編集する
[Regex]$notBackup = 'DAT$|QST$|DLC|ABC|^FOO|B[AR]$'
2-4. 生成されるバックアップファイルの命名規則を変更する
既定では、バックアップファイルの命名規則は西暦-月-日.7z
となっています。Get-Date
のフォーマット指定を変更することで、例えばこれを西暦-月-日_時-分.7z
と変更することもできます。フォーマットについては、ページ下部の参考リンクを参照してください。実際に編集する前に PowerShell 上で実行して、意図した通りの出力になるか確認してください。
`にある
[String]$backupName = (Get-Date -Format 'yyyy-MM-dd') + '.7z'`の行に移動'yyyy-MM-dd'
を編集する` にある
[Array]$backupList = Get-ChildItem -File -Filter ????-??-??.7z -Name`の行に移動????-??-??.7z
を生成されるファイル名に合うように編集する?
は、ワイルドカードで「任意の一文字」を意味します。
注意:日付の表記によく用いられる/
や:
は、Windows 環境下ではファイル名に使用することができません。-
か_
の使用をおすすめします。
[String]$backupName = (Get-Date -Format 'yyyy-MM-dd_HH-mm') + '.7z'
[Array]$backupList = Get-ChildItem -File -Filter ????-??-??_??-??.7z -Name
3. PPSSPP のセーブデータフォルダにスクリプトを保存する
- エディタ上で「名前を付けて保存」を選択
- 「PPSSPP\memstick\PSP\SAVEDATA」に移動
- ファイル名は「savedata-backup.ps1」をコピペして、このスクリプトを保存
保存時の文字コードについて
PowerShell には大きく分けて 2 種類のエディションがあり、デフォルトでそれぞれ異なる文字コードを使用しています。そのためスクリプトにマルチバイト文字(日本語など)が含まれていると、予期しないエラーが発生する可能性があります。コメント部分(#
)のマルチバイト文字は、文字化けしても無視されるので動作に影響しません。
- Windows PowerShell
- Windows 10 にデフォルトでインストールされている PowerShell。デフォルトでは青い画面。
- 日本語ロケールでは、デフォルトの文字コードは
Shift_JIS(ANSI)
- PowerShell Core
- クロスプラットフォームで動作する、オープンソースの新しい PowerShell。デフォルトでは黒い画面。
- デフォルトの文字コードは
UTF-8 BOMなし
詳しい情報はPowerShell Core:Dev Basics/Keyword | @ITや、PowerShell Core から PowerShell 7 に至る道 - Ver.1.1 | SlideShareを参照してください。
スクリプトを保存するときの文字コードは、使用する PowerShell に合わせる形になります。Windows PowerShell ならShift_JIS(ANSI)
で保存、PowerShell Core を使用するならUTF-8 BOMなし
で保存してください。
スクリプトを手動で実行する
すでに同名(同じ日付)のファイルが存在するときは、そのファイルが上書き保存されます。
- ドラッグ&ドロップで実行
- PowerShell を起動
- このスクリプトを PowerShell にドラッグ&ドロップして
Enter
- 警告が表示される場合は、
y
を入力してEnter
- 右クリックで実行
- スクリプトを右クリック
- 「PowerShell で実行」をクリック
- 警告が表示される場合は、
y
を入力してEnter
4. スクリプトをタスクスケジューラに登録して実行を自動化する
4-1. 【管理者権限】タスクスケジューラを起動する
- 「ファイル名を指定して実行」から起動
Win+R
キーを押して「ファイル名を指定して実行」を起動taskschd.msc
を入力してEnter
- Windows スタートメニューのアプリ一覧から起動
- Windows スタートボタンをクリック
- アプリ一覧をスクロールし「Windows 管理ツール」フォルダをクリック
- 「タスクスケジューラ」をクリック
4-2. タスク用のフォルダを作成する
タスクスケジューラには、OS や他のプログラムが作成したタスクが既に登録されています。後でタスクを管理するときのために「ユーザが作成したタスク」を「システムが作成したタスク」とはフォルダで分けて保存するのがおすすめです。
- 左ペインの「タスクスケジューラライブラリ」を選択
- 右クリックして「新しいフォルダー」をクリックし、
User
を入力
4-3. タスクを作成する
- 上記で作成した「User」フォルダを選択、右クリックして「基本タスクの作成」をクリック
- 基本タスクの作成
- 名前:
PPSSPPSavedataBackup
をコピペ - 説明:
PPSSPPのセーブデータを自動的にバックアップします。実行には「7-Zip x64」がインストールされている必要があります。ファイル名の命名規則は「YYYY-MM-DD」で、ファイル形式は7zです。
をコピペ - 「次へ」をクリック
- 名前:
- トリガー
- 「毎日」を選択
- 「次へ」をクリック
- トリガー/毎日
- 「毎日」の詳細設定が表示されるので、実行したい時間を選択
- 注意:指定した時間に PC が起動していない場合、処理はスキップされます。
- 「次へ」をクリック
- 操作
- 「プログラムの開始」を選択
- 「次へ」をクリック
- プログラムの開始
- プログラム/スクリプト:
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe
をコピペ。PowerShell Coreを使用する場合は、代わりに%PROGRAMFILES%\PowerShell\7\pwsh.exe
をコピペ - 引数の追加 (オプション):
-Command スクリプトの絶対パス
をコピペ - 注意:「スクリプトの絶対パス」に空白が含まれる場合は、パス全体を
"
で囲んでください。 - 「次へ」をクリック
- プログラム/スクリプト:
- タスクの要約が表示されるので、間違いがないか確認して「完了」をクリック
ある日を境に実行されなくなってしまった場合は、フォルダの移動やリネームなどによって、スクリプトまでのパスが変更された可能性があります。タスクスケジューラを開いて、スクリプトの絶対パスを確認してみてください。
参考リンク
PowerShell
- Get-ChildItem and the–Include and –Filter parameters | Under The Stairs
- PowerShell における"戻り値"と"Return"について | しばたテックブログ
- How can I get the current PowerShell executing file? | Stack Overflow
- pushd/popd でフォルダーを移動する:Tech TIPS | @IT
日付
- PowerShell Date Format | Stephanos Constantinou Blog
- PowerShell Get-Date Format | Javatpoint
- 【Powershell】Get-Date コマンドで日付・時刻のフォーマット一覧 | ぴぐろぐ
文字コード
パス
エラー処理
- Set-StrictMode についてちょっとだけ詳しく説明してみる | しばたテックブログ
- PowerShell スクリプトのエラー処理の覚書 | 鷲ノ巣
- $null について知りたかったことのすべて - PowerShell | Microsoft Docs
- .net - How can I check if a string is null or empty in PowerShell? | Stack Overflow
正規表現
タスクスケジューラ
- 【Windows 10 対応】タスクスケジューラで定期的な作業を自動化する:Tech TIPS | @IT
- Windows のタスクスケジューラーで PowerShell のスクリプトを実行する際には「パス」に注意:Tech TIPS | @IT
- タスクスケジューラのタスクを停止するまでの時間でハマった | ぴぐろぐ