PowerShellでSFTPを自動化する方法|WinSCPの接続・転送・定期実行

PowerShellとWinSCPを組み合わせることで、SFTPを利用した安全で効率的な大量ファイル転送を自動化する方法を学びます。SFTP(Secure File Transfer Protocol)は、セキュリティを重視したファイル転送プロトコルで、データ保護が重要な場面で広く利用されています。特に、日々の定期的なファイル転送作業を自動化することは、人的ミスの削減や業務効率化に大きく寄与します。本記事では、PowerShellとWinSCPを用いた具体的な設定方法やスクリプト作成の手順をわかりやすく解説し、誰でも実践できる自動化システム構築の知識を提供します。

目次

PowerShellでSFTPを始める前の確認表

PutFilesやGetFilesを呼んだだけで成功と判定せず、転送結果のCheckを確認してから後続処理へ進めます。

確認項目この記事の実装
使うPowerShellWindows PowerShell 5.1は.NET Framework版DLL、PowerShell 7はnetstandard2.0版DLL。WinSCP.exeも同じ製品版を使う。
接続の認証ユーザーの認証と、接続先を確認するSSHホスト鍵は別。ホスト鍵は管理者等の信頼できる経路で照合する。
成功・失敗複数転送はCheckを確認し、成功時0・失敗時1を返す。0件成功と必要ファイルが届いたかも分ける。
タスクの実行ユーザーWindowsの資格情報XMLは保存した端末・ユーザーで復号する。ログとデータへのアクセス権も確認する。

以下はWindows上でWinSCPの.NETアセンブリを使う方法です。PowerShell用のSFTPコマンドが標準で追加される説明ではありません。非公式ラッパーモジュールを使う手順とは分け、APIと失敗判定を直接確認します。

SFTPとは?概要と重要性

SFTPの概要


SFTP(Secure File Transfer Protocol)は、SSH(Secure Shell)を基盤とした安全なファイル転送プロトコルです。従来のFTP(File Transfer Protocol)とは異なり、データ通信が暗号化されるため、機密性やセキュリティが求められる環境に適しています。これにより、転送中のデータが盗聴されたり改ざんされたりするリスクを大幅に低減できます。

SFTPの重要性


SFTPは以下の理由から多くの企業や組織で採用されています:

1. セキュリティの向上


暗号化通信により、転送データを安全に保護します。特に、個人情報や業務上の機密情報を扱う場合に必須です。

2. 安定した通信


エラー制御機能が備わっており、大量のデータを正確に転送できます。ネットワーク障害時は接続が中断する場合があり、再接続や再送を明示的に扱います。

3. 多くのシステムでの対応


Windows、Linux、macOSなど、幅広いプラットフォームで利用可能であり、クロスプラットフォームの環境でも適応できます。

SFTPを活用した業務効率化


定期的なデータ転送が必要な業務において、SFTPを活用することで、手動操作の手間を削減し、自動化による効率化を図ることができます。本記事では、SFTPを活用した自動化システムの構築方法を具体的に説明します。

PowerShellとWinSCPの連携方法

PowerShellとは


PowerShellは、Windows環境で利用できる高度なタスク自動化および構成管理ツールです。コマンドラインインターフェース(CLI)とスクリプト作成機能を兼ね備えており、ファイル操作やシステム管理、外部ツールとの連携を効率的に実現します。

WinSCPとは


WinSCPは、Windows向けのSFTPクライアントで、ファイル転送やディレクトリの同期を安全かつ簡単に行えるツールです。特に、WinSCPの.NETライブラリを利用することで、PowerShellスクリプトから直接SFTPサーバーへの接続や操作が可能になります。

PowerShellとWinSCPを連携する理由


PowerShellとWinSCPを連携することで、以下の利点があります:

1. 自動化の容易さ


PowerShellスクリプトを使用して、定型的なSFTP操作(例:ファイルのアップロード・ダウンロード)を自動化できます。

2. 高い柔軟性


WinSCPの.NETライブラリを利用することで、細かな制御や複雑な処理もスクリプトで実現可能です。

WinSCPのインストールと準備

  1. WinSCP公式サイトからWinSCPをダウンロードし、インストールします。
  2. インストールディレクトリにあるWinSCPnet.dllをスクリプトで利用できるように準備します(通常、C:\Program Files (x86)\WinSCPに配置されています)。

