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
    }
}