Managing Citrix NetScaler by email with Octoblu and NITRO

Managing Citrix NetScaler by email with Octoblu and NITRO

Managing Citrix NetScaler by email with Octoblu and NITRO

This post has already been read 2716 times!

“It would be great if we could enable the developers to enable and disable their own Citrix NetScaler Load Balancer vServers by just sending an e-mail in.  It would mean they could manage their own objects on the NetScaler without any input from IT and without the need to provide access to the NetScaler Itself”

This was the question asked by Carl Behrent the other day, and I have to say, it got me thinking.  Now I know this could probably be done with NetScaler Management and Analytics but I wanted to use Octoblu.  Why you ask?  Well because you can, and its cool :o)

So, this post will show you how to manage your NetScaler vServers from an email using Octoblu, Powershell and NITRO.

First thing your going to need is a flow.  Head over to your Octoblu portal and create a new flow.  Give it a meaningful name.

Next add a new trigger to that flow and name that accordingly

If you look on the right hand side you will see the email address required to start the trigger.  Now this could be used but giving that email address to any developer (no matter how smart) would be a nightmare to remember.  Set up a forwarder for an easier to remember address.

In my case I am hosting my email in Office 365, so I have set up octoblu@bretty.me.uk to forward tot he triggers email address

Test that your email forwarding is working by sending an email to your new address and checking the debug output in the Octoblu console.  You will see all the information about who and what was send via email to the trigger

Next you will need a Powershell connector to execute the local Powershell scripts that will manage the NetScaler using NITRO

NOTE: If you do not know how to set up a connector please take a look at my previous article on Octoblu and NetScalers – this will walk you through the process required

Next you will need to copy and paste the script at the bottom of this post and put it into a file called netscaler-management.ps1 in a directory on the same server as the Octoblu Connector for Powershell.  In my case I have it in c:\scripts\octoblu

There are 5 main functions in the script

  • NS-Login
  • NS-Logout
  • NS-EnablevServer
  • NS-Disable-vServer
  • NS-Octoblu-email-manage

Back in Octoblu you are going to need a function to strip the subject and sender from all the information that will come in with the email

Add a Function and enter the following code

msg.subject = msg.payload.subject;
msg.sender = msg.payload.sender;
return msg;

This will strip the subject line and sender information and put it in the msg variable

Next add your Powershell Connector and link the function to that

To use the msg variable in Powershell we are going to put the subject and sender into environment variables and send this into Powershell

On the right set up 2 new environment variables called subject and sender and pipe the msg.sender and msg.subject values into them

Set the Powershell thing to execute a script and paste in the following code that will take the subject and sender environment variables, combine them and pass them into the function NS-Octoblu-email-manage

$subject = $env:subject
$sender = $env:sender
$data = $subject + "," + $sender
Import-Module C:\scripts\octoblu\netscaler-management.ps1
NS-Octoblu-email-manage $data

Finally I would like to see the output of what is happening in my monitoring Slack Channel so I have added my monitorbot-post and linked that to the output of the Powershell function.

If you need to know how to set this up please see references in my last post here

Enter the channel you want to post the messages into and set the text to

{{msg.data.stdout}}

That’s it, your ready to test.

Details for Testing

The function will look for the following format in the subject line

keyword,vserver_name,password

There are 2 options for the keyword

  • enable-vserver
  • disable-vserver

The password in the script is set to “password” – make sure you change that to something more complex.

Sender.  In this example I have hard coded the sender dave@bretty.me.uk to be the only email address that can use the function.  In practice this would not be a good thing as you would have to maintain a huge list of names within the function.  This could be modified to look for email attributes for users in a specific Active Directory group or something similar.

You could also add a check for the vServer name, well you should do this really.  This function will enable the user if allowed to enable and disable ANY vServer on the NetScaler, this should be locked down to only the vServers you want to manage by email.

Below is the output from my Slack channel showing the functions carried out by Octoblu.

That’s it, hopefully you will now be able to manage your NetScaler vServers by email.  Below you will find a demo and the script you need to copy into your netscaler-management.ps1 file.

Laters,

b@m

Demo

Script

