Dmgdotnet's Blog

Sitecore and stuff

Remove old Sitecore installs

Posted by dmgdotnet on November 8, 2011

If you are like me and tend to do a fresh install of Sitecore everytime you begin a new module or feature then you will have a very large list of Sitecore sites in IIS.  The main reason I never clean these out is due to the work involved of Removing IIS site, detaching db’s, deleting files etc. etc.  To speed this up I thought I would give PowerShell a run at automating this for me.  The resulting script does a reasonable job of this however I am new to PowerShell and would welcome any pointers or improvements to what I came up with.

param($site)

if($site -eq $null){"No site paramater"; exit; }
import-module WebAdministration

if ( (Get-PSSnapin -Name SqlServerCmdletSnapin100 -ErrorAction SilentlyContinue) -eq $null )
{
    Add-PsSnapin SqlServerCmdletSnapin100
}
if ( (Get-PSSnapin -Name SqlServerProviderSnapin100 -ErrorAction SilentlyContinue) -eq $null )
{
    Add-PsSnapin SqlServerProviderSnapin100
}

$SqlServerConnectionTimeout = 8

function Match-Path
{
    param($dbFilePath, $dbdirs)
    foreach($dir in $dbdirs)
    {
      if([regex]::escape($dir.ToLower()) -eq [regex]::escape($dbFilePath.ToLower()))
      {
        return $true
      }
    }
    return $false
}

$website = Get-Website | Where {$_.Name -eq $site}
if($website -eq $null)
{
    "Website not found - Cannot Continue"
    exit
}
else
{
    "Website found: " + $website.Name
}

"Continue? 'y' to continue removal"
$cont = Read-Host
if($cont -ne 'y')
{
  exit
}

"Stopping Site: " + $website.Name
Stop-Website $website.Name
$website.Name + " Stopped"

$websitepath = $website.PhysicalPath
$apppath = $websitepath | Split-Path -parent
$appPath
$dbfiles = Get-ChildItem $apppath -recurse -include *.mdf
$dbdirectories = $dbfiles | Split-Path -parent | Get-Unique
"Found database directories: " + $dbdirectories

foreach($dbServer in gci SQLSERVER:\SQL\localhost)
{
    $arrService = Get-Service -Name ("MSSQL$" + $dbServer.DisplayName)

    if($arrService.Status -eq "Running")
    {
       $matches = $dbServer.databases | Where {Match-Path $_.PrimaryFilePath $dbdirectories} | foreach-object -process {$_.Name  }
       if($matches -ne $null)
       {
           "Found attached databases: " + $matches
            "Detaching Dbs"
            foreach($db in $matches)
            {
                $dbServer.KillAllprocesses($db.Name)
                "Detach: " + $db
                $dbServer.DetachDatabase($db, $false, $false)
            }

        } else
        {
            "No attached dbs found on " + $arrService.Name
        }
    }

}

gci IIS:\AppPools\ | Where {$_.Name -match $website.Name} | foreach{$_.Stop()}

"Deleting Site: " + $website.Name

Remove-Website $website.Name

if(($apppath | Split-Path -leaf) -eq "wwwroot" )
{
    "Deleting all files: " + $websitepath
    "Continue? 'y' to delete"
    $response = Read-Host
     if($response -eq "y")
    {
        "Deleting..."
        Remove-Item -Recurse -Force $websitepath
    }else{
        "Delete Skipped"
    }
}else
{
    "Deleting all files; " + $apppath
    "Continue? 'y' to delete"
    $response = Read-Host
    if($response -eq "y")
    {
        "Deleting..."
        Remove-Item -Recurse -Force $apppath
    }else{
        "Delete Skipped"
    }
}

gci IIS:\AppPools\ | Where {$_.Name -match $website.Name} | foreach{$_.Start()}

Get-ChildItem HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall | Where {$_.GetValue("InstallLocation") -match [regex]::escape($apppath) + "\\"} | foreach{ Remove-Item $_.Name.Replace("HKEY_LOCAL_MACHINE\", "HKLM:\") }
Get-ChildItem "HKLM:\SOFTWARE\Wow6432Node\Sitecore CMS" | Where {$_.GetValue("InstanceDirectory") -match [regex]::escape($apppath) + "\\"} | foreach{ Remove-Item $_.Name.Replace("HKEY_LOCAL_MACHINE\", "HKLM:\") }

EDIT:
Made some changes around cleaning up some registry entries and some other modifications. Starting to feel a little bit Hacky but hey, it does the job. Use with caution!

Leave a comment