【Windows】ファイルサーバ移行検証_AD環境ではない(WORKGROUP)場合でのデータコピー実行

PowerShell

はじめに

本記事ではWORKGROUP環境でのデータコピーについて紹介します。アクセス権のコピーを特に意識しない場合は、コピー&ペーストでも良さそうですが、大規模データを定期的にコピーする場合にはスケジュール実行することもありますし、差分コピーをする場合はいつも通りのデータコピーではダメでしょう。参考になれば幸いです。

※本記事は下記のファイルサーバ移行検証の一部です。

構成

既存ファイルサーバ(データのコピー元
ホスト名:filesv-win-01
IPアドレス:172.16.1.137
OS:WindowsServer 2022

新規ファイルサーバ(データのコピー先)
ホスト名:filesv-win-02
IPアドレス:172.16.1.138
OS:WindowsServer 2022

切り替えの流れ

本記事で紹介する手順は個人的な経験となりますが、流れは以下のような流れを想定しています。

既存サーバと新規サーバを接続
テスト用スクリプトの実行
データコピーの定期実行(切り替えまで随時実行)

私が経験したシステム更改作業はオンプレサーバの更改が多く、エンドユーザーの職場環境のすぐ側に設置されているサーバーが多かったです。そのため、数TBあるデータをすぐにコピーできるはずもなく、データコピーを数日かけて実施きていました。データコピーで使用するネットワークが業務で使うネットワークと同じ場合、データコピーを実施する時間を夜間に限定したり、使用できる帯域を制限したりすることもありました。実施環境によって要件は異なりますので、実施の際は事前に確認しておきましょう。

既存サーバと新規サーバの接続

データコピー用に接続します。システム更改を想定して書きますが、データコピーのために既存と新規が一時的に並行稼働することになります。IPアドレスは一時的に使用する仮のアドレスを割り当てる必要があるでしょう。

テスト用スクリプトの実行

既存サーバと新規サーバがネットワーク的に接続できている想定で進めます。
以下のスクリプトは、データコピーコマンドである「robocopy」コマンドをテストモードで実行するスクリプトです。

スクリプトについて説明します。
認証情報:「$netUseCommand = “net use $source /user:fileuser01 Share_test01!”」で指定しています。
コピー元のデータ:「$source = “\\172.16.1.137\share”」で指定しています。
コピー先:「$destination = “E:\share”」で指定しています。
 ※今回は「\\172.16.1.137\share」のデータを実行端末のローカルである「E:\share」にコピーします。
コマンド実行結果:「C:\work\log\」に保管されます。

また、先に書いている通り、あくまでもテストモードなので、実際にコピーされません。
robocopyのオプションについては適宜要件に応じて編集してください。

# ネットワーク共有のパス
$source = "\\172.16.1.137\share"
# ローカルのコピー先ディレクトリ
$destination = "E:\share"

# 実行日時を含むログファイル名の生成
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$logFile = "C:\work\log\test_log_$timestamp.txt"

# ログディレクトリが存在しない場合は作成
$logDir = Split-Path $logFile
if (!(Test-Path -Path $logDir)) {
    New-Item -ItemType Directory -Path $logDir -Force
}

# ログ記録関数
function Write-Log {
    param (
        [string]$message
    )
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logMessage = "$timestamp - $message"
    $logMessage | Out-File -FilePath $logFile -Encoding UTF8 -Append
}

# ログにテスト開始メッセージを書き込む
Write-Log -message "Start copy."

# コピー操作のシミュレーション
Write-Log -message "コピー元: $source"
Write-Log -message "コピー先: $destination"

# 必要なら認証情報を設定
$netUseCommand = "net use $source /user:fileuser01 Share_test01!"
Write-Log -message "実行するNet Useコマンド: $netUseCommand"
Invoke-Expression $netUseCommand

# Robocopyの実行
# /COPY:DAT のみを使用し、アクセス権(SOU)をコピーしないようにする
$robocopyArgs = "$source $destination /MIR /COPY:DAT /R:3 /W:10 /IPG:10 /L"
Write-Log -message "実行するRobocopyコマンド: robocopy $robocopyArgs"

# Robocopyの実行と出力キャプチャ
$robocopyCommand = "robocopy $robocopyArgs > "$logFile" 2>&1"
cmd.exe /c $robocopyCommand

# ネットワーク共有の接続を解除
$netUseDisconnectCommand = "net use $source /delete"
Write-Log -message "実行するNet Use切断コマンド: $netUseDisconnectCommand"
Invoke-Expression $netUseDisconnectCommand

以下は実行結果の例です。

末尾に結果が集約されています。不一致や失敗がないことを確認します。

本番用のデータコピースクリプト

テストモードで問題なく実行できたら、本番用のスクリプトを実行します。以下がそのスクリプトになります。

テスト用スクリプトとほとんど同じで、違いは「/L」オプションの有無とログの名前のみです。当たり前ですが、テストで実行したスクリプトに対し、違う構文のスクリプトを本番実行しないよう注意しましょう。※テストの意味がなくなります。

# ネットワーク共有のパス
$source = "\\172.16.1.137\share"
# ローカルのコピー先ディレクトリ
$destination = "E:\share"

# 実行日時を含むログファイル名の生成
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$logFile = "C:\work\log\copy_log_$timestamp.txt"

# ログディレクトリが存在しない場合は作成
$logDir = Split-Path $logFile
if (!(Test-Path -Path $logDir)) {
    New-Item -ItemType Directory -Path $logDir -Force
}

# ログ記録関数
function Write-Log {
    param (
        [string]$message
    )
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logMessage = "$timestamp - $message"
    $logMessage | Out-File -FilePath $logFile -Encoding UTF8 -Append
}

# ログにテスト開始メッセージを書き込む
Write-Log -message "Start copy."

# コピー操作のシミュレーション
Write-Log -message "コピー元: $source"
Write-Log -message "コピー先: $destination"

# 必要なら認証情報を設定
$netUseCommand = "net use $source /user:fileuser01 Share_test01!"
Write-Log -message "実行するNet Useコマンド: $netUseCommand"
Invoke-Expression $netUseCommand

# Robocopyの実行
# /COPY:DAT のみを使用し、アクセス権(SOU)をコピーしないようにする
$robocopyArgs = "$source $destination /MIR /COPY:DAT /R:3 /W:10 /IPG:10"
Write-Log -message "実行するRobocopyコマンド: robocopy $robocopyArgs"

# Robocopyの実行と出力キャプチャ
$robocopyCommand = "robocopy $robocopyArgs > "$logFile" 2>&1"
cmd.exe /c $robocopyCommand

# ネットワーク共有の接続を解除
$netUseDisconnectCommand = "net use $source /delete"
Write-Log -message "実行するNet Use切断コマンド: $netUseDisconnectCommand"
Invoke-Expression $netUseDisconnectCommand

データコピーの定期実行(切り替えまで随時実行)

スケジュール実行する前の確認について

テストモードで実行できたので、コピー自体は成功しますが、実際の作業時には以下の2点は確認しておきましょう。

コピー実行時に帯域や負荷が上がっていないか
スケジューラからの実行で成功するか

帯域制御をかける場合は、想定通りの範囲内に収まっているかを確認します。タスクマネージャーで確認できるので、コピー実行と同時に確認しましょう。また、スケジュール実行する場合は手動実行して成功するかどうか見ておくと安心です。

スケジュール実行について

タスクスケジューラでPowerShellを実行する手順は、以下を参照してください。

以上でコピー実施までの流れを確認できました。次回はデータコピーができているかの確認を行います。