function NS-Login 
{
<# 
.SYNOPSIS 
 Logs into a Citrix NetScaler.
.DESCRIPTION 
 Logs into a NetScaler ADC and creates a global variable called $NSSession to be used to invoke NITRO Commands.
.PARAMETER NSIP 
 Citrix NetScaler NSIP.
.PARAMETER UserName 
 UserName to be used for login.
.PARAMETER Password
 The Password to be used for Login 
.NOTES 
 Name: NS-Login
 Author: David Brett - Citrix CTP
 Date Created: 15/03/2017
.CHANGE LOG
 David Brett - 15/03/2017 - Initial Script Creation 
.LINK 
 http://bretty.me.uk
#>

[cmdletbinding(
 DefaultParameterSetName = '',
 ConfirmImpact = 'low'
 )]

Param (
 [Parameter(
 Mandatory = $False,
 Position = 0,
 ParameterSetName = '',
 ValueFromPipeline = $True)]
 [string]$NSIP,
 [Parameter(
 Mandatory = $False,
 Position = 1,
 ParameterSetName = '',
 ValueFromPipeline = $True)]
 [string]$UserName,
 [Parameter(
 Mandatory = $False,
 Position = 2,
 ParameterSetName = '',
 ValueFromPipeline = $True)]
 [string]$Password
 )

#Check to see if parameters were passed in, if not then prompt the user for them
 if ($NSIP -eq "") {$NSIP = read-host "Enter NetScaler IP"}
 if ($UserName -eq "") {$UserName = read-host "Enter NetScaler User Name"}
 if ($Password -eq "") {
 $SecurePassword = read-host "Enter NetScaler Password" -AsSecureString
 $BasePassword = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
 $Password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BasePassword)
 }

#Validate That the IP Address is valid
 Validate-IP $NSIP

#Set up the JSON Payload to send to the netscaler
 $PayLoad = ConvertTo-JSON @{
 "login"=@{
 "username"=$UserName;
 "password"=$Password
 }
 }

#Connect to NetScaler
 Invoke-RestMethod -uri "$NSIP/nitro/v1/config/login" -body $PayLoad -SessionVariable saveSession -Headers @{"Content-Type"="application/vnd.com.citrix.netscaler.login+json"} -Method POST

#Build Global NetScaler Session Variable
 $Global:nsSession = New-Object -TypeName PSObject
 $nsSession | Add-Member -NotePropertyName Endpoint -NotePropertyValue $NSIP -TypeName String
 $nsSession | Add-Member -NotePropertyName WebSession -NotePropertyValue $saveSession -TypeName Microsoft.PowerShell.Commands.WebRequestSession

#Return NetScaler Session
 return $nsSession
}

function NS-Logout {
<# 
.SYNOPSIS 
 Logs out of a Citrix NetScaler.
.DESCRIPTION 
 Logs out of a Citrix NetScaler and clears the NSSession Global Variable.
.PARAMETER NSIP 
 Citrix NetScaler NSIP. 
.NOTES 
 Name: NS-Logout
 Author: David Brett - Citrix CTP
 Date Created: 15/03/2017 
.CHANGE LOG
 David Brett - 15/03/2017 - Initial Script Creation 
.LINK 
 http://bretty.me.uk
#>

[cmdletbinding(
 DefaultParameterSetName = '',
 ConfirmImpact = 'low'
 )]

Param (
 [Parameter(
 Mandatory = $False,
 Position = 0,
 ParameterSetName = '',
 ValueFromPipeline = $True)]
 [string]$NSIP
 )

#Validate That the IP Address is valid
 Validate-IP $NSIP

#Check to see if a valid NSSession is active. If not then quit the function
 if ($NSSession -eq "") {
 write-host -ForegroundColor Red "No valid NetScaler session found, quitting"
 break
 }

#Set up the JSON Payload to send to the netscaler
 $PayLoad = ConvertTo-JSON @{
 "logout"=@{
 }
 }

#Logout of the NetScaler
 Invoke-RestMethod -uri "$NSIP/nitro/v1/config/logout" -body $PayLoad -WebSession $NSSession.WebSession -Headers @{"Content-Type"="application/vnd.com.citrix.netscaler.logout+json"} -Method POST

#Clear the Global Variable for the NetScaler Session
 Remove-Variable -name nsSession -Scope global -force
}

