Barracuda Load Balancer- Powershell

Working on my Powershell skills, I was playing around with a Barracuda Load Balancer and noticed it supported some APIs which is kind of cool. At first I was playing around with it in postman and got to login and put some servers in maintenance mode, but then thought it would be really neat if I could get this working in Powershell, that way us humans can just run a script and even thinking in the "future" maybe have some automated process (a.k.a AI) handle this for us. ;) So in this post I'll talk about the script I created and some of the small challenges I had with this overall it was kind of neat putting this together. TLDR: Here is the script if you don't want to read:

 1# Barracuda Load Balancer Powershell Script
 2# Minimum version of Powershell is 6.0.4 – Can download stable releases @ https://github.com/PowerShell/PowerShell
 3# Puts servers in Maintenance, Disable or Enable status
 4# Put the URI API of the LB (example: "https://192.168.1.5/restapi/v2")
 5$uri = ""
 6# Put the group name, usually its "default" unless you have something different
 7$groupname = "default"
 8# Put the service name you would like to modify, you can find this in the LB going to BASIC->Services
 9$servicename = ""
10# Put the server you would like to modify, you can find the names of the servers under BASIC->Services
11# You can add additional servers to this list if you want to modify multiple servers at once, add additional variables
12$realserver1 = ""
13$realserver2 = ""
14# What status would you change the servers in the LB to? Valid values are enable, disable, or maintenance. Values are lower-case sensitive
15$status = "enable"
16# Login into Barracuda you will get a prompt to login, currently only local accounts work for API. 
17$credential = Get-Credential Message "Please type a username and password to login into the Barracuda LB"
18$password = $credential.GetNetworkCredential().password
19$username = $credential.GetNetworkCredential().username
20# POST Request to Login into Barracuda
21$authUrl_Body = @{
22    password = $password
23    username = $username
24}
25# Convert this request into JSON and call it $jsonurlbody
26$jsonauth_Body = $authUrl_Body | ConvertTo-Json
27#Grab the token to and keep note of it, and use to login into Barracuda from now on
28$auth = Invoke-RestMethod Uri "$uri/login" ContentType "application/json" Method POST Body $jsonauth_Body SkipCertificateCheck
29$authtoken = $auth.token
30# Barracuda only supports username only no password required when we have the token put this into a PSCredential to null the password
31$lbcred = New-Object System.Management.Automation.PSCredential ("$authtoken", (new-object System.Security.SecureString))
32# POST Request to put a server into Maintenance, Enable, or Disable
33$statusURL_Body = @{
34    status = $status
35}
36# Convert this request into JSON and call it $jsonstatus_Body
37$jsonstatus_Body = $statusURL_Body | ConvertTo-Json
38# Put $realserver1 into $status "status"
39Invoke-RestMethod Uri "$uri/virtual_service_groups/$groupname/virtual_services/$servicename/servers/$realserver1" Credential $lbcred Authentication Basic ContentType "application/json" Method PUT Body $jsonstatus_Body SkipCertificateCheck | ConvertTo-Json
40# Put $realserver2 into $status "status"
41Invoke-RestMethod Uri "$uri/virtual_service_groups/$groupname/virtual_services/$servicename/servers/$realserver2" Credential $lbcred Authentication Basic ContentType "application/json" Method PUT Body $jsonstatus_Body SkipCertificateCheck | ConvertTo-Json
42# If you have additional servers copy the command above and replace it with a different variable

The first thing I was stuck on was the way Barracuda uses the API token, I was able to have to load balancer give me the token but Powershell also wanted a password with that API token. Barracuda only uses the username as the token to login. So I needed to configure Powershell to null the password when logging with the API token. A quick search on the web led me to create the $lbcred variable.

Another small gotcha was when using the default version of Powershell on Windows 10 I was having a problem with the login and really didn't want to create a curl header or anything like that. I also wanted to keep the username and password out of the script. When you run the script it will ask you what the username and password is and use that while the script it running, I thought it would be easier. So when researching this, and I didn't actually know this but there are different updated versions of Powershell which are available on GitHub and they work different operating systems besides Windows. So that's pretty cool, and also tells you how much I pay attention to Powershell :).

When looking at the release notes for Powershell 6.0.4 they made some modifications to the Invoke-RestMethod command for -Authentication switch so I downloaded Powrshell 6.0.4 and then found it does not work with Powershell ISE. :(

Which is what I have been using and I now needed to download Visual Studio Code which is a free download and install  the Powershell extenstion so that I could run it within that program. Again just goes to show you how much I know about this stuff. After all of that I was able to login into the load balancer using the token API!

The last command I just needed a json to tell the load balancer want I wanted to do with the servers, I could put them in maintenance, enable or disable status and if I had more than one server in the load balancer, I just copied the command again and used a different variable for each server. After that I was able to put servers in a different via Powershell!


Static Comments:

Ryan -

Jeremy, That token is usually only good for a limited time, its best to get a new one each time you run the script. Ryan


Jeremy Edwards -

I also already generated a token, so that part isn't necessary for the script to generate if there is a way to incorporate the token into a field.


Ryan -

Jeremy, That error tells me that you are connecting over HTTP instead of HTTPS, I would use HTTPS when doing anything that involves passwords, and really anything nowadays. If you read the error message it tells you what you need to do if you want to use HTTP add the -AllowUnencryptedAuthentication to the Invoke-RestMethod. There a multiple ways to put the username and password in the script, a common way is to create a key file and a password file. A search engine is your friend :) The reason I did not use it in this script is I didn't have a good place to store to the the password or key file securely. By having the username and password prompt it also gives you time to cancel the script in case you run it by accident... Ryan


Jeremy Edwards -

Ryan, I updated to PowerShell 6.1.2 and ran the script again. That did fix the username/password issue, but I'm still getting an error. Also, how would we run this if we wanted the username and password to be kept in the script? My boss wants it fully automated with no user intervention. Invoke-RestMethod : The cmdlet cannot protect plain text secrets sent over unenc rypted connections. To suppress this warning and send plain text secrets over un encrypted networks, reissue the command specifying the AllowUnencryptedAuthentic ation parameter. At C:\curltest.ps1:38 char:1 + Invoke-RestMethod -Uri "$uri/virtual_service_groups/$groupname/virtua ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (Microsoft.Power...stMethodCommand:In vokeRestMethodCommand) [Invoke-RestMethod], ValidationMetadataException + FullyQualifiedErrorId : WebCmdletAllowUnencryptedAuthenticationRequiredExcepti on,Microsoft.PowerShell.Commands.InvokeRestMethodCommand


Ryan -

Hey Jeremy, For that Invoke-RestMethod to work with the -SkipCertificateCheck switch you need to at least have Powershell 6.0.0. https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-6 For this script to work you need have Powershell 6.0.4 at least because of the -Authentication switch. Microsoft made some modifications to it and this script uses those modifications. So use Powershell 6.0.4 or above. Ryan


Jeremy Edwards -

Congrats! This almost works. Invoke-RestMethod : A parameter cannot be found that matches parameter name 'SkipCertificateCheck'. At C:\curltest.ps1:27 char:111 + ... $jsonauth_Body -SkipCertificateCheck + ~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Invoke-RestMethod], ParameterBindingException + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.InvokeRestMethodCommand Invoke-WebRequest : A parameter cannot be found that matches parameter name 'Authentication'. At C:\curltest.ps1:38 char:123 + ... ential $lbcred -Authentication Basic -ContentType "application/json" -Method PUT ... + ~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Invoke-WebRequest], ParameterBindingException + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.InvokeWebRequestCommand