My role as a Systems Engineer here at lockstep revolves mostly around networking and firewall design and implementation. However, in addition to that, I do a lot of automation scripting. I script almost entirely in powershell, so I wanted to find a way to talk to the Palo Alto firewalls from powershell. The first option was to use putty/plink to just run commands and parse the output; this doesn’t work very well due to limitations in plink. Luckily, Palo Alto Networks firewalls provide a pretty nice RESTful api. So I started working on a powershell module for this purpose and I’m happy to introduce poweralto!
Poweralto is written entirely in native powershell and is completely open source. Today, I’m going to go over how it works and a couple of my favorite cmdlets.
First, a little on the PA api. Every api call has a type and an action, usually there is also an xpath, and sometimes and element. Any call that isn’t generating your api token also contains a key. The following describes these components briefly:
- type: what kind of request is it; keygen, config, op, report, export, import, log, or user-id
- action: these differ based on the type; show, get, set, edit, delete, rename, clone, move, etc…
- xpath: this is an xml path to the portion of the config you want to work with
- element: this would refer to the node in the xml that you’re attempting to edit
- key: your generated api key
Access to the RESTful api is accomplished over http or https. In order to do this in powershell, I use a .net call to the System.Net.Webclient class.
$WebClient = New-Object System.Net.WebClient
$url = "https://url_to_api_call"
$WebClient.DownloadString($url)
These are all the thing you need to communicate between powershell and the PA. Now lets do some stuff. First thing you need to do is generate your API key. This is done by issuing the following call:
http(s)://hostname/api/?type=keygen&user=username&password=password
This will return a string that is your key to use for any other calls. Now, you could do that and manually provide that key to all your future scripts. Or, you could use poweralto! The first cmdlet you’ll want to use in any script is Get-PaConnectionString. All you need to do is provide it with the ip/hostname of your PA, it will prompt your creds and return the beginning of a valid api call url.
C:\> Get-PaConnectionString 10.10.42.73
https://10.10.42.73/api/?key=LUFRPT1SanJaQVpiNEg4TnBkNGVpTmRpZTRIamR4OUE9Q2lMTU
JGREJXOCs3SjBTbzEyVSt6UT00
In addition to returning the string, Get-PaConnectionString will also add it to a global variable ($global:PaConnectionArray) that all the other cmdlets know to look in for connections. This is an array so you can run the cmdlet multiple times against multiple systems and easily script commands across all of them at once.
So, now you’ve got yourself a valid way to connect, you need only append the rest of an api call url string to this and you’re in business. Of course, there’s no reason to do that yourself. Next up, we have Send-PaApiQuery, as the name suggests, this function is what I use to send all my queries. The rest of the cmdlets are simply fancy ways to use this one. Don’t get me wrong, they’re cool, they do things with the data, add in error checking, progress bars, etc… But the meat of this module is right here.
Currently you can perform any and all api queries with this cmdlet except for: import, log and user-id types, or anything else that is going to send a file to the PA. This is mostly because the WebClient class hasn’t been cooperating with me on that front. But I do intend to get that working in the future. So here’s a few examples:
$Interfaces = Send-PaApiQuery -config show -xpath "/config/devices/entry/network/virtual-router/entry[@name='default']/interface"
This query will return the following xml:
or in powershell:
C:\> $interfaces.response.result.interface
member
——
{ethernet1/1, ethernet1/2, ethernet1/3, ethernet1/4…}
View currently logged in admins:
C:\> $admins = Send-PaApiQuery -op "<show><admins></admins></show>"
C:\> $admins.response.result.admins.entry
admin : admin
from : 10.10.42.11
type : Web
session-start : 12/28 10:09:06
idle-for : 00:00:00s
admin : admin
from : 10.10.42.11
type : Web
session-start : 12/28 09:39:47
idle-for : 00:00:38s
admin : admin
from : 10.10.42.11
type : Web
session-start : 12/28 10:09:04
idle-for : 00:40:13s
Commit the current candidate config:
C:\> $commit = Send-PaApiQuery -Commit
C:\> $commit.response.result
msg job
— —
msg 133
So there you go, I’m sure you can see how this can be used in your scripts to make some pretty cool things happen automatically. This is just a small subset of what poweralto is capable of, there are currently 16 cmdlets and I’ve been adding more every couple of weeks. Be sure and checkout poweralto.com for the full skinny. I’d certainly welcome any ideas or issues you run into, just submit them to my github.