VMware Cloud Community
AlanRaczek
Contributor
Contributor

Get output from New-SSHShellStream in an ESXi shell session

Given the following code:

#Start SSH session
$ssh = New-SSHSession -ComputerName $lvhost -Credential $hostCreds -AcceptKey
Start-Sleep -Seconds 5

#Send commands to esx
$SSHStream = New-SSHShellStream -Index $ssh.SessionId
$SSHStream.WriteLine("cd /scratch/log")
$SSHStream.WriteLine("pwd")
Start-Sleep -seconds 10
$esxout = $SSHStream.read()
$esxout
$sshstream
break

I need a simple way to see that the ("cd /scratch/log") actually worked. When I do the $esxout=$SSHStream.read() I get ALL the output including the banner and all the commands I typed. I just want to see that the "pwd" command gives me the current directory after the "cd" command and I can make sure the "cd" command worked.

I guess I could parse all output and do a substring?

Ty.

0 Kudos
12 Replies
LucD
Leadership
Leadership

A stream can be compared with a continuous stream of characters, so you have to make sure you read everything up to the point where you want to capture the output.
I normally use a Read which I throw away up to the point where I send the command whose output I want to capture.
For me it works with a single ReadLine just after the 'pwd', some Linux type tty echo the commands as well.
So there it would be your 2nd ReadLine() that returns the output you want to capture

#Start SSH session
$ssh = New-SSHSession -ComputerName $lvhost -Credential $hostCreds -AcceptKey

#Send commands to esx
$SSHStream = New-SSHShellStream -Index $ssh.SessionId
$SSHStream.WriteLine("cd /scratch/log")
$SSHStream.read() | Out-Null
$SSHStream.WriteLine("pwd")
$SSHStream.readline() 

 


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
AlanRaczek
Contributor
Contributor

 

I knew I had to separate the commands out somehow but just couldn't picture it. This makes total sense! Thank you for the quick

response.

 

...alan

0 Kudos
AlanRaczek
Contributor
Contributor

Hmmm,

The output I get is just

pwd

Even tried a sleep to let it work...

#Send commands to esx
$SSHStream = New-SSHShellStream -Index $ssh.SessionId
$SSHStream.WriteLine("cd /scratch/log")
$SSHStream.read() | out-null
$SSHStream.WriteLine("pwd")
Start-Sleep 10
$esxout = $SSHStream.readline()
$esxout

break

0 Kudos
LucD
Leadership
Leadership

I forgot an extra readline(), the 1st one reads the echo of the pws command.

#Start SSH session
$ssh = New-SSHSession -ComputerName $lvhost -Credential $hostCreds -AcceptKey

#Send commands to esx
$SSHStream = New-SSHShellStream -Index $ssh.SessionId
$SSHStream.WriteLine("cd /scratch/log")
$SSHStream.read() | Out-Null
$SSHStream.WriteLine("pwd")
$SSHStream.readline() | Out-Null
$SSHStream.readline() 


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
LucD
Leadership
Leadership

stream.png


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Pilu1978
Enthusiast
Enthusiast

Hi LucD,

I need some help on the below as I am trying to capture the output of the command to a variable but every time it is coming as blank. Please advise.

#Start SSH session
$ssh = New-SSHSession -ComputerName $esx -Credential $hostCreds -AcceptKey

#Send commands to esx
$SSHStream = New-SSHShellStream -Index $ssh.SessionId
$SSHStream.WriteLine("vmware -v")
$output = $SSHStream.read()

Write-Host $output

 

0 Kudos
LucD
Leadership
Leadership

Working with the Stream is tricky, since you get everything back that is echoed to the console.
It does require that you know exactly what is being produced, so you filter out the unnecessary lines.

In your case, this should do the trick

$esx = 'MyEsx'
$user = 'root'
$pswd = 'VMware1!'
$cmd = 'vmware -v'

$hostCreds = New-Object -TypeName PSCredential -ArgumentList $user,(ConvertTo-SecureString -String $pswd -AsPlainText -Force)

#Start SSH session
$ssh = New-SSHSession -ComputerName $esx -Credential $hostCreds -AcceptKey -Force

#Send commands to esx
$SSHStream = New-SSHShellStream -Index $ssh.SessionId

# Skip banner and other output
do {
    $SSHStream.Read() | Out-Null
} while ($SSHStream.DataAvailable)

# Send command
$SSHStream.WriteLine($cmd)

# Wait for command output
while (-not $SSHStream.DataAvailable){
    Start-Sleep -Milliseconds 100
}
$output = $SSHStream.Read()
Remove-SSHSession -SSHSession $ssh | Out-Null

$output.Split("`n") | Where-Object { $_ -notmatch "\[$($user)|^$($cmd)" }


But why use the stream in this case?
This can be done, much simpler with an Invoke-SSHCommand.

$esx = 'MyEsx'
$user = 'root'
$pswd = 'VMware1!'
$cmd = 'vmware -v'

$hostCreds = New-Object -TypeName PSCredential -ArgumentList $user, (ConvertTo-SecureString -String $pswd -AsPlainText -Force)

#Start SSH session
$ssh = New-SSHSession -ComputerName $esx -Credential $hostCreds -AcceptKey -Force
$output = Invoke-SSHCommand -SSHSession $ssh -Command $cmd
Remove-SSHSession -SSHSession $ssh | Out-Null

$output.output


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Pilu1978
Enthusiast
Enthusiast

Thanks a lot LucD. 

Actually there is an requirement to gather some information from Cisco UCS fabric Interconnect and I am using Posh-SSH to achieve it.

However I am not able to run any command using Invoke-SSHCommand. It is hanging but New-SSHShellStream is running properly.

I will try the code you shared and let you know the result. Thanks Again.

0 Kudos
Pilu1978
Enthusiast
Enthusiast

No LucD. I am still not getting the output.

0 Kudos
LucD
Leadership
Leadership

Works for me. This is what is returned


LucD_0-1675344306748.png

How do you run the script?
Is it exactly the same as I posted?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Pilu1978
Enthusiast
Enthusiast

As mentioned I am using posh-SSH to connect my UCS fabric-interconnect (switch) over SSH and run the command to check the uptime of the IOM modules. The 1st command is "connect iom 1" which will be the below output from which I need only the "Attaching to FEX 1 ..." portion.

Attaching to FEX 1 ...
To exit type 'exit', to abort type '$.'
Bad terminal type: "dumb". Will assume vt100.
fex-1#

2nd command is "sh system uptime" and it gives the following output:

System start time: Sat Sep 12 12:45:21 2021
System uptime: 101 days, 0 hours, 11 minutes, 32 seconds
Kernel uptime: 101 days, 0 hours, 22 minutes, 11 seconds
fex-1#

I need the 2 lines in the middle to be saved on variable from the above output

Lastly exit command to come out from fex-1# prompt

This way it should print for the uptime of all 10 IOM modules present in the UCSM. 

   

0 Kudos
LucD
Leadership
Leadership

Sorry, I don't have access to a UCS platform.

You will have to experiment yourself I'm afraid


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos