Matching on multiple lines with -contains or -like

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.

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:

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

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

if ($robots -like "*$disallowall*") {

    Write-Host "yes" -ForegroundColor Green

}

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

$disallowall = 'User-agent: \*\r?\nDisallow: /'

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

if ($robots -match $disallowall) {

    Write-Host "yes" -ForegroundColor Green

}

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

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:

PS C:\WINDOWS\system32> "red","white","blue" -contains "white"
True

PS C:\WINDOWS\system32> "red","white","blue" -contains "purple"
False

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

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: /”)

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

$array = @(
    "one",
    "two",
    "three"
)

$array -contains 'three' # true

$array -contains 'hree' # false

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

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

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?

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

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