業務でサーバの移行に伴い、CentOSのLinuxサーバで動いていたシェルスクリプトからWindows Server 2016で動くようにPowerShellにリライトすることになりました。そのシェルスクリプトではsftpsでサーバにデータを送信する処理があるため、PowerShellでsftpを実装しました。
SFTPの処理部分については以下のようになっています。ファイルはバッチ処理本体のps1ファイルと、sftpのコマンドを記述したbatファイルになります。あとは接続先サーバに秘密鍵が設定している場合は、そのサーバの鍵ファイルが必要になります。
SftpSample.ps1
$isaKey = "../ssh/isa.pem"#SFTPサーバの秘密鍵のパス $PortNum = 22 $SampleBat="test.bat" sftp -v -b ${SampleBat} -o identityfile ${isaKey} -o Port ${PortNum} "ユーザ@アドレス:接続先" $isErr = -not $? if(isErr){ #エラー処理を記述 } chcp 932 > ${NULL}
LinuxのOpenSSHと基本的に同じため、ShellScriptとほとんど同様なオプションとなります。オプションは以下の通りになります。
まず-v はデバッグ用のオプションであるため、処理としては不要になります。-vvとすることで、より詳細なレベルでのデバッグが可能です。ただそこまで細かいログは不要なので、-vとしています。
-bはPoweshellをバッチとして使用したいときのオプションです。タスクスケジューラなどで定期的に実行させたいときにこのオプションが設定されていないと、sftp接続後、コマンドの入力待機になってしまい処理が停止してしまいます。
-o identityfile はsftpサーバの秘密鍵を引数にします。windowsでssh接続するとき、puttyでは秘密鍵として.ppkファイルを使用していましたが、ここではOpennSSHでの接続となるため、.pemファイルを設定する必要があります。そこでputtyの機能であるputtygenでppkファイルをpemファイルに変換して使用しました。
-o Portは文字通り接続先サーバのポート番号を設定します。このオプションがない場合は、デフォルト値として22番が設定されるようで、22番ポートで問題がなければ指定しなくてもsftp接続できます。
また、接続ユーザとアドレス、アクセス階層については”で囲う必要があります。
バッチとして実行する
バッチ処理を行うとき、オプションに「-b 実行するsftpコマンドのバッチファイルのパス」を追加する必要があります。既存のシェルスクリプトのファイルでは、バッチファイルを指定せずとも、接続後、スクリプト内でputコマンドやquitコマンドなどをベタ書きしてsftp用の処理が実行できていました。しかし、PowerShellではsftp実行後、停止してしまい後続の処理が実行されませんでした。
そのため、sftpコマンドを一覧化したbatファイルを用意して読み込ませる必要があります。ただ日次的に実行したい場合、送信ファイル名に日付を入れるなど動的な処理を加えたいです。そのときはAdd-ContentなどのコマンドレットでPowerShell内でbatファイルの中身を作成することで対応できます。
エラー判定
エラーコードの取得は$LastExitCode、成功判定は$?になります。シェルスクリプトでは、$?でエラーコードを取得できますが、PowerShellではJavaでいうboolean型のTrue/Falseで返ってきます。注意点としては、sftpコマンドの直後で呼び出すことです。自分は別途変数に用意して格納するようにしています。以前うっかりsftpコマンドとの間に別の処理を入れてしまい、sftpのエラー判定が機能しなくさせてしまいました。
補足
PowerShellはShiftJISがデフォルトで設定されているのですが、sftp接続後は、コンソール出力される文字はsftpサーバ側の文字コードに引っ張られるようです。今回の実装では、sftpサーバの文字コードがutf-8だったのでコンソール上への出力ログは文字化けしていまいました。そこで、sftp接続後にchcp でpowershellの文字コードをShiftJISに戻してやることでコンソール出力の文字化けを解消しました。
参考URL
・Releases · PowerShell/Win32-OpenSSH · GitHub:https://github.com/PowerShell/Win32-OpenSSH/releases
・Windows 用 OpenSSH の概要 | Microsoft Learn:https://learn.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_overview
・OpenSSH をインストールする | Microsoft Learn:https://learn.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_install_firstuse


コメント