Start-IpsGcpPrepareJob.ps1

<#
 .Synopsis
  Implement an image prepare job.

 .Description
  Implement an image prepare job. This function supports preparing image on Google cloud platform.
#>

Function Start-IpsGcpPrepareJob
{
    [CmdletBinding(DefaultParameterSetName = 'cmd')]
    Param(
        [Parameter(Mandatory = $true, ParameterSetName = 'file')]
        [obsolete("Use command-line arguments as input of configuration data.")]
        [string]$ConfigJsonFile,
        [Parameter(Mandatory = $true, ParameterSetName = 'cmd')]
        [string]$CustomerId,
        [Parameter(Mandatory = $true, ParameterSetName = 'cmd')]
        [string]$CloudProvisioningType,
        [Parameter(Mandatory = $true, ParameterSetName = 'cmd')]
        [string]$CloudCwSecretId,
        [Parameter(Mandatory = $true, ParameterSetName = 'cmd')]
        [string]$CloudDiskName,
        [Parameter(Mandatory = $true, ParameterSetName = 'cmd')]
        [psobject[]]$XdReconfigure,
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [string]$Deployment,
        [Parameter(Mandatory = $true, ParameterSetName = 'cmd')]
        [string]$ResourceLocationId,
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [string]$GcpZone = "us-east4-a",
        [Parameter(Mandatory = $true, ParameterSetName = 'cmd')]
        [string]$VpcNetworkName,
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [string]$VpcNetworkSubnetName,
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [bool]$UsePublicIP = $false,
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [string[]]$NetworkTags,
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [string]$AssetsId,
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [psobject]$Tags = [PSCustomObject]@{},
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [int]$Timeout = 3600,
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [string]$Prefix = "ce",
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [bool]$CeDebug,
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [bool]$InstallMisa = $true,
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [bool]$ForceMisa = $false,
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [string]$InstallPvs,
        [Parameter(Mandatory = $false, ParameterSetName = 'cmd')]
        [string[]]$Flags,
        [Parameter(Mandatory = $false)]
        [string]$SecureClientId = '',
        [Parameter(Mandatory = $false)]
        [string]$SecureSecret = '',
        [Parameter(Mandatory = $false)]
        [string]$LogFileName = 'PrepareGcp.log',
        [Parameter(Mandatory = $false)]
        [switch]$OverwriteLog,
        [Parameter(Mandatory = $false)]
        [switch]$Force
    )

    Begin
    {
        Add-PSSnapin Citrix.*
    }
    Process
    {
        # Initialize Logger
        # Set parameter 'Verbose' by internal parameter 'VerbosePreference', since the option -Verbose is occupied by powershell cmdlet
        if($VerbosePreference -eq 'Continue')
        {
            $Verbose = $True
        } else {
            $Verbose = $False
        }
        LogInit $LogFileName $OverwriteLog $Verbose

        # Initialize config data
        if ($PSCmdlet.ParameterSetName -eq 'file') {
            LogIt "Loading config from $ConfigJsonFile"
            $configData = Get-Content -Raw -Path $ConfigJsonFile | ConvertFrom-Json
            LogIt "Config: $configData" $False
            $CustomerId = $configData.CustomerId
            $CloudProvisioningType = $configData.CloudProvisioningType
            $CloudCwSecretId = $configData.CloudCwSecretId
            $CloudDiskName = $configData.CloudDiskName
            $XdReconfigure = $configData.XdReconfigure
            $Deployment = $configData.Deployment
            if($configData.psobject.Properties.name -contains "PrepareResourceLocationId") { $ResourceLocationId = $configData.PrepareResourceLocationId }
            else { $ResourceLocationId = $configData.ResourceLocationId }
            if([String]::IsNullOrWhiteSpace($configData.GcpZone)) { $GcpZone = "us-east4-a" }
            else { $GcpZone = $configData.GcpZone }
            $VpcNetworkName = $configData.VpcNetworkName
            $VpcNetworkSubnetName = $configData.VpcNetworkSubnetName
            $UsePublicIP = $configData.UsePublicIP
            $NetworkTags = $configData.NetworkTags
            $AssetsId = $configData.AssetsId
            if($configData.psobject.Properties.name -contains "Tags") { $Tags = $configData.Tags }
            if([String]::IsNullOrWhiteSpace($configData.Timeout)) { $Timeout = 3600 }
            else { $Timeout = [int]$configData.Timeout }
            if([String]::IsNullOrWhiteSpace($configData.Prefix)) { $Prefix = "ce" }
            else { $Prefix = $configData.Prefix }
            $CeDebug = $configData.CeDebug
            $InstallMisa = $configData.InstallMisa
            $ForceMisa = $configData.ForceMisa
            $InstallPvs = $configData.InstallPvs
            $Flags = $configData.Flags
        }

        try {
            # Authenticate to Citrix Cloud
            $parameters = AuthToCitrixCloud $CustomerId $SecureClientId $SecureSecret
            if ([string]::IsNullOrWhiteSpace($SecureClientId) -Or [string]::IsNullOrWhiteSpace($SecureSecret)) {
                $SecureClientId = $parameters.ApiKey
                $SecureSecret = $parameters.SecretKey
            }
        }
        catch {
            return
        }

        # Prepare
        try {
            LogIt "Starting prepare workflow"
            #
            # Run the prepare workflow
            #
            Write-Host "***** Call Method: PrepareImageJob *****"
            $platformPrepareData = @{
                zone = $GcpZone
                VpcNetworkName = $VpcNetworkName
                UsePublicIP = $UsePublicIP
                targetImageName = $CloudDiskName
            }
            if ($VpcNetworkSubnetName) {
                $platformPrepareData["VpcNetworkSubnetName"] = $VpcNetworkSubnetName
            }
            if ($NetworkTags) {
                $platformPrepareData["NetworkTags"] = $NetworkTags
            }
            #Add default tags
            $Tags = Convert-ObjectToHashtable $Tags
            $Tags['ctx-user'] = ($env:UserName).ToLower()
            $prepareData = @{
                platform = "Gcp"
                provisioningType = $CloudProvisioningType
                platformCredentialId = $CloudCwSecretId
                resourceLocationId = $ResourceLocationId
                XdReconfigure = $XdReconfigure
                tags = $Tags
                timeoutInSeconds = $Timeout
                prefix = $Prefix
                ceDebug = $CeDebug
            }
            if ($AssetsId)
            {
                $prepareData['assetsId'] = $AssetsId
            }
            if ($CloudProvisioningType -eq "Pvs")
            {
                if ($InstallPvs)
                {
                    $prepareData['installPvs'] = $InstallPvs
                }
                $prepareData['installMisa'] = $false
                $prepareData['forceMisa'] = $false
            }
            elseif ($CloudProvisioningType -eq "Mcs")
            {
                $prepareData['installMisa'] = $InstallMisa
                $prepareData['forceMisa'] = $ForceMisa
            }
            if ($Flags)
            {
                $prepareData['flags'] = $Flags
            }
            # Convert the object to JSON to use in the POST body (Note: Default depth is 2 when serializing)
            $json = ($prepareData + $platformPrepareData) | ConvertTo-Json -Depth 10
            LogIt "$($prepareData["CloudProvisioningType"]) Prepare POST body $json" $False

            # Send the POST
            try {
                $response = Invoke-CCRestMethod 'Post' $Deployment "images/`$prepare" $CustomerId $SecureClientId $SecureSecret $True $json
                $JobId = $response.id
                LogIt "Image Prepare started with id $JobId"
            } catch {
                throw "Failed to start prepare: $_"
            }
        }
        catch {
            LogIt "Workflow failed: $_"
            exit 1
        }
        finally {
            #Check if it comes to the end of pipeline
            if ($PSCmdlet.MyInvocation.PipelinePosition  -lt $PSCmdlet.MyInvocation.PipelineLength) {
                $output = [PSCustomObject]@{
                    CustomerId = $CustomerId
                    Deployment = $Deployment
                    JobId = $JobId
                    LogFileName = $LogFileName
                }
                Write-Output $output
            } else{
                Clear-XDCredentials
            }
        }
    }
}