Web 制作の現場では、サーバーに入ってファイルをコピーしたり、データベースをエクスポートしたりと、地味だけれど欠かせない作業がいくつもあります。その代表格が バックアップ
もし本番環境の WordPress が壊れてしまったら、復旧できなければ致命的です。

とはいえ、毎回 FTP ソフトを立ち上げてファイルを転送し、phpMyAdmin を開いて SQL をエクスポートする…そんな作業は非常に面倒です。

一般的に有名なFTPソフト

ソフト名種類特徴バックアップ用途での利点注意点
FileZillaオープンソース(無料)最も有名なFTPクライアント。FTP/SFTP対応。UIがシンプル。無料で使える。ドラッグ&ドロップで一括転送可能。自動同期やスケジュール機能は標準では弱い。
WinSCPオープンソース(無料)SFTP/FTP/FTPS対応。スクリプトやバッチで自動化可能。バックアップ処理をスクリプト化できるため、自動バックアップ向き。設定に慣れる必要あり。
Cyberduck無料(寄付歓迎)FTP/SFTPのほか、クラウド(S3, Google Drive等)も対応。サーバーとクラウドをまたいだ保存が可能。軽快さはやや劣る。日本語訳に違和感あり。
FFFTP日本製・無料Windows向け老舗。日本語UIで使いやすい。軽量でシンプル。古くからの定番。更新が少なく、SFTP対応が不安定。

個人的にはアイコンのかわいさから「Cyberduck」をずっと使ってます。WinSCPは高機能ですが、Web制作の現場で、しかも開発じゃないので「Cyberduck」で十分だと感じてます。

一方で、Dreamweaverはバックアップに不向きです。
ディレクトリの移動をするたびに設定が必要で、動作が遅く、バックアップ自動化やスケジュール転送などといった機能はほとんどないので改善してくれたらよいのに。。。といつも思ってます。

バックアップに必要なサーバー情報

項目用途備考
サーバーアカウント名SSH / FTP 接続時に必要例: cfgo123456
サーバーホスト名接続先サーバーを指定例: sv*.xserver.jp
ドメイン名バックアップ対象の WordPress サイト例: amarga.jp
WordPress設置ディレクトリファイルをまとめるフォルダ例: /home/ユーザー名/example.com/public_html/サブディレクトリ名/
データベース名mysqldump でエクスポートする対象例: wordpress_xyz001
データベースユーザー名DB にアクセスするためのユーザー例: db_taro*123
データベースパスワードDBに接続する際に必要セキュリティのため環境変数で管理推奨

ローカル環境の準備

  • バックアップ保存先フォルダ 例: C:\Backups\web\xxxxx\
  • スクリプト保存場所 例: C:\Scripts\wordpress-bk\xxxxx\
  • 環境変数の設定 DBパスワードを環境変数に登録(例: setx DB_PASS “password”)
  • ログ管理ルール ログファイルの保存場所と保存形式を決めておく

事前チェック

  • SSH でサーバーに接続できるか?
  • mysqldump コマンドがサーバーで使えるか?
  • tar コマンドでファイル圧縮が可能か?
  • ローカルPCの scp コマンドでダウンロードできるか?(ロカール側)
  • ディスク容量(サーバー・ローカル両方)が十分あるか?

そこで今回、PowerShell と ChatGPT を使って「1クリックで WordPress 全体をバックアップするスクリプト」を作ってみました。

私はプログラマーではなく、普段は WordPress のカスタマイズや Web 制作が中心。PowerShell なんて使ったこともありませんでした。
それでも ChatGPT に相談しながら進めた結果、初心者でも実用レベルの自動化ツールを作れることを実感しました。

なぜ自動化したかったのか

Web 制作の仕事をしていると、こんなシーンに何度も遭遇します。

  • レンタルサーバーの PHP バージョンを上げたら画面が真っ白になった
  • プラグインの更新でエラーが出て管理画面に入れなくなった
  • サーバー移転前にローカルへ丸ごとコピーしておきたい
  • レンタルサーバー標準のバックアップ機能は復元方法がわからないし、復元テストを人様のwebサーバーでするのが怖い

こういう時、自前のバックアップがあれば安心です。
でも毎回 FTP・phpMyAdmin を使って手作業するのは非効率。
「ワンクリックで全部まとめて保存できたらいいのに」と思ったのが出発点です。

