Regex Match Multi-line Cisco Switch Config

Welcome Forums General PowerShell Q&A Regex Match Multi-line Cisco Switch Config

Viewing 4 reply threads
  • Author
    Posts
    • #194057
      Participant
      Topics: 1
      Replies: 1
      Points: 14
      Rank: Member

      Here’s the goal:

      • Using PowerShell, parse a multiple Cisco switch configs and:
      • Extract the hostname
      • Extract the name of all interfaces
      • If the interface description exists, extract
      • If the interface ip address exists, extract
      • If the ip helper exists, extract

      Here’s a sample string:

      !
      hostname SOME-HOSTNAME-01
      !

      !
      interface Loopback0
      ip address 192.168.1.1 255.255.255.255
      ip ospf network point-to-point
      !
      interface FastEthernet0/0
      description Some-Sample-DescriptionWithOdd/[email protected]
      ip address 192.168.1.2 255.255.255.0
      ip helper-address 192.168.1.3
      ip helper-address 192.168.1.4
      duplex auto
      speed auto
      !
      interface FastEthernet0/1
      no ip address
      shutdown
      duplex auto
      speed auto
      !

      Here’s the script sample:

      $config = Get-Content -Path $configPath

      $hostname = $config| Select-String -Pattern ‘(?smi)^hostname (?<hostname>\S*)’

      $psobject = New-Object -TypeName PSObject

      $psobject | Add-Member -MemberType NoteProperty -Name hostname -Value ($hostname.matches.groups | Where name -eq ‘hostname’).value

      $interfaceStatements = $config| Select-String -Pattern ‘(?m)^interface[^!]*’ -AllMatches | Foreach {$_.Matches} | Foreach {$_.Value}

       

      When I return the value of $interfaceStatements, I was expecting to see a multiline string that ends right before the ‘!’, but I’m only seeing the first line in each:

      interface Loopback0
      interface FastEthernet0/0
      interface FastEthernet0/1

    • #194195
      Senior Moderator
      Topics: 5
      Replies: 133
      Points: 706
      Helping Hand
      Rank: Major Contributor

      The problem is that by default Get-Content reads each line of an input file into a new element in an array, so your $config variable is actually an array with each line as an element. You can verify this by adding

      $config.Count

      after the Get-Content line.
      With your example input, this returns 23. Your Select-String regex is working correctly, but it is only getting the lines of the input file one at a time as separate array elements, rather than the entire block of text all at once.

      You can fix this by adding the -Raw parameter to Get-Content:

      $config = Get-Content -Path $configPath -Raw

      In my testing, this returned the expected output (with no other changes to the script):

      interface Loopback0
      ip address 192.168.1.1 255.255.255.255
      ip ospf network point-to-point
      
      interface FastEthernet0/0
      description Some-Sample-DescriptionWithOdd/[email protected]
      ip address 192.168.1.2 255.255.255.0
      ip helper-address 192.168.1.3
      ip helper-address 192.168.1.4
      duplex auto
      speed auto
      
      interface FastEthernet0/1
      no ip address
      shutdown
      duplex auto
      speed auto
    • #194213
      Participant
      Topics: 13
      Replies: 1683
      Points: 2,849
      Helping Hand
      Rank: Community Hero

      Try something like this:

      $txt = @"
      !
      hostname SOME-HOSTNAME-01
      !
      ...
      !
      interface Loopback0
      ip address 192.168.1.1 255.255.255.255
      ip ospf network point-to-point
      !
      interface FastEthernet0/0
      description Some-Sample-DescriptionWithOdd/[email protected]
      ip address 192.168.1.2 255.255.255.0
      ip helper-address 192.168.1.3
      ip helper-address 192.168.1.4
      duplex auto
      speed auto
      !
      interface FastEthernet0/1
      no ip address
      shutdown
      duplex auto
      speed auto
      !
      "@
      
      #Emulate Get-Content
      $config = $txt -split [environment]::NewLine
      
      $hostname = $config | Select-String -Pattern '^hostname (?<HostName>.*)$'
      $interface = $config | Select-String -Pattern '^interface (?<Interface>.*)$'
      
      [pscustomobject]@{
          HostName = $hostname.Matches[0].Groups['HostName'].Value
          Interface = $interface.Matches | foreach {$_.Groups['Interface'].Value}
      }

      Output:

      HostName         Interface                                    
      --------         ---------                                    
      SOME-HOSTNAME-01 {Loopback0, FastEthernet0/0, FastEthernet0/1}
      
    • #194243
      Participant
      Topics: 0
      Replies: 1
      Points: 5
      Rank: Member

      To throw another solution out there:

      $config = Get-Content -Path C:\Users\jneedle\Desktop\testnote.txt -Raw
      
      $information = @()
      
      $hostname = ($config| Select-String -Pattern "(?<=hostname ).+").Matches.Value
      
      $interfaces = ($config | Select-String -Pattern "(?smi)^interface.+?(?=!)" -AllMatches).Matches.Value
      
      Foreach($interface in $interfaces) {
      $result = "" | Select HostName, Interface, Description, IPAddress, IPHelper
      $result.HostName = $hostname
      $result.Interface = ($interface | Select-String "(?<=interface.).+").Matches.Value
      $result.Description = ($interface | Select-String "(?<=description.).+").Matches.Value
      $result.IPAddress = ($interface | Select-String "(?<=ip address.).+").Matches.Value
      $result.IPHelper = ($interface | Select-String -Pattern "(?<=ip helper.).+" -AllMatches).Matches.Value -join "`n"
      $information += $result
      }

      Output when returning information:

      HostName : SOME-HOSTNAME-01
      Interface : Loopback0
      Description : 
      IPAddress : 192.168.1.1 255.255.255.255
      IPHelper :
      
      HostName : SOME-HOSTNAME-01
      Interface : FastEthernet0/0
      Description : Some-Sample-DescriptionWithOdd/[email protected]
      IPAddress : 192.168.1.2 255.255.255.0
      IPHelper : address 192.168.1.3
      address 192.168.1.4
      
      HostName : SOME-HOSTNAME-01
      Interface : FastEthernet0/1
      Description : 
      IPAddress : 
      IPHelper :
    • #194309
      Participant
      Topics: 1
      Replies: 1
      Points: 14
      Rank: Member

      Thank you all for the replies.



      @Grokkit
      , that -Raw was exactly what I needed. I got it working now.

      @Rob Simmers, that’s a great way to nest each of the properties of the interface

      @JoshuaNeedle87, that’s about exactly what I ended up finishing up this morning, once that -Raw was in there.

      Hope you guys have a great Christmas coming up!

Viewing 4 reply threads
  • The topic ‘Regex Match Multi-line Cisco Switch Config’ is closed to new replies.