2

In short, I need to find a specific line in a long file that starts with "set ip " and continues with some parameter that I need to replace. this line appears multiple times in the file so I need to find it between 2 specific lines.

The longer story: We will soon get to configure many FortiGate Firewalls for our offices, most of the settings, policies etc. will be the same but the external IP changes, some other addresses change etc. So I'm trying to make a powershell script that will take an existing config (which might change) and find the specific lines I need and replace them. I tried with regex but couldn't make it work for me on multiple lines. basically for a reference I need to find the "set ip " in the following part:

config system interface
    edit "wan1"
        set vdom "root"
        set ip 7.7.7.7 255.255.255.252
        set allowaccess ping https ssh
        set ident-accept enable
        set type physical
        set scan-botnet-connections block
        set alias "WAN1"
        set role wan
        set snmp-index 1
    next

(IP was changed for security) and so on. what I've got so far is:

get-content .\Fortigate.conf  | select-string -pattern "^#","set uuid " -notmatch

sadly nothing I tried to cut that part of text to search only there worked. for example with regex I tried:

get-content .\Fortigate.conf  | select-string -pattern "^#","set uuid " -notmatch | select-string -Pattern '(?m)edit "wan1".*?end'
DimiBoy
  • 21
  • 1
  • Use the `-Raw` switch on `Get-Content` if you want to use the multi-line flag – Maximilian Burszley May 10 '18 at 10:08
  • Actually, `(?m)` is redundant here, did you want to use `(?s)` to make `.` match an LF char? You can only use it if you read the whole file in, not read it line by line (see the comment above). – Wiktor Stribiżew May 10 '18 at 10:17
  • I tried as -Raw but it didn't work for me at all, sadly I don't understand almost nothing in regex and it mostly was copied and worked on some online regex checker website. – DimiBoy May 10 '18 at 10:31
  • So, you have the file as shown above, right? What is the expected result? – Wiktor Stribiżew May 10 '18 at 10:43
  • in the end it should be same file with same structure but some details changed, for example that IP line will now be: set ip 5.5.5.5 255.255.255.250 – DimiBoy May 10 '18 at 11:34

1 Answers1

0

For this issue, I would not try to regex multiple line but approach it the PowerShell way "Implement for the Middle of a Pipeline" and remember information as which section your in, e.g.:

Read each specific line (if you writing a cmdlet, use the processmethod section):

get-content .\Fortigate.conf  | ForEach {...

Remember the current edit section:

$Wan = ($_ | Select-String 'edit[\s]+"(.*)"').Matches.Groups[1].Value

Catch the specific set within the (edit) section:

$SetIP = ($_ | Select-String 'set[\s]+ip[\s]+(.*)').Matches.Groups[1].Value

Make your decisions based on the values and section, e.g.:

If ($Wan -eq $MyWan) {
    if (($SetIP -Split "[\s]+") -Contains $MyIP) {...

Drop your new string entry (intermediately) on the pipeline:

Write-Output "        set ip $MyNewIP"

Or keep the original string entry:

Else {Write-Output $_}
iRon
  • 20,463
  • 10
  • 53
  • 79