I am trying to parse through a .txt dump of firewall rules (100 ). I want to search each rule for a specific parameter (ex. set ips-sensor). If that rule contains the parameter, I want the script to print "value found". If not, I want the script to print "value not found". I have treated each rule as a paragraph and used a delimiter on "next". I cannot get the foreach loop to work. Here is what I have:
$paragraphs = Get-Content C:\firewall_rules.txt -Delimiter "next"
#$line = $paragraphs.Split([string[]]"`r`n", [StringSplitOptions]::None)
$exists = $paragraphs | Where-Object { $_ -like '*set ips-sensor*' }
$noexists = $paragraphs | Where-Object {$_ -notlike '*set ips-sensor*'}
$result = foreach ($line in $paragraphs) {$line.Split([string[]]"`r`n", [StringSplitOptions]::None)}
foreach ($result in $paragraphs)
{
if (?)
{
Write-Host "value found"
}
elseif (?)
{
Write-Host "value not found"
}
}
Here is an example of the exact format:
edit 168
set name "Office Stuff"
set srcintf "Office"
set dstintf "port11"
set srcaddr "overthere"
set internet-service enable
set action accept
set schedule "always"
set logtraffic all
set fsso disable
set nat enable
next
edit 174
set name "My Policy"
set srcintf "Office"
set dstintf "port1"
set srcaddr "overthere"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
set utm-status enable
set logtraffic all
set ips-sensor "default"
next
edit 68
set name "Naughty IPs"
set srcintf "Office"
set dstintf "port1"
set srcaddr "all"
set dstaddr "faraway"
set schedule "always"
set service "ALL"
set logtraffic all
set ips-sensor "default"
set fsso disable
my expected output should be -
value not found
value found
value found
Any help is appreciated.
CodePudding user response:
Nice question, I've added comments on the code so you can follow the thought process.
# Define the word we want to match
$find = 'ips-sensor'
# Set Paragraph counter
$z = 1
# $file will be an array with 3 elements / paragraphs given the example we got
foreach($paragraph in $file)
{
# Set the line counter (this will be reset on each paragraph)
$i = 0
# Set a result hashtable and assume we will not find the word we're looking for
$out = [ordered]@{
Paragraph = $z
Status = 'Not Found'
LineNumber = ''
Line = ''
}
# Split this paragraph on new lines and filter only those elements that are
# not empty strings and loop through it
foreach($line in $paragraph -split '\r?\n' -ne '')
{
# Increment the line counter
$i
# Self explanatory
if($line -match $find)
{
$out.Status = 'Found'
$out.LineNumber = $i
$out.Line = $line.Trim()
# Break the inner loop, if we are here we don't need to keep looping
# over this array
break
}
}
# Cast a pscustomobject which can be easily manipulated and exported
[pscustomobject]$out
# Increment Paragraph counter
$z
}
Result
Paragraph Status LineNumber Line
--------- ------ ---------- ----
1 Not Found
2 Found 12 set ips-sensor "default"
3 Found 10 set ips-sensor "default"
If you wanted to find multiple words on your dump file, the code would require a few modifications:
$find = 'ips-sensor', 'naughty' -join '|'
$z = 1
foreach($paragraph in $file)
{
$i = 0
$out = [ordered]@{
Paragraph = $z
Status = 'Not Found'
LineNumber = ''
Line = ''
}
foreach($line in $paragraph -split '\r?\n' -ne '')
{
$i
if($line -match $find)
{
$out.Status = 'Found'
$out.LineNumber = $i
$out.Line = $line.Trim()
[pscustomobject]$out
}
}
if($out.Status -eq 'Not Found')
{
[pscustomobject]$out
}
$z
}
Result
Paragraph Status LineNumber Line
--------- ------ ---------- ----
1 Not Found
2 Found 12 set ips-sensor "default"
3 Found 2 set name "Naughty IPs"
3 Found 10 set ips-sensor "default"
CodePudding user response:
Since you've already broken the text up into chunks, they can be passed to a foreach-object and you just simply need to test if the desired string is found.
Get-Content C:\firewall_rules.txt -Delimiter 'next' | ForEach-Object {
if($_ -Match 'set ips-sensor'){
"Value found"
}
else{
"Value not found"
}
}
This produces your desired output.
Value not found
Value found
Value found