PowerShellでWinSCPを使うための基本設定


まずPowerShellのバージョンと実行形態を確認します。DLLを読み込むコードと基本の接続コードは後で示します:

# Windowsで実行。5.1と7では使うDLLが異なる
$PSVersionTable | Select-Object PSVersion, PSEdition
# 先にGUIと管理者の情報でホスト鍵を照合する
# 実行例は下のUpload.ps1へ集約し、この段階で接続しない

次のステップ


この基本的な連携方法をベースに、大量のファイル転送を効率化する方法やエラーハンドリングの実装について詳しく解説していきます。

DLLとホスト鍵を実行前に用意する

WinSCP公式によると、Automation.zipのルートDLLはWindows PowerShell用、netstandard2.0内のDLLはPowerShell 6/7用です。後述の読み込み例はスクリプト内で使い、同じパッケージのWinSCP.exeを用意します。単にPowerShell 7へ変えるだけでは旧DLLをそのまま使えません。

ホスト鍵の公式説明に従い、サーバー管理者等からSHA-256指紋を取得し、GUIのサーバー情報と照合します。サンプルの文字列や全ホスト鍵を受け入れる設定を本番へ流用しません。鍵不一致が起きたら変更の理由を管理者へ確認します。

必要なツールと環境設定

事前準備:必要なツールのインストール


PowerShellでSFTP自動化システムを構築するには、以下のツールと環境が必要です:

1. PowerShell


Windows OSには標準でPowerShellがインストールされていますが、最新版を使用することをお勧めします。最新バージョンのPowerShell(PowerShell 7など)は、Microsoft公式サイトからインストールできます。

2. WinSCP

  • WinSCPを公式サイト(WinSCP公式)からダウンロードしてインストールします。
  • インストール後、WinSCPnet.dll(WinSCPの.NETライブラリ)をスクリプトで参照できるよう準備します。通常、インストールディレクトリに配置されています。

3. SSHキー(任意)

  • セキュリティを強化するため、パスワード認証ではなくSSHキーを使用することを推奨します。
  • OpenSSHやPuTTYを使用して公開鍵と秘密鍵を作成し、SFTPサーバーに設定します。

環境設定

1. WinSCPの環境確認


インストール後、WinSCPを一度起動し、以下を確認します:

  • SFTPサーバーへの接続テストを実行します。
  • 必要なホスト名、ポート番号、ユーザー名、パスワードまたはSSHキーを取得します。

2. PowerShell環境の準備

  • まず実行ポリシーを確認します。組織ポリシーを回避せず、必要な変更の有無を管理者へ確認してください。
Get-ExecutionPolicy -List

MachinePolicy/UserPolicyで指定された設定はCurrentUserの変更より優先されます。確認だけでは設定は変わりません。

3. WinSCP.NETライブラリの設定

  • WinSCPnet.dllのパスをPowerShellスクリプト内で指定します。例:
# Automation.zipをC:\SftpJob\WinSCPへ展開した例
$winScpRoot = 'C:\SftpJob\WinSCP'
$dllRelative = if ($PSVersionTable.PSEdition -eq 'Desktop') {
    'WinSCPnet.dll'
} else { 'netstandard2.0\WinSCPnet.dll' }
Add-Type -Path (Join-Path $winScpRoot $dllRelative)

推奨されるディレクトリ構造


自動化システムのファイルを整理するために、以下のようなディレクトリ構造を推奨します:

# C:\SftpJob\Upload.ps1        転送処理
# C:\SftpJob\WinSCP\          同じ版のDLLとEXE
# C:\SftpJob\Config\sftp.xml  実行ユーザーの資格情報
# C:\SftpJob\Data\            送信済みか確認する元データ
# C:\SftpJob\Logs\            実行ごとのログ

次のステップ


環境が整ったら、SFTP接続スクリプトを作成し、実際にファイルを転送する方法を学びます。次の項目では、スクリプトの基本構造について詳しく説明します。

基本スクリプトの準備と補足例の読み方

次の基本コードをUpload.ps1として保存します。先に「資格情報ファイル」の初回準備を、タスクを実行するWindowsユーザーで行ってください。ConfigとLogs、転送先の存在・アクセス権、認証方式を確認し、テスト用の非機密ファイル1件で検証します。

