Bulk Addition of IP Address Objects On Fortigate using CSV, and PowerShell

During a recent redesign of a large Fortigate deployment I needed to be able to import large numbers of IP address objects into the new build.  Simply copying the configuration to the new box was out of the question as there were just as many Objects buried in the configuration that were not wanted/needed in the new build.

I had a spreadsheet developed listing everything I needed so I built this simple PowerShell script that will write a config that can be pasted into the Fortigate CLI.  It builds the Objects, and imports a comment for each to add clarity down the road, when an administrator needs to know what an object is for.  It also provides the option to create an address group and apply all of the objects to that group, and again a Comment is created on the group object as well.

This script can save a large amount of time on a rebuild, or new Fortigate deployment.  It is also a great help if you just want to add a bunch of Objects and group them, and do things consistently and quickly.

Script Walk Through:

The Script Looks for a CSV file named Addresses.csv in the same folder as the script. The file would have the following column Headings: Name,Address,Mask,Comment as shown in the screen below:

Running the Script in PowerShell will ask a few basic questions:

  1. Do you Use VDOM’s
  2. What is the Name of the VDOM you are adding the Objects to (Case Sensitive)
  3. Do you want to create a group for these Objects, If yes it asks for a group name and comment.

 

 

 

 

The Script Builds the configuration and dumps it to a text file.  It will then ask if you would like to open it in notepad.

 

The file content can be copied from Notepad and pasted into the Fortigate CLi using your favorite SSH client

 

 

 

 

 

Notes:

  • Currently the script only creates Subnet Objects, however I am looking to build the capability of it checking the address and if it looks like a FQDN it would create and FQDN object instead.

Script Contents:


#############################################################
#
# Script: Create-AddressObjects.PS1
# Description: This Script will Read a CSV file Included In
# In the folder with the script. Currently Hard Coded to
# ".\Addresses.csv". you will also be prompted to provide a
# Name and Comment info for any group that you want to create
# for these new adddress objects.
#
#
#
#
#############################################################
#Make Script location the current folder
Split-Path -parent $MyInvocation.MyCommand.Definition | Set-Location

function Answer-YesNo {
#Function Returns Boolean output from a yes/no question
#
# Usage: Answer-YesNo "Question Text" "Title Text"
#
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes",""
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No",""
$choices = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no)
$caption = "Warning!" #Default Caption
if ($args[1] -ne $null){
$caption = $args[1]} # Caption Passed as argument
$message = "Do you want to proceed" #Default Message
if ($args[0] -ne $null){
$message = $args[0]} #Message passed as argument
$result = $Host.UI.PromptForChoice($caption,$message,$choices,0)
if($result -eq 0) {return $true}
if($result -eq 1) {return $false}
}
clear
Write-Host -ForegroundColor Green "
#############################################################################
#
# FORTIGATE 5.X / 6.x ADDRESS OBJECT BULK IMPORT SCRIPT GENERATOR
#
# Ver. 1.2 / August 18 2018
# Author: Dan Parr /dparr@granite-it.net
#
# This Script is provided without warranty of any kind.
# Use at your own discretion.
#
#############################################################################

"

