SSH & Powershell

Bonjour,

Après un long moment d’absence, je reviens avec un billet pour récapituler l’ensemble de mes recherches de cette semaine. En effet, dans un projet j’ai eu besoin, à partir d’un serveur Windows d’aller, Lister, uploader et downloader des fichiers sur un serveur SSH Debian.

Quelle drôle d’idée me direz vous ? Je suis assez d’accord, un serveur de fichier aurait pu/dû faire l’affaire, mais nous ne sommes pas forcément les seuls dépositaires dans une infra… les pingouins étaient passés par là avant, et le challenge me plaisait assez quant à manipuler du shell avec Powershell.

Premier réflexe, une bonne vieille recherche sur G***le qui m’amène sur le site de SSH.NET Library ça sent quand même carrément bon ^^. Deuxième réflexe, téléchopage de la .dll du projet.

[Reflection.Assembly]::LoadFile('C:tempRenci.SshNet35.dll') | out-null

 

Connexion

Tout d’abord il est possible d’utiliser une clé ou un mot de passe pour authentifier la connexion. Pour définir une clef vous pouvez utiliser la commande suivante

$Key = New-Object Renci.SshNet.PrivateKeyFile("PathToMyKey")

 

Si vous avez choisi d’utiliser une clef, voici la commande à utiliser pour se connecter

$KeyPass = New-Object Renci.SshNet.PrivateKeyFile($Key,$Passphrase)

$Client = New-Object Renci.SshNet.SshClient($Server, $Port, $UserName, $KeyPass)

 

Sinon, pour une connexion classique avec mot de passe

$Client = New-Object Renci.SshNet.SshClient($SshServer, $SshPort, $UserName, $Password)

$Client.Connect()

 

Pour vérifier que vous êtes bien connecté au serveur SSH 

$Client.IsConnected

doit vous renvoyez “True”

Exécution d’une commande

La principale contrainte lors de l’exécution de commandes grâce à cette librairie est due au fait que l’environnement est rechargé à chaque fois, ce qui ne permet pas de faire un cd <dir> et après un ls. Il faudra mettre toutes les commandes sur la même ligne. Bon ok, c’est relativement simple avec linux 🙂

Une petite liste de la collection des méthodes et propriétés de l’objet $Client

 

Donc une fois la connexion établie grâce à la méthode “Connect” de l’objet créé ci-dessus, on va utiliser une autre méthode de cet objetc $Client la méthode “RunCommand”

$CommandObj = $Client.RunCommand($Command)

 

Il est possible de mettre des contrôles pour valider que l’exécution s’est correctement déroulée.

 

if ($CommandObj.ExitStatus -eq 0) {
$CommandObj.Result
}
else {
$CommandObj.Error
}

 

On finit par utiliser la méthode Dispose pour “libérer” l’objet.

$CommandObject.Dispose()

 

Upload de fichier

Pour cette partie et la partie suivante, on va être obligé d’ouvrir une connexion sftp avec notre shell.

 

$ConnInfo = New-Object Renci.SshNet.PasswordConnectionInfo($RepositoryIp, $RepositoryPort, $User, $Password)
$Client = New-Object Renci.SshNet.SftpClient($ConnInfo)
$Client.Connect()

 

 

Ensuite, on va aller lire le fichier que l’on souhaite uploader sur notre serveur et utiliser la méthode UploadFile pour l’envoyer.

 

$FileStream = New-Object System.IO.FileStream($File, [System.IO.FileMode]::Open)
$Client.UploadFile($FileStream, "$File")

 

Rien de bien compliquer finalement, il est possible de mettre des contrôles pour vérifier le bon déroulement de cet upload, en faisant une connexion classique au Serveru SSH, en utilisant la méthode Get qui va retourner les informations d’un répertoire ou d’un fichier.

Rappel, après chaque ouverture de fichier, libérer le 😉

$FileStream.Flush()
$FileStream.Close()
$FileStream.Dispose()

 

Et si vous en avez fini, fermez la connexion !

$Client.Disconnect()
$Client.Dispose()

 

Download de fichier

Le download de fichier est en asymétrique de l’upload, vous me direz, normal!

$ConnInfo = New-Object Renci.SshNet.PasswordConnectionInfo($RepositoryIp, $RepositoryPort, $User, $Password)
$Client = New-Object Renci.SshNet.SftpClient($ConnInfo)
$Client.Connect()

 

Ensuite, on va créer le fichier que l’on souhaite downloader sur notre serveur et utiliser la méthode DownloadFile pour le télécharger.

$FileStream = [System.IO.File]::Create($File)
$Client.DownloadFile("$File", $FileStream)

 

PS: n’oubliez le rappel de l’upload de fichier qui vaut aussi pour le download

Déconnexion

Pour se déconnecter, c’est tout bête!

 

$Client.Disconnect()
$Client.Dispose()

 

En espérant vous avoir fait découvrir cette librairie .Net que j’ai juste défrichée, il y a beaucoup plus à faire !

Je suis en train de préparer un module, un peu plus complet que ceux présent sur la toile, je vous le mettrais à disposition dès qu’il sera prêt.

Salut.

 

Updated: Changement de la méthode de création du keypass 🙂