ServerName、HostKey、SourceMask、RemoteDirectoryを実環境の値へ指定します。SourceMaskは複数ファイル用マスク、RemoteDirectoryは既存の受信ディレクトリです。コードのremove=$falseでローカル元データを残しますが、同名の送信先ファイルは置き換わる可能性があるため、テスト先を用意してください。

後半の短いコードはOpen済みのSessionや転送対象を用意した状態で使う補足例です。一覧を上から全部つないで実行しません。目的に必要な部分だけを基本コードへ組み込み、Sessionをfinallyで閉じます。各例は静的な構文確認とAPI資料の照合を行いましたが、実際のSFTP接続・資格情報・サーバー権限は読者の環境で確認が必要です。

SFTP接続スクリプトの基本構造

SFTP接続の基本的なPowerShellスクリプト


ここでは、WinSCPの.NETライブラリを使用してSFTPサーバーに接続し、ファイルをアップロードするための基本スクリプトを紹介します。

スクリプトの概要


このスクリプトは、以下の機能を含んでいます:

  • SFTPサーバーへの接続
  • 指定ディレクトリへのファイルのアップロード
  • 接続中のエラー処理

基本スクリプト

# Upload.ps1:Windows用。事前に同じユーザーで資格情報を保存
param(
    [Parameter(Mandatory=$true)][string]$ServerName,
    [Parameter(Mandatory=$true)][string]$HostKey,
    [Parameter(Mandatory=$true)][string]$SourceMask,
    [Parameter(Mandatory=$true)][string]$RemoteDirectory
)
$ErrorActionPreference = 'Stop'
$session = $null
try {
    $winScpRoot = Join-Path $PSScriptRoot 'WinSCP'
    $dllRelative = if ($PSVersionTable.PSEdition -eq 'Desktop') {
        'WinSCPnet.dll'
    } else { 'netstandard2.0\WinSCPnet.dll' }
    Add-Type -Path (Join-Path $winScpRoot $dllRelative)
    $credential = Import-Clixml -LiteralPath (Join-Path $PSScriptRoot 'Config\sftp.xml')
    if ($credential -isnot [System.Management.Automation.PSCredential]) {
        throw '資格情報ファイルの型を確認してください'
    }
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
        Protocol = [WinSCP.Protocol]::Sftp
        HostName = $ServerName
        UserName = $credential.UserName
        SecurePassword = $credential.Password
        SshHostKeyFingerprint = $HostKey
    }
    $logDirectory = Join-Path $PSScriptRoot 'Logs'
    New-Item -ItemType Directory -Path $logDirectory -Force | Out-Null
    $session = New-Object WinSCP.Session
    $session.ExecutablePath = Join-Path $winScpRoot 'WinSCP.exe'
    $session.SessionLogPath = Join-Path $logDirectory ('session-{0}-{1}.log' -f (Get-Date -Format 'yyyyMMddHHmmss'), $PID)
    $session.ReconnectTime = [TimeSpan]::FromSeconds(120)
    $session.Open($sessionOptions)
    $transferOptions = New-Object WinSCP.TransferOptions
    $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
    # 複数ファイルの送信先は末尾を / にする。元ファイルは削除しない
    $destination = $RemoteDirectory.TrimEnd('/') + '/'
    $result = $session.PutFiles($SourceMask, $destination, $false, $transferOptions)
    $result.Check()
    foreach ($transfer in $result.Transfers) { Write-Output $transfer.FileName }
    if ($result.Transfers.Count -eq 0) { Write-Warning '転送対象が0件でした' }
}
catch { Write-Error $_ -ErrorAction Continue; exit 1 }
finally { if ($null -ne $session) { $session.Dispose() } }
exit 0

スクリプトの重要なポイント

1. セッションオプションの設定

  • HostName、UserName、SecurePasswordなど、接続に必要な情報を設定します。
  • SshHostKeyFingerprintを指定することで、サーバーの信頼性を確認します。

2. ファイル転送の設定

  • TransferOptionsで転送モードを指定します(BinaryまたはAscii)。
  • ファイルパスを指定する際、*を使用して複数ファイルを対象にできます。

