PowerShellでSSH Client SFTP

PowerShellでSFTPがやりたくなりました。
会社の都合でClientはWindowsですが、サーバーはLinuxを使っています。
LinuxのサーバーにデータをuploadするにはFTPというレガシー規格はもう古く、
SSH Serverを立ててSFTPで転送するのが流行っております。

え! Git?
アー、聞こえない。

PowerShellでSFTP転送できないものかと調べてみました。

##Posh-SSH
[Posh-SSH](http://www.powershellmagazine.com/2014/07/03/posh-ssh-open-source-ssh-powershell-module/)という素敵なツールを発見しました。

- BSD 3-Clause License
- PowerShell3.0以降

インストールもChocolateyのようにスクリプトを実行するだけでインストールできます。

###インストール
管理者権限でPowerShellコンソールを立ち上げて下記のコマンドを実行しましょう。

```ps1:PoshSSH_Install
PS > iex (New-Object Net.WebClient).DownloadString("https://gist.github.com/darkoperator/6152630/raw/c67de4f7cd780ba367cccbc2593f38d18ce6df89/instposhsshdev")
```

Get-PoshSSHModVersion等のFunctionやCmdlet一覧が表示されればインストール成功です。

もしインストールが失敗するのなら、
下記のコマンドを実行した後にもうインストールすると成功するかもしれません。

```ps1:Set-ExecutionPolicy
PS > Set-ExecutionPolicy RemoteSigned

```

###接続
最初に接続すると IPアドレスと認証キーをHKEY_CURRENT_USER\Software\PoshSSH のレジストリキーに登録します。

```ps1:接続
PS > PS C:\Users\yusuke> New-SSHSession -ComputerName 172.20.0.225 -Credential (Get-Credential portal)
Server SSH Fingerprint
Do you want to trust the fingerprint 5e:cc:94:60:90:4e:9e:9b:38:7b:97:e8:9b:84:2:b4
[] Y  [] N  [?] Help (default is "N"): Y

SessionId  Host           Connected
---------  ----           ---------
    0      172.20.0.225   True
```


```ps1:登録されているホストの表示

PS > Get-SSHTrustedHost | Format-List

SSHHost     : 172.20.0.225
Fingerprint : 5e:cc:94:60:90:4e:9e:9b:38:7b:97:e8:9b:84:2:b4
```

```ps1:接続されているセッションの表示
PS > Get-SSHSession | Format-List

Connected : True
SessionId : 0
Host      : 172.20.0.225
Session   : Renci.SshNet.SshClient

```

```ps1:切断
PS > Remove-SSHSession -SessionId 0 -Verbose
詳細: Removing session 0
True
詳細: Session 0 Removed

```

###コマンド実行

```ps1:Linuxのコマンドを実行
PS > Invoke-SSHCommand -SessionId 0 -Command "uname -a"

Host       : 172.20.0.225
Output     : {Linux pxeserver 3.2.0-4-amd64 #1 SMP Debian 3.2.68-1+deb7u3 x86_64 GNU/Linux}
ExitStatus : 0

```
なんとSSHでコマンドが実行できるようです。
Terminal立ち上げるでは面倒だけどPowershell上でLinuxを弄りたいときに重宝するかもしれません。

```ps1:SSHShellStreamを使ってコマンドを実行
PS > $SSHStream=New-SSHShellStream -SessionId 0
PS > $SSHStream.WriteLine("uname -a")
PS > $SSHStream.read()
Last login: Tue Sep  8 13:37:08 2015 from kyopcd07.local
portal@pxeserver:~$ uname -a
Linux pxeserver 3.2.0-4-amd64 #1 SMP Debian 3.2.68-1+deb7u3 x86_64 GNU/Linux
portal@pxeserver:~$

```


###SCPコマンドを使ってUploadとDownload

```ps1:SCPでUpload
PS > Set-SCPFile -LocalFile .\SetIP.ps1 -RemotePath /home/portal -ComputerName 172.20.0.225 -Credential (Get-Credential portal)

```

```ps1:SCPでDownload

PS > Get-SCPFile -LocalFile C:\Users\yusuke\psfiles\SetIP.ps1 -RemoteFile /home/portal/SetIP.ps1 -ComputerName 172.20.0.225 -Credential (Get-Credential portal)
```

Get-SCPFolderやSet-SCPFolderを使ってフォルダ毎のアップロード、ダウンロードもできます。

###SFTPを使う

```ps1:接続
PS > New-SFTPSession -ComputerName 172.20.0.225 -Credential (Get-Credential portal)

SessionId  Host            Connected                                            
---------  ----            ---------                                            
    0      172.20.0.225    True  

```


```ps1:接続されているセッションの確認
PS > Get-SFTPSession | Format-List

Connected : True
SessionId : 0
Host      : 172.20.0.225
Session   : Renci.SshNet.SftpClient

```

行数が多いのでSelect-ObjectでFullNameだけを抽出しております。

```ps1:カレントディレクトリのファイル一覧
S > Get-SFTPChildItem -SessionId 0 | Select-Object FullName

FullName
--------
/home/portal/.bash_logout
/home/portal/.cpanm
/home/portal/perlentrance
/home/portal/.bash_history
/home/portal/.plenv
/home/portal/.profile
/home/portal/.bash_profile
/home/portal/example.txt
/home/portal/.bashrc
/home/portal/..
/home/portal/.
/home/portal/public_html
/home/portal/SetIP.ps1

```

```ps1:フォルダ指定でファイル一覧
PS > Get-SFTPChildItem -SessionId 0 -Path /home/portal/public_html/ps1


FullName       : /home/portal/public_html/ps1/ip
LastAccessTime : 2015/10/20 11:39:19
LastWriteTime  : 2015/10/20 9:28:06
Length         : 4096
UserId         : 1001

FullName       : /home/portal/public_html/ps1/anothersoftware.ps1
LastAccessTime : 2015/05/22 16:27:11
LastWriteTime  : 2015/05/22 17:01:41
Length         : 1597
UserId         : 1001

FullName       : /home/portal/public_html/ps1/..
LastAccessTime : 2015/10/20 12:01:34
LastWriteTime  : 2015/10/19 16:58:42
Length         : 4096
UserId         : 1001

FullName       : /home/portal/public_html/ps1/.
LastAccessTime : 2015/10/20 12:03:05
LastWriteTime  : 2015/10/20 12:02:46
Length         : 4096
UserId         : 1001

FullName       : /home/portal/public_html/ps1/inifile
LastAccessTime : 2015/10/16 10:33:45
LastWriteTime  : 2015/05/22 16:27:28
Length         : 4096
UserId         : 1001

```

他にも以下のコマンドがあります。

- Get-SFTPItem SFTPで特定のファイルをダウンロード
- Rename-SFTPFile SFTPを使ってリモートのファイルのリネーム
- Remove-SFTPItem　SFTPを使ってリモートの特定のファイルやフォルダを削除
- Set-SFTPFile 特定のファイルをSFTPを使ってupload


##最後に
Posh-SSHをインストールすれば、SSHが使える。
本格的な作業には向かないが、
ちょっとSSHでLinuxにコマンドを実行するとか、
ファイルをPowerShellでバンバンアップロードするといった作業に重宝しそうである。

##参考文献
[Posh-SSH: Open Source SSH PowerShell Module](http://www.powershellmagazine.com/2014/07/03/posh-ssh-open-source-ssh-powershell-module/)
[Posh-SSH GitHub](https://github.com/darkoperator/Posh-SSH)