function Validate-IP {
<# 
.SYNOPSIS 
 Validate a passed in IP Address.
.DESCRIPTION 
 Validate a passed in IP Address.
.PARAMETER IPAddress 
 IP Address to be validated. 
.NOTES 
 Name: Validate-IP
 Author: David Brett - Citrix CTP
 Date Created: 15/03/2017 
.CHANGE LOG
 David Brett - 15/03/2017 - Initial Script Creation 
.LINK 
 http://bretty.me.uk
#>

[cmdletbinding(
 DefaultParameterSetName = '',
 ConfirmImpact = 'low'
 )]

Param (
 [Parameter(
 Mandatory = $False,
 Position = 0,
 ParameterSetName = '',
 ValueFromPipeline = $True)]
 [string]$IPAddress
 )

if ([BOOL]($IPAddress -as [IPADDRESS])){
 return $True 
 } else {
 write-Host -ForegroundColor Red "$IPAddress is an invalid address - quitting"
 break
 }
}

function NS-DisablevServer {
<# 
.SYNOPSIS 
 Disable a vServer on a NetScaler.
.DESCRIPTION 
 Disable a vServer on a NetScaler.
.PARAMETER vServerName 
 vServerName to be disabled. 
.NOTES 
 Name: NS-DisablevServer
 Author: David Brett - Citrix CTP
 Date Created: 15/03/2017 
.CHANGE LOG
 David Brett - 15/03/2017 - Initial Script Creation 
.LINK 
 http://bretty.me.uk
#>

[cmdletbinding(
 DefaultParameterSetName = '',
 ConfirmImpact = 'low'
 )]

Param (
 [Parameter(
 Mandatory = $False,
 Position = 0,
 ParameterSetName = '',
 ValueFromPipeline = $True)]
 [string]$vServerName,
 [Parameter(
 Mandatory = $False,
 Position = 1,
 ParameterSetName = '',
 ValueFromPipeline = $True)]
 [string]$NSIP
 )

#Check if there is a valid NetScaler session active
 if ($nssession -eq $null) {
 write-host -ForegroundColor Red "NetScaler Login is required to continue, please use NS-Login, quitting"
 break
 }

#Validate that there is a vServer name and a valid NetScaler IP Passed into the function
 if ($vServerName -eq "") {$vServerName = read-host "Enter the vServer name that you want to disable"}
 if ($NSIP -eq "") {$NSIP = read-host "Enter the NetScaler IP that hosts the vServer"}

#Check if the vServer exists and is already disabled
 $Url = "$NSIP/nitro/v1/config/lbvserver/$vServerName"
 $Method = "GET"
 $ContentType = "application/json"

try {
 $vServerStatus = Invoke-RestMethod -uri $Url -WebSession $nsSession.WebSession -ContentType $ContentType -Method $Method
 $CStatus = $vServerstatus.lbvserver.curstate
 } catch {
 $ErrException = $_.Exception.Response.StatusCode.value__
 if ($ErrException -eq 404) {
 write-host -ForegroundColor Red "vServer name is not found, quitting"
 break
 }
 }

if ($CStatus -eq "UP" ) {
 #Set up the NetScaler Url for NITRO
 $Url = "$NSIP/nitro/v1/config/lbvserver?action=disable"

#Set the HTTP Method
 $Method = "POST"

#Set the Request Header for Content Type
 $ContentType = "application/json"
 
 #Set up the JSON Payload to send to the netscaler
 $PayLoad = ConvertTo-JSON @{
 "lbvserver"=@{
 "name"=$vServerName
 }
 }

#Execute the NetScaler Nitro Command and catch the output. If error then break the function
 Invoke-RestMethod -uri $Url -WebSession $nsSession.WebSession -ContentType $ContentType -Body $Payload -Method $Method
 write-host -ForegroundColor Green "$vServerName has been disabled"
 } else {
 #vServer is already disabled - function not required
 write-host -ForegroundColor Red "vServer is already disabled, quitting"
 }
}

