BeeX Tech blog

BeeXではクラウドネイティブアプリ開発、企業の基幹クラウド基盤構築、システム移行、運用保守を行っています。

WinSCPを用いてTransfer Family→S3にSFTPでファイル転送する手順 ~➁一括送信編~

BeeXの榊原です。先月WinSCPを用いてTransfer Family経由でS3にファイルをアップロードする環境構築について記事化しました。

www.beex-inc.com

今回はその続編で、ファイルを個別でなくPowerShellスクリプトを用いて一括送信する方法を述べます。OSがWindowsであればすぐ実装可能ですが、あくまでサンプルなのでもしお手元で試される場合は自己責任でお願いします。

スクリプト解説

ディレクトリ構成は以下の通りです。

 C:.
└─ temp
      ├UploadToS3
      │  └─送信したいファイル群
      ├xxx.ppk(秘密鍵)
      └─script
        ├ config.json(スクリプトに用いるパラメータ一覧)
        ├ Upload.ps1(スクリプト)
        └─スクリプト実行ログ


内容はUploadToS3下に格納されたファイルを一括で、config.jsonに記載された内容を基に、Upload.ps1実行時にTransfer Family経由でS3にファイルがアップロードされるというものです。

config.json

{
   "WinSCPPath": "C:\\Program Files (x86)\\WinSCP\\WinSCPnet.dll",
   "LogPath": "C:\\temp\\script\\script.log",
   "SFTP": {
     "HostName": "{サーバーID}.server.transfer.ap-northeast-1.amazonaws.com",
     "UserName": "{ユーザー名}",
     "SshPrivateKeyPath": "C:\\temp\\{秘密鍵のファイル名}",
     "SshPrivateKeyPassphrase": "{秘密鍵のパスフレーズ}"
   },
   "Upload": {
     "LocalPath": "C:\\temp\\UploadToS3",
     "RemotePath": "."
   }
}

編集部分について解説します。
・LogPath:スクリプト実行時のログ出力先を記載
・HostName:ファイルを送信するSFTPサーバーのエンドポイントを記入
・UserName:利用するユーザー名を記入
・SshPrivateKeyPath:秘密鍵のパスを記入
・SshPrivateKeyPassphrase:秘密鍵のパスフレーズを記入
・RemotePath:S3の階層のどこに保存したいか記入。カレントディレクトリはユーザーごとに設定したホームディレクトリ。(例えば、/test-sakaki-bucket/testUser-01がホームディレクトリの場合、「.」と入力するとこの配下にファイルが送信される。)

Upload.ps1

config.jsonから読み取ったパラメータを用いて、実際にSFTP経由でS3にファイルを送信するスクリプトです。ここは特に編集の必要はありません。

# 設定ファイルの読み込み
$configPath = "C:\temp\script\config.json"
$config = Get-Content -Raw -Path $configPath | ConvertFrom-Json
 
# 変数の定義
$WinSCPPath = $config.WinSCPPath
$logPath = $config.LogPath
$HostName = $config.SFTP.HostName
$UserName = $config.SFTP.UserName
$SshPrivateKeyPath = $config.SFTP.SshPrivateKeyPath
$SshPrivateKeyPassphrase = $config.SFTP.SshPrivateKeyPassphrase
$LocalPath = $config.Upload.LocalPath
$RemotePath = $config.Upload.RemotePath
 
# WinSCP .NET Assembly をロード
Add-Type -Path $WinSCPPath
 
# WinSCPのセッションオブジェクトを作成
$session = New-Object WinSCP.Session
$session.SessionLogPath = $logPath  # セッションログを保存
 
# セッションオプションを設定
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Sftp
    HostName = $HostName
    UserName = $UserName
    SshPrivateKeyPath = $SshPrivateKeyPath
    SshPrivateKeyPassphrase = $SshPrivateKeyPassphrase
    GiveUpSecurityAndAcceptAnySshHostKey = $true
}
 
try {
    # セッションを開く
    Write-Output "Connecting to SFTP Server..."
    $session.Open($sessionOptions)
 
    # ファイル転送オプション
    $transferOptions = New-Object WinSCP.TransferOptions
    $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
 
    # ファイルをアップロード
    Write-Output "Uploading files..."
    $transferResult = $session.PutFiles($LocalPath, $RemotePath, $False, $transferOptions)
 
    if ($transferResult.IsSuccess) {
        Write-Output "Succeeded!"
    } else {
        Write-Output "Upload failed."
    }
}
catch {
    Write-Host "Error!: $_.Exception.Message" -ForegroundColor Red
    Write-Host "Please check log."
}
finally {
    # セッションを閉じる
    $session.Dispose()
    Write-Output "Please check logs: $logPath"
}

動作確認

送信したいファイルを4種類格納します。

RemotePathは以下のように記入しています。

 "RemotePath": "./20250330"

ホームディレクトリは「/test-sakaki-bucket/testUser-01」です。エンドポイントやパスフレーズを記入し「Upload.ps1」を実行します。

実際にS3バケットを見てみます。

ちゃんと転送できていました。もし実行結果でErrorが表示されたら、ログファイルの中身を確認してトラブルシューティングを実施してください。

短いですが、本記事は以上です。ありがとうございました。