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