0

I'm using powershell with the SSH.Net library to connect to ssh servers and run commands. Mostly that works fine, except I have a system that only has keyboard-interactive authentication enabled (and I can't change that).

I found an answer that describes how to use an EventHandler in C# to perform keyboard-interactive type authentication, but I haven't been able to successfully port that to powershell. It appears to be something with the way that I'm handling the event, but I'm not sure exactly what. Any help would be greatly appreciated!

When I try running the below code, I get this error:

Exception calling "Connect" with "0" argument(s): "Value cannot be null.
Parameter name: data"
At C:\Users\nathan\Documents\ssh-interactive-test.ps1:35 char:1
+ $Client.connect()
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentNullException

This is the relevant section of code that I'm running:

$scriptDir = $(Split-Path $MyInvocation.MyCommand.Path)
[reflection.assembly]::LoadFrom((Resolve-Path "$scriptDir\Renci.SshNet.3.5.dll")) | Out-Null

$ip = "ip address"
$user = "username"
$pass = "password"

$kauth = New-Object Renci.SshNet.KeyboardInteractiveAuthenticationMethod($user)
$pauth = New-Object Renci.SshNet.PasswordAuthenticationMethod($user, $pass)
$action = { 
    foreach ($prompt in $event.SourceEventArgs.Prompts) {
        if ($prompt.Request -like 'Password:*') {
            $prompt.Response = $pass
        }
    }
}
$oe = Register-ObjectEvent -InputObject $kauth -EventName AuthenticationPrompt -Action $action
$connectionInfo = New-Object Renci.SshNet.ConnectionInfo($ip, 22, $user, $pauth, $kauth)
$Client = New-Object Renci.SshNet.SshClient($connectionInfo)
$Client.connect()

Thanks for reading!

Community
  • 1
  • 1
Nathan Coad
  • 1
  • 1
  • 2
  • Based on the error it looks like the connect method is expecting an input called data, which you need to put inside the brackets. Suggest looking at the documentation for that method to work out what type/content 'data' should be. – Mark Wragg Mar 01 '17 at 07:20
  • That was one of my thoughts, however the working C# code that I linked to does not have any such input called data. – Nathan Coad Mar 02 '17 at 03:50

1 Answers1

3

this interactive keyboard login will work for you in PowerShell. Ideas taken from C# code example by Renci.SshNet Below will run a sample command and grab output of each line:

$scriptDir = $(Split-Path $MyInvocation.MyCommand.Path)
$ip = "ip address"
$user = "username"
$pass = "password"
$port = 22
Add-Type -Path "$scriptDir\Renci.SshNet.dll"

$action = {
    param([System.Object]$sender, [Renci.SshNet.Common.AuthenticationPromptEventArgs]$e)
    foreach ($prompt in $e.Prompts) {
        if ($prompt.Request.tolower() -like '*password:*') {
            prompt.Response = $pass;
        }
    }
}
$connectionInfo = [Renci.SshNet.KeyboardInteractiveConnectionInfo]::new($ip, $port, $user);
$oe = Register-ObjectEvent -InputObject $connectionInfo -EventName AuthenticationPrompt -Action $action
[Renci.SshNet.SshClient]$client = [Renci.SshNet.SshClient]::new($ip, $port, $user,$pass);
$client.Connect();
[Renci.SshNet.ShellStream]$shellStream = $client.CreateShellStream("dumb", 80, 24, 800, 600, 1024);
$shellStream.WriteLine("ps ax");
$result = $shellStream.ReadLine([System.TimeSpan]::FromMilliseconds(200));
while($result -ne $null) {
    Write-Host $result;
    if($result.Length -gt 1) {
        $result = $shellStream.ReadLine([System.TimeSpan]::FromMilliseconds(200));
    }
}
$client.Disconnect();
Iggy Zofrin
  • 515
  • 3
  • 10