Reading text variable line by line

I have a text variables:

????????????
********************************************************************************
*  Copyright(c) 2004-2009 Hangzhou H3C Tech. Co., Ltd. All rights reserved.    *
*  Without the owner's prior written consent,                                  *
*  no decompiling or reverse-engineering shall be allowed.                     *
********************************************************************************


Login authentication


Password:

How can I read it line by line?
Try so:

        $i = 0
        foreach ($Line in $Result) {
          $Line.Substring($i)
          $i = $i + 1
        }

but get only one step of cycle.
I need to analyze the last line of the variable: it is equal to ‘Username’ or ‘Password’.

Why would you like to do that if you only …

Assumed the name of your variable is $Result you can get the last line with

$Result[-1]

Hi!

$Result[-1]

returns only the last character:

:

First I need to analyze the penultimate line to login (enter username and password):

        $Result = waitfor 'Username'
        $Writer.writeline('admin')
        $Writer.Flush()

        $Result = waitfor 'Password'
        $Writer.writeline('*******')
        $Writer.Flush()

there are switches thet do not ask for Username, and immediately need to enter a password.
and then execute:

        $Result = waitfor 'Viersion software'
        $Writer.writeline('display version')
        $Writer.Flush()

and read the version firmware of the switch with $Result:

display version
H3C Comware Platform Software
Comware Software, Version 3.10, Release 2108P04
Copyright (c) 2004-2009 Hangzhou H3C Technologies Co., Ltd. All rights reserved.
H3C S3100-26TP-PWR-EI uptime is 0 week, 0 day, 0 hour, 1 minute

H3C S3100-26TP-PWR-EI with 1 Processor 
64M     bytes SDRAM
8M      bytes Flash Memory
Config Register points to FLASH

Hardware Version is REV.A
Bootrom Version is 555
CPLD Version is 003
[Subslot 0] 24FE         Hardware Version is REV.A
[Subslot 1]  1GE         Hardware Version is REV.A
[Subslot 2]  1GE         Hardware Version is REV.A

<CFGSWI11>

so I think I need to read $Result line by line

It depends pretty much on how you create this variable. SSo how do you populate $Result?

What is waitfor?

What is $Writer?

Please keep in mind we cannot see your screen and we cannot read your mind. If you use custom functions you should share them here as well. Otherwise we can only guess what’s wrong. :man_shrugging:t4: So please share your complete or at least all relevant code.

Again … how do you populate $Result?

I’d recommand to keep using standard PowerShell cmdlets and functions and try to avoid dotNet methods until there is a particular need for.

I use two custom functions:

function readtelnet {
    $response = ""
    While($Stream.DataAvailable) {
      $Read = $Stream.Read($Buffer, 0, 1024)
      $response += ($Encoding.GetString($Buffer, 0, $Read))
    }
    return $response;
  }
  
function waitfor {
    param([string]$search, [int]$timeout)
    if ($timeout -eq 0) {
      $timeout = 3
    }
    $pause = 100
    $pending = readtelnet
    $myResult = $pending
    $counter = 0
    while ($pending -notmatch $search -and $counter -le ($timeout * (1000/$pause))) {
      $counter ++
      Start-Sleep -m $pause
      $pending = readtelnet
      $myResult += $pending
    }
    return $myResult
}

which I found here on the forum.
Enable Notifications​ SSH from Windows to Open VMS using PS
I connect to the swithch:

$SocetNew = New-Object Net.Sockets.TcpClient
$SocetNew.Connect("1.11.1.1",23)
if ($SocetNew.Connected) {
        $Stream = $SocetNew.GetStream()
        $Writer = New-Object System.IO.StreamWriter($Stream)
        $Buffer = New-Object System.Byte[] 1024
        $Encoding = New-Object System.Text.ASCIIEncoding
}

and then i need enter Username and Password. For that, first I try to find out whot the switch asking:

        $Result = waitfor ''
        $Writer.writeline('')
        $Writer.Flush()

and then enter Username and Password or only Password:

        $Result = waitfor 'Username'
        $Writer.writeline('admin')
        $Writer.Flush()

        $Result = waitfor 'Password'
        $Writer.writeline('***********')
        $Writer.Flush()

and read the version firmvare:

        $Result = waitfor 'Viersion software'
        $Writer.writeline('display version')
        $Writer.Flush()

Here is all scrept:

function readtelnet {
    $response = ""
    While($Stream.DataAvailable) {
      $Read = $Stream.Read($Buffer, 0, 1024)
      $response += ($Encoding.GetString($Buffer, 0, $Read))
    }
    return $response;
  }
  
function waitfor {
    param([string]$search, [int]$timeout)
    if ($timeout -eq 0) {
      $timeout = 3
    }
    $pause = 100
    $pending = readtelnet
    $myResult = $pending
    $counter = 0
    while ($pending -notmatch $search -and $counter -le ($timeout * (1000/$pause))) {
      $counter ++
      Start-Sleep -m $pause
      $pending = readtelnet
      $myResult += $pending
    }
    return $myResult
}

