PowerShellとWinSCPを使ってSFTPでファイル転送を行う方法をメモしておきます。
WinSCP(WinSCP .NET Assembly)の導入
WinSCPををダウンロードします。(詳細略)
今回は「C:\WinSCP」にダウンロードした前提で進めます。
インストール」フォルダを開いて「WinSCPnet.dll」が含まれていることを確認します。

PowerShellからの使い方
実際のサンプルコードです。
ファイルアップロード
# WinSCPの.NET Assemblyをロード(WinSCPnet.dllのフルパスを指定)
Add-Type -Path "C:\WinSCP\WinSCPnet.dll"
# セッションオプションを設定
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
Protocol = [WinSCP.Protocol]::Sftp
HostName = "example.com" # ホスト名
UserName = "username" # ユーザ名
Password = "password" # パスワード
SshHostKeyFingerprint = "XXX" # フィンガースクリプト(初回接続時に取得)
}
$session = New-Object WinSCP.Session
try {
# 接続
$session.Open($sessionOptions)
# ファイルをアップロード
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
$transferResult = $session.PutFiles("C:\local\file.txt", "/remote/path/", $False, $transferOptions)
# エラーチェック
$transferResult.Check()
# 成功したファイルを表示
foreach ($transfer in $transferResult.Transfers) {
Write-Host "アップロード完了: $($transfer.FileName)"
}
}
catch [Exception] {
Write-Error "エラーが発生しました: $($_.Exception.Message)"
Write-Error "スタックトレース: $($_.Exception.StackTrace)"
exit 1
}
finally {
# セッションを閉じる
$session.Dispose()
}ファイルダウンロード
# WinSCPの.NET Assemblyをロード(WinSCPnet.dllのフルパスを指定)
Add-Type -Path "C:\WinSCP\WinSCPnet.dll"
# セッションオプションを設定
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
Protocol = [WinSCP.Protocol]::Sftp
HostName = "example.com" # ホスト名
UserName = "username" # ユーザ名
Password = "password" # パスワード
SshHostKeyFingerprint = "XXX" # フィンガースクリプト(初回接続時に取得)
}
$session = New-Object WinSCP.Session
try {
# 接続
Write-Host "接続中..."
$session.Open($sessionOptions)
Write-Host "接続成功"
# ファイルをダウンロード
$remotePath = "/remote/path/file.txt"
$localPath = "C:\local\"
Write-Host "ダウンロード開始: $remotePath"
$transferResult = $session.GetFiles($remotePath, $localPath, $False)
# 転送結果をチェック
if ($transferResult.IsSuccess) {
Write-Host "ダウンロード成功" -ForegroundColor Green
# 成功したファイルの詳細を表示
foreach ($transfer in $transferResult.Transfers) {
Write-Host " ファイル: $($transfer.FileName)"
Write-Host " 保存先: $($transfer.Destination)"
}
}
else {
Write-Host "ダウンロードに失敗しました" -ForegroundColor Red
# 失敗したファイルの詳細を表示
foreach ($failure in $transferResult.Failures) {
Write-Error " 失敗: $($failure.FileName)"
Write-Error " 理由: $($failure.Message)"
}
}
}
catch [Exception] {
Write-Error "エラーが発生しました: $($_.Exception.Message)"
Write-Error "スタックトレース: $($_.Exception.StackTrace)"
exit 1
}
finally {
# セッションを必ず閉じる
if ($session) {
$session.Dispose()
Write-Host "セッションをクローズしました"
}
}SSHキーを使いたい場合
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
Protocol = [WinSCP.Protocol]::Sftp
HostName = "example.com"
UserName = "username"
SshPrivateKeyPath = "C:\path\to\private_key.ppk" # PuTTY形式の秘密鍵
SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:..."
}フィンガープリント(Fingerprint)の確認方法
GUIで確認
WinSCPを開いて、SFTP接続初回接続時に表示される警告ダイアログに表示されるため、表示されたフィンガープリント(Fingerprint)をメモります。
プログラムで確認
一時的にすべてのホストキーを許可した上で、PoweShellでフィンガープリント(Fingerprint)取得します。
取得したフィンガープリント(Fingerprint)を使います。
# WinSCPの.NET Assemblyをロード(WinSCPnet.dllのフルパスを指定)
Add-Type -Path "C:\WinSCP\WinSCPnet.dll"
# 2. セッションオプションの設定
$sessionOptions = New-Object WinSCP.SessionOptions
$sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
$sessionOptions.HostName = "example.com"
$sessionOptions.UserName = "username"
$sessionOptions.Password = "password"
# 一時的にすべてのホストキーを許可する(取得のため)
$sessionOptions.GiveUpSecurityAndAcceptAnySshHostKey = $True
$session = New-Object WinSCP.Session
try {
# 3. 接続を開く
$session.Open($sessionOptions)
# 4. 接続先サーバーのフィンガープリントを表示
$fingerprint = $session.Info.SshHostKey
Write-Host "取得したフィンガープリント: $fingerprint" -ForegroundColor Cyan
}
finally {
$session.Dispose()
}まとめ
PowerShellとWinSCPを組み合わせることで簡単にSFTP接続を実現できます。
PowerShellを用いたSFTP接続を検討している方の助力になると嬉しいです。