How to delete folder and files of Azure web app using webjob

90 views Asked by At

We have issue on our mvc web application, to overcome problem we are trying to delete folder and kill process of Azure web app. For this we have created one console application, which query processes and kill it manually and written power shell script to delete folder and files but on production Azure web app we have 2 instances due to which powershell script run only on one instance. How can we delete folder using power shell script or any other option we have to delete files. Below is a code to kill processes :

using Microsoft.ApplicationInsights.Extensibility;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace TestConsoleApp
{
   public class AzureWebAppProcessRecycle
   {
      static async Task Main(string[] args)
      {
        Console.WriteLine("Application restart started....");
        try
        {
            FormUrlEncodedContent tokenPayload = new FormUrlEncodedContent(new[]
                            {
                            new KeyValuePair<string, string>("client_id", ConfigurationManager.AppSettings["ClientId"]),
                            new KeyValuePair<string, string>("grant_type", "client_credentials"),
                            new KeyValuePair<string, string>("resource", ConfigurationManager.AppSettings["Resource"]),
                            new KeyValuePair<string, string>("client_secret", ConfigurationManager.AppSettings["ClientSecret"]),
                        });

            //Generate auth token
            HttpClient httpClient = new HttpClient();
            var tokenResponse = await httpClient.PostAsync($"{ConfigurationManager.AppSettings["AuthUrl"]}", tokenPayload);

            if (tokenResponse != null && tokenResponse.StatusCode == System.Net.HttpStatusCode.OK)
            {
                string jsonString = await tokenResponse.Content.ReadAsStringAsync();
                var tokenObject = JsonConvert.DeserializeObject<JObject>(jsonString);
                httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue($"Bearer", $"{tokenObject["access_token"]}");

                string listInstancesUrl = ConfigurationManager.AppSettings["ListInstancesUrl"];
                var instancesDetails = await httpClient.GetAsync(listInstancesUrl);
                if (instancesDetails != null)
                {
                    string jsonInstanceString = await instancesDetails.Content.ReadAsStringAsync();
                    var instancesListObj = JsonConvert.DeserializeObject<ProcessDetails>(jsonInstanceString);
                    if (instancesListObj != null && instancesListObj.value != null && instancesListObj.value.Count > 0)
                    {
                        foreach (var instance in instancesListObj.value)
                        {
                            string listProcessUrl = string.Format(ConfigurationManager.AppSettings["ListProcessUrl"], instance.name);
                            var processDtl = await httpClient.GetAsync(listProcessUrl);
                            if (processDtl != null)
                            {
                                string jsonProcessString = await processDtl.Content.ReadAsStringAsync();
                                var processListObj = JsonConvert.DeserializeObject<ProcessDetails>(jsonProcessString);
                                if (processListObj != null && processListObj.value != null && processListObj.value.Count > 0)
                                {
                                    foreach (var process in processListObj.value)
                                    {
                                        Console.WriteLine("Process : - " + JsonConvert.SerializeObject(process)); ;
                                        if (string.Equals(process.properties.name, "w3wp", StringComparison.InvariantCultureIgnoreCase))
                                        {
                                            string processUrl = "https://management.azure.com" + process.id + "?api-version=2022-03-01";
                                            var getProDtl = await httpClient.GetAsync(processUrl);
                                            if (getProDtl != null)
                                            {
                                                string processPropsObj = await getProDtl.Content.ReadAsStringAsync();
                                                if (string.IsNullOrEmpty(processPropsObj) || (!string.IsNullOrEmpty(processPropsObj) && !processPropsObj.Contains("is_scm_site")))
                                                {
                                                    var processKillresp = await httpClient.DeleteAsync(processUrl);
                                                    if (processKillresp != null)
                                                    {
                                                        string killprocess = await processKillresp.Content.ReadAsStringAsync();
                                                        Console.WriteLine("Process kill details :- " + processPropsObj);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                        }
                    }
                }
            }
            else
            {
                string jsonString = await tokenResponse.Content.ReadAsStringAsync();
                Console.WriteLine("Failed to Connect service. Details are : " + jsonString);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Failed to complete..." + ex.ToString());
        }
        Console.WriteLine("Application restart done....");
    }
  }
}

And power shell script is as follow :

try
{
    $CDrivefolderPath="C:\home\site\wwwroot\ImagesCollection"
    Get-ChildItem -Path $CDrivefolderPath -Include *.* -Recurse -EA 0 | ForEach-Object { Remove-Item $_.FullName -Force -ErrorAction SilentlyContinue }
 }
 catch
 {}
 finally
 {
    .\TestConsoleApp.exe
 }

Please help me to remove this folders file from all instances instead of only one instance.

Thanks,
Sandy

1

There are 1 answers

0
Suresh Chikkam On

As stating to the @D A point once try to redeploy the application or follow the below approach.

  • Use the Azure Kudu API (Azure SCM, or Site Control Manager) which is an advanced management platform for Azure Web Apps. You can interact with Kudu API to perform operations on all instances. Here's a PowerShell script to delete files and folders using the Kudu API.
# Specify your Azure Web App name and resource group
$webAppName = "YourWebAppName"
$resourceGroupName = "YourResourceGroupName"

# Specify the path of the folder you want to delete
$folderPath = "site\wwwroot\ImagesCollection"

# Get the list of all instances
$instances = (Get-AzureRmAppServicePlan -ResourceGroupName $resourceGroupName | Get-AzureRmWebApp -Name $webAppName).HostNames

foreach ($instance in $instances)
{
    # Construct the Kudu API URL for each instance
    $kuduUrl = "https://$webAppName.scm.azurewebsites.net/api/vfs/site/wwwroot/$folderPath"

    # Authenticate to the Kudu API (use a deployment token)
    $kuduUserName = $webAppName
    $kuduPassword = "YourDeploymentToken" # Replace with your deployment token

    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $kuduUserName, $kuduPassword)))

    # Delete the folder and its contents
    $result = Invoke-RestMethod -Uri $kuduUrl -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method DELETE
    Write-Host "Deleted folder on instance $instance."
}
  • You can use Azure Deployment Slots to manage separate environments.

  • Create a deployment script or use a release management tool to deploy the script to each instance. The script should be deployed to the same location on all instances.

  • The PowerShell script you want to execute (testade.ps1) is present in the specified path on all instances and contains the logic to delete the folder and files.