$SocetNew = New-Object Net.Sockets.TcpClient
try {
    $SocetNew.Connect("1.11.1.1",23)                  
    if ($SocetNew.Connected) {
        $Stream = $SocetNew.GetStream()
        $Writer = New-Object System.IO.StreamWriter($Stream)
        $Buffer = New-Object System.Byte[] 1024
        $Encoding = New-Object System.Text.ASCIIEncoding

        $Result = waitfor ''
        $Writer.writeline('')
        $Writer.Flush()

        # need read whot the switch asking with $Result

        $Result = waitfor 'Username'
        $Writer.writeline('admin')
        $Writer.Flush()

        $Result = waitfor 'Password'
        $Writer.writeline('*******')
        $Writer.Flush()

        $Result += waitfor 'UNFAS1_A_\$ ' 30
        $Writer.Flush()

        $Result = waitfor 'Viersion software'
        $Writer.writeline('display version')
        $Writer.Flush()

        # need read Version software of the switch with $Result

        Start-Sleep -s 1
        readtelnet
 
        $Writer.Close()
        $Stream.Close()
        
        Write-Output "Success"
    }
    else {
        Write-Output "Failed"
    }
}
catch {
    Write-Output "Failed"
}
finally {
    $SocetNew.Dispose()
}


OK. I have no experiences with telnet used with PowerShell. So I cannot say anything to that.

But your initial question was …

In PowerShell a text usually is an array of lines. If you have a raw string as a big chunk with multiple line breaks in it you can turn it into an array of lines to be able to treat it as you need it.

So assumed your variable name is $result and it is a raw string with line breaks in it you can use …

$SplittedResult = $Result -split '\r\n'

… to split it into individual elements of an array. And now you can access each individual line either with a loop or by its index. And the index of the last element ist [-1]. And so you can access the last line of the text saved as array with …

$SplittedResult[-1]

… to read it line by line you could use …

foreach ($Line in $SplittedResult) {
    "Do something meaningful with the line '$($Line)'"
}

Thenks for you help!
I have anothe question. :slightly_smiling_face:
I read Version Softwar in the $Result variable and form another variable $VersResult. How do I assing each $Result string to a new variable from a new string?

        $VersResult = ''
        $SplitResult = $Result -split '\r\n'
        foreach ($Line in $SplitResult) {
          if ($Line -notlike '*<*' -and $Line -notlike '*display version*') {
            $VersResult += $Line        #here I wont with new line
          }
        }

If you have another question you should create a new thread with a new question please.

How do you check for a version string? Usually we use a -match operator for this purpose. And then you have the automatic variable $Matches.

if ($Line -match '(\d+(\.\d+){1,3})') {
    $Version = $Matches[0]
}

Hi!
I andestyn about create a new thread.
About version softwar, I wont read not only the version numbre, but allthe information that the

display version

command returns. This is the following:

<CFZASWI101>display version
H3C Comware Platform Software
Comware Software, Version 3.10, Release 2108P04
Copyright (c) 2004-2009 Hangzhou H3C Technologies Co., Ltd. All rights reserved.
H3C S3100-26TP-PWR-EI uptime is 0 week, 2 days, 18 hours, 52 minutes

H3C S3100-26TP-PWR-EI with 1 Processor 
64M     bytes SDRAM
8M      bytes Flash Memory
Config Register points to FLASH

Hardware Version is REV.A
Bootrom Version is 555
CPLD Version is 003
[Subslot 0] 24FE         Hardware Version is REV.A
[Subslot 1]  1GE         Hardware Version is REV.A
[Subslot 2]  1GE         Hardware Version is REV.A

<CFZASWI101>

Unnecessary informacion I remove as I showed above, creating a new variable $VersResult, but I don’t know how to split rows.

??

What kind of command is this?

And what are you after?

I already showed to you and you seem to already used it in you second to last reply.

Thenk you! I understand that for new questions need to create a new topic :slightly_smiling_face:
display version
this is CMD-command that returns the switch firmware version in variable $Result.
But at the beginning and at the end of the text contains information that is not relevant to the version softwar. So I’m trying to give into a new variable, Just the information I need.
The example you recommended:

        foreach ($Line in $SplitResult) {
          if ($Line -match '(\d+(\.\d+){1,3})') {
            $Version = $Matches[0]
          }
        }

only returns version number
3.10
I try the following code:

        $VersResult = ''
        $SplitResult = $Result -split '\r\n'
        foreach ($Line in $SplitResult) {
          if ($Line -notlike '*<*' -and $Line -notlike '*display version*') {
            $VersResult += "`n" + $Line
          }
        }

but don’t get the expected result.
I’ll probably leave the result in the $Result variable. There’s a lot more to do and not a lot of time.

But you are still continuing this thread?! :thinking:

And what is the expected result???