Copy-DiskToGCP.ps1
<# .SYNOPSIS Copy a disk to Google Cloud. .DESCRIPTION Copy a disk to a Google Cloud image. .PARAMETER FileName Specifies the filename of the disk to be copied. The file can be either local or on a share. .PARAMETER ImageName Specifies the name of the Google Cloud image to copy the disk to. .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. .PARAMETER ServiceAccountKeyFile Specifies the name of a file containing Google Cloud service principal credentials. .INPUTS None. .OUTPUTS None .EXAMPLE Copy-DiskToGCP -FileName C:\demo\disk.vhd -ImageName demo -ServiceAccountKeyFile demo-project-af94dadb30a1.json #> Function Copy-DiskToGCP { [CmdletBinding()] Param( [Parameter(Mandatory = $True)] [string] $FileName, [Parameter(Mandatory = $True)] [string] $ImageName, [Parameter(Mandatory = $True)] [string] $ServiceAccountKeyFile, [Parameter()] [int] $Threads, [Parameter()] [string] $LogFile, [Parameter()] [switch] $OverwriteLog, [Parameter()] [switch] $Force ) Begin { InitUploadLog $LogFile $OverwriteLog } Process { try { # Temporary solution to redirecting 1.48 assemblies that are compile time referenced in the Google.Api.Gax.Rest assemblies # to the 1.49 assemblies that the other Google assemblies reference # This is the powershell way to accomplish Binding Redirects, that are typically done in the configuration file. $modulePath = (Get-Item (Get-Module -Name Citrix.Image.Uploader).Path).DirectoryName $GoogleApis = [reflection.assembly]::LoadFrom($modulePath + "\bin\netstandard2.0\Google.Apis.dll") $GoogleApisCore = [reflection.assembly]::LoadFrom($modulePath + "\bin\netstandard2.0\Google.Apis.Core.dll") $GoogleApisAuth = [reflection.assembly]::LoadFrom($modulePath + "\bin\netstandard2.0\Google.Apis.Auth.dll") $OnAssemblyResolve = [System.ResolveEventHandler] { param($s, $e) Log "Resolving assembly '$($e.Name)'" $False if (($e.Name.StartsWith("Google.Apis.Core, Version=1.49.0.0")) -or ($e.Name.StartsWith("Google.Apis.Auth, Version=1.49.0.0")) -or ($e.Name.StartsWith("Google.Apis, Version=1.49.0.0"))) { Log ("This workaround may no longer be necessary. The Google assemblies may now be referencing the correct assemblies. " + "Try removing this event handler (OnAssemblyResolve) and try again.") $False } if ($e.Name -eq "Google.Apis.Core, Version=1.48.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab") { Log ("Forcing the Assembly '$($e.Name)' to be '$($GoogleApisCore.GetName().Name), " + "Version=$($GoogleApisCore.GetName().Version)'") $False return $GoogleApisCore } if ($e.Name -eq "Google.Apis.Auth, Version=1.48.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab") { Log ("Forcing the Assembly '$($e.Name)' to be '$($GoogleApisAuth.GetName().Name), " + "Version=$($GoogleApisAuth.GetName().Version)'") $False return $GoogleApisAuth } if ($e.Name -eq "Google.Apis, Version=1.48.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab") { Log "Forcing the Assembly '$($e.Name)' to be '$($GoogleApis.GetName().Name), Version=$($GoogleApis.GetName().Version)'" $False return $GoogleApis } foreach($a in [System.AppDomain]::CurrentDomain.GetAssemblies()) { if ($a.FullName -eq $e.Name) { return $a } } return $null } Log "Registering AssemblyResolve event handling" $False [System.AppDomain]::CurrentDomain.add_AssemblyResolve($OnAssemblyResolve) if ($Force) { CleanUpGcpDisk $ServiceAccountKeyFile $ImageName } $InformationPreference = "Continue" try { UploadToGcp $ImageName $FileName $ServiceAccountKeyFile $Global:UploadLogFile } catch [System.Reflection.ReflectionTypeLoadException] { Log "Message: $($_.Exception.Message)" $False Log "StackTrace: $($_.Exception.StackTrace)" $False Log "LoaderExceptions: $($_.Exception.LoaderExceptions)" $False try { Log "Redirected Google SDK package version and retry uploading process" UploadToGcp $ImageName $FileName $ServiceAccountKeyFile $Global:UploadLogFile } catch { ThrowError ([UploaderException]::new("Failed to copy the disk to Google Cloud", $_.Exception)) } } catch { ThrowError ([UploaderException]::new("Failed to copy the disk to Google Cloud", $_.Exception)) } } catch [UploaderException] { LogIfSslError $_ $PSCmdlet.ThrowTerminatingError($_) } catch { Log $_ LogIfSslError $_ $PSCmdlet.ThrowTerminatingError($_) } } } |