How to repair your Sitecore instance in seconds

Another day and another PS Script for Sitecore dinosaurs in pre-docker age. This one does a basic repair of your instance without disturbing your custom dlls/configs. If you backed-up your webroot folders maybe this doesn't hold water but most of the times we forget to do it at least the first time! Useful in scenarios wherein you messed up your local environment dlls/configs or folder system - Think of those Object reference ysod errors. Would work better with a VS code publish to reset your local instance back to working condition. The main advantage is, you don't need to manually copy over folders/files from scwdp file. This one auto-downloads the xp0 developer zip file and repairs the structure of your local instance.



This script works for 9.x and 10.x instances. Based on size of a file in bin folder, replaces correct version of file if there is a different file (size) version deployed to web root folders. Size comparison is applicable only for bin folder and not others. Note that the folder can be parameterised but could give unexpected results if something like App_Config is passed.  You could also provide a dummy prefix and this script will dump all files from scwdp to the concerned folders.

Testing:

1. Delete Sitecore.Kernel.dll from a 9.3 instance and you have this ysod:

Server Error in '/' Application.

Compilation Error

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: CS0234: The type or namespace name 'UserProfile' does not exist in the namespace 'Sitecore.Security' (are you missing an assembly reference?)

Source Error:

Line 283:      </providers>
Line 284:    </roleManager>
Line 285:    <profile defaultProvider="sql" enabled="true" inherits="Sitecore.Security.UserProfile, Sitecore.Kernel">
Line 286:      <providers>
Line 287:        <clear/>

Source File: c:\inetpub\wwwroot\sc93insc.dev.local\Web.config    Line: 285






Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.8.9032.0


2. Next, run the PS repair script as follows:

.\Repair_Sitecore_Script.ps1 -SitePrefix sc93in

3. The script downloads the zip for the version from SDN if not existing, unzips the same and uses it as reference to check the web site's file system and repair in case there is a missing file(s) or folder(s). If the reference folder is present, uses the same for cross-checking in the consequent runs:


4. File system structure built by the script:



5. In case file system is fine, provides relevant message:



Constraints:

- Currently works for xp0 topology but topology can be parameterised

- if files like ConnectionStrings.config are deleted, wouldn't be able to repair unless VS publish complements in some way


