Samples/UCSMFirmwareUpdate.ps1

<#

.SYNOPSIS
                This script automates the upgrade of UCS firmware
                
.DESCRIPTION
                This script logs into Cisco.com, download firmware bundles to a local working directory, upload bundles to the target UCS domain and walk through all steps of the upgrade

.PARAMETERSET
                hfp: To upgrade all components infra as well as servers
                infraOnly: To upgrade only infra component

.EXAMPLE
                UCSMFirmwareUpdate.ps1 -ucs xx.xx.xx.xx -version 'x.x(xx)' -imagedir c:\work\images -hfp "all"
                UCSMFirmwareUpdate.ps1 -ucs xx.xx.xx.xx -version 'x.x(xx)' -imagedir c:\work\images -hfp "default"
                Upgrades all components of UCS
                -ucs -- UCS Manager IP -- Example: "1.2.3.4"
                -version -- UCS Manager version to upgrade
                -imagedir -- Path to download firmware bundle
                -hfp -- Firmware Host Pack. Values can be "all" or "default"
                All parameters are mandatory
                The prompts that will always be presented to the user will be for Username and Password for UCS and for cisco software image download


.EXAMPLE
                UCSMFirmwareUpdate.ps1 -ucs xx.xx.xx.xx -version 'x.x(xx)' -imagedir c:\work\images -infraOnly
                Upgrade Infrastructure only portion of UCSM
                -infraOnly -- Optional SwitchParameter when specified upgrades Infrastructure only
                 
.NOTES
                Author: Eric Williams
                Email: ericwill@cisco.com
                Company: Cisco Systems, Inc.
                Version: v1.1
                Date: 06/05/2014
                Disclaimer: Code provided as-is. No warranty implied or included. This code is for example use only and not for production

.INPUTS
                UCSM IP Address
                UCS Manager version to upgrade
                Directory path to download firmware image bundles
                Switch Parameter to upgrade infrastructure only portion
                HFP Parameter specifies which HFP to be upgraded

.OUTPUTS
                None
                
.LINK
                https://communities.cisco.com/docs/DOC-36062

#>


param(
    [parameter(Mandatory=${true})][string]${version},
    [parameter(Mandatory=${true})][string]${ucs},
    [parameter(Mandatory=${true})][string]${imageDir},
    [parameter(ParameterSetName='hfp', Mandatory=${true})][ValidateSet("all","default")][string]${hfp},
    [parameter(ParameterSetName='infraOnly', Mandatory=${true})][Switch]${infraOnly}
)

function Set-LogFilePath($LogFile)
{
    Write-Host "Creating log file under directory ${LogFile}\Logs\"
    $Global:LogFile = "$LogFile\Logs\Script.$(Get-Date -Format yyyy-MM-dd.hh-mm-ss).log"
    if([System.IO.File]::Exists($Global:LogFile) -eq $false)
    {
        $null = New-Item -Path $Global:LogFile -ItemType File -Force
    }
}

