info@techdevops.com | 437-991-3573 | Data Engineering Services
TechDevOps.com
Resources Tools
Experts in Microsoft SQL Server on Windows, Linux, Containers | Clusters, Always On, FCI | Migrations, Cloud, Performance



Powershell - Automate Get Azure Traffic Manager EndPoints Monitor Status
by BF (Principal Consultant; Architecture; Engineering)
2016-05-03








Pre-requisite:

Use PowerShell to create an Application(Active Directory Application), a Service Principal & then assign that Service
Principal to a Role which grants permissions to read all resources in the subscription.


Once those are created, you can then authenticate, as the Service Principal, to Azure within unattended Powershell code/script.

Authenticating a service principal with Azure Resource Manager




Powershell Code:

This Powershell code will make a call to Azure REST API for Traffic Manager Endpoint Status monitor value & alert using SMPT call & log the
results to a file. One method to automate this is to create a Task Scheduler that calls a batch file that calls Powershell.exe which
executes a .ps1 file.

Note: May need to run Microsoft Web Platform Installer to install Azure Powershell Tools on the Server that runs the Automation
(Task Scheduler) Job.


#http://hindenes.com/trondsworking/2015/07/19/certificate-based-authentication-to-azure-resource-manager-using-powershell/
#Non-Arm - Publish Settings File

#SMTP:
$SMTPServer = "smtp.xyz.net"
$SMTPPort = "25"
$Username = "azure_xyz@azure.com"
$Password = "zyx"
$to = "xyz@xyz.ca"
$subject = "Alert - Traffic Manager XYZ - EndPoint disabled or offline"
$message = New-Object System.Net.Mail.MailMessage
#$message.subject = $subject
$message.to.add($to)
$message.from = "alerts@xyz.com"
$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
#$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
#$smtp.send($message)

#Log:
$LogFilePath = "C:\Powershell\AzureTrafficManagerEndpointStatusCheck\Log.txt"

#Sub:
$subscription_id = "xyz"
$resource_group_name = "RG_TM_XYZ"
$adTenant = "XYZ"
$profile_name = "XYZ"

#Login-AzureRmAccount w/ previously created Azure Application & Service Principal:
#https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal/
$username = "xyz@xyz.onmicrosoft.com"
$pass = ConvertTo-SecureString -String "xyz" -AsPlainText -Force
#$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $pass
$cred = New-Object System.Management.Automation.PSCredential ("xyz", $pass)
Login-AzureRmAccount -Credential $cred -ServicePrincipal -TenantId "xyz"
#Add-AzureRmAccount -Credential $cred -TenantId $adTenant -SubscriptionId $subscription_id

#Get-AzureRmSubscription -SubscriptionName "xyz"
#Select-AzureRmSubscription -SubscriptionName "xyz"

#Define HTTP Headers, RESTAPI URL, Timeout
$LogHeaders = "Date&Time(UTC)`tEndPoint-Name`tEndPoint-Status`tMonitor-Status"

#add-content -path $LogFilePath -Value $LogHeaders -Force

#REST API URL
$RESTAPI_URL = "https://management.azure.com/subscriptions/$subscription_id/resourceGroups/$resource_group_name/providers/Microsoft.Network/trafficManagerProfiles/$profile_name"+"?api-version=2015-11-01";

#Set Timeout
[int] $TimeOut_Sec = 5

#Get the Bearer token for HTTP GET call to Azure:
#Credit: https://blogs.technet.microsoft.com/keithmayer/2014/12/30/leveraging-the-azure-service-management-rest-api-with-azure-active-directory-and-powershell-list-azure-administrators/
#Load ADAL Assemblies
$adal = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
$adalforms = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll"
[System.Reflection.Assembly]::LoadFrom($adal)
[System.Reflection.Assembly]::LoadFrom($adalforms)
#Set Azure AD Tenant name
#$adTenant
#Set well-known client ID for Azure PowerShell
$clientId = "1950a258-227b-4e31-a9cf-717495945fc2"
#Set redirect URI for Azure PowerShell
$redirectUri = "urn:ietf:wg:oauth:2.0:oob"
#Set Resource URI to Azure Service Management API
$resourceAppIdURI = "https://management.core.windows.net/"
#Set Authority to Azure AD Tenant
$authority = "https://login.windows.net/$adTenant"
#Create Authentication Context tied to Azure AD Tenant
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority

#$userName = "xyz@wxyz.onmicrosoft.com"
#$password = "xyz"
$creds = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserCredential" -ArgumentList $userName,$pass

#Acquire token
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $creds)
#Create Authorization Header
$authHeader = $authResult.CreateAuthorizationHeader()

$RequestHeader = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$RequestHeader.Add("Authorization", "$authHeader")
$RequestHeader.Add("Content-Type", "application/json")

#Define function for logging in file
function LogDetails
{ param([string]$LogData)

Add-Content -Path $LogFilePath -Value $LogData -Force

}


#while ($true)
#{
#Create a new PS object to hold the resposne JSON
$RESTResponseJSON = New-Object PSObject;

Try
{

$RESTResponseJSON = (Invoke-RestMethod -Uri $RESTAPI_URL -Method Get -Headers $RequestHeader -TimeoutSec $TimeOut_Sec -Credential $cred);

foreach ($ep in $RESTResponseJSON.properties.endpoints)
{

If ($ep.properties.endpointStatus -notcontains 'Enabled' -or $ep.properties.endpointMonitorStatus -notcontains 'Online') {
add-content -path $LogFilePath -Value $LogHeaders -Force
LogDetails("$((get-date).ToUniversalTime())" +"`t" + $ep.name + "`t" + $ep.properties.endpointStatus + "`t" + $ep.properties.endpointMonitorStatus )
#Write-Host("$((get-date).ToUniversalTime())" +"`t" + $ep.name + "`t" + $ep.properties.endpointStatus + "`t" + $ep.properties.endpointMonitorStatus )
$message.subject = "Azure PRD Alert: Traffic Manager: XYZ: " + $ep.name + " " + $ep.properties.endpointStatus
$smtp.send($message)
}
}

}
Catch
{
LogDetails("$((get-date).ToUniversalTime())" + "`t"+ "Error: `t" + $_.Exception.Message);
}

#Adding delay of 10 seconds, you can change to x it if you want to check the endpoint status in every x seconds
#Start-Sleep -Milliseconds 50000
#}




Fiddler:


Use Fiddler to capture the HTTP/HTTPS calls to Azure made from the Powershell code:


Image #1: Fiddler - Calls to & from Azure






Image #2: Fiddler - HTTP GET with Bearer Token & HTTP Response