Copy-DiskToAzure.ps1

<#
.SYNOPSIS
Copy a disk to Azure.

.DESCRIPTION
Copy a disk to an Azure managed disk.

.PARAMETER FileName
Specifies the filename of the disk to be copied. The file can be either local or on a share.

.PARAMETER ManagedDiskName
Specifies the name of the Azure managed disk to copy the disk to.

.PARAMETER Location
Specifies the Azure location to create the managed disk in..

.PARAMETER ResourceGroup
Specifies the resource group to create the managed disk in.

.PARAMETER SubscriptionId
Specifies the ID of the Azure subscription the destination resource group is in.

.PARAMETER ClientId
Azure client ID.

.PARAMETER Secret
Azure client secret.

.PARAMETER TenantId
Azure tenant ID.

.PARAMETER Tags
Specifies tags to label the managed disk with.

.PARAMETER StorageType
Specifies the Azure storage type to use for the managed disk. Must be one of "Standard_LRS", "Premium_LRS", "StandardSSD_LRS", "Premium_ZRS" or "
StandardSSD_ZRS". "Premium_LRS" is the default.

.PARAMETER Timeout
Specifies a timeout for the upload of the disk.

.PARAMETER Threads
Specifies the number of threads to use for uploading to the cloud.

.PARAMETER Install
Install required powershell modules.

.PARAMETER LogFile
Specifies the path to the file to log to. ".\Upload.log" is the default.

.PARAMETER OverwriteLog
If specified the log file is overwritten otherwise it is appended to.

.PARAMETER Force
If the destination of the copy already exists delete it before doing the copy.

.INPUTS
None.

.OUTPUTS
None.

.EXAMPLE

PS> Copy-DiskToAzure -FileName C:\images\disk.vhd -ManagedDiskName example -SubscriptionId efa90dc7-c7d7-4f7b-b633-80a896a56b11 -Location eastus -ResourceGroup ips-test -Tags @{Organization = "ACME"; User = "RoadRunner"}

.EXAMPLE

PS> $CopyParams = @{
  FileName = 'D:\images\disk.vhd'
  ManagedDiskName = 'example'
  Location = 'eastus'
  ResourceGroup = 'ips-test'
  SubscriptionId = 'efa90dc7-c7d7-4f7b-b633-80a896a56b11'
  TenantId = '8419d489-5d5a-4d5d-b0b2-015375868dbe'
  ClientId = '6d7647e2-555e-44fe-89ab-aea9bcfdf8f7'
  Secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
  Tags = @{Organization = "ACME"; User = "RoadRunner"}
}

PS> Copy-DiskToAzure @CopyParams

#>


Function Copy-DiskToAzure
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $True)]
        [string] $FileName,

        [Parameter(Mandatory = $True)]
        [string] $ManagedDiskName,

        [Parameter(Mandatory = $True)]
        [string] $SubscriptionId,

        [Parameter(Mandatory = $True)]
        [string] $Location,

        [Parameter(Mandatory = $True)]
        [string] $ResourceGroup,

        [Parameter()]
        [string] $StorageType = "Premium_LRS",

        [Parameter()]
        [string] $ClientId,

        [Parameter()]
        [string] $Secret,

        [Parameter()]
        [string] $TenantId,

        [Parameter()]
        [HashTable] $Tags=@{},

        [Parameter()]
        [int] $Timeout = 36000,

        [Parameter()]
        [int] $Threads,

        [Parameter()]
        [switch] $Install,

        [Parameter()]
        [string] $LogFile,

        [Parameter()]
        [switch] $OverwriteLog,

        [Parameter()]
        [switch] $Force
    )

    Begin
    {
        InitUploadLog $LogFile $OverwriteLog
    }

    Process
    {
        try
        {
            LoadModules @('Az.Accounts', 'Az.Compute') $Install
            AuthAzure $ClientId $Secret $TenantId $SubscriptionId
            if ($Force)
            {
                CleanUpAzureDisk $ManagedDiskName $ResourceGroup
            }
            elseif ($null -ne (GetAzureDisk $ManagedDiskName $ResourceGroup))
            {
                $msg = "Managed disk '$ManagedDiskName' aleady exists in resource group $ResourceGroup. Consider using the -Force option"
                ThrowError ([UploaderException]::new($msg))
            }
            $fileSize = GetVhdSize $FileName
            $diskUrlWithSas = CreateManagedDisk -sizeInBytes $fileSize -uploadTimeout $Timeout -azureStorageType $StorageType -azureLocation $Location -targetResourceGroup $ResourceGroup -cloudDiskName $ManagedDiskName -tags $Tags
            $InformationPreference = "Continue"
            try
            {
                $parameters = @{
                    destination = $diskUrlWithSas
                    path = $FileName
                    threads = $Threads
                    targetResourceGroup = $ResourceGroup
                    cloudDiskName = $ManagedDiskName
                    debug = ($PSCmdlet.MyInvocation.BoundParameters["Debug"].IsPresent -eq $true)
                    logFileName = $Global:UploadLogFile
                }
                UploadToAzure @parameters
            }
            catch
            {
                ThrowError ([UploaderException]::new("Failed to copy the disk to Azure", $_.Exception))
            }
        }
        catch [UploaderException]
        {
            LogIfSslError $_
            $PSCmdlet.ThrowTerminatingError($_)
        }
        catch
        {
            Log $_
            LogIfSslError $_
            $PSCmdlet.ThrowTerminatingError($_)
        }
    }
}