I need to send a list of commands to several devices. For each IP, open an SSH-connection with the given credentials from User and Password textboxes, run all of the commands and return the output to the Output textbox.
Normally I'd use
plink.exe -ssh admin@172.16.17.18 -pw PassW0rd "command"
Unfortunately, the remote host does not let me do that:
Sent password
Access granted
Opening session as main channel
Opened main channel
Server refused to start a shell/command
FATAL ERROR: Server refused to start a shell/command
However, if I connect without handing over a command:
Sent password
Access granted
Opening session as main channel
Opened main channel
Allocated pty (ospeed 38400bps, ispeed 38400bps)
Started a shell/command
Welcome to XXX
System_Name>#
Now, I can type my commands and have them executed. I tried PoshSSH, which lets me connect but any command times out.
I broke down the lines from the IP- and Command-boxes into string-arrays and made for loops. Then I tried several approaches with Start-Job
and SystemDiagnostics.Process*
without success.
Now I'm a bit clueless and would appreciate any help:
for ($a=0; $a -lt $IPArray.Length; $a++){
# Open an interactive Session with plink like
# plink.exe -ssh ' + $User + '@' + $IPArray[$a] + ' -pw ' + $Passwd
for ($b=0; $b -lt $CommandArray.Length; $b++){
# Send $CommandArray[$b] to plink-Session
# Wait for command to finish
# Read output and send it to the textbox
}
}
Edit: Thanks to Martin Prikryl's answer I'm a step further:
for ($a=0; $a -lt $IPArray.Length; $a++){
$User = $UserTextBox.text
$IP = $IPArray[$a]
# $Passwd = $PwdTextBox.Text
$Outputtext= $Outputtext + "~~~~~ " + $IP + " ~~~~~" + "`r`n"
$isSession = New-SSHSession -ComputerName $IP -Credential $User
$isStream = $isSession.Session.CreateShellStream("PS-SSH", 0, 0, 0, 0, 1000)
for ($b=0; $b -lt $CommandArray.Length; $b++){
$Command = $CommandArray[$b]
$isStream.WriteLine("$Command")
Start-Sleep -Seconds 1
}
$isReturn = $isStream.Read()
$Outputtext= $Outputtext + $isReturn + "`r`n"
$outputBox.Text = $Outputtext
}
returns:
~~~~~ 172.16.17.18 ~~~~~
Welcome to XXX
System_18>#echo 1
1
System_18>#echo 2
2
System_18>#ping 8.8.8.8
PING 8.8.8.8 56 data bytes
~~~~~ 172.16.17.19 ~~~~~
Welcome to XXX
System_19>#echo 1
1
System_19>#echo 2
2
System_19>#ping 8.8.8.8
PING 8.8.8.8 56 data bytes
~~~~~ 172.16.17.20 ~~~~~
Welcome to XXX
System_20>#echo 1
1
System_20>#echo 2
2
System_20>#ping 8.8.8.8
PING 8.8.8.8 56 data bytes
Now I need to achieve two things:
Get the credentials from the corresponding input fields (Currently, I need to type in the password once for each IP)
Done:
$User = $UserTextBox.text $Passwd = ConvertTo-SecureString $PwdTextBox.Text -AsPlainText -Force $SSHCred = New-Object System.Management.Automation.PSCredential -ArgumentList ($User, $Passwd) # ... $isSession = New-SSHSession -ComputerName $IP -Credential $SSHCred
Make it wait for a command to finish, before sending the next one. (Currently, it just waits 1 second)
However, I'm happy that the remote hosts now talk to me, at least. Thank you.
Should I open new questions, if I need further help with the script or continue to log the progress, here?