Matching on multiple lines with -contains or -like

Welcome Forums General PowerShell Q&A Matching on multiple lines with -contains or -like

  • This topic has 8 replies, 4 voices, and was last updated 1 month ago by
    Participant
    .
Viewing 7 reply threads
  • Author
    Posts
    • #250355
      Participant
      Topics: 4
      Replies: 14
      Points: 48
      Rank: Member

      Hello,

      I would like to be able to match on multiple lines and I am having troubles trying to figure out how to do this.  I have a feeling I am going to need regex but I am not sure.  Any help would be greatly appreciated.

      $url = "http://contoso.com/robots.txt"

      $disallowall = {
      User-agent: *
      Disallow: /
      }

      $robots = (Invoke-WebRequest -Uri $url -ErrorAction Stop).content | Out-String
      if ($robots -contains $disallowall){

      Write-Host "yes" -ForegroundColor Green

      }

      The issue I am having is “ $robots -contains $disallowall” says its false even though $disallowall definitely contains these two lines.  I have tried to use “*$disallow*” and other variations but cannot get this to match on the multiple lines in $disallowall variable with -contains or -like.  Obviously the URL in this example wouldnt match but in my working example it does.

    • #250382
      Participant
      Topics: 0
      Replies: 77
      Points: 343
      Helping Hand
      Rank: Contributor

      It is unclear if {} are required in your match string. A beginning and ending pair of {} denotes a script block in PowerShell. When comparing strings, it is likely unnecessary. Using quotes, here-strings, and other string formatting mechanisms will be the way to go.

      If the downloaded content has line breaks that match your [console]::NewLine configuration, you could simply just use a here-string with the -like operator:

      If the line break characters are unknown, you can test with -match, which uses regex. That will allow for a specific newline character pattern match. This will match 0 or 1 carriage returns and a line feed. It also escapes the literal *.

      • #250388
        Participant
        Topics: 4
        Replies: 14
        Points: 48
        Rank: Member

        It appears your code blocks took on some formatting.  Can you please re-post your code suggestions?

    • #250391
      Participant
      Topics: 13
      Replies: 1753
      Points: 3,136
      Helping Hand
      Rank: Community Hero

      There are several issues. First, are you sure that Invoke-RestMethod is returning what you expect as it’s odd to refer directly to a txt file. The $disallowall is defined as a script block. The contains operator is an array comparison:

      This most likely would not work unless the content is array and a line matches exactly. What exactly does the $robots contain?

    • #250394
      Participant
      Topics: 4
      Replies: 14
      Points: 48
      Rank: Member

      Rob,

      Using my real URL (not contoso.com), the $robots contains the following.

      #robots.txt file

      User-agent: *
      Disallow: /

      I am checking robots.txt to confirm that file contains the following two lines consecutively.

      User-agent: *
      Disallow: /

      Also, I have tried to match on this using regex and I cannot get that working either.

      $robots -match [regex]”User-agent: \*[\r\n]Disallow: \/”)

      • This reply was modified 1 month ago by Mike.
      • This reply was modified 1 month ago by Mike.
      • This reply was modified 1 month ago by Mike.
    • #250406
      Participant
      Topics: 7
      Replies: 557
      Points: 2,122
      Helping Hand
      Rank: Community Hero

      When using the -contains operator on an array, it will look at/match elements.

      [/crayon]

      String types have a .Contains method you can use to find text. Something like this works

      ($array | Out-String).Contains('hree') # true

    • #250427
      Participant
      Topics: 4
      Replies: 14
      Points: 48
      Rank: Member

      Thanks Adminofthings45!  This seemed to be the part I needed.

      $disallowall = @
      User-agent: *
      Disallow: /
      @

      Can you tell me why you wrap the variable value in @?  I understand that leading with @ forces it to be an array (even if it only contains a single value) however why is it necessary to end with @ also?

    • #250430
      Participant
      Topics: 0
      Replies: 77
      Points: 343
      Helping Hand
      Rank: Contributor

      @''@ is a here-string. It is used to help preserve formatting for strings that span multiple lines.

    • #250460
      Participant
      Topics: 4
      Replies: 14
      Points: 48
      Rank: Member

      Perfect!  Thank you AdminOfThings45!  I really appreciate your guidance.

Viewing 7 reply threads
  • You must be logged in to reply to this topic.