1+ [CmdletBinding ()]
2+ param ()
3+
4+ Trace-VstsEnteringInvocation $MyInvocation
5+
6+ # Get inputs for the task
7+ $sourcePath = Get-VstsInput - Name SourcePath - Require
8+ $destination = Get-VstsInput - Name Destination - Require
9+ $connectedServiceName = Get-VstsInput - Name ConnectedServiceNameARM - Require
10+ $storageAccount = Get-VstsInput - Name StorageAccountRM
11+ $containerName = Get-VstsInput - Name ContainerName
12+ $blobPrefix = Get-VstsInput - Name BlobPrefix
13+ $environmentName = Get-VstsInput - Name EnvironmentNameRM
14+ $resourceFilteringMethod = Get-VstsInput - Name ResourceFilteringMethod
15+ $machineNames = Get-VstsInput - Name MachineNames
16+ $vmsAdminUserName = Get-VstsInput - Name VmsAdminUsername
17+ $vmsAdminPassword = Get-VstsInput - Name VmsAdminPassword
18+ $targetPath = Get-VstsInput - Name TargetPath
19+ $additionalArgumentsForBlobCopy = Get-VstsInput - Name AdditionalArgumentsForBlobCopy
20+ $additionalArgumentsForVMCopy = Get-VstsInput - Name AdditionalArgumentsForVMCopy
21+ $cleanTargetBeforeCopy = Get-VstsInput - Name CleanTargetBeforeCopy - AsBool
22+ $copyFilesInParallel = Get-VstsInput - Name CopyFilesInParallel - AsBool
23+ $skipCACheck = Get-VstsInput - Name SkipCACheck - AsBool
24+ $enableCopyPrerequisites = Get-VstsInput - Name EnableCopyPrerequisites - AsBool
25+
26+ if ($destination -ne " AzureBlob" ) {
27+ $blobPrefix = " "
28+ }
29+
30+ # Constants
31+ $useHttpsProtocolOption = ' '
32+ $ErrorActionPreference = ' Stop'
33+ $telemetrySet = $false
34+ $isPremiumStorage = $false
35+
36+ $sourcePath = $sourcePath.Trim (' "' )
37+ $storageAccount = $storageAccount.Trim ()
38+ $containerName = $containerName.Trim ().ToLower()
39+
40+ $additionalArgumentsForBlobCopy = $additionalArgumentsForBlobCopy.Trim ()
41+ $additionalArgumentsForVMCopy = $additionalArgumentsForVMCopy.Trim ()
42+ $useDefaultArgumentsForBlobCopy = ($additionalArgumentsForBlobCopy -eq " " )
43+
44+ # azcopy location on automation agent
45+ $azCopyExeLocation = ' AzCopy\AzCopy.exe'
46+ $azCopyLocation = [System.IO.Path ]::GetDirectoryName($azCopyExeLocation )
47+
48+ # Import RemoteDeployer
49+ Import-Module $PSScriptRoot \ps_modules\RemoteDeployer
50+
51+ # Initialize Azure.
52+ Import-Module $PSScriptRoot \ps_modules\VstsAzureHelpers_
53+
54+ $endpoint = Get-VstsEndpoint - Name $connectedServiceName - Require
55+
56+ # Update PSModulePath for hosted agent
57+ . " $PSScriptRoot \Utility.ps1"
58+
59+ CleanUp- PSModulePathForHostedAgent
60+
61+ $vstsEndpoint = Get-VstsEndpoint - Name SystemVssConnection - Require
62+ $vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken
63+
64+ if (Get-Module Az.Accounts - ListAvailable) {
65+ $encryptedToken = ConvertTo-SecureString $vstsAccessToken - AsPlainText - Force
66+ Initialize-AzModule - Endpoint $endpoint - connectedServiceNameARM $connectedServiceName - encryptedToken $encryptedToken
67+ }
68+ else {
69+ Write-Verbose " No module found with name: Az.Accounts"
70+ throw (" Could not find the module Az.Accounts with given version. If the module was recently installed, retry after restarting the Azure Pipelines task agent." )
71+ }
72+
73+ # Import the loc strings.
74+ Import-VstsLocStrings - LiteralPath $PSScriptRoot / Task.json
75+
76+ # Load all dependent files for execution
77+ . " $PSScriptRoot \AzureFileCopyRemoteJob.ps1"
78+
79+ # Enabling detailed logging only when system.debug is true
80+ $enableDetailedLogging = ($env: system_debug -eq " true" )
81+
82+ # Telemetry
83+ Import-Module $PSScriptRoot \ps_modules\TelemetryHelper
84+
85+ # Sanitizer
86+ Import-Module $PSScriptRoot \ps_modules\Sanitizer
87+ $useSanitizerCall = Get-SanitizerCallStatus
88+ $useSanitizerActivate = Get-SanitizerActivateStatus
89+
90+ if ($useSanitizerCall ) {
91+ $sanitizedArgumentsForBlobCopy = Protect-ScriptArguments - InputArgs $additionalArgumentsForBlobCopy - TaskName " AzureFileCopyV5"
92+ $sanitizedArgumentsForVMCopy = Protect-ScriptArguments - InputArgs $additionalArgumentsForVMCopy - TaskName " AzureFileCopyV5"
93+ }
94+
95+ if ($useSanitizerActivate ) {
96+ $additionalArgumentsForBlobCopy = $sanitizedArgumentsForBlobCopy -join " "
97+ $additionalArgumentsForVMCopy = $sanitizedArgumentsForVMCopy -join " "
98+ }
99+
100+ # ### MAIN EXECUTION OF AZURE FILE COPY TASK BEGINS HERE ####
101+ try {
102+ try {
103+ # Importing required version of azure cmdlets according to azureps installed on machine
104+ $azureUtility = Get-AzureUtility
105+
106+ Write-Verbose - Verbose " Loading $azureUtility "
107+ . " $PSScriptRoot /$azureUtility "
108+
109+ # Telemetry for endpoint id
110+ $telemetryJsonContent = " {`" endpointId`" :`" $connectedServiceName `" }"
111+ Write-Host " ##vso[telemetry.publish area=TaskEndpointId;feature=AzureFileCopy]$telemetryJsonContent "
112+
113+
114+ # creating storage context to be used while creating container, deleting container
115+ $storageContext = Create- AzureStorageContextWithConnectedAcc - StorageAccountName $storageAccount
116+
117+ # Geting Azure Storage Account type
118+ $storageAccountType = Get-StorageAccountType $storageAccount $endpoint $connectedServiceName $vstsAccessToken
119+ Write-Verbose " Obtained Storage Account type: $storageAccountType "
120+ if (-not [string ]::IsNullOrEmpty($storageAccountType ) -and $storageAccountType.Contains (' Premium' )) {
121+ $isPremiumStorage = $true
122+ }
123+
124+ # creating temporary container for uploading files if no input is provided for container name
125+ if ([string ]::IsNullOrEmpty($containerName ) -or ($destination -ne " AzureBlob" )) {
126+ $containerName = [guid ]::NewGuid().ToString()
127+ Write-Verbose " Container Name input not found. Creating Temporary container for uploading files."
128+ Create- AzureContainer - containerName $containerName - storageContext $storageContext
129+ }
130+ else {
131+ # checking if the containerName provided exist or not
132+ $containerPresent = Get-AzureContainer - containerName $containerName - storageContext $storageContext
133+
134+ # creating container if the containerName provided does not exist
135+ if ($null -eq $containerPresent ) {
136+ Write-Verbose " Creating container if the containerName provided does not exist"
137+ Create- AzureContainer - containerName $containerName - storageContext $storageContext
138+ }
139+ }
140+
141+
142+ # Getting Azure Blob Storage Endpoint
143+ $blobStorageEndpoint = Get-blobStorageEndpoint - storageAccountName $storageAccount - endpoint $endpoint - vstsAccessToken $vstsAccessToken
144+
145+ # Setting environment variable for tracking Azure Pipelines usage in AzCopy telemetry
146+ $env: AZCOPY_USER_AGENT_PREFIX = " TFS_useragent"
147+ }
148+ catch {
149+ Write-Verbose $_.Exception.ToString ()
150+ Write-Telemetry " Task_InternalError" " TemporaryCopyingToBlobContainerFailed"
151+ throw
152+ }
153+
154+ # Set optional arguments for azcopy blob upload
155+ if ($useDefaultArgumentsForBlobCopy ) {
156+ # Adding default optional arguments:
157+ # log-level: Defines the log verbosity for the log file. Default is INFO(all requests/responses)
158+
159+ Write-Verbose " Using default AzCopy arguments for uploading to blob storage"
160+
161+ $additionalArgumentsForBlobCopy = " --log-level=INFO"
162+
163+ # Add more arguments if required
164+
165+ # Premium storage accounts only support page blobs
166+ if ($isPremiumStorage ) {
167+ Write-Verbose " Setting BlobType to page for Premium Storage account."
168+ $additionalArgumentsForBlobCopy += " --blob-type=PageBlob"
169+ }
170+
171+ # $root container does not support sub folders. So excluding recursive copy option for $root container.
172+ if ($containerName -ne ' $root' ) {
173+ Write-Verbose " Adding argument for recursive copy"
174+ $additionalArgumentsForBlobCopy += " --recursive"
175+ }
176+ }
177+
178+ Check- ContainerNameAndArgs - containerName $containerName - additionalArguments $additionalArgumentsForBlobCopy
179+
180+ # Uploading files to container
181+ Upload- FilesToAzureContainer - sourcePath $sourcePath `
182+ - endPoint $endpoint `
183+ - storageAccountName $storageAccount `
184+ - containerName $containerName `
185+ - blobPrefix $blobPrefix `
186+ - blobStorageEndpoint $blobStorageEndpoint `
187+ - azCopyLocation $azCopyLocation `
188+ - additionalArguments $additionalArgumentsForBlobCopy `
189+ - destinationType $destination `
190+ - useDefaultArguments $useDefaultArgumentsForBlobCopy `
191+ - cleanTargetBeforeCopy $cleanTargetBeforeCopy `
192+ - useSanitizerActivate $useSanitizerActivate
193+
194+ # Complete the task if destination is azure blob
195+ if ($destination -eq " AzureBlob" ) {
196+ # Get URI for output variable
197+ $storageAccountContainerURI = $storageContext.BlobEndPoint + $containerName + " /"
198+ Write-Host " ##vso[task.setvariable variable=StorageContainerUri]$storageAccountContainerURI "
199+
200+ Remove-EndpointSecrets
201+ Write-Verbose " Completed Azure File Copy Task for Azure Blob Destination"
202+
203+ return
204+ }
205+
206+ # Copying files to Azure VMs
207+ try {
208+ # Normalize admin username
209+ if ($vmsAdminUserName -and (-not $vmsAdminUserName.StartsWith (" .\" )) -and ($vmsAdminUserName.IndexOf (" \" ) -eq -1 ) -and ($vmsAdminUserName.IndexOf (" @" ) -eq -1 )) {
210+ $vmsAdminUserName = " .\" + $vmsAdminUserName
211+ }
212+ # getting azure vms properties(name, fqdn, winrmhttps port)
213+ $azureVMResourcesProperties = Get-AzureVMResourcesProperties - resourceGroupName $environmentName `
214+ - resourceFilteringMethod $resourceFilteringMethod - machineNames $machineNames - enableCopyPrerequisites $enableCopyPrerequisites `
215+ - connectedServiceName $connectedServiceName - vstsAccessToken $vstsAccessToken
216+
217+ $azureVMsCredentials = Get-AzureVMsCredentials - vmsAdminUserName $vmsAdminUserName - vmsAdminPassword $vmsAdminPassword
218+
219+ # Get Invoke-RemoteScript parameters
220+ $invokeRemoteScriptParams = Get-InvokeRemoteScriptParameters - azureVMResourcesProperties $azureVMResourcesProperties `
221+ - networkCredentials $azureVMsCredentials `
222+ - skipCACheck $skipCACheck
223+
224+ # Copies files on azureVMs
225+ Copy-FilesToAzureVMsFromStorageContainer - targetMachineNames $invokeRemoteScriptParams.targetMachineNames `
226+ - credential $invokeRemoteScriptParams.credential `
227+ - protocol $invokeRemoteScriptParams.protocol `
228+ - sessionOption $invokeRemoteScriptParams.sessionOption `
229+ - blobStorageEndpoint $blobStorageEndpoint `
230+ - containerName $containerName `
231+ - targetPath $targetPath `
232+ - cleanTargetBeforeCopy $cleanTargetBeforeCopy `
233+ - copyFilesInParallel $copyFilesInParallel `
234+ - additionalArguments $additionalArgumentsForVMCopy `
235+ - azCopyToolLocation $azCopyLocation `
236+ - fileCopyJobScript $AzureFileCopyRemoteJob `
237+ - enableDetailedLogging $enableDetailedLogging `
238+ - useSanitizerActivate $useSanitizerActivate
239+
240+ Write-Output (Get-VstsLocString - Key " AFC_CopySuccessful" - ArgumentList $sourcePath , $environmentName )
241+ }
242+ catch {
243+ Write-Verbose $_.Exception.ToString ()
244+
245+ Write-Telemetry " Task_InternalError" " CopyingToAzureVMFailed"
246+ throw
247+ }
248+ finally {
249+ Remove-AzureContainer - containerName $containerName - storageContext $storageContext
250+ Remove-EndpointSecrets
251+ Write-Verbose " Completed Azure File Copy Task for Azure VMs Destination" - Verbose
252+ Trace-VstsLeavingInvocation $MyInvocation
253+ }
254+ }
255+ finally {
256+ Disconnect-AzureAndClearContext - authScheme $endpoint.Auth.Scheme - ErrorAction SilentlyContinue
257+ }
0 commit comments