This post has already been read 10567 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
[embedyt] https://www.youtube.com/watch?v=dCm8f-bMYTg[/embedyt]
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 https://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 https://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 https://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 https://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 https://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 https://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] } } }
Pingback: Citrix NetScaler GSLB Management with Octoblu and NITRO | bretty.me.uk
Pingback: Managing Citrix NetScaler by email with Octoblu and NITRO