3. エラーハンドリング

  • try-catch-finally構文を利用して、エラー発生時の処理を記述します。
  • 接続が正常に閉じられるよう、finallyブロックでセッションを確実に終了します。

次のステップ


この基本スクリプトを応用して、大量のファイルを効率的に転送する方法やエラー発生時の詳細なログ記録を実装していきます。

大量ファイル転送のための工夫

大量ファイル転送時に直面する課題


大量のファイルをSFTPで転送する場合、以下の課題が発生する可能性があります:

  • ネットワークの不安定性:長時間の転送で接続が切れる可能性があります。
  • スクリプトのパフォーマンス:大量のファイルを1つずつ転送すると時間がかかります。
  • 失敗したファイルの再転送:転送失敗時に手動で対処するのは非効率です。

これらの課題を解決するための工夫を以下に紹介します。

ネットワークの不安定性への対策

自動再接続の設定


WinSCPセッションで自動再接続を有効にすることで、ネットワーク障害時の影響を軽減します。

# 新しいSessionを開く前に設定する。既定も120秒
$session = New-Object WinSCP.Session
$session.ReconnectTime = [TimeSpan]::FromSeconds(120)
try { $session.Open($sessionOptions); # 必要な転送処理をここへ組み込む
}
finally { $session.Dispose() }

部分的な転送の再開


ResumeSupportは転送の再開・一時名での転送を制御します。Onは全ファイルが対象で、既定は現在100KB超が対象です。再接続の時間制限と別の設定で、サーバー側の権限・一時ファイルや変更中の送信元も確認してください。

# 上のUpload.ps1のPutFilesより前に挿入する場合
$transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::On

スクリプトのパフォーマンス向上

逐次送信から始める


最初は逐次送信で成否を確認します。無制限のStart-Jobは接続数を増やし、失敗の回収も複雑にします。並列化はサーバー側上限と結果・例外・後片付けを設計した後に検討します。

# 補足例:同じファイルを多数のJobへ無制限に投入しない
# Open済みのSessionを利用する逐次送信の例
$files = Get-ChildItem -LiteralPath 'C:\local\path' -File
foreach ($file in $files) {
    $session.PutFileToDirectory($file.FullName, '/remote/path/', $false, $transferOptions) | Out-Null
}

ファイルリストの事前読み込み


ファイルリストを事前に読み込んでおくことで、スクリプトの効率性を高めます。

# 空ファイルを除外するのは業務仕様で許される場合だけ
$files = Get-ChildItem -LiteralPath 'C:\local\path' -File |
    Where-Object { $_.Length -gt 0 }

補足例のPutFileToDirectoryは単一ファイル用で、失敗時に例外を自動で投げます。PutFiles/GetFilesが返す結果のCheckとは扱いが異なります。ファイル名をパターンとして渡す必要がない場合に使い、受信先をディレクトリとして指定します。

失敗したファイルの再転送

ログ記録とリトライ機能


転送の成否をログに記録し、失敗したファイルをリトライする仕組みを組み込みます。

# $filesは送信対象ファイル。失敗を構造化して保存する補足例
$failedFiles = @()
foreach ($file in $files) {
    try { $session.PutFileToDirectory($file.FullName, '/remote/path/') | Out-Null }
    catch { $failedFiles += [pscustomobject]@{ Path=$file.FullName; Error=$_.Exception.Message } }
}
$failedFiles | Export-Csv -LiteralPath 'C:\Logs\failed.csv' -NoTypeInformation -Encoding UTF8

失敗ファイルのみ再転送


失敗したファイルをログから読み込み、再度転送を試みます。

# 接続原因を解消してから、CSVの対象だけ再送する補足例
$failedFiles = Import-Csv -LiteralPath 'C:\Logs\failed.csv'
foreach ($failed in $failedFiles) {
    $session.PutFileToDirectory($failed.Path, '/remote/path/') | Out-Null
}

次のステップ


これらの工夫により、大量のファイルを効率的かつ安全に転送する準備が整いました。次に、エラーハンドリングと詳細なロギングを通じて、信頼性をさらに向上させる方法を学びます。

エラーハンドリングとロギングの実装

エラーハンドリングの重要性


