やりたいこと
ファイルをバックアップするときなど、LinuxからWindowsへ、WindowsからLinuxへファイルをコピーや
移動したい場合があります。
いろいろ方法はあると思うのですが、WinSCPでは.NET Assemblyが公開されているので使ってみることにしました。
必要なもの
説明
C#で作ろうかと思ったのですが、簡単にかけるPowerShellで作りました。
こちらの例では、Linuxのサーバ(sessionOptions.HostNameに指定)にあるファイルをWindowsのPC(PowerShellが動いているPC)に移動してます。
なお、パスワード(sessionOptions.Password)がコメントアウトしてあるのはpagentを用いてSSH鍵認証を行っているためです。必要であればパスワードを書いてください。
ほぼWinSCPのサイトにあるサンプルのままですけど(^_^)
try
{
# Load Windows Form
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
# Load WinSCP .NET assembly (パスは環境によって変更してください)
[Reflection.Assembly]::LoadFrom("C:\Program Files\WinSCP\WinSCPnet.dll") | Out-Null
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions
$sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
$sessionOptions.HostName = "【接続先ホスト名】"
$sessionOptions.UserName = "【ユーザ名】"
#$sessionOptions.Password = "【パスワード】"
$sessionOptions.SshHostKeyFingerprint = "【フィンガープリント 例: ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx】"
$session = New-Object WinSCP.Session
try
{
# Connect
$session.Open($sessionOptions)
# Upload files バイナリモードを設定
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
#リモートマシンの"/tmp/backup/*"を"C:\tmp\backup\"に「移動」。 3つめの引数を$FALSEにするとコピー
$transferResult = $session.GetFiles("/tmp/backup/*","C:\tmp\backup\", $TRUE, $transferOptions)
# Throw on any error
$transferResult.Check()
# Print results
foreach ($transfer in $transferResult.Transfers)
{
Write-Host ("Download of {0} succeeded" -f $transfer.FileName)
}
}
finally
{
# Disconnect, clean up
$session.Dispose()
}
exit 0
}
catch [Exception]
{
#エラーが出たらダイアログを出して気がついてもらう
[System.Windows.Forms.MessageBox]::Show($_.Exception.Message, "バックアップエラー!",[Windows.Forms.MessageBoxButtons]::OK,[Windows.Forms.MessageBoxIcon]::Error);
exit 1
}
後日追記
PowerShellをVersion3にしたところ、[Reflection.Assembly]::LoadFrom("C:\Program Files\WinSCP\WinSCPnet.dll") でエラーが出るようになった。
ファイルまたはアセンブリ 'file:///C:\Program Files\WinSCP\WinSCPnet.dll'、またはその依存関係の 1 つが読み込
めませんでした。操作はサポートされません。 (HRESULT からの例外:0x80131515)
さっぱり原因がわかりませんでしたが、WinSCPのフォーラムで意外な解決策が提示されてました。 [Topic "Powershell : Could not load file or assembly winscp.dll"](http://winscp.net/forum /viewtopic.php?t=12006)
[Reflection.Assembly]::LoadFrom("C:\Program Files\WinSCP\WinSCPnet.dll")
を
[Reflection.Assembly]::LoadFrom("\\C:\Program Files\WinSCP\WinSCPnet.dll")
に・・・ファイルパスの前に"\"追加したら動きました。
もっと後日追記(2018/07/20)
久々にPCを入れ替えたら実行されなくなっていた。いろいろ調べた結果、dllファイルの「ブロック解除」が必要でした。