# Reading text variable line by line

**URL:** <https://forums.powershell.org/t/reading-text-variable-line-by-line/20307>\
**Category:** PowerShell Help\
**Created:** [August 30, 2022, 10:47am UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307 "2022-08-30T10:47:00Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![hztpaserg](https://avatars.discourse-cdn.com/v4/letter/h/eb8c5e/32.png) [@hztpaserg](https://forums.powershell.org/u/hztpaserg)\
**Post date:** [August 30, 2022, 10:47am UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/1 "2022-08-30T10:47:00Z")

</div>

I have a text variables:

```auto
????????????
********************************************************************************
* 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:

```auto
        $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’.

---

<div class="post-metadata">

**Author:** ![Olaf](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/olaf/32/992_2.png) [@Olaf](https://forums.powershell.org/u/Olaf)\
**Post date:** [August 30, 2022, 11:28am UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/2 "2022-08-30T11:28:04Z")

</div>

> [@hztpaserg](#):
>
> How can I read it line by line?

Why would you like to do that if you only …

> [@hztpaserg](#):
>
> … need to analyze the last line of the variable

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

```auto
$Result[-1]

```

---

<div class="post-metadata">

**Author:** ![hztpaserg](https://avatars.discourse-cdn.com/v4/letter/h/eb8c5e/32.png) [@hztpaserg](https://forums.powershell.org/u/hztpaserg)\
**Post date:** [August 31, 2022, 7:06am UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/3 "2022-08-31T07:06:43Z")

</div>

Hi!

```auto
$Result[-1]

```

returns only the last character:

```auto
:

```

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

```auto
        $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:

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

```

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

```auto
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

---

<div class="post-metadata">

**Author:** ![Olaf](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/olaf/32/992_2.png) [@Olaf](https://forums.powershell.org/u/Olaf)\
**Post date:** [August 31, 2022, 7:54am UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/4 "2022-08-31T07:54:37Z")

</div>

> [@hztpaserg](#):
>
> returns only the last character:

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

> [@hztpaserg](#):
>
> `$Result = waitfor 'Username'`

What is `waitfor`?

> [@hztpaserg](#):
>
> ` $Writer.writeline('admin')`

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. 🤷🏽‍♂️ So please share your complete or at least all relevant code.

> [@hztpaserg](#):
>
> so I think I need to read $Result line by line

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.

---

<div class="post-metadata">

**Author:** ![hztpaserg](https://avatars.discourse-cdn.com/v4/letter/h/eb8c5e/32.png) [@hztpaserg](https://forums.powershell.org/u/hztpaserg)\
**Post date:** [August 31, 2022, 9:13am UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/5 "2022-08-31T09:13:49Z")

</div>

> [@Olaf](#):
>
> 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:

```auto
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](https://forums.powershell.org/t/ssh-from-windows-to-open-vms-using-ps/18841)  
I connect to the swithch:

```auto
$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:

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

```

and then enter Username and Password or only Password:

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

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

```

and read the version firmvare:

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

```

Here is all scrept:

```auto
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()
}

```

---

<div class="post-metadata">

**Author:** ![Olaf](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/olaf/32/992_2.png) [@Olaf](https://forums.powershell.org/u/Olaf)\
**Post date:** [September 1, 2022, 7:49pm UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/6 "2022-09-01T19:49:45Z")

</div>

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

But your initial question was …

> [@hztpaserg](#):
>
> I have a text variables: …  
> …  
> How can I read it line by line?

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 …

```PowerShell
$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 …

```auto
$SplittedResult[-1]

```

… to read it line by line you could use …

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

```

---

<div class="post-metadata">

**Author:** ![hztpaserg](https://avatars.discourse-cdn.com/v4/letter/h/eb8c5e/32.png) [@hztpaserg](https://forums.powershell.org/u/hztpaserg)\
**Post date:** [September 2, 2022, 12:00pm UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/7 "2022-09-02T12:00:36Z")

</div>

Thenks for you help!  
I have anothe question. 🙂  
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?

```auto
        $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
          }
        }

```

---

<div class="post-metadata">

**Author:** ![Olaf](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/olaf/32/992_2.png) [@Olaf](https://forums.powershell.org/u/Olaf)\
**Post date:** [September 2, 2022, 1:32pm UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/8 "2022-09-02T13:32:34Z")

</div>

> [@hztpaserg](#):
>
> I have anothe question. 🙂

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

> [@hztpaserg](#):
>
> I read Version Softwar in the $Result variable and form another variable $VersResult.

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`.

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

```

---

<div class="post-metadata">

**Author:** ![hztpaserg](https://avatars.discourse-cdn.com/v4/letter/h/eb8c5e/32.png) [@hztpaserg](https://forums.powershell.org/u/hztpaserg)\
**Post date:** [September 5, 2022, 7:08am UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/9 "2022-09-05T07:08:35Z")

</div>

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

```auto
display version

```

command returns. This is the following:

```auto
<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.

---

<div class="post-metadata">

**Author:** ![Olaf](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/olaf/32/992_2.png) [@Olaf](https://forums.powershell.org/u/Olaf)\
**Post date:** [September 5, 2022, 8:01am UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/10 "2022-09-05T08:01:36Z")

</div>

> [@hztpaserg](#):
>
> I andestyn about create a new thread.

??

> [@hztpaserg](#):
>
> `display version`

What kind of command is this?

> [@hztpaserg](#):
>
> command returns. This is the following:

And what are you after?

> [@hztpaserg](#):
>
> but I don’t know how to split rows.

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

---

<div class="post-metadata">

**Author:** ![hztpaserg](https://avatars.discourse-cdn.com/v4/letter/h/eb8c5e/32.png) [@hztpaserg](https://forums.powershell.org/u/hztpaserg)\
**Post date:** [September 5, 2022, 9:26am UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/11 "2022-09-05T09:26:52Z")

</div>

Thenk you! I understand that for new questions need to create a new topic 🙂  
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:

```auto
        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:

```auto
        $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.

---

<div class="post-metadata">

**Author:** ![Olaf](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/olaf/32/992_2.png) [@Olaf](https://forums.powershell.org/u/Olaf)\
**Post date:** [September 5, 2022, 10:36am UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/12 "2022-09-05T10:36:12Z")

</div>

> [@hztpaserg](#):
>
> I understand that for new questions need to create a new topic

But you are still continuing this thread?! 🤔

> [@hztpaserg](#):
>
> but don’t get the expected result.

And what is the expected result???

---

<div class="post-metadata">

**Author:** ![dotnVo](https://avatars.discourse-cdn.com/v4/letter/d/4af34b/32.png) [@dotnVo](https://forums.powershell.org/u/dotnVo)\
**Post date:** [May 16, 2024, 8:16pm UTC](https://forums.powershell.org/t/reading-text-variable-line-by-line/20307/13 "2024-05-16T20:16:39Z")

</div>


