Public/Test-PANRule.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
Function Test-PANRule {
<#
.SYNOPSIS
  This will run the operations passed and retun the result in xml
 
.DESCRIPTION
  This runs the command test security-policy-match with the filters provided.
 
.PARAMETER from
    Source Zone
 
.PARAMETER to
    Destination Zone
 
.PARAMETER source
    Source IP address
 
.PARAMETER destination
    Destination IP address
 
.PARAMETER protocol
    IP protocol number, tcp = 6, udp = 17, icmp = 1, sctp = 132
 
.PARAMETER destination_port
    Destination port for tcp, udp, or sctp
 
.PARAMETER application
    Application that will eventually choosen
 
.PARAMETER source_user
    Source user if applicable
 
.PARAMETER category
    URL Category if applicable
 
.PARAMETER Show_All
    Flag to show all results
 
.PARAMETER Addresses
    This is a set of addresses to run the command on, The firewalls must have the same master key for this to work
 
.PARAMETER Key
    This is a key to just use
 
.PARAMETER Tag
    This is the shortname to use to reference auth information and addresses
 
.PARAMETER Path
   Path to the file that has the tag data
 
.EXAMPLE
    The example below will return all rules that could match a ping packet from the inside to outside
    PS C:\> $result = Test-PANRule -from "Inside" -to "Outside" -source '192.0.2.2' -destination '1.1.1.1' -protocol 1 -category 'any' -Show_All
 
.NOTES
    Author: Steve Borba https://github.com/sjborbajr/PAN-Power
    Last Edit: 2019-04-05
    Version 1.0 - initial release
    Version 1.0.1 - Updating descriptions and formatting
    Version 1.0.3 - Remove Direct Credential option
    Version 1.0.5 - Add SkipCertificateCheck for pwsh 6+
    Version 1.0.6 - added Edit config and commit and cert check skip for 5
 
#>

  [CmdletBinding()]
  Param (
    [Parameter(Mandatory=$False)]  [string]    $from,
    [Parameter(Mandatory=$False)]  [string]    $to,
    [Parameter(Mandatory=$true)]   [string]    $source,
    [Parameter(Mandatory=$true)]   [string]    $destination,
    [Parameter(Mandatory=$true)]   [int]       $protocol,
    [Parameter(Mandatory=$False)]  [int]       $destination_port,
    [Parameter(Mandatory=$False)]  [string]    $application,
    [Parameter(Mandatory=$False)]  [string]    $source_user,
    [Parameter(Mandatory=$False)]  [string]    $category,
    [Parameter(Mandatory=$False)]  [Switch]    $Show_All,
    [Parameter(Mandatory=$False)]  [Switch]    $SkipCertificateCheck,
    [Parameter(Mandatory=$False)]  [string]    $Tag,
    [Parameter(Mandatory=$False)]  [string]    $Path = '',
    [Parameter(Mandatory=$False)]  [string[]]  $Addresses,
    [Parameter(Mandatory=$False)]  [string]    $Key
  )

  #Get Data from panrc based on tag, an empty tag is "ok" and returns data
  $TagData = Get-PANRCTagData -Tag $Tag -Path $Path

  #If addresses were not passed, use addresses from panrc
  If ($Addresses -eq '' -or $null -eq $Addresses) {
    If ($TagData.Addresses) {
      $Addresses = $TagData.Addresses
    } else {
      "No Addresses Found"
      Return
    }
  }

  #Use other key if passed
  If ($Key.Length -gt 0) {
    $Auth = "key=$Key"
  } else {
    If ($TagData.Auth) {
      $Auth = $TagData.Auth
    } else {
      "No Authentication Information Found"
      return
    }
  }

  #Build the command
  $Command = ''
  If ($from)             { $Command =             "$Command<from>$from</from>"                         }
  If ($to)               { $Command =               "$Command<to>$to</to>"                             }
  If ($source)           { $Command =           "$Command<source>$source</source>"                     }
  If ($destination)      { $Command =      "$Command<destination>$destination</destination>"           }
  If ($protocol)         { $Command =         "$Command<protocol>$protocol</protocol>"                 }
  If ($destination_port) { $Command = "$Command<destination-port>$destination_port</destination-port>" }
  If ($application)      { $Command =      "$Command<application>$application</application>"           }
  If ($source_user)      { $Command =      "$Command<source-user>$source_user</source-user>"           }
  If ($category)         { $Command =         "$Command<category>$category</category>"                 }
  If ($Show_All)         { $Command =         "$Command<show-all>yes</show-all>"                       }
  $command = "<test><security-policy-match>$Command</security-policy-match></test>"

    #Run the command and get the results
  $Type = "op"
  $Return = @()
  ForEach ($Address in $Addresses) {
    $HashArguments = @{
      URI = "https://"+$Address+"/api/?type=$Type&cmd=$Command&"+$Auth
    }
    If ($SkipCertificateCheck) {
      If ($Host.Version.Major -ge 6) {
        $HashArguments += @{SkipCertificateCheck = $True}
      } else { Ignore-CertificateValidation }
    }
    $Response = Invoke-RestMethod @HashArguments
    if ( $Response.response.status -eq 'success' ) {
      $Return = $Return + $Response.response
    } else {
      $Return = $Return + $Response.response
      If (1 -eq 2) { 
        #Need flag to determine if we should quit on first error
        $Return
        Return
      }
    }
  }

  #Pass the data back
  $Return
  Return
}