Remove files and foldes on Azure before a new deploy from VSTS

前端 未结 3 687
野趣味
野趣味 2020-11-29 09:32

As part of my build process in VSTS I want to delete all files and folders (except af few) from my azure site before a new deploy. My guess is, that using a Azure Powershell

相关标签:
3条回答
  • 2020-11-29 10:18

    Here's a tweaked version of the script which should be included in your project and exported as an artefact as part of your build, I call mine Delete-WebAppFiles.ps1

    It expands on the previous answer by also handling virtual applications and having error handling for the case when the files do not exist e.g. on first deployment to a new environment

    param(
        [string]$resourceGroupName,
        [string]$webAppName,
        [string]$appPath="wwwroot",
        [string]$slotName="", 
        [string]$kuduPath,
        [bool]$recursive=$false
    )
    function Get-AzureRmWebAppPublishingCredentials($resourceGroupName, $webAppName, $slotName = $null){
        if ([string]::IsNullOrWhiteSpace($slotName)){
            $resourceType = "Microsoft.Web/sites/config"
            $resourceName = "$webAppName/publishingcredentials"
        }
        else{
            $resourceType = "Microsoft.Web/sites/slots/config"
            $resourceName = "$webAppName/$slotName/publishingcredentials"
        }
        $publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion 2015-08-01 -Force
        Write-Host $publishingCredentials   
        return $publishingCredentials
    }
    function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName, $slotName = $null){
        $publishingCredentials = Get-AzureRmWebAppPublishingCredentials $resourceGroupName $webAppName $slotName
        Write-Host $publishingCredentials.Properties.PublishingUserName
        Write-Host $publishingCredentials.Properties.PublishingPassword
        return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword))))
    }
    function Delete-KuduFile($resourceGroupName, $webAppName, $appPath, $slotName, $kuduPath, $recursive){
    
        $kuduApiAuthorisationToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppName $slotName
        if ($recursive -eq $true) {
            if (-not ($kuduPath.endswith("recursive=true"))) {
               if (-not ($kuduPath.endswith("/"))) {
                  $kuduPath += "/"
               }
               $kuduPath += "?recursive=true"
            }
        }
        if ($slotName -eq ""){
            $kuduApiUrl = "https://$webAppName.scm.azurewebsites.net/api/vfs/site/$appPath/$kuduPath"
        }
        else{
            $kuduApiUrl = "https://$webAppName`-$slotName.scm.azurewebsites.net/api/vfs/site/$appPath/$kuduPath"
        }
    
        Write-Output $kuduApiUrl
        Write-Output $kuduApiAuthorisationToken
    
        try
        {
            Invoke-RestMethod -Uri $kuduApiUrl `
                            -Headers @{"Authorization"=$kuduApiAuthorisationToken;"If-Match"="*"} `
                            -Method DELETE
        } catch {
            Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ 
            Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
            if (-not ($_.Exception.Response.StatusCode.value__ -eq 404)) {
                throw $PSItem
            }
        }    
    }
    
    Delete-KuduFile $resourceGroupName $webAppName $appPath $slotName $kuduPath $recursive
    

    You can then add a Powershell task as mentioned above which should look a little like this...

    0 讨论(0)
  • 2020-11-29 10:19

    This is how you can test your settings that you use in the PowerShell scripts above using Postman.

    I found it useful to play with the REST API using Postman to understand what the PowerShell scripts above were doing and understand what status codes I could expect back from the API. I also noticed that the recursive logic for deleting a directory returns a 409 Conflict error even though is DOES delete the files.

    In the examples below, my app service is called "YatesDeleteMe"

    Create a base 64 encoded username and password string to use below in your authorization header OR run the PowerShell scripts above and it will output one for you

    1. Download your app service's publish file, which can be downloaded from the Overview tab in the Azure portal.
    2. Open the file with a text editor
    3. Find the username (user name example: $YatesDeleteMe ) and password (password example: ch222cDlpCjx4Glq333qo4QywGPMs1cK2Rjrn6phqZ9HswtgEEE12CrhDmcn )
    4. Create a string out of them and separate them with a colon (should look something like this: $YatesDeleteMe:ch222cDlpCjx4Glq333qo4QywGPMs1cK2Rjrn6phqZ9HswtgEEE12CrhDmcn )
    5. Base 64 encode them using your own program a site. The result should look something like this: JFlhdGVzRGVsZXRlTWU6Y2gyMjJjRGxwQ2p4NEdscTMzM3FvNFF5d0dQTXMxY0syUmpybjZwaHFaOUhzd3RnRUVFMTJDcmhEbWNu

    Retrieve a single file

    1. Open Postman
    2. Change the verb to GET
    3. Enter your URL to the file you want to retrieve (e.g., https://YatesDeleteMe.scm.azurewebsites.net/api/vfs/site/wwwroot/web.config). For more info on paths see this
    4. Added a header-->
      • Key: Authorization
      • Value: Basic YourBase64EncodedStringFromAbove
    5. Left-click the "Send" button and the file will download

    Delete a single file

    1. Open Postman
    2. Change the verb to DELETE
    3. Enter your URL to the file you want to delete (e.g., https://YatesDeleteMe.scm.azurewebsites.net/api/vfs/site/wwwroot/web.config)
    4. Added a header-->
      • Key: Authorization
      • Value: Basic YourBase64EncodedStringFromAbove
    5. Added a header-->
      • Key: If-Match
      • Value: *
    6. Left-click the "Send" button and the file will deleted

    Delete all the files in a directory

    1. Open Postman
    2. Change the verb to DELETE
    3. Enter your URL to the folder you want to delete PLUST add slash and then the query string ?recursive=true (e.g., https://YatesDeleteMe.scm.azurewebsites.net/api/vfs/site/wwwroot/?recursive=true)
    4. Added a header-->
      • Key: Authorization
      • Value: Basic YourBase64EncodedStringFromAbove
    5. Added a header-->
      • Key: If-Match
      • Value: *
    6. Left-click the "Send" button and the folder will deleted. I always get a 409 error back, but the folder is deleted.

    Reference

    • Blog post with pictures here.
    0 讨论(0)
  • 2020-11-29 10:22

    First, it’s better to include the files to the project that the web app needs, then just check Remove additional files at destination option (Check Publish using Web Deploy option first) to remove additional files.

    Secondly, you can remove the files through Kudu API.

    DELETE /api/vfs/{path}    (Delete the file at path)
    

    More information, you can refer to: Interacting with Azure Web Apps Virtual File System using PowerShell and the Kudu API

    Update (Add Kudu sample):

    1. Add Azure PowerShell step/task
    2. Sepcify arguments, for example: -resourceGroupName XXX -webAppName XXX -kuduPath Global.asax

    Script:

    param(
        [string]$resourceGroupName,
        [string]$webAppName,
        [string]$slotName="", 
        [string]$kuduPath
    )
    function Get-AzureRmWebAppPublishingCredentials($resourceGroupName, $webAppName, $slotName = $null){
        if ([string]::IsNullOrWhiteSpace($slotName)){
            $resourceType = "Microsoft.Web/sites/config"
            $resourceName = "$webAppName/publishingcredentials"
        }
        else{
            $resourceType = "Microsoft.Web/sites/slots/config"
            $resourceName = "$webAppName/$slotName/publishingcredentials"
        }
        $publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion 2015-08-01 -Force
        Write-Host $publishingCredentials   
        return $publishingCredentials
    }
    function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName, $slotName = $null){
        $publishingCredentials = Get-AzureRmWebAppPublishingCredentials $resourceGroupName $webAppName $slotName
        Write-Host $publishingCredentials.Properties.PublishingUserName
        Write-Host $publishingCredentials.Properties.PublishingPassword
        return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword))))
    }
    function Delete-FileToWebApp($resourceGroupName, $webAppName, $slotName = "", $kuduPath){
    
        $kuduApiAuthorisationToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppName $slotName
        if ($slotName -eq ""){
            $kuduApiUrl = "https://$webAppName.scm.azurewebsites.net/api/vfs/site/wwwroot/$kuduPath"
        }
        else{
            $kuduApiUrl = "https://$webAppName`-$slotName.scm.azurewebsites.net/api/vfs/site/wwwroot/$kuduPath"
        }
    
        Write-Output $kuduApiUrl
        Write-Output $kuduApiAuthorisationToken
        Invoke-RestMethod -Uri $kuduApiUrl `
                            -Headers @{"Authorization"=$kuduApiAuthorisationToken;"If-Match"="*"} `
                            -Method DELETE
    }
    
    Delete-FileToWebApp $resourceGroupName $webAppName $slotName $kuduPath
    
    0 讨论(0)
提交回复
热议问题