Functions.ps1

Function LoadModules([string[]]$modules, [bool]$installModule = $False)
{
    foreach ($module in $modules)
    {
        if (Get-Module -ListAvailable -Name $module)
        {
            Log "Module $module exists" $False
        }
        else
        {
            if ($installModule)
            {
                Log "Installing $module" $False
                Install-Module -Name $module -Scope CurrentUser -AllowClobber -Force
            }
            else
            {
                $msg = "Module $module is missing. You can either install it manually or add -Install in the cmdlet to auto-install all " +
                       "missing required modules"
                ThrowError ([UploaderError]::new($msg))
            }
        }
    }
}

Function ErrorIsResourceNotFound([object]$err)
{
    try
    {
        return $err[0].Exception.Message -like "*ResourceNotFound*"
    }
    catch
    {
    }
    return $False
}

Function GetVhdSize([string]$path)
{
    try
    {
        $fileSize = Get-VhdSize -File $path -RoundUp -IncludeFooterSize
        Log "VHD size for $path is $fileSize"
        return $fileSize
    }
    catch
    {
        ThrowError ([UploaderError]::new("Failed to get VHD size for $($path)", $_.Exception))
    }
}

Function InitUploadLog([string]$logFile, [bool]$overwrite)
{
    if ([String]::IsNullOrWhiteSpace($logFile))
    {
        $logFile = '.\Upload.log'
    }
    $Global:UploadLogFile = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($logFile)
    $timestamp = (Get-Date).ToUniversalTime().ToString("u")
    if ($overwrite)
    {
        "$($timestamp): New log" | Out-File -FilePath $Global:UploadLogFile
    }
    else
    {
        "$($timestamp): New log" | Out-File -FilePath $Global:UploadLogFile -Append
    }
    Write-Host "Logging to $($Global:UploadLogFile)"
}

Function Log([string]$message, [bool]$echoToScreen = $True)
{
    $timestamp = (Get-Date).ToUniversalTime().ToString("u")
    $stampedMessage = "$($timestamp): $message"
    if ($echoToScreen)
    {
        Write-Host $stampedMessage
    }
    $stampedMessage | Out-File -FilePath $Global:UploadLogFile -Append
}

Function LogWarning([string]$message) {
    if ($null -ne $Global:UploadLogFile) {
        Write-Warning $message
        $timestamp = (Get-Date).ToUniversalTime().ToString("u")
        "$($timestamp): $message" | Out-File -FilePath $Global:UploadLogFile -Append
    }
}

Function LogIfSslError([System.Management.Automation.ErrorRecord]$err)
{
    if (CheckForSSLError $err)
    {
        Log ("There was a SSL/TLS error while trying to copy the disk. This is commonly caused by there being an intercepting proxy between " +
             "the machine the command is being run on and the cloud. Check with your network administrator.")
    }
}

Function CheckForSSLError([System.Management.Automation.ErrorRecord]$err)
{
    $ex = $err.Exception
    while ($null -ne $ex)
    {
        if ($ex.Message -like '*remote certificate is invalid*' -or $ex.Message -like '*certificate verify failed*')
        {
            return $True
        }
        $ex = $ex.InnerException
    }
    return $False
}

Function ThrowError([UploaderError]$exception, [bool]$echoToScreen = $True)
{
    if ($null -eq $exception.InnerException)
    {
        Log "$($exception.Message)." $echoToScreen
    }
    else
    {
        Log "$($exception.Message). $($exception.InnerException.Message)" $echoToScreen
    }
    throw $exception
}