function Write-Log
{
    [CmdletBinding()]
    param 
    ( 
        [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
        [String] $Message
    )
    
    $lineNum = (Get-PSCallStack).ScriptLineNumber[1]
    $Message = "Line: $lineNum - $Message"

    $ErrorActionPreference = 'Stop'

    "Info: $(Get-Date -Format g): $Message" | Out-File $Global:LogFile -Append
    Write-Host $Message
}

function Write-ErrorLog
{
    [CmdletBinding()] 
    param ( 
        [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
        [object] $Message
    )
    
    $lineNum = (Get-PSCallStack).ScriptLineNumber[1]
    $Message = "Line: $lineNum - $Message"

    "Error: $(Get-Date -Format g):" | Out-File $Global:LogFile -Append
    $Message | Out-File $LogFile -Append
    Write-Error $Message
    $trash = Disconnect-Ucs -ErrorAction Ignore
    exit   
}

function Connect-UcsManager
{
    # IP address and credentials to access the management server software that manages
    # firmware updates for the nodes of the solution.
    
    $ucsConnection = Connect-Ucs -Name ${ucs} -Credential ${ucsCred} -ErrorVariable errVar -ErrorAction SilentlyContinue
    if ($errVar)
    {
        Write-Log "Error attempting to connect to UCS Manager at $managementServerAddress. Details: $errVar"
        return $null
    }
    else
    {
        Write-Log "Connected to Cisco UCS Manager $managementServerAddress"
        return $ucsConnection
    }
}

function Wait-UcsManagerActivation
{
    $count = 0
    $ucsConnection = $null
    while ($ucsConnection -eq $null)
    {
        if ($count -eq 20)
        {
            Write-Log "Error creating a session to UCS Manager even after 20 attempts"
            return $null
        }
        Write-Log "Checking if UCS Manager $($Parameters.ManagementServerAddress) is reachable.."
        if ((Test-Connection -ComputerName ${ucs} -Quiet) -ne $true)
        {
            $count++
            Write-Log "UCS Manager is still not reachable.."
            Write-Log "Sleeping for 30 seconds.. "
            Start-Sleep -Seconds 30
            continue
        }
        $count++
        Write-Log "Attempt # $count - Trying to login to UCS Manager..."
        $ucsConnection = Connect-UcsManager
        if ($ucsConnection -eq $null)
        {
            Write-Log "Error creating a session to UCS Manager "
            Write-Log "Sleeping for 30 seconds..."
            Start-Sleep -Seconds 30
        }
        else
        {
            Write-Log "Successfully logged back into UCS Manager"
            return $ucsConnection
        }
    }
}

function Wait-UcsFabricInterconnectActivation($fiDetails)
{
    $count = 0
    $isComplete = $false
    do
    {
        if ($count -eq 20)
        {
            Write-Log "Error FI activation is still not completed even after 20 minutes. Exiting with error now"
            return $false
        }
        $count++
        Write-Log "Getting the status of FI $($fiDetails.Id)..."
        try 
        {        
            $fwStatus = $fiDetails | Get-UcsFirmwareStatus -ErrorAction Stop| Select OperState
            switch ($fwStatus.OperState)
            {
                { @("bad-image", "failed", "faulty-state") -contains $_ } { Write-Log "Firmware activation of the Fabric Interconnect $($fiDetails.Id) has failed. Status is $fwStatus"; $isComplete = $true; return $false }
                "ready" { Write-Log "Firmware activation of the Fabric Interconnect $($fiDetails.Id) is complete"; $isComplete = $true; return $true }
                { @("activating", "auto-activating", "auto-updating", "rebooting", "rebuilding", "scheduled", "set-startup", "throttled", "upgrading", "updating", "") -contains $_ }
                {
                    Write-Log "Firmware activation is in progress $fwStatus";
                    Write-Log "Sleeping for 1 minute...";
                    Start-Sleep -Seconds 60;
                    break
                }
            }            
        }
        catch
        {
            Write-Log "Failed to get the status of the firmware update process. $_.Exception"
            throw $_.Exception            
        }
    }
    while ($isComplete -eq $false)
}

function Wait-UcsServersActivation
{
    $count = 0
    $bladeServers = @()
    $rackServers = @()

    #Sleep for 15 seconds so that all the servers comes in upgrading state
    Start-Sleep -Seconds 15

    #get all servers for which firmware status is not ready and not in error or faulty state.
    $moNotInReadyState = Get-UcsServer | Get-UcsFirmwareStatus -Filter 'OperState -cne ready -and (OperState -cne "bad-image" -and OperState -cne failed -and OperState -cne "faulty-state")' | Get-UcsParent
    if ($moNotInReadyState.Count -gt 0)
    {
        Write-Log "Monitoring the state of below servers:"
        foreach ($mo in $moNotInReadyState)
        {
            Write-Log $mo.Dn
        }
    
        do
        {
            if ($count -eq 40)
            {
                Write-Log "Error servers activation is still not completed even after 2 hours. Exiting with error now"
                return $false
            }
            $count++
        
            Write-Log "Sleeping for 3 minutes...";
            Start-Sleep -Seconds 180;          
            
            try 
            {
                #Logs the operstate of all the servers.
                foreach($mo in $moNotInReadyState)
                {
                    $tmpOperState = $mo | Get-UcsFirmwareStatus | select OperState
                    $moDn = $mo.Dn
                    Write-Log "Server firmware activation for server: $moDn is in progress: $tmpOperState"
                }
                #exits from the monitoring if all the servers are in ready state.
                if (($moNotInReadyState | Get-UcsFirmwareStatus | ? {$_.OperState -ne "ready"}).Count -eq 0)
                {
                    Write-Log "Server firmware activation is done";
                    return $true
                }
            }
            catch
            {
                Write-Log "Failed to get the status of the firmware update process. $_.Exception"
                throw $_.Exception            
            }
        }
        while ($true)
    }
    else
    {
        Write-Log "No servers to Monitor. Please check server firmware status. Servers may be in 'ready', 'bad-image', 'failed' or 'faulty-state'."
    }

    return $true
}
function Ack-UcsFIRebootEvent
{
    $count = 0
    while ($fwAck -eq $null)
    {        
        $count++
        Write-Log "Checking if there is a Pending activity generated for the activation of the Primary FI"
        $fwAck = Get-UcsFirmwareAck -Filter 'OperState -ilike waiting-for-*'
        if ($fwAck -eq $null)
        {
            Write-Log "Pending activity is not generated yet sleeping for 1 minute and then retrying the operation.."
            Start-Sleep -Seconds 60
        }           
        if ($count -ge 40)            
        {
            Write-ErrorLog "Pending activity is not generated. This is an error case. Terminating firmware update"
        }   
    }
    Write-Log "UCS Manager has generated a pending activity for primary FI reboot."
    Write-Log "Acknowledging the reboot of the primary FI now"
    $trash = Get-UcsFirmwareAck -Filter 'OperState -ilike waiting-for-*' | Set-UcsFirmwareAck -AdminState "trigger-immediate" -Force
    Write-Log "Activation of the primary FI has started"
    Write-Log "This will take few minutes. Sleeping for 5 minutes.."
    Start-Sleep -Seconds 300
}

function Activate-UcsPrimaryFI
{
    $count = 0
    $isCompleted = $false
    $primaryFI = ""
    while (!$isCompleted)
    {
        $fwStatus = $null
        $count++
        if ($count -ge 20)
        {
            Write-ErrorLog "FI activation is still not completed even after 20 minutes. Exiting with error now"
        }
        if (Get-UcsStatus -ErrorAction SilentlyContinue -ErrorVariable errVar | ? { $_.HaConfiguration -eq "cluster" })
        {
            $primary = Get-UcsMgmtEntity -LeaderShip primary -ErrorAction SilentlyContinue -ErrorVariable errVar
            if($primary -ne $null)
            {
                $fwStatus = Get-UcsNetworkElement -Id $primary.Id -ErrorAction SilentlyContinue -ErrorVariable errVar | Get-UcsFirmwareStatus | Select OperState
            }
        }
        else
        {
            $primary = Get-UcsNetworkElement -ErrorAction SilentlyContinue -ErrorVariable errVar
            if($primary -ne $null)
            {
                $fwStatus = Get-UcsNetworkElement -ErrorAction SilentlyContinue -ErrorVariable errVar | Get-UcsFirmwareStatus | Select OperState
            }
        }
        
        if ( ($fwStatus -eq $null) -or ($primary -eq $null))
        {
            Write-Log "UCS Manager is not reachable.. Details: $errVar"
            Write-Log "UCS Manager connection is reset. Reconnecting.."
            $trash = Disconnect-Ucs -ErrorAction Ignore
            $ucsConnection = Wait-UcsManagerActivation
            if ($ucsConnection -eq $null)
            {
                Write-Log "ERROR: Unable to login back to the UCS Manager even after multiple retries."
                Write-Log "Terminating firmware update"
                Write-ErrorLog "Firmware Activation has failed"
            }
            else
            {
                #Setting the DefaultUcs so that we don't need to specify the handle for every method call
                $ExecutionContext.SessionState.PSVariable.Set("DefaultUcs", $ucsConnection)
                if (Get-UcsStatus | ? { $_.HaConfiguration -eq "cluster" })
                {
                    $primaryFI = Get-UcsNetworkElement -Id (Get-UcsMgmtEntity -Leadership primary).Id
                }
                else
                {
                    $primaryFI = Get-UcsNetworkElement
                }
                $primaryActivated = Wait-UcsFabricInterconnectActivation $primaryFI
                if (!$primaryActivated)
                {
                    Write-Log "ERROR: Activation of firmware faled on the $($subordFI.Id)"
                    Write-ErrorLog "Firmware Activation has failed"
                }
                else
                {
                    $updatedVersion = $primaryFI | Get-UcsMgmtController | Get-UcsFirmwareRunning -Deployment system | Select PackageVersion
                    Write-Log "Activation of firmware on $($primaryFI.Id) is successful. Updated version is $($updatedVersion.PackageVersion)"
                    break;
                }
            }
        }
        else
        {
            Write-Log "Activation of the primary FI is still in progress $($fwStatus.OperState)"
            Write-Log "Sleeping for a minute.."
            Start-Sleep -Seconds 60
        }
    }
    $trash = Disconnect-Ucs -ErrorAction Ignore
}

Set-LogFilePath $imageDir

if ((Get-Module | where {$_.Name -ilike "Cisco.UcsManager"}).Name -ine "Cisco.UcsManager")
{
    Write-Log "Loading Module: Cisco UCS PowerTool Module"
    Write-Log ""
    Import-Module Cisco.UcsManager
}  

if ((Get-Module | where {$_.Name -ilike "Cisco.Ucs.Common"}).Name -ine "Cisco.Ucs.Common")
{
    Write-Log "Loading Module: Cisco UCS PowerTool Module"
    Write-Log ""
    Import-Module Cisco.Ucs.Common
}      

# Script only supports one UCS Domain update at a time
$output = Set-UcsPowerToolConfiguration -SupportMultipleDefaultUcs $false

Try
{
    ${Error}.Clear()
    
    # Login into UCS
    Write-Log "Enter Credentials of UCS Manager to be upgraded to version: '$($version)'"
    ${ucsCred} = Get-Credential -Message "Enter Credentials of UCS Manager to be upgraded"
    Write-Log ""
    
    Write-Log "Logging into UCS Domain: '$($ucs)'"
    Write-Log ""
    $ucsConnection = Connect-UcsManager
    #Setting the DefaultUcs so that we don't need to specify the handle for every method call
    $ExecutionContext.SessionState.PSVariable.Set("DefaultUcs", $ucsConnection)
    
    if (${Error}) 
    {
        Write-Log "Error creating a session to UCS Manager Domain: '$($ucs)'"
        Write-Log " Error equals: ${Error}"
        Write-Log " Exiting"
        exit
    }

    #Check if the FI belongs to 6300 series.
    $sixtyThreeSeriesFI = $false
    ${fiModel} = (Get-UcsNetworkElement).Model | Select-Object -First 1
    if ($fiModel -cmatch "^UCS-FI-(?<modelNum>63\d\d).*$")
    {
        $sixtyThreeSeriesFIfound = $true
    }
    if ($fiModel -cmatch "^UCS-FI-(?<modelNum>64\d\d).*$")
    {
        $sixtyFourSeriesFIfound = $true
    }

    ${infraVersionA} = ${version} + 'A'
    ${infraVersionB} = ${version} + 'B'
    ${infraVersionC} = ${version} + 'C'
   
    ${versionSplit} = ${version}.Split("()")
    ${versionBundle} = ${versionSplit}[0] + "." + ${versionSplit}[1]
    
    ${bundle} = @()
    ${ccoImageList} = @()
    if ($sixtyThreeSeriesFIfound)
    {
        ${aSeriesBundle} = "ucs-6300-k9-bundle-infra." + ${versionBundle} + ".A.bin"
    }
    elseif($sixtyFourSeriesFIfound)
    {
        ${aSeriesBundle} = "ucs-6400-k9-bundle-infra." + ${versionBundle} + ".A.bin"
    }
    else
    {
        ${aSeriesBundle} = "ucs-k9-bundle-infra." + ${versionBundle} + ".A.bin"
    }
    
    if (${infraOnly} -eq $false)
    {
        ${bSeriesBundle} = "ucs-k9-bundle-b-series." + ${versionBundle} + ".B.bin"
        ${cSeriesBundle} = "ucs-k9-bundle-c-series." + ${versionBundle} + ".C.bin"
        ${bundle} = @(${aSeriesBundle},${bSeriesBundle},${cSeriesBundle})
    }
    elseif (${infraOnly} -eq $true)
    {
        ${bundle} = @(${aSeriesBundle})
    }
    
    Write-Log "Starting Firmware download process to local directory: ${imageDir}"
    Write-Log ""
    
    foreach(${eachBundle} in ${bundle})
    {
        ${fileName} = ${imagedir} +  "\" + ${eachBundle}
         if( test-path -Path ${fileName})
         {
              Write-Log "Image File : '${eachBundle}' already exist in local directory: '${imageDir}'"
         }
         else
         {
              ${ccoImageList} += ${eachBundle}
         }
    }    
    
    if(${ccoImageList} -ne ${null})
    {
        Write-Log  "Enter Cisco.com (CCO) Credentials"
        ${ccoCred} = Get-Credential -Message "Enter Cisco.com (CCO) Credentials"
        foreach(${eachbundle} in ${ccoImageList})
        {
            [array]${ccoImage} += Get-UcsSoftwareImageList -AllReleases -Credential ${ccoCred} -ErrorAction Stop | where { $_.ImageName -match ${eachbundle}}
            Write-Log "Preparing to download UCS Manager version '$($version)' bundle file: '$($eachbundle)'"
        }
        ${Error}.Clear()
        Write-Log  "Downloading UCS Manager version: '$($version)' bundles to local directory: $($imageDir)"
        Write-Log "Sleeping for 2 minutes ..."
        Start-Sleep -Seconds 120
        $output = ${ccoImage} | Get-UcsSoftwareImage -Path ${imageDir} -ErrorAction Stop
    }
    Write-Log "Firmware download process completed to local directory: ${imageDir}"
    Write-Log ""
    
    foreach (${image} in ${bundle})
    {
        Write-Log "Checking if image file: '$($image)' is already uploaded to UCS Domain: '$($ucs)'"
        ${firmwarePackage} = Get-UcsFirmwarePackage -Name ${image}
        ${deleted} = $false
        if (${firmwarePackage})
        {
               # Check if all the images within the package are present by looking at presence
            ${deleted} = ${firmwarePackage} | Get-UcsFirmwareDistImage | ? { $_.ImageDeleted -ne ""}
        }
    
        if (${deleted} -or !${firmwarePackage})
        {
            $Error.Clear()
            # If Image does not exist on FI, uplaod
            $fileName = ${imageDir} +  "\" + ${image}
            if((Get-UcsFirmwareDownloader -FileName ${image} -TransferState failed).count -ne 0)
            {
                Write-ErrorLog "Image: '$($image)' already exists under Download Tasks in failed state. Exiting..."
            }
            Write-Log "Uploading image file: '$($image)' to UCS Domain: '$($ucs)'"
            $trash = Send-UcsFirmware -LiteralPath $fileName | Watch-Ucs -Property TransferState -SuccessValue downloaded -FailureValue failed -PollSec 30 -TimeoutSec 600 -ErrorAction SilentlyContinue
            if ($Error -ne "")
            {
                Write-ErrorLog "Error uploading image: '$($image)' to UCS Domain: '$($ucs)'. Please check Download Tasks for details."
            }
            Write-Log "Upload of image file: '$($image)' to UCS Domain: '$($ucs)' completed"
            Write-Log ""  
        }
        else
        {
            Write-Log "Image file: '$($image)' is already uploaded to UCS Domain: '$($ucs)'"
            Write-Log ""  
        }
    }

    # Check if the status of the firmware boot unit is ready before proceeding with the firmware update
    if (!(Get-UcsNetworkElement | Get-UcsMgmtController | Get-UcsFirmwareBootDefinition  | Get-UcsFirmwareBootUnit | Where-Object { $_.OperState -eq 'ready'}))
    {
        Write-ErrorLog "Fabric Interconnect is not in ready state. Can't proceed with Firmware update."
    }

    # Start the Firmware Auto Install for the Infrastructure update. This will take care of updating the UCS Manager
    # both the Fabric Interconnects.
    $activatedVersion = Get-UcsMgmtController -Subject system | Get-UcsFirmwareRunning -Type system | Select Version

    if ($activatedVersion.Version -ne $version)
    {
        Write-Log "Triggering the auto install of the infrastructure firmware to $aSeriesBundle"
        try 
        {
            $trash = Start-UcsTransaction
            $trash = Get-UcsOrg -Level root | Get-UcsFirmwareInfraPack -Name "default" -LimitScope | Set-UcsFirmwareInfraPack -ForceDeploy "yes" -InfraBundleVersion ${infraVersionA} -Force
            $trash = Get-UcsSchedule -Name "infra-fw" | Get-UcsOnetimeOccurrence -Name "infra-fw" | Set-UcsOnetimeOccurrence -Date (Get-UcsTopSystem).CurrentTime -Force
            $trash = Complete-UcsTransaction -ErrorAction Stop | Out-Null
        }
        catch 
        {
            Write-ErrorLog "Failed to start firmware auto install process. Details: $_.Exception"        
        }
        
        Write-Log "Waiting until UCS Manager restarts"
        $trash = Disconnect-Ucs -ErrorAction Ignore
        Write-Log "Sleeping for 5 minutes ..."
        Start-Sleep -Seconds 300
        $ucsConnection = Wait-UcsManagerActivation
        #Setting the DefaultUcs so that we don't need to specify the handle for every method call
        $ExecutionContext.SessionState.PSVariable.Set("DefaultUcs", $ucsConnection)
        #Check if UCSM got activated to the new version.
        Write-Log "Checking the status of the firmware installation"
        #---->
        $activatedVersion = Get-UcsMgmtController -Subject system | Get-UcsFirmwareRunning -Type system | Select Version

        if ($activatedVersion.Version -eq $version)
        {
            Write-Log "UCS Manager is activated to the $activatedVersion successfully"
        }
        else
        {
            Write-Log "Activation has failed so terminating the update process"
            Write-ErrorLog "UCS Manager is at $activatedVersion version"
        }
    
        Start-Sleep -Seconds 60
        Write-Log "Checking the status of the FI activation"
        # Now check for the status of the FI activation. As part of the auto install first the secondary FI will be activated.
        if (Get-UcsStatus | ? { $_.HaConfiguration -eq "cluster" })
        {
            while ($subordFIActivated -eq $null) 
            {            
                try
                {
                    $subordFI = Get-UcsNetworkElement -Id (Get-UcsMgmtEntity -Leadership subordinate -ErrorAction Stop).Id    -ErrorAction Stop
                    $subordFIActivated = Wait-UcsFabricInterconnectActivation $subordFI                  
                }
                catch
                {
                    Write-Log "Failed to get the status $_.Exception"
                    $trash = Disconnect-Ucs -ErrorAction Ignore
                    $ucsConnection = Wait-UcsManagerActivation
                    if ($ucsConnection -eq $null)
                    {
                        Write-ErrorLog "Unable to connect to the UCS Manager. Terminating the process.."
                    }
                    #Setting the DefaultUcs so that we don't need to specify the handle for every method call
                    $ExecutionContext.SessionState.PSVariable.Set("DefaultUcs", $ucsConnection)        
                }
            }
            if (!$subordFIActivated)
            {
                Write-ErrorLog "Activation of firmware failed on the $($subordFI.Id)"
            }
            else
            {
                $updatedVersion = $subordFI | Get-UcsMgmtController | Get-UcsFirmwareRunning -Deployment system | Select PackageVersion
                Write-Log "Activation of firmware on $($subordFI.Id) is successful."
                Start-Sleep -Seconds 30
                
                Ack-UcsFIRebootEvent
                Activate-UcsPrimaryFI
            }
        }
        else
        {
            Ack-UcsFIRebootEvent
            Activate-UcsPrimaryFI
        }
    }
    else
    {
        Write-Log "UCS Manager is already at $activatedVersion version. Skipping FI upgrade..."
    }

    #=====================>>>>>>>>>>>Server Firmware Upgrade<<<<<<<<<<================================
    if (${infraOnly} -eq $false)
    {
        $Error.Clear()
        $trash = Disconnect-Ucs -ErrorAction Ignore
        $ucsConnection = Connect-UcsManager
        #Setting the DefaultUcs so that we don't need to specify the handle for every method call
        $ExecutionContext.SessionState.PSVariable.Set("DefaultUcs", $ucsConnection)

        try
        {
            if($hfp -eq "all")
            {
                $fwCompHostPackInfo = Get-UcsServiceProfile | select PnDn, OperHostFwPolicyName
                $fwCompHostPackDnList = @("org-root/fw-host-pack-default")
                foreach($eachfwCompHostPackInfo in $fwCompHostPackInfo)
                {
                    if (!($eachfwCompHostPackInfo.PnDn -eq "" -or $eachfwCompHostPackInfo.OperHostFwPolicyName -eq ""))
                    {
                        if(!$fwCompHostPackDnList.Contains($eachfwCompHostPackInfo.OperHostFwPolicyName))
                        {
                            $fwCompHostPackDnList += $eachfwCompHostPackInfo.OperHostFwPolicyName
                        }
                    }
                }
            }
            elseif($hfp -eq "default")
            {
                $fwCompHostPackDnList = @("org-root/fw-host-pack-default")
            }

            $fwCompHostPacks = $fwCompHostPackDnList | %{Get-UcsFirmwareComputeHostPack -Dn $_ -PolicyOwner local}

            #$trash = Get-UcsOrg -Level root | Add-UcsFirmwareComputeHostPack -ModifyPresent -BladeBundleVersion ${infraVersionB} -Name "default" -RackBundleVersion ${infraVersionC} -ErrorAction Stop
            $trash = $fwCompHostPacks | Set-UcsFirmwareComputeHostPack -BladeBundleVersion ${infraVersionB} -RackBundleVersion ${infraVersionC} -Force -ErrorAction Stop
            Write-Log "Triggered Server firmware upgrade. Modified Host Firmware Package. Version=${version}"

            while ($serverActivated -eq $null) 
            {            
                try
                {
                    $serverActivated = Wait-UcsServersActivation               
                }
                catch
                {
                    Write-Log "Failed to get the status $_.Exception"
                }
            }
        }
        catch
        {
            Write-Error "Failed modifying Host Firmware Package Version=${version}"
            Write-Log ${Error}
            $trash = Disconnect-Ucs -ErrorAction Ignore
            exit
        }
    }
    #=====================>>>>>>>>>>>Server Firmware Upgrade<<<<<<<<<<================================
    $trash = Disconnect-Ucs -ErrorAction Ignore
    Write-Log "Firmware update process completed."
    #return $true
}
Catch
{
    if (${Error} -like "*In order to download software, you must accept the EULA*")
    {
        Write-Log "Error occurred in script:"
        Write-Log " In order to download software, you must accept the EULA. You will receive an email within 24 hours which will have details on accepting EULA.`
        Once you accept the EULA by following the instructions mentioned in the email, re-run this script to proceed."

        $trash = Disconnect-Ucs -ErrorAction Ignore
        exit
    }
    else
    {
        Write-Log "Error occurred in script:"
        Write-Log ${Error}
        $trash = Disconnect-Ucs -ErrorAction Ignore
        exit
    }
}


# SIG # Begin signature block
# MIIjPgYJKoZIhvcNAQcCoIIjLzCCIysCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDkyxfIx7eez/Rp
# boytgBC7tkhPn/MEBgtn8/BYPgxhtKCCDIYwggXCMIIEqqADAgECAhAGs5ehxvr3
# 3+zjzsf3AEZXMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNV
# BAMTIkRpZ2lDZXJ0IEVWIENvZGUgU2lnbmluZyBDQSAoU0hBMikwHhcNMjAxMDIx
# MDAwMDAwWhcNMjMxMDI1MjM1OTU5WjCB1TETMBEGCysGAQQBgjc8AgEDEwJVUzEb
# MBkGCysGAQQBgjc8AgECEwpDYWxpZm9ybmlhMR0wGwYDVQQPDBRQcml2YXRlIE9y
# Z2FuaXphdGlvbjERMA8GA1UEBRMIQzExODM0NzcxCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9zZTEcMBoGA1UEChMTQ0lT
# Q08gU1lTVEVNUywgSU5DLjEcMBoGA1UEAxMTQ0lTQ08gU1lTVEVNUywgSU5DLjCC
# ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM4a4NqYk3Y87GtsF/vMeyKX
# mI/feQ6EfLH5mxedhBTki+8Lviz9zbN16EJfk0cT1rWI+bBHo2p49bhRMkdL3MkP
# fJQH4ts4OZDrCHDtlQ60RIxxK43/C/ZapYuMO8KhNXE613vXOBHBxqK5IGnH+LIV
# thl6bqM+FidqmIo/tj8Nijx52Ddu2RvA0cT/eS2hDZ/HZvXBddg26zjyySJr4NqZ
# 4rRJkUqh5jSEGUsl58vCK+kE9iWzeP8W1oJZE29EmOVOG309gltGaN1mN+v2kkKk
# sFa56p3YPDlYcbWRqRGsyffZNit5qh55ZJY3EFSndrVGdPR6CaZwMJXRnT8Zfg0C
# AwEAAaOCAfQwggHwMB8GA1UdIwQYMBaAFI/ofvBtMmoABSPHcJdqOpD/a+rUMB0G
# A1UdDgQWBBRAgSdqGJHDn1gp1w9Evrwh0VEUJjAxBgNVHREEKjAooCYGCCsGAQUF
# BwgDoBowGAwWVVMtQ0FMSUZPUk5JQS1DMTE4MzQ3NzAOBgNVHQ8BAf8EBAMCB4Aw
# EwYDVR0lBAwwCgYIKwYBBQUHAwMwewYDVR0fBHQwcjA3oDWgM4YxaHR0cDovL2Ny
# bDMuZGlnaWNlcnQuY29tL0VWQ29kZVNpZ25pbmdTSEEyLWcxLmNybDA3oDWgM4Yx
# aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0VWQ29kZVNpZ25pbmdTSEEyLWcxLmNy
# bDBLBgNVHSAERDBCMDcGCWCGSAGG/WwDAjAqMCgGCCsGAQUFBwIBFhxodHRwczov
# L3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEDMH4GCCsGAQUFBwEBBHIwcDAk
# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEgGCCsGAQUFBzAC
# hjxodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRFVkNvZGVTaWdu
# aW5nQ0EtU0hBMi5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEA
# VgLs7po2IfnfWflRgmBLQMmyUJcbSDxriBNMfkV4N46mcnyE0ZUpz8NPplBtC4Je
# EnXRGpJ73xGqsAzWcBZRkK+0bQ1Lt5LCtWagcBwGbnqnw+3u1wvkXVnvGH1FvDhJ
# BLtwN28mof498HDiyBTBtVAhW6vFxz/1LiD1Ax4D+r60FX1OHKTqZBUrKHSy1tpB
# KCARqbclQmCEkYI++IbrIFOoFh22UE3giyB2rDVRZcIYnl5xQIJgSewf4+3UmdCX
# zmDFZSJo8NiBJtzeFI5giBJxg9z0TYrw0KHyj5Nn/iQI55SxNIVPhInXJQ5GW4GF
# ekulx5a1IaJyMBEKO57BojCCBrwwggWkoAMCAQICEAPxtOFfOoLxFJZ4s9fYR1ww
# DQYJKoZIhvcNAQELBQAwbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0
# IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNl
# cnQgSGlnaCBBc3N1cmFuY2UgRVYgUm9vdCBDQTAeFw0xMjA0MTgxMjAwMDBaFw0y
# NzA0MTgxMjAwMDBaMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNVBAMTIkRpZ2lDZXJ0
# IEVWIENvZGUgU2lnbmluZyBDQSAoU0hBMikwggEiMA0GCSqGSIb3DQEBAQUAA4IB
# DwAwggEKAoIBAQCnU/oPsrUT8WTPhID8roA10bbXx6MsrBosrPGErDo1EjqSkbpX
# 5MTJ8y+oSDy31m7clyK6UXlhr0MvDbebtEkxrkRYPqShlqeHTyN+w2xlJJBVPqHK
# I3zFQunEemJFm33eY3TLnmMl+ISamq1FT659H8gTy3WbyeHhivgLDJj0yj7QRap6
# HqVYkzY0visuKzFYZrQyEJ+d8FKh7+g+03byQFrc+mo9G0utdrCMXO42uoPqMKhM
# 3vELKlhBiK4AiasD0RaCICJ2615UOBJi4dJwJNvtH3DSZAmALeK2nc4f8rsh82zb
# 2LMZe4pQn+/sNgpcmrdK0wigOXn93b89OgklAgMBAAGjggNYMIIDVDASBgNVHRMB
# Af8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcD
# AzB/BggrBgEFBQcBAQRzMHEwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2lj
# ZXJ0LmNvbTBJBggrBgEFBQcwAoY9aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29t
# L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNydDCBjwYDVR0fBIGHMIGE
# MECgPqA8hjpodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdoQXNz
# dXJhbmNlRVZSb290Q0EuY3JsMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2VydC5j
# b20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMIIBxAYDVR0gBIIB
# uzCCAbcwggGzBglghkgBhv1sAwIwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3
# LmRpZ2ljZXJ0LmNvbS9zc2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUH
# AgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQBy
# AHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBj
# AGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAg
# AEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQ
# AGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBt
# AGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBj
# AG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBl
# AHIAZQBuAGMAZQAuMB0GA1UdDgQWBBSP6H7wbTJqAAUjx3CXajqQ/2vq1DAfBgNV
# HSMEGDAWgBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEA
# GTNKDIEzN9utNsnkyTq7tRsueqLi9ENCF56/TqFN4bHb6YHdnwHy5IjV6f4J/SHB
# 7F2A0vDWwUPC/ncr2/nXkTPObNWyGTvmLtbJk0+IQI7N4fV+8Q/GWVZy6OtqQb0c
# 1UbVfEnKZjgVwb/gkXB3h9zJjTHJDCmiM+2N4ofNiY0/G//V4BqXi3zabfuoxrI6
# Zmt7AbPN2KY07BIBq5VYpcRTV6hg5ucCEqC5I2SiTbt8gSVkIb7P7kIYQ5e7pTcG
# r03/JqVNYUvsRkG4Zc64eZ4IlguBjIo7j8eZjKMqbphtXmHGlreKuWEtk7jrDgRD
# 1/X+pvBi1JlqpcHB8GSUgDGCFg4wghYKAgEBMIGAMGwxCzAJBgNVBAYTAlVTMRUw
# EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
# KzApBgNVBAMTIkRpZ2lDZXJ0IEVWIENvZGUgU2lnbmluZyBDQSAoU0hBMikCEAaz
# l6HG+vff7OPOx/cARlcwDQYJYIZIAWUDBAIBBQCgggEVMBkGCSqGSIb3DQEJAzEM
# BgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqG
# SIb3DQEJBDEiBCBRvMQjHSpDiWkXEyzVv+t+w2hhS25/wsQYQMU4A7Y4hzCBqAYK
# KwYBBAGCNwIBDDGBmTCBlqCBk4CBkABDAG8AbgBmAGkAZwB1AHIAZQAgAGEAbgBk
# ACAAZgBpAHIAbQB3AGEAcgBlACAAdQBwAGQAYQB0AGUAIAB0AGgAZQAgAE4AZQB4
# AHUAcwAgAHMAdwBpAHQAYwBoAGUAcwAgAGEAbgBkACAAVQBDAFMATQAgAGYAbwBy
# ACAAYQB6AHUAcgBlAHMAdABhAGMAazANBgkqhkiG9w0BAQEFAASCAQC0Z1Z/vi7e
# yWxKyP+czkywdJ2rfXONiN9a20PpUAnJCwpW3tC59irrkFKy+7TaJN1LfyiSq7EY
# vZy6JVw8wWHQFPGsq8NAJP9xmCxm86ZknOd95vYORajqiUNTptTH/X9RpuJsjx/Z
# vxzAW0W03urYFuTM8Rebagve6POt2rkoZ09lI2JgkPFTyiAhBdHMK7ObNe+3p4M/
# 3QjZHz8CMSzRJR85GOCA5QzRqus7w5VAl/PWmusrpcmP+bjyd3tpx6u+BoRZrHGM
# eaHRVdrslC81vK7Y38pcPkPVgTKvOKrA9PPbXLmgtxrpWP/+2SIhbozS9D4x31YG
# 1ev+s5uUHRo+oYITRTCCE0EGCisGAQQBgjcDAwExghMxMIITLQYJKoZIhvcNAQcC
# oIITHjCCExoCAQMxDzANBglghkgBZQMEAgEFADB5BgsqhkiG9w0BCRABBKBqBGgw
# ZgIBAQYLYIZIAYb5LwAGDQMwMTANBglghkgBZQMEAgEFAAQgSeIZAA/L3e4O4Bso
# ZbN97pBPwQqw5XWyY9i1ibmHnTECEEABh/oh/SEsbP89pQI6K78YDzIwMjMwNTA4
# MDY1MjI0WqCCD2QwggekMIIFjKADAgECAhBAAYD9DvXolVgjPR54g1q+MA0GCSqG
# SIb3DQEBCwUAMEUxCzAJBgNVBAYTAlVTMRIwEAYDVQQKEwlJZGVuVHJ1c3QxIjAg
# BgNVBAMTGVRydXN0SUQgVGltZXN0YW1waW5nIENBIDMwHhcNMjIwNTI1MjExMDU3
# WhcNMjMwODI0MjExMDU3WjBJMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRy
# dXN0MSYwJAYDVQQDEx1UcnVzdElEIFRpbWVzdGFtcCBBdXRob3JpdHkgMzCCAiIw
# DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALp7eYoJ+vne9oA1jzw1XoBTTOWq
# vgf2x/gV7sOXhAsCOe8Wy2Rul2R3PT+pGzyDvR/8DWoikVkAYBm0/bnIL6Y/IpOI
# f4fwVgdHHNJqIvYvbV1+PESwLzQ5A5soFLXw9E/otcCCwMaQhTOimABeo7P3lpaL
# rVX9FDLqxYHJ/YYKYAU2JRJG0z5SB2YYwRL5MhRBFTaGM9m9CdU2EK/50YHeYmoT
# kikdcDlBNKJ/qlM1CkNW3Uun2+mBPBtNkqbGcwoX41kmb+Vo6TRiq8zo7hosFlx3
# d7/0gfYmyrNGIjdH/2FrHPKUKbuIYR8WZP6C+kypSNsELZPfFGrBwjnr7jmBIwgi
# AXd52SlTXBpv6+upRRRggeLyNP+GQlhcSntTm1ByRSGIhGiWNEijNM/gYaw1JYxI
# fKgMReuTAdV99augSBY3b91uSVIhZp7hTl2ZHARK+/0IssO1YZ8ivZH3F8s52wAw
# faVA5Np23m+ZqaoC+1IrPCuYX6ZGewltvTq4hcs21IMIMcf84X1lfKqXsK+16uKk
# e2J1YCQlfp+BCONpDYtfdzfUySAFJKfs6SKflb8pgJiIPrHzVPpuSEO2/XJiMrMc
# fInp59bjzhvEayTu+PTTV7PD3FvEEnROnapip3brHmFRTlwBVo8mhl7dEXXoYI3V
# AsDRhDQJdB4xh9sbAgMBAAGjggKKMIIChjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB
# /wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDCBhQYIKwYBBQUHAQEEeTB3
# MDAGCCsGAQUFBzABhiRodHRwOi8vY29tbWVyY2lhbC5vY3NwLmlkZW50cnVzdC5j
# b20wQwYIKwYBBQUHMAKGN2h0dHA6Ly92YWxpZGF0aW9uLmlkZW50cnVzdC5jb20v
# Y2VydHMvdGltZXN0YW1waW5nMy5wN2MwHwYDVR0jBBgwFoAUyjLwNnzHKtqRtXyH
# ihG9uCJsvwkwggE8BgNVHSAEggEzMIIBLzAIBgZngQwBBAIwDQYLYIZIAYb5LwAG
# DQEwggESBgtghkgBhvkvAAYNAzCCAQEwSgYIKwYBBQUHAgEWPmh0dHBzOi8vc2Vj
# dXJlLmlkZW50cnVzdC5jb20vY2VydGlmaWNhdGVzL3BvbGljeS90cy9pbmRleC5o
# dG1sMIGyBggrBgEFBQcCAjCBpQyBolRoaXMgY2VydGlmaWNhdGUgaGFzIGJlZW4g
# aXNzdWVkIGluIGFjY29yZGFuY2Ugd2l0aCBJZGVuVHJ1c3QncyBUcnVzdElEIENl
# cnRpZmljYXRlIFBvbGljeSBmb3VuZCBhdCBodHRwczovL3NlY3VyZS5pZGVudHJ1
# c3QuY29tL2NlcnRpZmljYXRlcy9wb2xpY3kvdHMvaW5kZXguaHRtbDBGBgNVHR8E
# PzA9MDugOaA3hjVodHRwOi8vdmFsaWRhdGlvbi5pZGVudHJ1c3QuY29tL2NybC90
# aW1lc3RhbXBpbmczLmNybDAdBgNVHQ4EFgQUrxUhDN/aCm91R5wS0B3oe7g6aTMw
# DQYJKoZIhvcNAQELBQADggIBAAp1wnClUmkKnzDA17s0y2fxHRmg+9x2N0T11Khs
# fkXSJ1iGMt2yE9jDcXJ97dQPoXYy6UDKM7S9LgAOalo6uOMt/o5+cSb7BCbv1AIe
# lIkufAy2kkGMgX9jDR99ixl6wzpkrBo5pU/y1AOs4I1VEjQK3e+tLABo0qpZjqFa
# eGXPFc/zPVPG4whcNhmh3SqImJhCIPd8JMD3hy28yOsjaHVd5GKMNFD7OMWzuSxs
# 4x1Ezk3EeeX4MYUK3YWXowQbtTLBAkwlhIpzj8KGuY+99gsdkKKqa2aMhMrToH3K
# c4S2RueOO7NjPfYni9cfS0J1JO6MYn0KGgsap8tRsDEOfuhREmvZ037i8i98+ajD
# gMtLPksemSVDn4DseD14WfjgIRsTOphWE2hk8E6yVy/xOAETbMnANGHp2AY+YI+r
# ZgmdK7OVsWJgYcSBDhcLC+xZ7EDd8q50slMs2HUSC8RbL5ka5t4eft5CY/Vuf0wm
# AtLdVvpMQVMuZErS/rQ4QkVS3uB+NtVb0lSXbbormtPsV+dzcP1eprZ5ZjxMfrSQ
# 1wNEgx/ChHWExdlE0sdfRDJcZPbWT9Ep5RwLbFyYiHM19DCwfbxX6X6MbB3ohVBG
# /V03BPRsEjs4rLSfS0dMSYoVKv7Y57jQ3md4udgE/Urd947BBKWhY0+YspAtO7NO
# JlrRMIIHuDCCBaCgAwIBAgIQQAF/lJAVu6kSuFeWPUTs7jANBgkqhkiG9w0BAQsF
# ADBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5J
# ZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMjIwMzE2MjEwOTA1WhcN
# MzMwNjEyMjEwOTA1WjBFMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0
# MSIwIAYDVQQDExlUcnVzdElEIFRpbWVzdGFtcGluZyBDQSAzMIICIjANBgkqhkiG
# 9w0BAQEFAAOCAg8AMIICCgKCAgEAqGL0RYFG7mL0RgSXLynLNWhEVrhsKhrVL4rS
# G+NAp4v8TbAP2YXsqWB8yZgj9DQ55AECnmQ2Uo/BqQSsI/AOr9ctqZykItmca/nG
# jKezl1kZS2YoNc4Zjj+7QO9iNunclA06fBhI+iQHAam7isQLK3CwXRDLzKkMs7Ti
# sMoGQOSd0M8P6YY/QOGYv/+tCxmfvUz2GjWzQQemgiuLjvGhPwo+hrcNzays9j0G
# 7QtALkJ0KfvJS+guvCvSuEfDzt3BaPIpD2q6GYK+MUiNis3uwwngauyL4r048wdv
# USsf92Kyr6T1pAfjjPyVDNazf/w/BjzA6ewNevFVLNfE0DhQkXMmsNVGBzY5Phhl
# p5fbTwsrD19K0FPgbGO/l/Zp2dheeiCbe09bxbhdeahSBtTVPca4Vu3Ljz+PRZjF
# odq7+lziqqpqqCP/ikEnmK/QkxjCG7AkX384dxg7yb5jjtXOnP5Yv4SXuV4SNNVV
# UBJfbLXyYAf3Q0Dal85ZxNQd0QNPQIsYWv9ttTMVc6sVErdfTBPw355St6bHz91L
# UoDD0S/GjUif8LYhVlZGXlwjYmVZOb2Z7+DAamzjwVrSsrxGCJ66Coy1rKapJuHV
# sfGAW44p2ioIEZT3s6nQJkCt7te4ab1iWzaydZGAYyBao0K7kfK3vSp4AXsE5t5y
# 6dpHYo0CAwEAAaOCAp0wggKZMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/
# BAQDAgGGMIGJBggrBgEFBQcBAQR9MHswMAYIKwYBBQUHMAGGJGh0dHA6Ly9jb21t
# ZXJjaWFsLm9jc3AuaWRlbnRydXN0LmNvbTBHBggrBgEFBQcwAoY7aHR0cDovL3Zh
# bGlkYXRpb24uaWRlbnRydXN0LmNvbS9yb290cy9jb21tZXJjaWFscm9vdGNhMS5w
# N2MwHwYDVR0jBBgwFoAU7UQZwNPwBovupHu+QucmVMiONnYwggFEBgNVHSAEggE7
# MIIBNzAIBgZngQwBBAIwDQYLYIZIAYb5LwAGDQMwggEaBgtghkgBhvkvAAYNATCC
# AQkwSgYIKwYBBQUHAgEWPmh0dHBzOi8vc2VjdXJlLmlkZW50cnVzdC5jb20vY2Vy
# dGlmaWNhdGVzL3BvbGljeS90cy9pbmRleC5odG1sMIG6BggrBgEFBQcCAjCBrQyB
# qlRoaXMgVHJ1c3RJRCBDZXJ0aWZpY2F0ZSBoYXMgYmVlbiBpc3N1ZWQgaW4gYWNj
# b3JkYW5jZSB3aXRoIElkZW5UcnVzdCdzIFRydXN0SUQgQ2VydGlmaWNhdGUgUG9s
# aWN5IGZvdW5kIGF0IGh0dHBzOi8vc2VjdXJlLmlkZW50cnVzdC5jb20vY2VydGlm
# aWNhdGVzL3BvbGljeS90cy9pbmRleC5odG1sMEoGA1UdHwRDMEEwP6A9oDuGOWh0
# dHA6Ly92YWxpZGF0aW9uLmlkZW50cnVzdC5jb20vY3JsL2NvbW1lcmNpYWxyb290
# Y2ExLmNybDAdBgNVHQ4EFgQUyjLwNnzHKtqRtXyHihG9uCJsvwkwEwYDVR0lBAww
# CgYIKwYBBQUHAwgwDQYJKoZIhvcNAQELBQADggIBACtnO4f6QB6v2yDFeld3Pa1H
# 7Bmby2tSwzQ/5dB5WXmTZHlV433s7BDkpwGzK4fGBuTcx814uPUWWSwcL+f8bpfo
# zBv6p855j/AlKul1EiPMKkMlLtwdiK6sWT2x8qaTm4fMGbcpgUbQnxOo4BnzVUmg
# s3epm9/qXf9GaWXRz4maSWl4z3apD3X/5oMrriGWIiW6ivCq8bmOBUdm0I9quhW9
# Snk2JAaqkVCjs06rqE3rRblyNdrSypGzo5eBT498aCfcvDPJX2/q2PMkLvkKoXtV
# J1g4sEwDQxm2sg8QMEd2GKo+X7TqOeF8An7KOPDq9v0xtSsF4+ufFrl43vl6v4uM
# ey68wOHv6VmaGpCtWk1e6lSq9jLQqRBBg8CMwpw6niVyvkrdh4Tvu+5HLrareZBp
# 98PJ2cQzrHk1SiPcyDxSlhbXRks/TgKXTicUm3pZsKZcTvCXHcqulN1eoQ3z9azM
# IuR7RtdECz2RJUI6Xg//6ZdMMgaDnktMALgAyo9GgGGVimx4E2/aM5r0cm+RCrk9
# 56BTqahEdiGLWjgjq8dAJe4XfLtp6EmGvsw650uBbDA0Mg9nlSCFdGTMFBKlw65o
# 2oJaenMysAvE/VC39ZIEOBfk2IOj2GTYlOgHi0iIBIZf7SqdjhTAtoW7U9TTZj8S
# HRen/EEe1WEcfTawcOhJMYIDHzCCAxsCAQEwWTBFMQswCQYDVQQGEwJVUzESMBAG
# A1UEChMJSWRlblRydXN0MSIwIAYDVQQDExlUcnVzdElEIFRpbWVzdGFtcGluZyBD
# QSAzAhBAAYD9DvXolVgjPR54g1q+MA0GCWCGSAFlAwQCAQUAoIGYMBoGCSqGSIb3
# DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcNMjMwNTA4MDY1MjI0
# WjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBTy71bgeNSndiGNJX4ndDOhrNiLRjAv
# BgkqhkiG9w0BCQQxIgQgUMsmQfrSihgb3vp/Mqb/FCFBfSbPocCd1j/NQu44Xw0w
# DQYJKoZIhvcNAQEBBQAEggIAIx75Oxh9Dv09PfNQXmH2F3IbObB71QmkO+e4PYmY
# 2WcXVfdnBC0IZBjqvHCXwN+rSGL8T4u2Aa3Gf9l/MSa3Sr2qOSdkEoXMhe0CjHAF
# PE7ZELDy1HoJw+Nt5qdNEK4wqUrP7hlnfKQcVzXp5eVqX4iyLcb60FVprSZ4WITr
# UP4A/ejDHILCyMYMp6V/kPN6jC1VeyyasTmL45ItCBmdzWLUFiRmWxLGcIdIasjd
# IrmyFgZvep9SaNLN1Ci+w/kDu2ir/TEdPqkT6Fayd5mJRHo7wRCiKZAk3Nv9AvPf
# 7t/F3zzq+DChN7Tm2IDKj1szgcxdim+kMjUyD53ELMSIRebJzBedFTT+z4V1X++1
# +oekXVOTrx4Cgks4XX9wUiPNYavJrwZWKGLZ4YLaok5p/JKM3b8C3ju1ib769omB
# brt70i0Gn8uFFyG3iJzWUXN1rJFhpEySSdeW7h82sxfG7aYohGITYQ+JnLpNcCzm
# TDYz/vWSeNcCqpQrd356b402FYkkzH68noHA6UTWCUoAnlyzrDK6tzPOsbgjCOPt
# fVw2ONo3XvMgH2hdI1gw0mQA/zJRevVb7JxVbFOlXwTzvUbXULglLIVuAXtd52a7
# s6w/HkLFlRgeLSu/1RQXOhrHv+BV7Um4vAh3twBm//Tjvglil52p3y3iY87GTW6h
# BqA=
# SIG # End signature block