AdvancedRestart-AppService.ps1
<#PSScriptInfo .VERSION 1.0 .GUID 7b055134-bcbd-4a72-b670-d91cc17b83a9 .AUTHOR VIJAY RAAVI .COMPANYNAME Pennywise Solutions .COPYRIGHT .TAGS AppService Advanced Restart PaaS w3wp .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> <# .DESCRIPTION This script will kill Worker process(w3wp) in a scaled out environment and warms up the website, It will remove Resource Group and app service locks before killing w3wp process and adds Locks to Resource Group and its app services #> Param() workflow AdvancedRestart-AppService { [cmdletbinding()] param ( # Azure App Service Name [parameter(Mandatory=$true)] #[ValidateNotNullOrEmpty()] [string] $AppServiceName, # Name of ResourceGroup in which AppService Exists [parameter(Mandatory=$true)] #[ValidateNotNullOrEmpty()] [string] $ResourceGroupName, # Warm UP URL [parameter(Mandatory=$false)] #[ValidateNotNullOrEmpty()] [string] $Warm_UP_URL, [parameter(Mandatory=$false)] [string] $azureRunAsConnectionName = "AzureRunAsConnection" ) # Converter: Wrapping initial script in an InlineScript activity, and passing any parameters for use within the InlineScript # Converter: If you want this InlineScript to execute on another host rather than the Automation worker, simply add some combination of -PSComputerName, -PSCredential, -PSConnectionURI, or other workflow common parameters (http://technet.microsoft.com/en-us/library/jj129719.aspx) as parameters of the InlineScript inlineScript { $AppServiceName = $using:AppServiceName $ResourceGroupName = $using:ResourceGroupName $Warm_UP_URL = $using:Warm_UP_URL $azureRunAsConnectionName = $using:azureRunAsConnectionName filter timestamp {"[$(Get-Date -Format G)]: $_"} Write-Output "Recycle Activity started." | timestamp $VerbosePreference = "Continue" $ErrorActionPreference = "Continue" #"Stop" #"SilentlyContinue" #Authenticate with Azure Automation Run As account (service principal) $runAsConnectionProfile = Get-AutomationConnection ` -Name $azureRunAsConnectionName Add-AzureRmAccount -ServicePrincipal ` -TenantId $runAsConnectionProfile.TenantId ` -ApplicationId $runAsConnectionProfile.ApplicationId ` -CertificateThumbprint ` $runAsConnectionProfile.CertificateThumbprint | Out-Null Write-Output "Authenticated with Automation Run As Account." | timestamp #$AppServiceName = "Vijay-AS-APP" #$ResourceGroupName = "Vijay-AS-APP-RG" $AppServiceInstances = @() #Get the list of all WebApp instances in the particular App Service. $AppServiceInstances = Get-AzureRmResource -ResourceGroupName $ResourceGroupName -ResourceType Microsoft.Web/sites/instances -ResourceName $AppServiceName -ApiVersion 2015-11-01 $SubscriptionId = (Get-AzureRmContext).Subscription.SubscriptionId #Get Resource and Resource Group Locks and Remove Locks #Remove Resource Group Lock $RGLock= Get-AzureRmResourceLock -ResourceGroupName $ResourceGroupName -AtScope -ErrorAction SilentlyContinue if ($RGLock -eq $null) { # ResourceGroupLock doesn't exist, No Action to be taken Write-Output "Lock @ Resource Group Level doen't exsist" } else { # ResourceGroupLock exist, Delete it Write-Output "Deleting ResourceGroup Lock" Get-AzureRmResourceLock -ResourceGroupName $ResourceGroupName -AtScope -ErrorAction SilentlyContinue |Remove-AzureRmResourceLock -Force sleep -Seconds 5 } #Remove App Service Lock $ResourceLock= Get-AzureRmResourceLock -ResourceName $AppServiceName -ResourceType Microsoft.Web/sites -ResourceGroupName $ResourceGroupName -ErrorAction SilentlyContinue if ($ResourceLock -eq $null) { # ResourceLock doesn't exist, No Action to be taken Write-Output "Lock @ Resource Level doen't exsist" } else { # ResourceGroupLock exist, Delete it Write-Output "Deleting Resource Lock for $AppServiceName" Get-AzureRmResourceLock -ResourceName $AppServiceName -ResourceType Microsoft.Web/sites -ResourceGroupName $ResourceGroupName -ErrorAction SilentlyContinue |Remove-AzureRmResourceLock -Force sleep -Seconds 5 } foreach ($node in $AppServiceInstances) { $nodeId = $node.Name Write-Output "Listing all processes on {0} node" -f $nodeId # This gives you list of processes running # on a particular instance $processesList = Get-AzureRmResource ` -ResourceId /subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.Web/sites/$AppServiceName/instances/$nodeId/processes ` -ApiVersion 2015-08-01 foreach ($process in $processesList) { if ($process.Properties.Name -eq "w3wp") { $resourceId = "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.Web/sites/$AppServiceName/instances/$nodeId/processes/" + $process.Properties.Id $processInfoJson = Get-AzureRmResource -ResourceId $resourceId -ApiVersion 2015-08-01 # is_scm_site is a property which is set on the worker process for the KUDU $machineName = $processInfoJson.Properties.Environment_variables.COMPUTERNAME if ($processInfoJson.Properties.is_scm_site -ne $true) { $machineName = $processInfoJson.Properties.Environment_variables.COMPUTERNAME Write-Output "Instance ID $nodeId is for $machineName" Write-Output "Going to stop this process $($processInfoJson.Name) with PID $($processInfoJson.Properties.Id)" # Remove-AzureRMResource finally STOPS the worker process $result = Remove-AzureRmResource -ResourceId $resourceId -ApiVersion 2015-08-01 -Force if ($result -eq $true) { Write-Output "Process {0} stopped -f $($processInfoJson.Properties.Id)" #Warm Up App Service for ($i = 1; $i -lt 11; $i++) { $startTime = get-date #[String] $Warm_UP_URL="https://vijay-as-app.azurewebsites.net/"; $output = Invoke-WebRequest $Warm_UP_URL -UseBasicParsing #Write-Output "Request No: "+ $i $endTime = get-date Write-Output "($endTime - $startTime) took to warmup instance, Request No: $i" } # sleep -Seconds 1 } } } } } # Create Locks for ResourceGroup and Resource $ResourceLock= New-AzureRmResourceLock -ResourceName $AppServiceName -ResourceType "Microsoft.Web/sites" -ResourceGroupName $ResourceGroupName -LockName "$AppServiceName-Lock" -LockLevel CanNotDelete -LockNotes "$AppServiceName Locked from Deleting" -Force Write-Output $ResourceLock #sleep -Seconds 2 $RGLock= New-AzureRmResourceLock -ResourceGroupName $ResourceGroupName -LockName "$ResourceGroupName-Lock" -LockLevel CanNotDelete -LockNotes "$ResourceGroupName Locked from Deleting" -Force Write-Output $RGLock filter timestamp {"[$(Get-Date -Format G)]: $_"} Write-Output "Recycle Activity Ended." | timestamp } } |