大量ファイル転送では、ネットワークの切断やファイルアクセス権の問題など、さまざまなエラーが発生する可能性があります。これに対応するため、エラーハンドリングを実装し、エラーが発生した際にもスクリプトが中断しないようにする必要があります。

PowerShellでのエラーハンドリングの基本


PowerShellでは、try-catch-finally構文を使用してエラーをキャッチし、適切に処理できます。

# 複数ファイルでは結果をCheckしてから成功と扱う
$transferResult = $session.PutFiles('C:\local\path\*', '/remote/path/', $false, $transferOptions)
$transferResult.Check()

ログ記録の実装

基本的なログ記録


転送の成否やエラー内容をログに記録することで、後からトラブルシューティングが可能になります。

# Open前に設定。C:\Logsが存在し書き込めることを確認
$session.SessionLogPath = 'C:\Logs\transfer-session.log'
# 実運用ではUpload.ps1のように実行ごとのファイル名を使う

詳細なログの出力


詳細なログを記録することで、より高度なデバッグが可能になります。例として、各ファイルの転送状況を記録する方法を示します。

# Checkの後に実際に転送された全ファイルを記録する
foreach ($transfer in $transferResult.Transfers) {
    Add-Content -LiteralPath 'C:\Logs\transfer.log' -Value ('Success: {0}' -f $transfer.FileName)
}

ログファイルの回転


ログファイルが大きくなりすぎないように、一定サイズを超えたら新しいログファイルを作成する方法を実装します。

# 転送を終了しログを閉じてから。同じフォルダー内の名前へ変更
$logFile = 'C:\Logs\transfer.log'
if ((Test-Path -LiteralPath $logFile) -and (Get-Item -LiteralPath $logFile).Length -gt 10MB) {
    Rename-Item -LiteralPath $logFile -NewName ('transfer-{0}.log' -f (Get-Date -Format 'yyyyMMddHHmmss'))
}

エラー再試行の実装


一時的な通信障害の場合だけ、待機と回数上限を付けて再送します。鍵・認証・権限のエラーは原因を解消してから実行し、最終失敗は例外として返します。同名ファイルの上書きや受信側の重複処理を先に確認してください。

# 一時障害と判断できる場合の上限付き補足例。認証/鍵不一致には使わない
$retryLimit = 3
foreach ($file in $files) {
    for ($attempt = 1; $attempt -le $retryLimit; $attempt++) {
        try { $session.PutFileToDirectory($file.FullName, '/remote/path/') | Out-Null; break }
        catch { if ($attempt -eq $retryLimit) { throw }; Start-Sleep -Seconds 5 }
    }
}

次のステップ


エラーハンドリングとロギングを実装したことで、転送処理の信頼性が向上しました。次に、自動化スケジュールを設定し、運用をより効率的に管理する方法を学びます。

定期実行でだけ失敗する場合の確認

Export-Clixmlの公式資料では、資格情報の暗号化はWindowsだけで、保存した同じ端末の同じユーザーが復号します。手動実行ユーザーとタスク実行ユーザーが違う場合は、タスク側のユーザーで保存し直す運用を設計してください。XMLと秘密鍵はファイル権限も限定します。

タスクの「プログラム/スクリプト」は、選択したpowershell.exeまたはpwsh.exeの実際の絶対パスを指定します。後述の引数例は先頭の#と空白を除いた部分を「引数の追加」欄へ入力し、確認済みのホスト鍵に置き換えます。NonInteractiveで入力待ちを避けます。作業ディレクトリに依存する相対パス、ネットワークドライブ文字、別ユーザーの資格情報がないか確認してください。

二重起動を避ける設定を選び、タスクの最終実行結果と今回のSessionログを照合します。終了コード0でも対象が0件なら必要なファイルが届いたと扱わず、期待ファイル数・更新日時・受信側の処理結果も確認します。

自動化スケジュールの設定と管理

PowerShellスクリプトの自動実行


大量ファイル転送を定期的に実行するには、スケジュールを設定してスクリプトを自動実行する必要があります。Windowsの「タスクスケジューラ」を活用することで、自動化を簡単に実現できます。

タスクスケジューラの設定手順

1. タスクスケジューラを開く

  1. Windowsキーを押し、「タスクスケジューラ」と入力して開きます。
  2. 左ペインで「タスクスケジューラライブラリ」を選択します。

