How to revert a Sitecore hotfix in seconds

Continuing with my earlier blog article of installing a Sitecore hotfix, this one reverts the hotfix. It uses the original scwdp file to revert to old state of the corresponding dll. This script just needs the hotfix zip placed in same folder as the script then during execution, provide site prefix as param. Would download the scwdp file from SDN, if not present. Provides a base code to easily customise for other topologies. 

Unzips the hotfix file and checks if each of the files is present in the instance, removes the same. Then, opens the scwdp file and copies over the corresponding file, if present.

If zips are downloaded and expanded, smart enough to bypass operations and reduce execution time in further runs.





Run in PS prompt as follows: 

.\Revert_Hotfix_Script.ps1 -SitePrefix "sc103lkg"




Pre-requisites:
- Stop the 3 services - xConnect, ProcessingEngine and MA before execution
- Stop the IIS instances too


Testing:
- Tested to revert only one hotfix file so don't copy over multiple hotfix files in the folder
- Tested to revert 10.3.1 XP0 Cumulative hotfix back to 10.3.0 state

Github Link

#https://navansitecorenotes.blogspot.com/2023/06/powershell-script-to-uninstall-hotfix.html
#############################################################
param(
[Parameter(Mandatory = $true)]
[string]
[ValidateNotNullOrEmpty()]
$SitePrefix = "sc103instance",
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]$InstallSourcePath = (Join-Path $PSScriptRoot "."),
# The root folder with the WDP files.
[string]
$PatchType = "cumulative",
# Root folder where the site is installd. If left on the default [systemdrive]:\inetpub\wwwroot will be used
[string]
$SitePhysicalRoot = "c:\inetpub\wwwroot\",
# Site suffix matches what is used by SIA
[string]
$SiteSuffix = ".dev.local"
)
$watch = [System.Diagnostics.Stopwatch]::StartNew()
$watch.Start() # Timer start
$SitePhysicalRootSitecore = $SitePhysicalRoot + $SitePrefix.Trim() + "sc" + $SiteSuffix
$SitePhysicalRootxConnSrvr = $SitePhysicalRoot + $SitePrefix.Trim() + "xconnect" + $SiteSuffix
$SitePhysicalRootIdSrvr = $SitePhysicalRoot + $SitePrefix.Trim() + "identityserver" + $SiteSuffix
Write-Host "Site root" $SitePhysicalRootSitecore
Write-Host "Id root" $SitePhysicalRootIdSrvr
if (-not (Test-Path "Sitecore 10.3.0 rev. 008463 (Setup XP0 Developer Workstation rev. 1.5.0-r11).zip" -PathType Leaf)) {
$preference = $ProgressPreference
$ProgressPreference = "SilentlyContinue"
$sitecoreDownloadUrl = "https://sitecoredev.azureedge.net"
$packages = @{
"Sitecore 10.3.0 rev. 008463 (Setup XP0 Developer Workstation rev. 1.5.0-r11).zip" = "https://sitecoredev.azureedge.net/~/media/8F77892C62CB4DC698CB7688E5B6E0D7.ashx?date=20221130T160548"
}
# download packages from Sitecore
$packages.GetEnumerator() | ForEach-Object {
$filePath = Join-Path $InstallSourcePath $_.Key
$fileUrl = $_.Value
if (Test-Path $filePath -PathType Leaf)
{
Write-Host ("Required package found: '{0}'" -f $filePath)
}
else
{
if ($PSCmdlet.ShouldProcess($fileName))
{
Write-Host ("Downloading '{0}' to '{1}'..." -f $fileUrl,$filePath)
Invoke-WebRequest -Uri $fileUrl -OutFile $filePath -UseBasicParsing
}
else
{
# Download package
Invoke-WebRequest -Uri $fileUrl -OutFile $filePath -UseBasicParsing
}
}
}
Expand-Archive -Force -Path 'Sitecore * XP0 Developer Workstation rev. *.zip' -DestinationPath ".\xp0"
$ProgressPreference = $preference
Write-Host "Unzipped Sitecore Zip"
}
################################Unzip Sitecore wdp file - start
$SitecoreWebSiteZipPath = $InstallSourcePath + "\xp0\Sitecore * rev. * (OnPrem)_single.scwdp.zip"
Write-Host "Sitecore Wdp zip file whole path " $SitecoreWebSiteZipPath
#$SitecoreWebsiteZipPath = (Get-ChildItem $SitecoreWebSiteZipPath).FullName
#Write-Host "Website zip Path" $SitecoreWebsiteZipPath
$SitecoreWdpFileLocation = Split-Path $SitecoreWebSiteZipPath -Parent
Write-Host "Sitecore Wdp file unzip path " $SitecoreWdpFileLocation
Write-Host "Sitecore Wdp file whole path" $SitecoreWdpFileLocation"\SitecoreWdp"
if (-not (Test-Path $SitecoreWdpFileLocation"\SitecoreWdp")) {
Expand-Archive -Path $SitecoreWebSiteZipPath -DestinationPath $SitecoreWdpFileLocation"\SitecoreWdp" -Force
}
$SourcePath = $SitecoreWdpFileLocation + "\SitecoreWdp\Content\Website"
Write-Host "Source path " $SourcePath
################################Unzip Sitecore wdp file - end
################################Unzip Sitecore ID wdp file - start
$SitecoreIDWebSiteZipPath = $InstallSourcePath + "\xp0\Sitecore.IdentityServer * rev. * (OnPrem)_identityserver.scwdp.zip"
Write-Host "Sitecore Wdp ID zip file whole path " $SitecoreIDWebSiteZipPath
#$SitecoreIDWebsiteZipPath = (Get-ChildItem $SitecoreIDWebSiteZipPath).FullName
#Write-Host "ID Website zip Path" $SitecoreIDWebsiteZipPath
$SitecoreIDWdpFileLocation = Split-Path $SitecoreIDWebSiteZipPath -Parent
Write-Host "Sitecore Wdp ID file whole path" $SitecoreIDWdpFileLocation"\SitecoreIdWdp"
if (-not (Test-Path $SitecoreIDWdpFileLocation"\SitecoreIdWdp")) {
Expand-Archive -Path $SitecoreIDWebSiteZipPath -DestinationPath $SitecoreIDWdpFileLocation"\SitecoreIdWdp" -Force
}
$IdSourcePath = $SitecoreIDWdpFileLocation + "\SitecoreIdWdp\Content\Website"
Write-Host "Id Source path " $IdSourcePath
################################Unzip Sitecore ID wdp file - end
################################Unzip Sitecore xconnect wdp file - start
$SitecorexConnWebSiteZipPath = $InstallSourcePath + "\xp0\Sitecore * rev. * (OnPrem)_xp0xconnect.scwdp.zip"
Write-Host "Sitecore Wdp xConnect zip file whole path " $SitecorexConnWebSiteZipPath
#$SitecorexConnWebsiteZipPath = (Get-ChildItem $SitecorexConnWebSiteZipPath).FullName
#Write-Host "xConnect Website zip Path" $SitecorexConnWebsiteZipPath
$SitecorexConnWdpFileLocation = Split-Path $SitecorexConnWebSiteZipPath -Parent
Write-Host "Sitecore Wdp xConnect file whole path" $SitecorexConnWdpFileLocation"\SitecorexConnWdp"
if (-not (Test-Path $SitecorexConnWdpFileLocation"\SitecorexConnWdp")) {
Expand-Archive -Path $SitecorexConnWebSiteZipPath -DestinationPath $SitecorexConnWdpFileLocation"\SitecorexConnWdp" -Force
}
$xConnSourcePath = $SitecorexConnWdpFileLocation + "\SitecorexConnWdp\Content\Website"
Write-Host "xConn Source path " $xConnSourcePath
################################Unzip Sitecore xconnect wdp file - end
$HotFixFileName = Get-ChildItem -Path $InstallSourcePath -Filter *cumulative*.zip
Write-Host "Unzipping the hotfix zip file - " $HotFixFileName
if (-not (Test-Path ".\Hotfix")) {
Expand-Archive -Path $HotFixFileName -Force -DestinationPath "Hotfix"
}
if ($PatchType -eq 'cumulative')
{
# The path to the Sitecore cumulative Package to Deploy.
$SitecorePackageZipPath = $InstallSourcePath + "\Hotfix\Sitecore * rev. * (OnPrem)_single.cumulative.delta.scwdp.zip"
Write-Host $SitecorePackageZipPath
# The path to the Identity Server cumulative Package to Deploy.
$IdentityServerPackageZipPath = $InstallSourcePath + "\Hotfix\Sitecore.IdentityServer * rev. * (OnPrem)_identityserver.cumulative.delta.scwdp.zip"
Write-Host $IdentityServerPackageZipPath
# The path to the xConnect Server cumulative Package to Deploy.
$XConnectPackageZipPath = $InstallSourcePath + "\Hotfix\Sitecore * rev. * (OnPrem)_xp0xconnect.cumulative.delta.scwdp.zip"
Write-Host $XConnectPackageZipPath
}
else
{
# The path to the Sitecore Package to Deploy.
$SitecorePackageZipPath = $InstallSourcePath + "\Hotfix_Delta\Sitecore * rev. * (OnPrem)_single.delta.scwdp.zip"
# The path to the Identity Server Package to Deploy.
$IdentityServerPackageZipPath = $InstallSourcePath + "\Hotfix_Delta\Sitecore.IdentityServer * rev. * (OnPrem)_identityserver.delta.scwdp.zip"
# The path to the xConnect Server Package to Deploy.
$XConnectPackageZipPath = $InstallSourcePath + "\Hotfix_Delta\Sitecore * rev. * (OnPrem)_xp0xconnect.delta.scwdp.zip"
}
# The path to the Sitecore Package to Deploy.
$SitecorePackagePath = (Get-ChildItem $SitecorePackageZipPath).FullName
# The path to the Identity Server Package to Deploy.
$IdentityServerPackagePath = (Get-ChildItem $IdentityServerPackageZipPath).FullName
# The path to the xConnect Server Package to Deploy.
$XConnectPackagePath = (Get-ChildItem $XConnectPackageZipPath).FullName
$SitecorePackageUnzipPath = (Get-Item $SitecorePackageZipPath).FullName
$SitecorePackageUnzipDir = (Get-Item $SitecorePackageUnzipPath).DirectoryName + "\sitecore"
$SitecoreIdentityServerPackageUnzipPath = (Get-Item $IdentityServerPackageZipPath).FullName
$SitecoreIdentityServerPackageUnzipDir = (Get-Item $SitecoreIdentityServerPackageUnzipPath).DirectoryName + "\identity"
$SitecorexConnectServerPackageUnzipPath = (Get-Item $XConnectPackageZipPath).FullName
$SitecorexConnectServerPackageUnzipDir = (Get-Item $SitecorexConnectServerPackageUnzipPath).DirectoryName + "\xconnect"
if (-not (Test-Path $SitecorePackageUnzipDir)) {
Write-Host "Unzipping the Sitecore Package file to - " $SitecorePackageUnzipDir
Expand-Archive -Path $SitecorePackagePath -Destination $SitecorePackageUnzipDir -Force
}
if (-not (Test-Path $SitecoreIdentityServerPackageUnzipDir)) {
Write-Host "Unzipping the Identity Package file to - " $SitecoreIdentityServerPackageUnzipDir
Expand-Archive -Path $IdentityServerPackagePath -Destination $SitecoreIdentityServerPackageUnzipDir -Force
}
if (-not (Test-Path $SitecorexConnectServerPackageUnzipDir)) {
Write-Host "Unzipping the xConnect Package file to - " $SitecorexConnectServerPackageUnzipDir
Expand-Archive -Path $XConnectPackagePath -Destination $SitecorexConnectServerPackageUnzipDir -Force
}
#####################################################Sitecore webroot wdp package unzip and processing - start
$SitecoreHotFixTraversePath = $SitecorePackageUnzipDir + "\content\website"
Write-Host "Hotfix start path " $SitecoreHotFixTraversePath
$files = Get-ChildItem -Path $SitecoreHotFixTraversePath -Recurse -Force -File
Write-Host "Starting revert Operation at " $SitePhysicalRootSitecore
foreach ($file in $files)
{
$origPath = $file.FullName
$fileName = $file.FullName.Replace($SitecoreHotFixTraversePath,$SitePhysicalRootSitecore)
if (Test-Path $fileName) {
Write-Host "Removing " $fileName
Remove-Item $fileName -Force
}
#Replace hotfix path with wdp path
$WebSiteWdpPath = $origPath.Replace($SitecoreHotFixTraversePath,$SourcePath)
#check if the wdp path exists
if (Test-Path $WebSiteWdpPath) {
Write-Host "WDP Path " $WebSiteWdpPath
#if exists, copy over to webroot path
$WebSiteRootPath = $WebSiteWdpPath.Replace($SourcePath,$SitePhysicalRootSitecore)
Write-Host "Copy over Path " $WebSiteRootPath
Copy-Item $WebSiteWdpPath -Destination $WebSiteRootPath -Force
}
}
#####################################################Sitecore webroot wdp package unzip and processing - end
#####################################################Sitecore id wdp package unzip and processing - start
$SitecoreIdSrvrHotFixTraversePath = $SitecoreIdentityServerPackageUnzipDir + "\content\website"
Write-Host "Hotfix Id start path " $SitecoreIdSrvrHotFixTraversePath
$idfiles = Get-ChildItem -Path $SitecoreIdSrvrHotFixTraversePath -Recurse -Force -File
Write-Host "Starting id srvr revert Operation at " + $SitePhysicalRootIdSrvr
foreach ($file in $idfiles)
{
$OrigidPath = $file.FullName
$IdFileName = $file.FullName.Replace($SitecoreIdSrvrHotFixTraversePath,$SitePhysicalRootIdSrvr)
if (Test-Path $IdFileName) {
Write-Host "Removing " $IdFileName
Remove-Item $IdFileName -Force
}
#Replace hotfix id path with wdp id path
$IdWdpPath = $OrigidPath.Replace($SitecoreIdSrvrHotFixTraversePath,$IdSourcePath)
#check if the id wdp path exists
if (Test-Path $IdWdpPath) {
Write-Host "ID WDP Path " $IdWdpPath
#if exists, copy over to webroot path
$IdWebSiteRootPath = $IdWdpPath.Replace($IdSourcePath,$SitePhysicalRootIdSrvr)
Write-Host "Copy over ID Path " $IdWebSiteRootPath
Copy-Item $IdWdpPath -Destination $IdWebSiteRootPath -Force
}
}
#####################################################Sitecore id wdp package unzip and processing - end
#####################################################Sitecore id wdp package unzip and processing - start
$SitecorexConnHotFixTraversePath = $SitecorexConnectServerPackageUnzipDir + "\content\website"
Write-Host "Hotfix xConn start path " $SitecorexConnHotFixTraversePath
$xConnfiles = Get-ChildItem -Path $SitecorexConnHotFixTraversePath -Recurse -Force -File
Write-Host "Starting xConn srvr revert Operation at " + $SitePhysicalRootxConnSrvr
foreach ($file in $xConnfiles)
{
$OrigxConnPath = $file.FullName
$xConnFileName = $file.FullName.Replace($SitecorexConnHotFixTraversePath,$SitePhysicalRootxConnSrvr)
Write-Host "xconn file name path" $xConnFileName
if (Test-Path $xConnFileName) {
Write-Host "Removing " $xConnFileName
Remove-Item $xConnFileName -Force
}
#Replace hotfix xConn path with wdp xConn path
$xConnWdpPath = $OrigxConnPath.Replace($SitecorexConnHotFixTraversePath,$xConnSourcePath)
#check if the xConn wdp path exists
if (Test-Path $xConnWdpPath) {
Write-Host "xConnect WDP Path " $xConnWdpPath
#if exists, copy over to xconn webroot path
$xConnWebSiteRootPath = $xConnWdpPath.Replace($xConnSourcePath,$SitePhysicalRootxConnSrvr)
Write-Host "xConnect Copy over Path " $xConnWebSiteRootPath
Copy-Item $xConnWdpPath -Destination $xConnWebSiteRootPath -Force
}
}
#####################################################Sitecore id wdp package unzip and processing - end
Write-Host "Process Complete!"
$watch.Stop() # Stopping the timer
Write-Host "Execution time in seconds " $watch.Elapsed # Print script execution time
############################################################

Comments