Citrix.Image.Uploader/AzureFunctions.ps1
Function AuthAzure([string]$azureClientId, [string]$azureSecret, [string]$azureTenantId, [string]$azureSubscriptionId) { if ($azureClientId -And $azureSecret -And $azureTenantId) { Log "Authenticating to Azure as service principal $azureClientId in subscription $azureSubscriptionId" $secret = ConvertTo-SecureString $azureSecret -AsPlainText -Force $pscredential = New-Object -TypeName System.Management.Automation.PSCredential($azureClientId, $secret) $null = Connect-AzAccount -ServicePrincipal -Credential $pscredential -Tenant $azureTenantId -Subscription $azureSubscriptionId ` -ErrorAction Stop } else { $context = Get-AzContext if ($null -eq $context -or ($context.Subscription.Id -ne $azureSubscriptionId)) { Log "Authenticating to Azure interactively in subscription $azureSubscriptionId" $null = Connect-AzAccount -Subscription $azureSubscriptionId -ErrorAction Stop } else { Log "Already connected to subscription $azureSubscriptionId" $False } } } Function GetAzureDisk([string]$cloudDiskName, [string]$targetResourceGroup) { $err = "" $disk = Get-AzDisk -ResourceGroupName $targetResourceGroup -DiskName $cloudDiskName -ErrorAction SilentlyContinue -ErrorVariable err if ($null -ne $disk) { return $disk } if (ErrorIsResourceNotFound $err) { return $null } $msg = "Failure trying to find managed disk '$cloudDiskName' in resource group $targetResourceGroup" ThrowError ([UploaderError]::new($msg, $err.Exception)) } Function CleanUpAzureDisk([string]$cloudDiskName, [string]$targetResourceGroup) { $disk = GetAzureDisk $cloudDiskName $targetResourceGroup if ($null -ne $disk) { Log "Deleting existing managed disk '$cloudDiskName' in resource group $targetResourceGroup" $err = "" $result = Remove-AzDisk -ResourceGroupName $targetResourceGroup -DiskName $disk.Name -Force -ErrorAction SilentlyContinue -ErrorVariable err if ($null -eq $result) { ThrowError ([UploaderError]::new("Failed to delete existing managed disk '$($disk.Name)'", $err.Exception)) } Log "Remove-AzDisk status $($result.status)" $False Log "Deleted managed disk '$($disk.Name)'" } } Function CreateManagedDisk([long]$sizeInBytes, [int]$uploadTimeout, [string]$azureStorageType, [string]$azureLocation, [string]$targetResourceGroup, [string]$cloudDiskName, [HashTable]$tags = @{}) { $sasExpiryDuration = $uploadTimeout $azDiskConfigArgs = @{ AccountType = $azureStorageType Location = $azureLocation UploadSizeInBytes = $sizeInBytes CreateOption = 'Upload' OsType = 'Windows' HyperVGeneration = 'V2' } if ($tags.Count -ne 0) { $azDiskConfigArgs["Tag"] = $tags } $diskConfig = New-AzDiskConfig @azDiskConfigArgs Log "Creating managed disk '$cloudDiskName' with size $sizeInBytes bytes in resource group $targetResourceGroup location $azureLocation" $err = "" $disk = New-AzDisk -ResourceGroupName $targetResourceGroup -DiskName $cloudDiskName -Disk $diskConfig -WarningAction Ignore -ErrorAction SilentlyContinue ` -ErrorVariable err if ($null -eq $disk) { ThrowError ([UploaderError]::new("Failed to create managed disk '$cloudDiskName' in resource group $targetResourceGroup", $err.Exception)) } Log "Granting access to managed disk '$cloudDiskName' for $sasExpiryDuration seconds" $False $err = "" $access = Grant-AzDiskAccess -ResourceGroupName $targetResourceGroup -DiskName $cloudDiskName -DurationInSecond $sasExpiryDuration ` -Access 'Write' -ErrorAction SilentlyContinue -ErrorVariable err if ($null -eq $access) { ThrowError ([UploaderError]::new("Failed to create SAS for mananged disk '$cloudDiskName'", $err.Exception)) } $sas = $access.AccessSAS Log "Created managed disk '$cloudDiskName' with SAS $sas" $False return $sas } Function DoAzureUpload([ScriptBlock]$uploadScript, [string]$diskName, [int]$threads, [string]$targetResourceGroup, [string]$cloudDiskName) { Log ("Copying disk '$diskName' to managed disk '$cloudDiskName' " + $(if ($threads -le 0) { "(threads=default)" } else { "(threads=$threads)" })) $ex = $null try { & $uploadScript Log "Revoking Azure disk access" $False $err = "" $r = Revoke-AzDiskAccess -ResourceGroupName $targetResourceGroup -DiskName $cloudDiskName -ErrorAction SilentlyContinue -ErrorVariable err if ($null -eq $r) { ThrowError ([UploaderError]::new("Revoke-AzDiskAccess failed", $err.Exception)) $False } Log "Revoke-AzDiskAccess status '$($r.status)'" $False } catch { $ex = $_.Exception } finally { if ($null -eq $ex) { Log "Copied disk to Azure managed disk '$cloudDiskName'" } else { Log "Deleting managed disk '$cloudDiskName' because upload failed" $null = Remove-AzDisk -ResourceGroupName $targetResourceGroup -DiskName $cloudDiskName -Force throw $ex } } } Function UploadToAzure([string]$destination, [string]$path, [int]$threads, [string]$targetResourceGroup, [string]$cloudDiskName, [bool] $debug, [string]$logFileName) { $uploadScript = { $parameters = @{ File = $path Sas = $destination Threads = $threads LogFileName = $logFileName BlobDebug = $debug } Copy-ToAzDisk @parameters } DoAzureUpload $uploadScript $path $threads $targetResourceGroup $cloudDiskName } |