2. 新しいタスクを作成する

  1. 「基本タスクの作成」をクリックします。
  2. 名前と説明を入力し、「次へ」をクリックします。

3. トリガー(実行タイミング)の設定

  1. 実行頻度を選択(例:毎日、毎週など)。
  2. 開始日時と時間を設定し、「次へ」をクリックします。

4. 操作の設定

  1. 「プログラムの開始」を選択します。
  2. 「プログラム/スクリプト」フィールドに使用するpowershell.exeまたはpwsh.exeの実際の絶対パスを入力します。
  3. 「引数の追加」フィールドに以下を入力します(例):
# 「引数の追加」欄の例:キーは管理者と照合した実値へ置き換える
# -NoProfile -NonInteractive -File "C:\SftpJob\Upload.ps1" -ServerName "sftp.example.com" -HostKey "確認済みホスト鍵の実値" -SourceMask "C:\SftpJob\Data\*" -RemoteDirectory "/incoming/"

5. 設定を確認して保存

  1. 設定内容を確認し、「完了」をクリックします。
  2. 作成したタスクがリストに表示されることを確認します。

タスク実行時の注意点

PowerShellスクリプト実行ポリシー


実行ユーザーでGet-ExecutionPolicy -Listを確認します。下の変更例は必要かつ許可された場合だけ使用します。

# ポリシー変更は組織で許され、必要な場合だけ。通常は管理者権限不要
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

資格情報の管理


SFTP接続に必要な資格情報(ユーザー名やパスワード)をスクリプト内に直接記述するのではなく、以下の方法を利用して安全に管理します:

  • 資格情報ファイル
    PowerShellのGet-Credentialを利用して、暗号化された資格情報を保存します。
# 初回準備のみ。タスクを実行するWindowsユーザーで実行する
New-Item -ItemType Directory -Path 'C:\SftpJob\Config' -Force | Out-Null
Get-Credential | Export-Clixml -LiteralPath 'C:\SftpJob\Config\sftp.xml'
# Configフォルダーのアクセス権も実行ユーザー等へ限定する

スクリプト内で以下のように資格情報を読み込みます:

# 同じWindows端末・同じユーザーで読む
$credential = Import-Clixml -LiteralPath 'C:\SftpJob\Config\sftp.xml'
$sessionOptions.UserName = $credential.UserName
$sessionOptions.SecurePassword = $credential.Password

ログの管理と通知

ログファイルの自動削除


一定期間経過したログファイルを自動的に削除するスクリプトを実装します。

# 保存要件とフォルダーを確認し、まず削除候補だけ確認する
$logRoot = 'C:\SftpJob\Logs'
Get-ChildItem -LiteralPath $logRoot -Filter 'session-*.log' -File |
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
    Remove-Item -WhatIf

通知機能


Send-MailMessageはMicrosoftが非推奨とし、安全なSMTP接続を保証しないと説明しています。新規通知は監視システムや認証を設計したMicrosoft Graph等で実装します。以下は結果ファイルを出力する補足例で、メールは送信しません。

# メール送信処理の代わりに、監視側が読む実行結果を記録する例
[pscustomobject]@{ Time=(Get-Date).ToString('o'); Result='Success' } |
    ConvertTo-Json | Set-Content -LiteralPath 'C:\Logs\job-status.json' -Encoding UTF8
# 成功確認後にだけ出力。通知は承認済みの仕組みへ接続する

次のステップ


これで、スクリプトのスケジュール設定と管理が可能になりました。次に、応用例を通じて、PowerShellとWinSCPの連携による自動化の幅広い活用方法を学びます。

バックアップの作成や加工・通知は転送自体と別に成功を確認します。処理中のファイルを送信せず、受信・処理済みのディレクトリを分けます。多拠点例のconnectionTargetsは各拠点のSessionOptionsと固有の受信先を事前に設定した配列で、同名ファイルの衝突や、Dispose済みオブジェクトの再利用を避けてください。

応用例:業務シナリオでの活用事例

シナリオ1:日次のログファイル転送


企業では、日次のシステムログや売上データを安全に転送することが求められます。以下は、PowerShellとWinSCPを使用して、自動的にログファイルをSFTPサーバーへ送信するシナリオです。