$VDOMName= ""
$ScriptStart = ""
$UseVDOMs = Answer-YesNo "Does The Fortigate Configured with VDOMs?" "VDOM Configuration"
If ($UseVDOMs -eq $True){
#VDOM Names are Case Sensitive Using the wrong Case could create a new vdom in the CLI
$VDOMName = Read-Host "Please Enter VDOM Name (!!Case Sensitive!!):"
$ScriptStart = "
config vdom
edit $VDOMName"}
$MakeGroup = Answer-YesNo "Will you be creating a group for the imported Objects?" "Please Provide a Y or N Answer:"
$AddressObjects = Import-Csv .\Addresses.csv
$Script = "
$ScriptStart
config firewall address
"
$MemberList = ""
If ($MakeGroup -eq $true){
$GroupName = Read-Host -Prompt "
Please Enter the Name of the Object Group You Wish to Create
(NOTE:Avoid Using Spaces)"
$GroupComment = Read-Host -Prompt "
Enter A Comment Describing this Group
(ex. `"Webserver: dparr/Aug 4, 2016`")"
$GroupScript = "
$ScriptStart
config firewall addrgrp
edit `"$GroupName`"
set member"
}
$AddressObjects | foreach {
$Addr = $_.Address
$Name = $_.Name.substring(0,1).toupper()+$_.Name.substring(1).tolower()
$Mask = $_.Mask
$Comment = $_.Comment

$Script += "
edit `"$Name`"
set subnet $Addr $Mask
set comment `"$Comment`"
next"
if ($MakeGroup -eq $true){
$MemberList += " `"$Name`""}
}
$Script += "
end"
if ($MakeGroup -eq $true){
$GroupScript += "$MemberList
set comment `"$GroupComment`"
next
end"
}
Write-Host $Script
$Script > .\AddressScript.txt
$GroupScript >> .\AddressScript.txt
Clear

If ((Answer-YesNo "The CLI Script Has been Written to .\AddressScript.txt Would you like to open this file in notepad now?" "Open CLI Script File?") -eq $true){

Notepad .\AddressScript.txt
}

Script and CSV can be Downloaded From Here

Advertisements

Windows Powershell Script to Collect CDP and LLDP Information

Often as a Network administrator I find myself trying to determine what port, of which switch does a network drop connect back to.  I may need this information for VLAN changes etc.  I have a fluke Etherscope that has a CDP test but it is older and will not communicate with new non-cisco gear.

I have looked unsuccessfully for a simple tool to gather this information for me.  Every project I looked at on GitHub or Sourceforge seemed ill maintained and buggy.  I decided that I could use a Capture filter in Wireshark to capture CDP and LLDP packets. This succeeds in getting the info.  But reading through all the info in the packets, and expanding all the parts of the tree, is a pain.  I decided to simplify this by having a powershell script collect the information using TShark.exe and then parsing the output for the information I wanted to display.

This script requires that a recent version of Wireshark be installed on the system running the script along with the optional tshark components.

I am sure that some of the code here could be improved and welcome comments and suggestions.

############################################################################
# Script: PortCheck.ps1
#
# Description: Listens for CDP and LLDP Displays Switch Port Information
# For the Selected Interface
#
# Author: Dan Parr / 2016
#
# Version: 1.4
#
# NOTE: Script Requires a Recent Version of Wireshark to be installed in the
# Default program files directory
############################################################################


Function Process-CDP{

#This Function Pulls some info from the CDP Packet blob To Display to the User
#And Returns the display string. Could be expanded to Include any other details
#contained in the packet.

$Device = $args[0] | Select-String -Pattern "Device ID: " -Encoding Unicode
$Platform = $args[0] | Select-String -Pattern "Platform: " -Encoding Unicode
$IP = $args[0] | Select-String -Pattern "IP Address: " -Encoding Unicode
$Interface = $args[0]| Select-String -Pattern "Port ID: " -Encoding Unicode
$VLanID = $args[0]| Select-String -Pattern "Native VLAN: " -Encoding Unicode

$D = $Device[0].tostring().trim().replace("Device ID: ","Switch Name: ")
$P = $Platform[0].tostring().trim().replace("Platform: ","Switch Description: ")
#Truncate Platform information if needed

if ($P.lenght -gt 88){
$P = $P.substring(0,87).trim() + " (Truncated...)"}

$I = $IP[0].tostring().trim().replace("IP Address: ","Switch IP Address: ")
$V = $VLanID[0].tostring().trim().replace("Native VLAN: ","Current VLAN Assignment: ")
$Int = $Interface[0].tostring().trim().replace("Port Id: ","Switch Port: ")

$Response = "
######################################################
CDP information Collected
######################################################

$D
$Int
$I
$V

$P

######################################################"

$Response
}

Function Process-LLDP{

#This Function Pulls some info from the CDP Packet blob To Display to the User
#And Returns the display string. Could be expanded to Include any other details
#contained in the packet.

$Device = $args[0] | Select-String -Pattern "System Name: " -Encoding Unicode
$IP = $args[0] | Select-String -Pattern "Management Address: " -Encoding Unicode
$Platform = $args[0] | Select-String -Pattern "^\s*System Description" -Encoding Unicode
$Interface = $args[0]| Select-String -Pattern "Port ID: " -Encoding Unicode
$VLanID = $args[0]| Select-String -Pattern "Port VLAN Identifier: " -Encoding Unicode

$D = $Device[0].tostring().trim().replace("System Name: ","Switch Name: ")
$P = $Platform[0].tostring().trim().replace("System Description =","Switch Description:")
#Truncate Platform Info if needed
if ($P.length -gt 88){
$P = $P.substring(0,87).trim() + " (Truncated...)"}

$V = $VLanID[0].tostring().trim().replace("Port VLAN Identifier: ","Current VLAN Assignment: ")

$I = $IP[0].tostring().trim().replace("Management Address: ","Switch IP Address: ")
$Int = $Interface[0].tostring().trim().replace("Port Id: ","Switch Port: ")

$Response = "
######################################################
LLDP information Collected
######################################################

$D
$Int
$I
$V

$P

######################################################"

$Response

}

### MAIN SCRIPT ###

Clear
Write-Host -ForegroundColor Green "
#############################################################################
#
# PortCheck: CDP and LLDP Scanner
#
# Ver. 1.4 / Jan 26 2017
# Author: Dan Parr
#
# This Script is provided without warranty of any kind.
# Use at your own discretion.
# This Script Requires Wireshark (with TShark) to be installed
#
#############################################################################
"

#Utilize TShark.exe to display interfaces
$Command = "C:\Program Files\Wireshark\tshark.exe"
$InterfaceOptions = @('-D')

Write-Host "Collecting Adapters:"
#Execute Tshark.exe and pass an array of arguments
& $Command $InterfaceOptions

#Have user Input the interface ID number
$IntID = Read-Host -Prompt "Please Enter The Interface ID# That You want to Monitor"

##########################################################################
#TShark Command Line Options
##########################################################################

#Define a Capture Filter to Capture only CDP or LLDP packets
$CaptureFilter = "(ether proto 0x88cc) or ( ether host 01:00:0c:cc:cc:cc and ether[16:4] = 0x0300000C and ether[20:2] == 0x2000)"
#Define How long TShark will Wait in Seconds for a CDP or LLDP packet
$Duration = "120"

#Other CMD Options used:
#-c: Count of Packets to Capture
#-V: Collect Packtet Details
#-Q: Only Log true errors to stderr (quieter than -q)


#Found some possible unneeded command line options ('-S','-l')
#$Options= @('-i',"$IntID",'-f',$CaptureFilter,'-a',"duration:$Duration",'-S','-l','-c','1','-V','-Q')

$Options= @('-i',"$IntID",'-f',$CaptureFilter,'-a',"duration:$Duration",'-c','1','-V','-Q')

###########################################################################

Clear
Write-Host -ForegroundColor Green "
Listening for CDP or LLDP Advertisements on the Wire
This May Take up to 90 Seconds
"
#Execute TShark Command and pass an array of arguments. Use STDOut to populate Variable
$CDP = & $Command $Options
$CDP > .\Packet.txt
#Determine the type of Data Received and Act on it
If ((Select-String -Pattern "Cisco Discovery Protocol" -InputObject $CDP).length -gt 0) {
Write-Host -ForegroundColor Yellow "Received CDP Annoucement:
"
$CollectedInfo = Process-CDP $CDP
}
ElseIf ((Select-string -Pattern "Link Layer Discovery Protocol" -InputObject $CDP).length -gt 0) {
Write-Host -ForegroundColor Yellow "Found LLDP Annoucement on the Wire:
"
$CollectedInfo = Process-LLDP $CDP
}
Else {
Write-Host -ForegroundColor Magenta "No CDP Or LLDP info Received"
}
Set-Clipboard $CollectedInfo
Write-Host -ForegroundColor Green $CollectedInfo
Write-Host -ForegroundColor Yellow "Note: This information has been copied to the Windows clipboard
"
Read-host -Prompt "Press Enter to End the Script and close"