MigrateTo-AzureRM.psm1

function MigrateTo-AzureRM {
                <#
            .SYNOPSIS
            Migrates Azure Classic Virtual Networks, and all dependent resources to Resource Manager.
 
 
            .DESCRIPTION
            Running this command will allow you to migrate a Virtual Network, and the resources within it to Resource Manager.
 
            If you choose not to specify subscription ID's, a Virtual Network Name, Credentials, etc. you will be provided with an interface via the command line.
             
            .PARAMETER AzureCredentials
            You can pass in a credential object to use to sign in to Azure.
 
 
            .PARAMETER RMSubscriptionId
            Used to specify the ID of the subscription you want to migrate your Virtual Network and it's resources to.
 
 
 
            .PARAMETER ClassicSubscriptionId
            Used to specify the ID of the subscription where your Classic resources are located.
 
 
 
            .PARAMETER VirtualNetworkName
            Specify the name of the classic Virtual Network you would like to migrate.
 
             
            .PARAMETER Force
            Specify this switch to automatically choose "yes" when committing the migration after the migration preparation.
 
 
            .EXAMPLE
            The following example will run the function silently:
 
            $c = Get-Credential
            MigrateTo-AzureRM -AzureCredentials $c `
                  -RMSubscriptionId e87ec6e6-874c-4295-9ba2-17ddb4bfd911 `
                  -ClassicSubscriptionId e87ec6e6-874c-4295-9ba2-17ddb4bfd911 `
                  -VirtualNetworkName MIG-VNet `
                  -Force
 
            .EXAMPLE
            If you are unsure of what information to pass in to the cmdlet, the following example will provide an interactive interface for the user to provide input:
 
            MigrateTo-AzureVM
 
            #>

    [CmdletBinding()]
    param(
        [System.Management.Automation.PSCredential]$AzureCredentials = (Get-Credential -Message "Please enter Azure credentials"),
        [string]$RMSubscriptionId,
        [string]$ClassicSubscriptionId,
        [string]$VirtualNetworkName,
        [switch]$Force
    
    )



    #--------------------------------------------------------------------------------------------------------------------------------------
    # Prepare for Migration
    #--------------------------------------------------------------------------------------------------------------------------------------
    $ModulesRequired="Azure","AzureRM"

    foreach ($Module in $ModulesRequired)
    {

        if (!(Get-Package -Name $Module -ProviderName PowerShellGet -ErrorAction SilentlyContinue))
        {
            Write-Host "The required module, $Module, was not found on this computer. Attempting to install now..." -ForegroundColor
            Find-Package -Name $Module -ProviderName PowerShellGet -Source PSGallery | Install-Package -Force
            if (!$?) { write-host "Failed to install module: $Module - you may need to run PowerShell in an elevated prompt..." ; break}
        }

    }

    Clear-AzureProfile -Force



    #--------------------------------------------------------------------------------------------------------------------------------------
    # Azure RM Login
    #--------------------------------------------------------------------------------------------------------------------------------------

    try
    {
        $loggingin = Login-AzureRmAccount -Credential $AzureCredentials
        Write-Host " "
        Write-Host " "
        Write-Host "Logged into tenant $($loggingin.Context.Tenant) using login $($loggingin.Context.Account)" -ForegroundColor Green
    }
    catch
    {
        Write-Host $Error[0].Exception.Message -ForegroundColor Red
        break
    }

    if ($RMSubscriptionId)
    {
        $RMSubID = $RMSubscriptionId
       
        try
        {
            Select-AzureRmSubscription -SubscriptionId $RMSubID | Out-Null
        }
        catch
        {
            Write-Error "The Azure RM Subscription ID you provided is invalid. Please verify the ID is correct, or specify the function without the `"-RMSubscriptionID`" parameter."
            break
        }

    }
    else
    {
        $Subscriptions = Get-AzureRmSubscription -WarningAction SilentlyContinue

        if ($Subscriptions.Count -eq 1)
        {
            Select-AzureRmSubscription -SubscriptionId $Subscriptions.SubscriptionId | out-null
            $RMSubID = $Subscriptions.SubscriptionId
        }

        elseif ($Subscriptions.Count -gt 1)
        {

            $SubNum = 1
            Write-host " "
            Write-host "Please choose the Subscription for AZURE RESOURCE MANAGER" -ForegroundColor Yellow
            Write-host "---------------------------------------------------------" -ForegroundColor Yellow
            
            foreach ($Subscription in $Subscriptions)
            {
                Write-host "$($SubNum): " -ForegroundColor Green -NoNewline
                Write-host "$($Subscription.SubscriptionName) ($($Subscription.SubscriptionId))" -ForegroundColor Yellow
                $SubNum++
            }

            Write-host " "
            do
            {
                Write-Host "You have more than one subscription, please enter the number of the subscription you wish to use:" -ForegroundColor Yellow
                $SubOption = Read-host

                if (($SubOption -gt $SubNum) -or ($SubOption -eq 0))
                {
                    Write-Host "That number does not correlate to any of your subscriptions!" -ForegroundColor Red
                }

            } while (($SubOption -gt $SubNum) -or ($SubOption -eq 0))

            Write-host "Using Azure Subscription: $($Subscriptions[($SubOption - 1)].SubscriptionName)" -ForegroundColor Green
            Select-AzureRmSubscription -SubscriptionId $($Subscriptions[($SubOption - 1)].SubscriptionId) | out-null
            $RMSubID = $($Subscriptions[($SubOption - 1)].SubscriptionId)
        }
        else
        {
            Write-Error "You have no Subscriptions"
            break   
        }

    }


    #--------------------------------------------------------------------------------------------------------------------------------------
    # Azure Classic Login
    #--------------------------------------------------------------------------------------------------------------------------------------
    try
    {
        Add-AzureAccount -Credential $AzureCredentials | out-null
    }
    catch
    {
        Write-Host $Error[0].Exception.Message -ForegroundColor Red
        break
    }

    if ($ClassicSubscriptionId)
    {
        $CLSubID = $ClassicSubscriptionId

        try
        {
            Select-AzureSubscription -SubscriptionId $CLSubID | Out-Null
        }
        catch
        {
            Write-Error "The Azure Classic Subscription ID you provided is invalid. Please verify the ID is correct, or specify the function without the `"-ClassicSubscriptionID`" parameter."
            break
        }

    }
    else
    {
        $Subscriptions = Get-AzureSubscription -WarningAction SilentlyContinue

        if ($Subscriptions.Count -eq 1)
        {
            Select-AzureSubscription -SubscriptionId $Subscriptions.SubscriptionId
            $CLSubID = $Subscriptions.SubscriptionId
        }
        elseif ($Subscriptions.Count -gt 1)
        {
            $SubNum = 1
            Write-Host " "
            Write-host "Please choose the Subscription for AZURE CLASSIC" -ForegroundColor Yellow
            Write-host "------------------------------------------------" -ForegroundColor Yellow

            foreach ($Subscription in $Subscriptions)
            {
                Write-host "$($SubNum): " -ForegroundColor Green -NoNewline
                Write-host "$($Subscription.SubscriptionName) ($($Subscription.SubscriptionId))" -ForegroundColor Yellow
                $SubNum++
            }

            Write-host " "

            do
            {
                Write-Host "You have more than one subscription, please enter the number of the subscription you wish to use:" -ForegroundColor Yellow
                $SubOption = Read-host

                if (($SubOption -gt $SubNum) -or ($SubOption -eq 0))
                {
                    Write-Host "That number does not correlate to any of your subscriptions!" -ForegroundColor Red
                }
                else
                {
                    Write-host "Using Azure Subscription: $($Subscriptions[($SubOption - 1)].SubscriptionName)" -ForegroundColor Green
                    Select-AzureSubscription -SubscriptionId $($Subscriptions[($SubOption - 1)].SubscriptionId)
                    $CLSubID = $($Subscriptions[($SubOption - 1)].SubscriptionId)
                }

            } while (($SubOption -gt $SubNum) -or ($SubOption -eq 0))

        }
        else
        {
            Write-Error "You have no Subscriptions"
            break
        }
    }



    #--------------------------------------------------------------------------------------------------------------------------------------
    # Register Subscriptions to required namespace
    #--------------------------------------------------------------------------------------------------------------------------------------
    $RegisterUpdate = $false
    Write-Host " "
    Write-Host "Checking ProviderNamespace Registration for selected subscriptions..." -ForegroundColor Yellow

    foreach ($ID in ($RMSubID,$CLSubID))
    {
        Select-AzureRmSubscription -SubscriptionId $ID | Out-Null

        if (!((Get-AzureRmResourceProvider -ProviderNamespace Microsoft.ClassicInfrastructureMigrate).RegistrationState -eq "Registered"))
        {
            Register-AzureRmResourceProvider -ProviderNamespace Microsoft.ClassicInfrastructureMigrate -Force
            $RegisterUpdate = $true
        }

    }

    if ($RegisterUpdate)
    {
        Write-Host " "
        Write-Host "One or more ProvideNamespaces required registration, waiting for registration to propogate..." -ForegroundColor Yellow
        $percentage = 0.2777777777777778

        for ($a=1; $a -lt 360; $a++)
        {
            $percentage += 0.2777777777777778
            Write-Progress -Activity "Updating Microsoft.ClassicInfrastructureMigrate Registration..." -SecondsRemaining $(600 - $a) -PercentComplete $percentage -Status "Updating..."
            Start-Sleep 1
        }

        Write-Progress -Activity "Updating Microsoft.ClassicInfrastructureMigrate Registration..." -Completed -Status "Updated."
    }

    Select-AzureRmSubscription -SubscriptionId $RMSubID | Out-Null



    #--------------------------------------------------------------------------------------------------------------------------------------
    # Virtual Network selection
    #--------------------------------------------------------------------------------------------------------------------------------------
    $VNets = Get-AzureVNetSite

    if ($VirtualNetworkName)
    {

        if ($VNets | ? { $_.Name -ieq $VirtualNetworkName})
        {
            Write-Host " "
            Write-host "Preparing for migration of Azure Virtual Network $($VNets[($VNetOption - 1)].Name)..." -ForegroundColor Yellow
            Write-Host " "
            Write-Host "VERBOSE LOG" -ForegroundColor Cyan
            Move-AzureVirtualNetwork -Prepare -VirtualNetworkName $($VNets[($VNetOption - 1)].Name) -Verbose
            Write-Host " "

            if ($?)
            {
                Write-Host "Preparation Complete." -ForegroundColor Green
            }
            else
            {
                $Error[0]
                break
            }

        }
        else
        {

        }

    }
    else
    {
        $VNetNum = 1
        Write-Host " "
        Write-host "Which Virtual Network would you like to migrate?" -ForegroundColor Yellow
        Write-host "------------------------------------------------" -ForegroundColor Yellow

        foreach ($VNet in $VNets)
        {
            Write-host "$($VNetNum): " -ForegroundColor Green -NoNewline
            Write-host "$($VNet.Name) ($($VNet.Location))" -ForegroundColor Yellow
            $VNetNum++
        }

        Write-host " "

        do
        {
            Write-Host "You have more than one Virtual Network, please enter the number of the Virtual Network you wish to migrate:" -ForegroundColor Yellow
            $VNetOption = Read-host

            if (($VNetOption -gt $VNetNum) -or ($VNetOption -eq 0))
            {
                Write-Host "That number does not correlate to any of your Virtual Networks!" -ForegroundColor Red
            }
            else
            {
                Write-Host " "
                Write-host "Preparing for migration of Azure Virtual Network $($VNets[($VNetOption - 1)].Name)..." -ForegroundColor Yellow
                Write-Host " "
                Write-Host "VERBOSE LOG" -ForegroundColor Cyan
                Move-AzureVirtualNetwork -Prepare -VirtualNetworkName $($VNets[($VNetOption - 1)].Name) -Verbose
                Write-Host " "

                if ($?)
                {
                    Write-Host "Preparation Complete." -ForegroundColor Green
                }
                else
                {
                    pause
                }

            }


        } while (($VNetOption -gt $VNetNum) -or ($VNetOption -eq 0))

    }

    do
    {

        if (!$Force)
        {
            Write-Host "The Virtual Network is now ready to be moved. Would you like to continue? (y/n)" -ForegroundColor Yellow
            $MoveOption = Read-Host 
        }
        else
        {
            $MoveOption = 'y'
        }

        if ($MoveOption -ieq "y")
        {
            Write-Host "Committing Migration..." -ForegroundColor Yellow
            Write-Host " "
            Write-Host "VERBOSE LOG" -ForegroundColor Cyan
            Move-AzureVirtualNetwork -Commit -VirtualNetworkName $($VNets[($VNetOption - 1)].Name) -Verbose
            Write-Host " "
        }
        elseif ($MoveOption -ieq "n")
        {
            Write-Host "Aborting Migration..." -ForegroundColor Yellow
            Write-Host " "
            Write-Host "VERBOSE LOG" -ForegroundColor Cyan
            Move-AzureVirtualNetwork -Abort -VirtualNetworkName $($VNets[($VNetOption - 1)].Name) -Verbose
            Write-Host " "
        }
        else
        {
            Write-Host "You did not provide a valid option!" -ForegroundColor Red
        }

    } while (($MoveOption -ine "y") -and ($MoveOption -ine "n"))

} 

Export-ModuleMember -Function MigrateTo-AzureRM