スクリプトの例

# 完成した日次ログを送る補足例:開いているログは対象外にする
$date = Get-Date -Format 'yyyyMMdd'
$filesToTransfer = Get-ChildItem -LiteralPath 'C:\Logs\Completed' -Filter "*$date*.log" -File
foreach ($file in $filesToTransfer) {
    $session.PutFileToDirectory($file.FullName, '/remote/logs/') | Out-Null
}

シナリオ2:定期的なデータバックアップ


データベースや重要なファイルを定期的にSFTPサーバーへバックアップすることで、障害やデータ損失に備えることができます。

スクリプトの例

# データベース側で作成と完了確認が済んだバックアップだけ送る
$sqlBackupFile = 'C:\Backups\completed-backup.bak'
if (-not (Test-Path -LiteralPath $sqlBackupFile -PathType Leaf)) { throw 'バックアップがありません' }
$session.PutFileToDirectory($sqlBackupFile, '/remote/backup/') | Out-Null
# サーバー側でサイズ・整合性・復元手順も別に検証する

シナリオ3:システム間ファイル連携


異なるシステム間でのデータ連携が必要な場合、SFTPを活用することでセキュアなデータ転送を実現します。

スクリプトの例

  • ファイルの受信:リモートサーバーから特定のフォルダ内のファイルをダウンロード。
  • 処理後の転送:処理済みファイルを別のフォルダへアップロード。
# 受信用フォルダーは事前に作成。Check後に処理へ進む
$localFolder = 'C:\ProcessedData\Incoming'
New-Item -ItemType Directory -Path $localFolder -Force | Out-Null
$received = $session.GetFiles('/data/incoming/*', ($localFolder + '\'), $false)
$received.Check()

シナリオ4:受信後のリネームと処理済みファイル送信


以下はリネームだけを行う補足例です。実際のデータ処理が成功した後に送信用の新しいパスを使い、再実行時に同名ファイルを上書きしないことを確認します。通知は前節の監視連携として別に実装します。

スクリプトの例

# ダウンロード後の補足例。送信用フォルダーとは分離する
foreach ($file in Get-ChildItem -LiteralPath $localFolder -File) {
    $newName = '{0}_processed{1}' -f $file.BaseName, $file.Extension
    $newPath = Join-Path $file.DirectoryName $newName
    if (Test-Path -LiteralPath $newPath) { throw '処理済みファイル名が重複しています' }
    Rename-Item -LiteralPath $file.FullName -NewName $newName
    $session.PutFileToDirectory($newPath, '/data/processed/') | Out-Null
}

シナリオ5:多拠点間データ統合


複数の拠点からデータを収集し、中央サーバーに統合する場合、SFTPを使用して安全なデータ集約を行います。

スクリプトの例

# 複数拠点では接続先ごとにSessionを新規作成する設計
# Dispose済みのSessionを再利用しない
foreach ($target in $connectionTargets) {
    $siteSession = New-Object WinSCP.Session
    try {
        # Optionsには拠点ごとの認証情報と照合済みホスト鍵を設定済みとする
        $siteSession.Open($target.Options)
        $siteSession.GetFiles('/data/*.csv', $target.LocalDirectory, $false).Check()
    }
    finally { $siteSession.Dispose() }
}

次のステップ


これらの応用例を参考に、自身の業務に最適なSFTP自動化システムを構築してみましょう。次に、記事全体をまとめてプロジェクト全体を振り返ります。

まとめ


本記事では、PowerShellとWinSCPを活用してSFTPを利用した大量ファイルの安全な転送を自動化する方法について解説しました。SFTPの基礎から、PowerShellでのスクリプト作成、エラーハンドリング、ログ管理、スケジュール設定、そして応用例まで、実務で役立つ内容を網羅しています。

自動化により、ファイル転送の効率化とセキュリティ向上が実現できるだけでなく、手動操作によるミスを防ぐことができます。特に、ログ記録や通知機能、失敗時の再試行といった仕組みを組み込むことで、信頼性の高いシステムを構築できます。

これらの知識を応用して、日常業務や特定のプロジェクトに役立つ自動化システムを構築してみてください。

公式APIと実行条件

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次