#https://navansitecorenotes.blogspot.com/2023/06/how-to-repair-your-sitecore-instance-in.html
##########################################################
param(
[Parameter(Mandatory = $true)]
[string]
[ValidateNotNullOrEmpty()]
$SitePrefix = "sc93in",
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]$InstallSourcePath = (Join-Path $PSScriptRoot "."),
# Root folder where the site is installed. default [systemdrive]:\inetpub\wwwroot will be used
[string]
$SitePhysicalRoot = "c:\inetpub\wwwroot\",
# Site suffix matches what is used by SIA
[string]
$SiteSuffix = ".dev.local",
# Site suffix matches what is used by SIA
[string]
$SitecoreVersion = "9.3"
)
$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
switch ($SitecoreVersion)
{
"10.3.0" {
$SdnUrl = "https://sitecoredev.azureedge.net/~/media/8F77892C62CB4DC698CB7688E5B6E0D7.ashx?date=20221130T160548"
break
}
"10.2.0" {
$SdnUrl = "https://sitecoredev.azureedge.net/~/media/F6813A6E3E424AB99A6E9A7CC257648B.ashx?date=20211101T105423"
break
}
"10.1.0" {
$SdnUrl = "https://sitecoredev.azureedge.net/~/media/A76121649BE84CAD8DECAD641D307C32.ashx"
break
}
"10.0.0" {
$SdnUrl = "https://sitecoredev.azureedge.net/~/media/A74E47524738460B83332BAE82F123D1.ashx"
break
}
"10.0.1" {
$SdnUrl = "https://sitecoredev.azureedge.net/~/media/F348FF71C86D4F7096C2B929E0DA2F49.ashx?date=20201211T131403"
break
}
"9.3" {
$SdnUrl = "https://sitecoredev.azureedge.net/~/media/A1BC9FD8B20841959EF5275A3C97A8F9.ashx"
break
}
"9.2" {
$SdnUrl = "https://sitecoredev.azureedge.net/~/media/1C1D7C4CBC934A6AA36825974A18A72E.ashx"
break
}
}
if (-not (Test-Path .\$SitecoreVersion\xp0 -PathType Container)) {
$preference = $ProgressPreference
$ProgressPreference = "SilentlyContinue"
$sitecoreDownloadUrl = "https://sitecoredev.azureedge.net"
$packages = @{
"Sitecore Setup XP0 Developer Workstation.zip" = $SdnUrl
}
# 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.zip' -DestinationPath .\$SitecoreVersion\xp0
Remove-Item -Force -Path 'Sitecore * XP0 Developer Workstation.zip'
$ProgressPreference = $preference
Write-Host "Unzipped Sitecore Zip"
}
################################Unzip Sitecore wdp file - start
$SitecoreWebSiteZipPath = $InstallSourcePath + "\" + $SitecoreVersion + "\xp0\Sitecore * rev. * (OnPrem)_single.scwdp.zip"
Write-Host "Sitecore Wdp zip file whole 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 + "\" + $SitecoreVersion + "\xp0\Sitecore.IdentityServer * rev. * (OnPrem)_identityserver.scwdp.zip"
Write-Host "Sitecore Wdp ID zip file whole 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 + "\" + $SitecoreVersion + "\xp0\Sitecore * rev. * (OnPrem)_xp0xconnect.scwdp.zip"
Write-Host "Sitecore Wdp xConnect zip file whole 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
#####################################################Sitecore webroot wdp package unzip and processing - start
$SourcePath = Get-Item -Path $SourcePath
Write-Host "Wdp start path " $SourcePath
$files = Get-ChildItem -Path $SourcePath -Recurse -Force
Write-Host "Scanning for repair Operation at " $SitePhysicalRootSitecore
$WebSiteFixed = $false
foreach ($file in $files)
{
$origPath = $file.FullName
$WebSiteCopyToLocation = $origPath.Replace($SourcePath,$SitePhysicalRootSitecore)
if (-not (Test-Path $WebSiteCopyToLocation)) {
Write-Host -ForegroundColor blue "Change detected!!! Copy from Path " $origPath
Write-Host -ForegroundColor blue "Copy to Path " $WebSiteCopyToLocation
Copy-Item $origPath -Destination (Split-Path $WebSiteCopyToLocation -Parent) -Force
$WebSiteFixed = $true
}
else
{
if ((Split-Path (Split-Path $WebSiteCopyToLocation -Parent) -Leaf) -eq "bin")
{
#file present but check for length diff
$OrigSize = (Get-Item -Path $origPath).Length
$CurrSize = (Get-Item $WebSiteCopyToLocation).Length
if ($OrigSize -ne $CurrSize)
{
Write-Host -ForegroundColor blue "Change detected!!! DLL Size Difference... Copy from Path " $origPath
Write-Host -ForegroundColor blue "Copy to Path " $WebSiteCopyToLocation
Copy-Item $origPath -Destination (Split-Path $WebSiteCopyToLocation -Parent) -Force
$WebSiteFixed = $true
}
}
}
}
#####################################################Sitecore webroot wdp package unzip and processing - end
#####################################################Sitecore id wdp package unzip and processing - start
$IdSourcePath = Get-Item -Path $IdSourcePath
Write-Host "Wdp start path " $IdSourcePath
$idfiles = Get-ChildItem -Path $IdSourcePath -Recurse -Force
Write-Host "Scanning id srvr for repair Operation at " $SitePhysicalRootIdSrvr
foreach ($idfile in $idfiles)
{
$OrigidPath = $idfile.FullName
$WebSiteIdCopyToLocation = $OrigidPath.Replace($IdSourcePath,$SitePhysicalRootIdSrvr)
if (-not (Test-Path $WebSiteIdCopyToLocation)) {
Write-Host -ForegroundColor blue "Change detected!!! Copy from id Path " $OrigidPath
Write-Host -ForegroundColor blue "Copy to id Path " $WebSiteIdCopyToLocation
Copy-Item $OrigidPath -Destination (Split-Path $WebSiteIdCopyToLocation -Parent) -Force
$WebSiteFixed = $true
}
else
{
if ((Split-Path (Split-Path $WebSiteIdCopyToLocation -Parent) -Leaf) -eq "bin")
{
#file present but check for length diff
$OrigSize = (Get-Item -Path $OrigidPath).Length
$CurrSize = (Get-Item $WebSiteIdCopyToLocation).Length
if ($OrigSize -ne $CurrSize)
{
Write-Host -ForegroundColor blue "Change detected!!! DLL Size Difference... Copy from Path " $OrigidPath
Write-Host -ForegroundColor blue "Copy to Path " $WebSiteIdCopyToLocation
Copy-Item $OrigidPath -Destination (Split-Path $WebSiteIdCopyToLocation -Parent) -Force
$WebSiteFixed = $true
}
}
}
}
#####################################################Sitecore id wdp package unzip and processing - end
#####################################################Sitecore id wdp package unzip and processing - start
$xConnSourcePath = Get-Item -Path $xConnSourcePath
Write-Host "Wdp start path " $xConnSourcePath
$xConnfiles = Get-ChildItem -Path $xConnSourcePath -Recurse -Force
Write-Host "Scanning xConn srvr for repair Operation at " + $SitePhysicalRootxConnSrvr
foreach ($file in $xConnfiles)
{
$OrigxConnPath = $file.FullName
$WebSitexConnCopyToLocation = $OrigxConnPath.Replace($xConnSourcePath,$SitePhysicalRootxConnSrvr)
if (-not (Test-Path $WebSitexConnCopyToLocation)) {
Write-Host -ForegroundColor blue "Change detected!!! Copy from xConn Path " $OrigxConnPath
Write-Host -ForegroundColor blue "Copy to xConn Path " $WebSitexConnCopyToLocation
Copy-Item $OrigxConnPath -Destination (Split-Path $WebSitexConnCopyToLocation -Parent) -Force
$WebSiteFixed = $true
}
else
{
if ((Split-Path (Split-Path $WebSitexConnCopyToLocation -Parent) -Leaf) -eq "bin")
{
#file present but check for length diff
$OrigSize = (Get-Item -Path $OrigxConnPath).Length
$CurrSize = (Get-Item $WebSitexConnCopyToLocation).Length
if ($OrigSize -ne $CurrSize)
{
Write-Host -ForegroundColor blue "Change detected!!! DLL Size Difference... Copy from Path " $OrigxConnPath
Write-Host -ForegroundColor blue "Copy to Path " $WebSitexConnCopyToLocation
Copy-Item $OrigxConnPath -Destination (Split-Path $WebSitexConnCopyToLocation -Parent) -Force
$WebSiteFixed = $true
}
}
}
}
#####################################################Sitecore id wdp package unzip and processing - end
if (-not ($WebSiteFixed)) { Write-Host -ForegroundColor green "Nothing to fix... WebSite looks good!!!" }
Write-Host "Process Complete!"
$watch.Stop() # Stopping the timer
Write-Host "Execution time in seconds " $watch.Elapsed # Print script execution time
#######################################################

Comments