Remove Previous Versions

This script will loop through all lists in each site collection and remove previous versions of nintex workflows that are no longer running on an item. Its normally done by hand but with almost 300 sites I needed a way to do this efficiently. This can be scheduled to run during off hours on a regular basis. It runs quickly so runnung during the work day isn’t going to trip you up.

<#
    This script removes workflow associations that are no longer in use on all lists on all sites on the named web application.
#>
function SendeMail([string]$fileout)
{
	$smtpServer = "<your servers IP>" 

	$From = "<you>"
	$To = "<you>"

	$Subject = "Dead Versions Report"
	$Body = "Attached is a report of old versions of workflows that are no longer running and have been safely removed."


	try{
	    Send-MailMessage -To $To -Subject $Subject -Body $Body -SmtpServer $smtpServer -From $From -Attachments $fileout
	}catch{
     		$ErrorMessage = $_.Exception.Message
     		Write-Output $ErrorMessage 
}

}
clear-host;
$start = get-date
write-host "Started " $start
write-host "Please wait ..." -foregroundcolor green
 $outputFile = "PrevVersionsNotRunning.txt"

#Set the Web application URL
$WebAppURL="<FQDN OF YOUR WEB APPLICATION>"

#Get the Web Application       
$WebApp = Get-SPWebApplication $WebAppURL
 
#Get all Site collections from the web application
$SPSites  = $WebApp.Sites

for($a = $SPSites.Count; $a -ge 0; $a--){
  	$SPWeb = $SPSites[$a].allWebs
	for($b = $SPWeb.Lists.Count; $b -ge 0; $b--){	
	  try{
	   $SPList = $SPWeb.Lists[$b]
		$workflowAssociations = $SPList.WorkflowAssociations;
		if($null  -ne $workflowAssociations ){                  
                        for($i = $workflowAssociations.count; $i -ge 0; $i--){
                            if ($workflowAssociations[$i].Name -like "*Previous Version*" -and $workflowAssociations[$i].RunningInstances -eq 0) {                               
                              try{
                                write-output $workflowAssociations[$i].name " on " $SPWeb.url  |out-file $outputFile -append
                                        $workflowAssociations.Remove($workflowAssociations[$i]);
                                        $SPList.Update();
                                    }catch{write-output  $workflowAssociations[$i].name " FAILED on " $SPWeb.url  |out-file $outputFile -append }
                
                    }
                    }
		}	
	
	  }catch{}
}
}

$end = get-date	

write-host "Runtimes  " $start $end
SendeMail $outputFile

write-host "Total Time " $($end - $start)

Purging Nintex Database mappings

Sometimes its necessary to quickly get rid of the mappings of your nintex databases and this script lets you do that. I use this when a site setup goes south on me and I have to start over. I use a specific naming convention for my datbases so if they aren’t removed before running the setup script again, an error occurs because the DB already exists. So this script is run after the spsite has been removed and the spcontentdatabase has been dismounted from the web application. Not before because that adds some new errors that will need fixing.

/****** 
  You must be absolutely certain 
  that the ID is the correct one or
  you'll need to restore from backups 
  or manually readd the info
  you've removed!
******/

use Nintex_Config
SELECT *   FROM [Storage] order by DatabaseID desc
SELECT *   FROM [ContentDbMapping] order by NWContentDbId desc
SELECT *   FROM [Databases] order by DatabaseID desc


/* You best be sure this is right. 
This is the DatabaseID in the Databases table.
use Nintex_Config
  Declare @DBID INT = 269
  delete from [Databases] where DatabaseID = @DBID
  delete from [Storage] where DataBaseID = @DBID
  delete from [ContentDbMapping] where NWContentDbId = @DBID
  
*/ 

Notice the second set of queries is commented out. The first query is run and the databaseid id retrieved. It should be the top of the resultset. That integer is put pasted into the @DBID in the second query then the second query is highlighted and the entries are removed.

There are more efficient ways to do this but when I’m going under the covers to do things I prefer that the process require more steps and require me to be very very intentional. I run this in both dev and production farms so the extra steps are a good safeguard. The warnings were added in case I’m hit by a bus and someone stumbles across these scripts who may not be all that familiar with these tables.