ショートカットクリックでバックアップが一気に行くよ!

ChatGPT に相談しながら作った

最初は PowerShell なんて触ったことがなく、構文も全く知りませんでした。
それでも ChatGPT に「WordPress をバックアップしたい」「ファイルと DB をまとめたい」と投げかけていくと、コードを提案してくれます。

最初の段階ではデータベースのパスワードをスクリプトに直書きしていて、これではセキュリティ上危険だと指摘されました。そこで改善版として 環境変数から読み込む方式 に修正。

また、バックアップが失敗しているのに「完了」と表示されるのも問題だったため、エラーハンドリングを強化。処理に失敗したらその時点で止まるようにしました。

さらに、ログにサーバーのディレクトリ構造が丸見えなのも気になったので、サイズ情報だけを記録する形に変更。

こうして改良を重ねることで、実務で使える「安全版スクリプト」が完成しました。

完成したバックアップスクリプト

以下が完成版のコードです。
(※DBパスワードは環境変数に登録しておき、スクリプトには書かない方式です)

このスクリプトでは、サーバー上で mysqldump によりデータベースをエクスポートし、
さらに tar コマンドで WordPress 本体のファイルをまとめて圧縮します。

その後、ローカル PC にダウンロードしてログを自動出力する仕組みになっています。
最後には、バックアップ完了を知らせるポップアップが表示されるので、
「実行したのに成功したのか分からない」 といった不安もありません。

# =============================
# WordPress バックアップスクリプト
# ローカルPC (PowerShell) で実行
# =============================

# === サーバー設定 ===
$serverUser    = "exampleuser"                     # サーバーユーザー名
$serverHost    = "example.rakko.zone"              # サーバーホスト名
$domainName    = "example.com"                     # WordPress設置ドメイン
$backupName    = $domainName -replace '\.', '-'    # バックアップ用フォルダ名 (例: example-com)

$serverBase    = "/home/$serverUser/0Backups/$backupName"
$serverWebRoot = "/home/$serverUser/public_html/$domainName"

# === ローカル設定 ===
$localBase = "C:\Backups\xxx\$backupName"

# 今日の日付と時間 (ローカルで生成)
$today   = Get-Date -Format "yyyy-MM-dd"
$timeNow = Get-Date -Format "HHmm"   # 時刻 (例: 2130)

# ローカル: 日付フォルダを確認・作成
$localPath = Join-Path $localBase $today
if (-not (Test-Path $localPath)) {
    New-Item -ItemType Directory -Path $localPath -Force | Out-Null
}

# ログファイル名 (日付+時間)
$logPath = "$localBase\backup-check-$today-$timeNow.log"

Write-Output "=== [$today][$domainName] バックアップ開始 ==="

# === DBパスワードを環境変数から取得 ===
$dbPass = $env:DB_PASS
if (-not $dbPass) {
    Write-Output "❌ 環境変数 DB_PASS が未設定です"
    exit 1
}

# === エラーフラグ ===
$hasError = $false

# === サーバー作業 ===
Write-Output "1. サーバーに日付フォルダを作成中..."
ssh "$serverUser@$serverHost" "mkdir -p $serverBase/$today" 2>&1

Write-Output "2. データベースをバックアップ中 (db.sql)..."
$dbResult = ssh "$serverUser@$serverHost" "mysqldump -h localhost -u example_dbuser -p'$dbPass' example_dbname > $serverBase/$today/db.sql" 2>&1
if ($LASTEXITCODE -ne 0) {
    Write-Output "❌ DBバックアップ失敗: $dbResult"
    $hasError = $true
}

Write-Output "3. WordPressファイルを圧縮中 (files.tar.gz)..."
$fileResult = ssh "$serverUser@$serverHost" "tar -czf $serverBase/$today/files.tar.gz -C $serverWebRoot ." 2>&1
if ($LASTEXITCODE -ne 0) {
    Write-Output "❌ ファイル圧縮失敗: $fileResult"
    $hasError = $true
}

Write-Output "4. サーバー側のファイル情報を取得中..."
$serverFiles = ssh "$serverUser@$serverHost" "stat -c '%n %s' $serverBase/$today/* 2>/dev/null" |
    ForEach-Object { ($_ -split ' ')[-2..-1] -join ' ' }