function NS-EnablevServer {
<# 
.SYNOPSIS 
 Enable a vServer on a NetScaler.
.DESCRIPTION 
 Enable a vServer on a NetScaler.
.PARAMETER vServerName 
 vServerName to be enabled. 
.NOTES 
 Name: NS-EnablevServer
 Author: David Brett - Citrix CTP
 Date Created: 16/03/2017 
.CHANGE LOG
 David Brett - 16/03/2017 - Initial Script Creation 
.LINK 
 http://bretty.me.uk
#>

[cmdletbinding(
 DefaultParameterSetName = '',
 ConfirmImpact = 'low'
 )]

Param (
 [Parameter(
 Mandatory = $False,
 Position = 0,
 ParameterSetName = '',
 ValueFromPipeline = $True)]
 [string]$vServerName,
 [Parameter(
 Mandatory = $False,
 Position = 1,
 ParameterSetName = '',
 ValueFromPipeline = $True)]
 [string]$NSIP
 )

#Check if there is a valid NetScaler session active
 if ($nssession -eq $null) {
 write-host -ForegroundColor Red "NetScaler Login is required to continue, please use NS-Login, quitting"
 break
 }

#Validate that there is a vServer name and a valid NetScaler IP Passed into the function
 if ($vServerName -eq "") {$vServerName = read-host "Enter the vServer name that you want to disable"}
 if ($NSIP -eq "") {$NSIP = read-host "Enter the NetScaler IP that hosts the vServer"}

#Check if the vServer exists and is already enabled
 $Url = "$NSIP/nitro/v1/config/lbvserver/$vServerName"
 $Method = "GET"
 $ContentType = "application/json"

try {
 $vServerStatus = Invoke-RestMethod -uri $Url -WebSession $nsSession.WebSession -ContentType $ContentType -Method $Method
 $CStatus = $vServerstatus.lbvserver.curstate
 } catch {
 $ErrException = $_.Exception.Response.StatusCode.value__
 if ($ErrException -eq 404) {
 write-host -ForegroundColor Red "vServer name is not found, quitting"
 break
 }
 }

if ($CStatus -ne "UP" ) {
 #Set up the NetScaler Url for NITRO
 $Url = "$NSIP/nitro/v1/config/lbvserver?action=enable"

#Set the HTTP Method
 $Method = "POST"

#Set the Request Header for Content Type
 $ContentType = "application/json"
 
 #Set up the JSON Payload to send to the netscaler
 $PayLoad = ConvertTo-JSON @{
 "lbvserver"=@{
 "name"=$vServerName
 }
 }

#Execute the NetScaler Nitro Command and catch the output. If error then break the function
 Invoke-RestMethod -uri $Url -WebSession $nsSession.WebSession -ContentType $ContentType -Body $Payload -Method $Method
 write-host -ForegroundColor Green "$vServerName has been enabled"
 } else {
 #vServer is already enabled - function not required
 write-host -ForegroundColor Green "vServer is already enabled, quitting"
 }
}

function NS-Octoblu-email-manage ([string]$InputData) {
<# 
.SYNOPSIS 
 Disable a vServer on a NetScaler.
.DESCRIPTION 
 Takes an input comma delimited array and validates that the fields authorise the user to disable a NetScaler vServer.
.PARAMETER Input 
 Comma Delimited list of (trigger word,vServer name,sender,password) 
.NOTES 
 Name: NS-Octoblu-email-manage
 Author: David Brett - Citrix CTP
 Date Created: 16/03/2017 
.CHANGE LOG
 David Brett - 16/03/2017 - Initial Script Creation 
.LINK 
 http://bretty.me.uk
#>

#Take the input value and split into an array
 $InputArray = $InputData.split(",")

#Check if the first item in the array is the keyword disable-vserver or enable-vserver
 If($InputArray[0] -eq "disable-vserver" -or $InputArray[0] -eq "enable-vserver") {
 #Load the rest of the array into variables
 $vServerName = $InputArray[1]
 $Password = $InputArray[2]
 $Sender = $InputArray[3]

#Check if the sender is a valid person to be performing NetScaler vServer actions
 if ($InputArray[3] -eq "dave@bretty.me.uk") {
 #Check if the password is valid
 if($Password -eq "password") {
 #Check if the user wants to enable a vserver
 if($InputArray[0] -eq "disable-vserver") {
 #Login and disable the vserver passed into the function
 ns-login 192.168.0.201 nsroot nsroot
 NS-DisablevServer $vServerName 192.168.0.201
 ns-logout 192.168.0.201
 } else {
 if ($InputArray[0] -eq "enable-vserver" ) {
 #Login and enable the vserver passed into the function
 ns-login 192.168.0.201 nsroot nsroot
 NS-EnablevServer $vServerName 192.168.0.201
 ns-logout 192.168.0.201
 }
 }
 
 }
 } else {
 cls
 write-host Invalid sender $inputarray[3] Tried to disable $inputarray[1] with the password $inputarray[2]
 }
 }
}

2 thoughts on “Managing Citrix NetScaler by email with Octoblu and NITRO

  1. Pingback: Citrix NetScaler GSLB Management with Octoblu and NITRO | bretty.me.uk

  2. Pingback: Managing Citrix NetScaler by email with Octoblu and NITRO

Leave a Reply

Your email address will not be published. Required fields are marked *