问题
In my Azure DevOps Pipeline I would like to copy a folder e.g. Media from 1 environment/app service, say TEST to another environment/app service say Live. The Media folder in TEST may get updated AFTER the Ci/cd build has been deployed to the TEST environment - just to exclude answers that might suggest putting it in Git and including it as a Build artifact.
EDIT - Clarification on using the accepted answer.
My repo contains the given powershell script in the accepted answer as :
azure/Copy-Media-Test-To-Live.ps1
I then add the azure folder as an artifact in the build pipeline i.e.
Edit azure-pipelines.yml and Add:
- task: PublishPipelineArtifact@1
inputs:
path: $(System.DefaultWorkingDirectory)/azure/
artifact: azure
In the release pipeline - reference the script to perform the copy:
steps:
- task: AzurePowerShell@4
displayName: 'Azure PowerShell script: FilePath'
inputs:
azureSubscription: 'Your subscription '
ScriptPath: '$(System.DefaultWorkingDirectory)/_your-artifact-path/azure/Copy-Media-Test-To-Live.ps1'
azurePowerShellVersion: LatestVersion
回答1:
Any application running in an App Service Environment can be managed via Kudu. Kudu has an API for downloading a ZIP compressed archive of any folder currently deployed to an application. It can be accessed with a GET request to:
https://{{YOUR-APP-NAME}}.scm.azurewebsites.net/api/zip/site/{{FOLDER}}
You can use the Invoke-WebRequest
cmdlet in PowerShell to pull this content to local storage.
You do need to authenticate to use the Kudu API, which is easy in a browser, but when automating is a little more involved. Please see the following article which details how to retrieve and present a Basic Authorization header, as well as demonstrating how to use the command API to extract a ZIP file using the Invoke-RestMethod
cmdlet. Your service principal will need at least contributor access to your applications to get deployment credentials to use in the API calls.
https://blogs.msdn.microsoft.com/waws/2018/06/26/powershell-script-to-execute-commands-in-scm-website-on-all-instances/
EDIT (Include worked example script):
If you have multiple subscriptions and the context has not been set properly in the deployment runtime environment, you may need to use Set-AzContext -Subscription "<SubsciptionName>"
to set the context for getting the WebApp
$srcResGroupName = "Test"
$srcWebAppName = "tstest12"
$srcDirectory = "/site/wwwroot/myFolder/"
$dstResGroupName = "Test"
$dstWebAppName = "tstest123"
$dstDirectory = "/site/wwwroot/myFolder/"
# Get publishing profile for SOURCE application
$srcWebApp = Get-AzWebApp -Name $srcWebAppName -ResourceGroupName $srcResGroupName
[xml]$publishingProfile = Get-AzWebAppPublishingProfile -WebApp $srcWebApp
# Create Base64 authorization header
$username = $publishingProfile.publishData.publishProfile[0].userName
$password = $publishingProfile.publishData.publishProfile[0].userPWD
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))
$apiBaseUrl = "https://$($srcWebApp.Name).scm.azurewebsites.net/api"
# Download the ZIP file to ./tmp.zip
Invoke-RestMethod -Uri "$apiBaseUrl/zip$($srcDirectory)" `
-Headers @{UserAgent="powershell/1.0"; `
Authorization=("Basic {0}" -f $base64AuthInfo)} `
-Method GET `
-OutFile ./tmp.zip
# Get publishing profile for DESTINATION application
$dstWebApp = Get-AzWebApp -Name $dstWebAppName -ResourceGroupName $dstResGroupName
[xml]$publishingProfile = Get-AzWebAppPublishingProfile -WebApp $dstWebApp
# Create Base64 authorization header
$username = $publishingProfile.publishData.publishProfile[0].userName
$password = $publishingProfile.publishData.publishProfile[0].userPWD
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))
$apiBaseUrl = "https://$($dstWebApp.Name).scm.azurewebsites.net/api"
# Upload and extract the ZIP file
Invoke-RestMethod -Uri "$apiBaseUrl/zip$($dstDirectory)" `
-Headers @{UserAgent="powershell/1.0"; `
Authorization=("Basic {0}" -f $base64AuthInfo)} `
-Method PUT `
-InFile ./tmp.zip `
-ContentType "multipart/form-data"
来源:https://stackoverflow.com/questions/58580956/how-to-copy-a-folder-from-a-test-app-service-to-a-live-app-service-on-azure