Upgrade.ps1

function update-netapp-cbs-appliance { 
  
  [CmdletBinding()]
  param(          
    [Parameter(Mandatory)]
    [System.Management.Automation.PSCredential]
    $scvcredential
  )
 
  BEGIN {
      
    $ISOName = "Cb-vm-1.0x11.iso"
    $ContainerName = "cbsavsanfova"   
    $StorageAccountName = "cbsavsanfovahosting"   
    
    $ApplianceUser = $ApplianceUser.Trim()
  }

  PROCESS {
    
    Write-DebugLog -Message "Update-NetAppCBSAppliance execution is started."
    
    Invoke-PreflightNetAppCBSAVSCheck

    Write-DebugLog -Message "Downloading ISO file..." 
    $GetLocation = Get-Location
    Write-DebugLog -Message "OVA path: $GetLocation"
    Write-DebugLog -Message "Source path: $GetLocation/$ISOName"
    
    try {
      $BlobContent = Get-BlobContent -BlobName $ISOName -StorageAccountName $StorageAccountName -ContainerName $ContainerName -ErrorAction Stop
      Write-DebugLog -Message $BlobContent
      Write-DebugLog -Message "ISO file downloaded."
    }
    catch {
      Write-DebugLog -Message $_.exception | Out-String
      Write-Error -ErrorId  "UPGRADE_DOWNLOAD_ISO_FAILED" -Message  "Unable to download the ISO file."
      Write-Error $_.exception.message  -ErrorAction Stop
    } 

    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
    
    $scvLogin = $scvcredential.UserName
    $scvPwd = $scvcredential.GetNetworkCredential().Password
    
    $Body = @{
      username = $scvLogin
      password = $scvPwd
    }     
  
    $mobObject = (Get-View ExtensionManager | Select-Object -ExpandProperty ExtensionList | Select-Object Key, @{N = 'Server'; E = { $_.Server.url } } |  Where-Object { $_.Key -eq "com.netapp.aegis" })
    Write-DebugLog $mobObject | out-string

    if ($mobObject) {
      Write-DebugLog "Cloud Backup Service is registered"
      Write-DebugLog $mobObject.Server
      $serverUrl = $mobObject.Server
    }
    else {
      Write-DebugLog "Cloud Backup Service is not registered"
      Write-Error "Cloud Backup Service is not registered"  -ErrorAction Stop
    }
    
    Write-DebugLog $serverUrl
    $serverUrlWithouthHttps = $serverUrl.replace("https://", "")
    Write-DebugLog $serverUrlWithouthHttps
    $ApplianceIPAddress = $serverUrlWithouthHttps.substring(0, $serverUrlWithouthHttps.indexof(":"))
    Write-DebugLog "ApplianceIPAddress"
    Write-DebugLog $ApplianceIPAddress

    try {
      Write-DebugLog -Message "Validating appliance credentials"    
      $scvURL = "https://$ApplianceIPAddress"
      
      $JsonBody = $Body | ConvertTo-Json  
      $response = Invoke-RestMethod -Uri $scvURL":8080/login" -Body $JsonBody -Method POST -ContentType "application/json" -SkipCertificateCheck
        
      if ($response.PSObject.Properties.Match('error').Count) {
        Write-DebugLog -Message $response.error | Out-String
    
        if ($response.error.name -eq "USER_NAME_OR_PASSWORD_DO_NOT_MATCH") {
          Write-Error -ErrorId  "UPGRADE_USER_NAME_OR_PASSWORD_DO_NOT_MATCH" -Message  "Unable to login to appliance"
          Write-Error $response.error.message  -ErrorAction Stop
        }
        else {
          Write-Error -ErrorId  "UPGRADE_UNABLE_TO_LOGIN" -Message  "Unable to login to appliance"
          Write-Error $response.error.message  -ErrorAction Stop
        }
      }
      else {
        Write-DebugLog -Message "Appliance user credential validated"
      }
    }
    catch {
      Write-Error $_.exception.message  -ErrorAction Stop
    }  
    
    $ApplianceVirtualMachine = Get-ApplianceVirtualMachineUsingTag
  
    Test-ApplianceExistOrNot -ApplianceVirtualMachine  $ApplianceVirtualMachine

    $vmObject = Get-VM -Name  $ApplianceVirtualMachine
    $IsIPInExtensionData = $vmObject.ExtensionData.Guest.IpAddress -eq $ApplianceIPAddress
        
    Write-DebugLog "IsIPInExtensionData : $IsIPInExtensionData"
        
    if ($IsIPInExtensionData -eq $false) {
      Write-DebugLog "Appliance IP address not found"
      Write-Error "No IP address assigned for the appliance"  -ErrorAction Stop
    }
  
    $VmDatastore = Get-Datastore -RelatedObject $ApplianceVirtualMachine
  
    Test-DataStore -VmDatastore $VmDatastore -FreeSapce 2
 
    Restart-VMwareVM -ApplianceVirtualMachine $ApplianceVirtualMachine
    
    Test-Installation -ApplianceIPAddress "" -ApplianceVirtualMachine $ApplianceVirtualMachine
        
    Write-DebugLog -Message "Test-Installation execution is completed"
    
    $vmObject = Get-VM -Name  $ApplianceVirtualMachine
    $ApplianceIPAddress = $vmObject.ExtensionData.Guest.IpAddress
    
    Write-DebugLog -Message  "Generate datastore drive name"    
       
    $suffix = 0
    $ds = "cbsdsdrvup0"

    while ($true) {
      $suffix = $suffix + 1;
      $ds = "cbsdsdrvup${suffix}"
      $isDSDsDriveEXist = Test-Path -Path ${ds}:\
      Write-DebugLog -Message "DataStoreDrive Name = $ds : isDSDsDriveEXist : $isDSDsDriveEXist"  
      if ($isDSDsDriveEXist -eq $false) {       
        Write-DebugLog -Message "Break while loops"  
        break
      }
    }
      
    try {
      Write-DebugLog -Message  "Get-Datastore $VmDatastore | New-DatastoreDrive -Name ${ds}" | Out-String  
      $NewDatastoreDrive = Get-Datastore $VmDatastore | New-DatastoreDrive -Name ${ds}  -ErrorAction Stop   
    }
    catch {
      Write-DebugLog -Message  "Error while creating datastore drive."
      Write-DebugLog -Message  $_.exception | Out-String
      Write-Error -ErrorId "UPGRADE_NEW_DATASTORE_DRIVE_FAILED" -Message  "Error while creating datastore drive."
      Write-Error $_.exception.Message  -ErrorAction Stop
    }
  
    Write-DebugLog -Message  "Generate folder name" 
  
    $suffix = 0;
    $CbsFolderName = "UpdateCBSISOfiles0";  
    while ($true) {
      $suffix = $suffix + 1;
      $CbsFolderName = "UpdateCBSISOfiles${suffix}"
      $isIsoFolderEXist = Test-Path -Path ${ds}:\$CbsFolderName
      Write-DebugLog -Message "ISO Folder Name = ${ds}:\$CbsFolderName : isDSDsDriveEXist : $isIsoFolderEXist"  
      if ($isIsoFolderEXist -eq $false) {       
        Write-DebugLog -Message "Break while loop"  
        break
      }
    }
     
    Write-DebugLog -Message  "Folder name generated" 
  
    Write-DebugLog -Message  "Test-Path -Path ${ds}:\${CbsFolderName}"
    $isIsoFolderEXist = Test-Path -Path "${ds}:\${CbsFolderName}"
    Write-DebugLog -Message  "isIsoFolderEXist = $isIsoFolderEXist"
    if ($isIsoFolderEXist -eq $false) {
      try {
        Write-DebugLog -Message  "New-Item -Type Directory -Path ${ds}:\${CbsFolderName} | Out-Null"
        New-Item -Type Directory -Path ${ds}:\${CbsFolderName}  | Out-Null
      }
      catch {
        Write-DebugLog -Message  $_.exception | Out-String
        Write-DebugLog -Message "Error while creating datastore folder ${ds}:\${CbsFolderName}."
      }
    }
      
    try {
      $GetLocation = Get-Location
      Write-DebugLog -Message "OVA path: $GetLocation"
      Write-DebugLog -Message "Source path: $GetLocation/$ISOName"
      Write-DebugLog -Message "Copy-DatastoreItem -Item -Destination -Force"
      $NewDatastoreDrive = Copy-DatastoreItem -Item "$GetLocation/$ISOName" -Destination ${ds}:\${CbsFolderName}\0.iso -Force
    }
    catch {
      Write-DebugLog  -Message $_.exception | Out-String
      Write-Error  -ErrorId "upgrade-copydatastore-failed" -Message  $_.exception.Message -ErrorAction Stop 
    }
      
    try {
      Write-DebugLog -Message "Mount datastore"
      Write-DebugLog -Message "Get-VM -Name $ApplianceVirtualMachine | Get-CDDrive | Set-CDDrive -IsoPath [$VmDatastore]${CbsFolderName}\0.iso -Confirm:$false -Connected $true "
      $CDDrive = Get-VM -Name $ApplianceVirtualMachine | Get-CDDrive | Set-CDDrive -IsoPath "[$VmDatastore]${CbsFolderName}\0.iso" -Confirm:$false -Connected $true
    }
    catch {
      Write-Error  -ErrorId "UPGRADE_MOUNT_FAILED" -Message  $_.exception.Message
      Write-DebugLog  -Message $_.exception  | Out-String 
    }
  
    $Body = @{
      username = $scvLogin
      password = $scvPwd
    }     
        
    $scvURL = "https://$ApplianceIPAddress"
    
    $JsonBody = $Body | ConvertTo-Json
    
    $response = Invoke-RestMethod -Uri $scvURL":8080/login" -Body $JsonBody -Method POST -ContentType "application/json" -SkipCertificateCheck
      
    $token = $response.result.token
    $Header = @{ Authorization = "Bearer $token" }
        
    $currentVersion = Invoke-RestMethod -Uri $scvURL":8080/api/rest/v1/agentversion" -Headers $Header -ContentType "application/json" -SkipCertificateCheck
      
    if ($currentVersion) {
      Write-DebugLog -Message "currentVersion" 
      Write-DebugLog -Message $currentVersion  | Out-String 
      Write-DebugLog -Message "currentVersion.result"
      Write-DebugLog -Message $currentVersion.result | Out-String 
      Write-DebugLog -Message  "currentVersion.result.scv_build"
      Write-DebugLog -Message  $currentVersion.result.scv_build | Out-String     
    }
    else {
      Write-DebugLog -Message "currentVersion is empty"
    }
  
    try {
      $logFile = Invoke-RestMethod -Uri $scvURL":8080/api/rest/v1/upgrade" -Headers $Header -Method POST -ContentType "application/json" -SkipCertificateCheck
      if ($logFile) {
        Write-DebugLog -Message "logFile created"
      }
      else {
        Write-DebugLog -Message "logFile is empty" 
      }
      
      Write-DebugLog -Message "Sleep for 3 minutes..." 
      Start-Sleep 300
          
      $response = Invoke-RestMethod -Uri $scvURL":8080/login" -Body $JsonBody -Method POST -ContentType "application/json" -SkipCertificateCheck
      $token = $response.result.token
      $Header = @{ Authorization = "Bearer $token" }
      $upgradedVersion = Invoke-RestMethod -Uri $scvURL":8080/api/rest/v1/agentversion" -Headers $Header -ContentType "application/json" -SkipCertificateCheck
      
      if ($upgradedVersion) {
        Write-DebugLog -Message "currentVersion" 
        Write-DebugLog -Message $upgradedVersion  | Out-String 
        Write-DebugLog -Message "currentVersion.result"
        Write-DebugLog $upgradedVersion.result | Out-String 
        Write-DebugLog -Message  "currentVersion.result.scv_build"
        Write-DebugLog -Message  $upgradedVersion.result.scv_build | Out-String     
      }
      else {
        Write-DebugLog -Message "Upgraded Version is empty"
      }
  
      if ($currentVersion.result.scv_build -ne $upgradedVersion.result.scv_build -or $currentVersion.result.scv_version -ne $upgradedVersion.result.scv_version) {
        Write-DebugLog -Message  "Upgrade of virtual appliance is successful."
        
      }
      else {
        $Parameters = @{
          filePath = $logFile.result.logFileName
        }
  
        $logFileContent = Invoke-RestMethod -Uri $scvURL":8080/api/rest/v1/readlogfile" -Headers $Header -Body $Parameters -ContentType "application/json" -SkipCertificateCheck
        Write-Error -Message "Upgrade of virtual appliance is failed."
        Write-Error -ErrorId "upgrade-log-failed"  -Message $logFileContent.result.logFileContent 
        Write-DebugLog -Message "Upgrade of virtual appliance is failed."
        Write-DebugLog -Message $logFileContent.result.logFileContent  
      }  
    }
    catch {
      Write-DebugLog -Message  $_.exception | Out-String
      Write-Error -Message $_.exception.message
    }
  
    # Below code is to make sure if upgrade fails, cd drive should be disconnected before deleting temporary
    # cd drives and folders created during upgrade steps.
    try {
      #disconnect
      Get-VM -Name $ApplianceVirtualMachine | Get-CDDrive | Set-CDDrive -NoMedia -Confirm:$false
    }
    catch {
      Write-DebugLog -Message  $_.exception | Out-String
    }
  
    try {
      Write-DebugLog -Message  "Removing folder for ISO"
      Remove-Item ${ds}:\${CbsFolderName} -Recurse
    }
    catch {
      Write-DebugLog -Message  "Error while deleting datastore folder."
      Write-DebugLog -Message   $_.exception | Out-String
      Write-Error -ErrorId $_.exception.message
    }
      
    try {
      Write-DebugLog -Message  "Remove-PSDrive -Name"
      Write-DebugLog -Message "Remove-PSDrive -Name ${ds}"
      Remove-PSDrive -Name ${ds}
    }
    catch {
      Write-DebugLog -Message  "Error while deleting datastore folder."
      Write-DebugLog -Message  $_.exception | Out-String
      Write-Error -ErrorId $_.exception.message
    }    
  }

  END {
    Write-DebugLog -Message "Update-NetAppCBSAppliance execution is completed"
  }   
}