Before you apply patches or extensions to ESX/ESXi hosts, you might want to test the patches and extensions by applying them to hosts in a test environment. You can then use Update Manager PowerCLI to export the tested baselines to another Update Manager server instance and apply the patches and extensions to the other hosts.

Update Manager PowerCLI is a command-line and scripting tool built on Windows PowerShell, and provides a set of cmdlets for managing and automating Update Manager. For more information about installing and using Update Manager PowerCLI, see VMware vSphere Update Manager PowerCLI Installation and Administration Guide.

This workflow describes how to test patches by using one Update Manager instance and how to export the patch baseline containing the tested patches to another Update Manager instance.

  1. Create fixed host patch baselines.

    Create fixed patch baselines containing the patches that you want to test. Fixed patch baselines do not change their content when new patches are downloaded into the Update Manager patch repository. You can create a fixed patch baseline from the Baselines and Groups tab of the Update Manager Administration view. For more information and a detailed procedure, see Create a Fixed Patch Baseline.

  2. Attach the patch baselines to a container object containing the hosts that you want to scan or remediate.

    The container object can be a folder, cluster, or datacenter. You can attach baselines and baseline groups to objects from the Update Manager Compliance view. For more information about attaching baselines and baseline groups to vSphere objects, see Attach Baselines and Baseline Groups to Objects.

  3. Scan the container object.

    After you attach baselines to the selected container object, you must scan it to view the compliance state of the hosts in the container. You can scan selected objects manually to start the scanning immediately. For detailed instructions on how to scan your hosts manually, see Manually Initiate a Scan of ESX/ESXi Hosts.

    You can also scan the hosts in the container object at a time convenient for you by scheduling a scan task. For more information and detailed instructions about scheduling a scan, see Schedule a Scan.

  4. Review the scan results displayed in the Update Manager Client Compliance view.

    For a detailed procedure about viewing scan results and for more information about compliance states, see Viewing Scan Results and Compliance States for vSphere Objects.

  5. (Optional) Stage the patches in the attached baselines to the hosts that you want to update.

    You can stage the patches and copy them from the Update Manager server to the hosts before applying them. Staging patches speeds up the remediation process and helps minimize host downtime during remediation. For a detailed procedure about staging patches and extensions to hosts, see Stage Patches and Extensions to ESX/ESXi Hosts.

  6. Remediate the container object.

    Remediate the hosts that are in Non-Compliant state to make them compliant with the attached baselines. For more information about remediating hosts against patch or extension baselines, see Remediate Hosts Against Patch or Extension Baselines.

  7. Export the patch baselines from the Update Manager server that you used to test the patches, and import them to another Update Manager server.

    You can export and import patch baselines from one Update Manager server to another by using an Update Manager PowerCLI script. The following example script creates a duplicate of the baseline MyBaseline on the $destinationServer.

    Note:

    The script works for fixed and dynamic patch baselines as well as for extension baselines.

    # $destinationServer = Connect-VIServer <ip_address_of_the_destination_server>
    # $sourceServer = Connect-VIServer <ip_address_of_the_source_server>
    # $baselines = Get-PatchBaseline MyBaseline -Server $sourceServer
    # ExportImportBaselines.ps1 $baselines $destinationServer
    Param([VMware.VumAutomation.Types.Baseline[]] $baselines, [VMware.VimAutomation.Types.VIServer[]]$destinationServers)
    
    $ConfirmPreference = 'None'
    $includePatches = @()
    $excludePatches = @()
    
    function ExtractPatchesFromServer([VMware.VumAutomation.Types.Patch[]]$patches, 
    [VMware.VimAutomation.Types.VIServer]$destinationServer){
    	$result = @()
    	if ($patches -ne $null){
    		foreach($patch in $patches){
    			$extractedPatches = Get-Patch -Server $destinationServer -SearchPhrase $patch.Name
       if ($extractedPatches -eq $null){
        Write-Warning -Message "Patch '$($patch.Name)' is not available on the server $destinationServer"
       } else {
        $isFound = $false
        foreach ($newPatch in $extractedPatches){
         if ($newPatch.IdByVendor -eq $patch.IdByVendor){
          $result += $newPatch
          $isFound = $true
    	  		}
    	  	}
        if ($isFound -eq $false) {
         Write-Warning -Message "Patch '$($patch.Name)' with VendorId '$($patch.IdByVendor)' is not available on the server $destinationServer"
        }
       }
      }
     }
     return .$result;
    }
    
    function
    CreateStaticBaseline([VMware.VumAutomation.Types.Baseline]$baseline,[VMware.VimAutomation.Types.VIServer]$destinationServer){
     $includePatches = ExtractPatchesFromServer $baseline.CurrentPatches $destinationServer
     if ($includePatches.Count -lt 1){
      write-error "Static baseline '$($baseline.Name)' can't be imported. No one of the patches it contains are available on the server $destinationServer"
     } else {
      $command = 'New-PatchBaseline -Server $destinationServer -Name $baseline.Name -Description $baseline.Description -Static -TargetType $baseline.TargetType -IncludePatch $includePatches'
      if ($baseline.IsExtension) {
       $command += ' -Extension'
      }
    
      Invoke-Expression $command
     }
    }
    
    function 
    CreateDynamicBaseline([VMware.VumAutomation.Types.Baseline]$baseline,[VMware.VimAutomation.Types.VIServer]$destinationServer)
    {
     if ($baseline.BaselineContentType -eq 'Dynamic'){
      $command = 'New-PatchBaseline -Server $destinationServer -Name $baseline.Name -Description $baseline.Description -TargetType $baseline.TargetType -Dynamic -SearchPatchStartDate $baseline.SearchPatchStartDate - SearchPatchEndDate $baseline.SearchPatchEndDate -SearchPatchProduct $baseline.SearchPatchProduct -SearchPatchSeverity $baseline.SearchPatchSeverity -SearchPatchVendor $baseline.SearchPatchVendor'
     } elseif ($baseline.BaselineContentType -eq 'Both'){
    		$includePatches = ExtractPatchesFromServer $baseline.InclPatches $destinationServer
     	$excludePatches = ExtractPatchesFromServer $baseline.ExclPatches $destinationServer
    
      $command = 'New-PatchBaseline -Server $destinationServer -Name $baseline.Name -Description $baseline.Description -TargetType $baseline.TargetType -Dynamic -SearchPatchStartDate $baseline.SearchPatchStartDate -SearchPatchEndDate $baseline.SearchPatchEndDate -SearchPatchProduct $baseline.SearchPatchProduct -SearchPatchSeverity $baseline.SearchPatchSeverity -SearchPatchVendor $baseline.SearchPatchVendor'
      if ($includePatches.Count -gt 0){
       $command += ' -IncludePatch $includePatches'
      }
    
      if ($excludePatches.Count -gt 0){
      $command += ' -ExcludePatch $excludePatches'
      }
     }
    
     #check for null because there is known issue for creating baseline with null SearchPatchPhrase
     if ($baseline.SearchPatchPhrase -ne $null){
      $command += ' -SearchPatchPhrase $baseline.SearchPatchPhrase'
     }
    
     Invoke-Expression $command
    }
    
    foreach ($destinationServer in $destinationServers) {
     if ($baselines -eq $null) {
      Write-Error "The baselines parameter is null"
     } else {
      foreach($baseline in $baselines){
       if ($baseline.GetType().FullName -eq 'VMware.VumAutomation.Types.PatchBaselineImpl'){
        Write-Host "Import '" $baseline.Name "' to the server $destinationServer" 
        if($baseline.BaselineContentType -eq 'Static'){
         CreateStaticBaseline $baseline $destinationServer
        } else {
         CreateDynamicBaseline $baseline $destinationServer
        }
       } else {
        Write-Warning -Message "Baseline '$($baseline.Name)' is not patch baseline and will be skipped."    
       }
      }
     }
    }
    

    You have now exported the tested baseline to another Update Manager server.

  8. Apply the patches to your ESX/ESXi hosts by using the Update Manager server instance to which you exported the tested patch baseline.