PowerShell script to restart role instances for WebApp

The Azure PowerShell cmdlets for WebApp allow you to restart a WebApp or a WebApp slot. They do not however allow to restart an instance within the WebApp - or to be precise, the w3wp.exe process within that instance as it is the one that runs the WebApp instance. This is however a convenient feature to have which the "Diagnose and Solve problems" blade of App Service in the Azure management portal allow you to do (so-call Advanced Application restart - see step 3 of https://blogs.msdn.microsoft.com/appserviceteam/2016/05/18/web-app-troubleshooting-blade/). Sometimes you do no have access to the portal or you do want to automate this work and then a PowerShell script comes handy.

This is a very slight revision over Brando Zhang's StackOverflow answer at https://stackoverflow.com/questions/43810248/powershell-for-an-advanced-application-restart-on-an-azure-web-app

The improvements are to take the parameters as formal inputs to the script. Also the resource group name is extracted from Get-AzureRmWebApp. Finally I introduced a 5 minutes pause between each instance restart. This because I used this script today to force a load-balancing in our own service hence didn't want all instances to be down at the same time.

I've hacked the login and connect quickly so you will get two prompts. Likely this can be refined to keep only one.

You can copy-paste this script into a text file named RestartWebAppInstances.ps1

 
Param(
  [Parameter(Mandatory=$True)][string]$subscriptionId,
  [Parameter(Mandatory=$True)][string]$webAppName
)

Login-AzureRmAccount
Connect-AzureRmAccount
Select-AzureRmSubscription -SubscriptionId $subscriptionId
Set-AzureRmContext -SubscriptionId $subscriptionId

$webApp = Get-AzureRmWebApp -Name $webAppName
$rgGroup = $webApp.ResourceGroup

$webSiteInstances = @()

#This gives you list of instances
$webSiteInstances = Get-AzureRmResource -ResourceGroupName $rgGroup -ResourceType Microsoft.Web/sites/instances -ResourceName $webAppName -ApiVersion 2015-11-01 

$sub = (Get-AzureRmContext).Subscription.SubscriptionId 

foreach ($instance in $webSiteInstances)
{
    $instanceId = $instance.Name
    "Going to enumerate all processes on {0} instance" -f $instanceId 

    # This gives you list of processes running
    # on a particular instance
    $processList =  Get-AzureRmResource `
                    -ResourceId /subscriptions/$sub/resourceGroups/$rgGroup/providers/Microsoft.Web/sites/$webAppName/instances/$instanceId/processes `
                    -ApiVersion 2015-08-01 

    foreach ($process in $processList)
    {               
        if ($process.Properties.Name -eq "w3wp")
        {            
            $resourceId = "/subscriptions/$sub/resourceGroups/$rgGroup/providers/Microsoft.Web/sites/$webAppName/instances/$instanceId/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 

            $computerName = $processInfoJson.Properties.Environment_variables.COMPUTERNAME

            if ($processInfoJson.Properties.is_scm_site -ne $true)
            {
                $computerName = $processInfoJson.Properties.Environment_variables.COMPUTERNAME
                "Instance ID" + $instanceId  + "is for " +   $computerName

                "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)
                { 
                    "Process {0} stopped " -f $processInfoJson.Properties.Id
                }

                "Sleep for 5 minutes"
                Start-Sleep -s 300
            }
       }
    }
}

Comments

  • Anonymous
    March 28, 2019
    I had issues getting this to work with the Az module, so I tinkered with it and came up with something that works properly with Az 1.6.0, and is ready for use in Azure Automation. If you're using Automation, you'll need to have these modules installed: Az.Accounts, Az.Resources, Az.Automation, Az.WebsitesIf you're not using Automation, remove $AutomationConnection, $ConnectionSplat, and Connect-AzAccount near the top, and make sure you've run Connect-AzAccount manually.Updated version of this is available in this GitHub Gist: https://gist.github.com/natescherer/63e19abd538ab0766c013f7ebe560f5b
    • Anonymous
      March 29, 2019
      Thank you Nate for sharing!
  • Anonymous
    June 20, 2019
    This blog has been moved off the MSDN platform. Find further content and update at https://www.linkedin.com/today/author/daviburgComments are locked as part of the blog migration, so please reach out to your customer support contact for assistance with Microsoft products and services.