4

this is my code:

@( 
  ' ', #for "Press any key to continue" 
  'show mac-address'
  ) | plink <ip> -P 22 -ssh -v -l admin -pw pwd -batch 

Read-Host -Prompt “Press Enter to exit”

sometimes i get this output:

←[1;13r←[1;1HSession sent command exit status 0
Main session channel closed
All channels closed

and sometimes i get this output:

Remote side unexpectedly closed network connection
FATAL ERROR: Remote side unexpectedly closed network connection

If i write the plink command without Pipe:

plink <ip> -P 22 -ssh -v -l admin -pw pwd -batch 

It works. But i need it automated

Elias
  • 125
  • 2
  • 22

2 Answers2

1

As mentioned in your comment (and edited in your question)

plink <ip> -P 22 -ssh -v -l admin -pw pwd -batch `n;show mac-address

works fine. You could automate this by just joining your statements together with Join-String:

$ip = "192.168.123.123"
@(
    "\n",
    "show-mac-address",
    "just-another-command"
) | Join-String -Separator ";" | ForEach-Object {
    plink $ip -P 22 -ssh -v -l admin -pw pwd -batch $_
}

This basic example simply renders to plink 192.168.123.123 -P 22 -ssh -v -l admin -pw pwd -batch \n;show-mac-address;just-another-command.

This happens in two steps: Join-String takes your input array from the pipeline and joins it together to one string: \n;show-mac-address;just-another-command. This one string is then passed thru the pipeline to ForEach-Object. This cmdlet takes it, sets PsItem to this Value and executes the plink command one time for every string passed to it (which is in fact only one element)

For older PowerShell-Versions [string]::Join(";", $statements) might be of help for you.

Clijsters
  • 4,031
  • 1
  • 27
  • 37
1

I happen to have an Aruba switch and found that specifying non-interactive SSH with -batch, or commands with -m, just causes the switch to disconnect your session like you're seeing. Maybe there's a setting to allow it?

I found this works pretty well, using more of a .net approach due to issues with Start-Process redirection. This opens plink in a separate process, and sends commands to its stdin:

# set up a process with redirection enabled
$psi = New-Object System.Diagnostics.ProcessStartInfo
  $psi.FileName               = "plink.exe" #process file
  $psi.UseShellExecute        = $false      #start the process from it's own executable file
  $psi.WorkingDirectory       = 'C:\Program Files (x86)\PuTTY' # or add to path
  $psi.RedirectStandardInput  = $true       #enable the process to read from our standard input
  $psi.RedirectStandardOutput = $true       #enable reading standard output from powershell
  # update these:
  $psi.Arguments = "$IPADDRESS -P 22 -ssh -l admin -pw $PASS"

# launch plink
$plink = [System.Diagnostics.Process]::Start($psi);
sleep 1

# send key presses to plink shell
$plink.StandardInput.AutoFlush = $true
$plink.StandardInput.WriteLine() # press return to begin session
$plink.StandardInput.WriteLine() # press any key to continue (banner)
$plink.StandardInput.WriteLine('show mac-address') # get macs
$plink.StandardInput.WriteLine('exit') # exit and confirm logoff
$plink.StandardInput.WriteLine('exit') 
$plink.StandardInput.WriteLine('y')

# read output from process
$output = $plink.StandardOutput.ReadToEnd()

# exit plink
$plink.Close()


# outputs like so (trimmed of banners etc)
$output

MAC Address       Port                            VLAN
----------------- ------------------------------- ----
005056-00000X     15                              1
005056-00000Y     9                               1
005056-00000Z     11                              1

You may have to play around with the commands a bit, but I found plink was pretty generous with how quickly input gets thrown at it

I did notice if the plink process is waiting (ssh session still connected), then ReadToEnd() will wait forever. Maybe it can be replaced with a ReadLine() loop, but it can be hard to tell when it's done.

Cpt.Whale
  • 4,784
  • 1
  • 10
  • 16
  • The `-batch` cannot cause problems. The `-m` indeed can. Other than that, you are doing basically the same what @Clijsters does. – Martin Prikryl Jan 20 '23 at 06:48
  • @MartinPrikryl nah, plink tries to start or initialize(?) a shell if you feed commands into `-batch`, which causes this (or at least my) switch to boot you with `Session sent command exit status 0 [...] SH command execution is not supported.`, though sometimes the line portion complaining about SH gets eaten if you try to send a list of commands – Cpt.Whale Jan 20 '23 at 16:58
  • I do not really understand your comment. But `-batch` does not have any effect on communication with the server. It affects only how local Plink user prompts are handled. – Martin Prikryl Jan 22 '23 at 18:09
  • @Cpt.Whale your Solution works. But: i get the mac-address-table but with: [24;1H[2K-- MORE --, next page: Space, next line: Enter, quit: Control-C[24;1H[24;1H[2K[24;1H [24;1H[2K-- MORE --, next page: Space, next line: Enter, quit: Control-C[24;1H[24;1H[2K[24;1H – Elias Jan 26 '23 at 10:41
  • @Cpt.Whale But the Putty window doesnt close it stuck at ReadToEnd. I need to manually close the window – Elias Jan 26 '23 at 10:55
  • @Elias ah, I didn't have enough mac addresses for multiple pages - you may have to send some more `WriteLine()` entries after the mac address command. The "next page" prompt is eating the `exit` commands, so powershell can't read to end (because putty is still active). Plink in the windows cmd console just has issues in general with ansi escape characters, so there's not much you can do there (maybe start plink from powershell core like `filename=pwsh.exe` and `args="-NoExit c:\folder\plink.exe [plink args...]"` – Cpt.Whale Jan 26 '23 at 15:50
  • All this said, I'm pretty sure it's going to be easier to automate using snmp to grab these if you can. A different ssh client like openssh might do better as well – Cpt.Whale Jan 26 '23 at 15:54