# === ローカル作業 ===
Write-Output "5. サーバーからローカルへダウンロード中..."
try {
    scp -r "${serverUser}@${serverHost}:${serverBase}/${today}/*" $localPath
    if (-not (Test-Path "$localPath\db.sql")) {
        Write-Output "❌ DBのコピー失敗"
        $hasError = $true
    }
    if (-not (Test-Path "$localPath\files.tar.gz")) {
        Write-Output "❌ ファイル圧縮データのコピー失敗"
        $hasError = $true
    }
}
catch {
    Write-Output "❌ SCP コピー処理でエラー発生"
    $hasError = $true
}

Write-Output "6. ローカル側のファイル情報を取得中..."
$localFiles = Get-ChildItem $localPath -ErrorAction SilentlyContinue |
    ForEach-Object { "$($_.Name) $($_.Length)" }

Write-Output "7. ログに出力中..."
"=== サーバー側 ==="   | Out-File -FilePath $logPath -Encoding UTF8
$serverFiles            | Out-File -FilePath $logPath -Append -Encoding UTF8

"`n=== ローカル側 ===" | Out-File -FilePath $logPath -Append -Encoding UTF8
$localFiles             | Out-File -FilePath $logPath -Append -Encoding UTF8

"`n=== バックアップステータス ===" | Out-File -FilePath $logPath -Append -Encoding UTF8
"完了日時: $(Get-Date)"              | Out-File -FilePath $logPath -Append -Encoding UTF8
if ($hasError) {
    "結果: ⚠️ エラーあり。詳細は上記ログを確認してください。" | Out-File -FilePath $logPath -Append -Encoding UTF8
} else {
    "結果: ✅ 正常終了" | Out-File -FilePath $logPath -Append -Encoding UTF8
}

# === 完了メッセージ(ポップアップ表示) ===
Add-Type -AssemblyName PresentationFramework

[xml]$xaml = @"
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        Title="WordPress Backup"
        SizeToContent="WidthAndHeight"
        WindowStartupLocation="CenterScreen"
        Background="#f0f0f0"
        FontFamily="Meiryo UI"
        FontSize="14"
        ResizeMode="NoResize">
    <StackPanel Margin="20">
        <TextBlock Text="WordPress バックアップ結果" 
                   FontSize="16" FontWeight="Bold" 
                   Foreground="DarkBlue" Margin="0,0,0,10"/>
        <TextBlock Text="$domainName のバックアップが完了しました。" 
                   Foreground="Black" Margin="0,0,0,5"/>
        <TextBlock Text="ログファイル: $logPath" 
                   Foreground="Gray" FontSize="12"/>
        <Button Name="OkButton" Content="OK" Width="80" Margin="0,15,0,0" 
                HorizontalAlignment="Center" IsDefault="True"/>
    </StackPanel>
</Window>
"@

# XAML を読み込む
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
$window = [Windows.Markup.XamlReader]::Load($reader)

# OK ボタンを取得してイベント設定
$okButton = $window.FindName("OkButton")
$okButton.Add_Click({ $window.Close() })

# 表示
$window.ShowDialog() | Out-Null


実際に使ってみての感想

最初は「本当に自分にできるのかな?」とやや不安でした。
でも ChatGPT に質問を投げながら、動かない箇所を1つずつ直していくうちに、思っていた以上にすぐ形になりました。(実質4時間)

特に印象的だったのは、自分のレベルに合わせて段階的にアドバイスをくれる点です。
「パスワードを環境変数に移した方がいい」など、初心者だと気付けない落とし穴も補ってくれます。
そのおかげで、最終的に安全で実用的なコードになったと思います。

まとめ

  • WordPress のバックアップは「ファイル+DB」の両方が必要
  • PowerShell を使えば、ワンクリックでバックアップ可能
  • ChatGPT に相談しながら進めることで、初心者でも実用レベルの自動化ができる
  • セキュリティを考え、パスワードは環境変数で管理するのがベストプラクティス

これで更新やサーバー作業の前に「1クリックでバックアップ」を取れるようになり、毎月のバックアップ作業が楽になりました!

ログも残すようにしたよ!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です