Here’s a very cool script that is a huge time saver for applying the cumulative updates to SharePoint.
To use it, just copy the code below into a text file and save that file as a .ps1 file. (e.g. C:\UpdateFolder\CUInstall.ps1)
05/07/2017 – When I originally wrote this post I had mentioned That I had no idea who wrote this code; but, I can tell you that I didn’t and that it works! And, that is all still true except for the part about who wrote it. It was written by Russ Maxwell in 2013 – https://blogs.msdn.microsoft.com/russmax/2013/04/01/why-sharepoint-2013-cumulative-update-takes-5-hours-to-install/
Thanks Russ!
########################### ##Ensure Patch is Present## ########################### $patchfile = Get-ChildItem | where{$_.Extension -eq ".exe"} if($patchfile -eq $null) { Write-Host "Unable to retrieve the file. Exiting Script" -ForegroundColor Red Return } ######################## ##Stop Search Services## ######################## ##Checking Search services## $srchctr = 1 $srch4srvctr = 1 $srch5srvctr = 1 $srv4 = get-service "OSearch15" $srv5 = get-service "SPSearchHostController" If(($srv4.status -eq "Running") -or ($srv5.status-eq "Running")) { Write-Host "Choose 1 to Pause Search Service Application" -ForegroundColor Cyan Write-Host "Choose 2 to leave Search Service Application running" -ForegroundColor Cyan $searchappresult = Read-Host "Press 1 or 2 and hit enter" Write-Host if($searchappresult -eq 1) { $srchctr = 2 Write-Host "Pausing the Search Service Application" -foregroundcolor yellow Write-Host "This could take a few minutes" -ForegroundColor Yellow $ssa = get-spenterprisesearchserviceapplication $ssa.pause() } elseif($searchappresult -eq 2) { Write-Host "Continuing without pausing the Search Service Application" } else { Write-Host "Run the script again and choose option 1 or 2" -ForegroundColor Red Write-Host "Exiting Script" -ForegroundColor Red Return } } Write-Host "Stopping Search Services if they are running" -foregroundcolor yellow if($srv4.status -eq "Running") { $srch4srvctr = 2 set-service -Name "OSearch15" -startuptype Disabled $srv4.stop() } if($srv5.status -eq "Running") { $srch5srvctr = 2 Set-service "SPSearchHostController" -startuptype Disabled $srv5.stop() } do { $srv6 = get-service "SPSearchHostController" if($srv6.status -eq "Stopped") { $yes = 1 } Start-Sleep -seconds 10 } until ($yes -eq 1) Write-Host "Search Services are stopped" -foregroundcolor Green Write-Host ####################### ##Stop Other Services## ####################### Set-Service -Name "IISADMIN" -startuptype Disabled Set-Service -Name "SPTimerV4" -startuptype Disabled Write-Host "Gracefully stopping IIS W3WP Processes" -foregroundcolor yellow Write-Host iisreset -stop -noforce Write-Host "Stopping Services" -foregroundcolor yellow Write-Host $srv2 = get-service "SPTimerV4" if($srv2.status -eq "Running") {$srv2.stop()} Write-Host "Services are Stopped" -ForegroundColor Green Write-Host Write-Host ################## ##Start patching## ################## Write-Host "Patching now keep this PowerShell window open" -ForegroundColor Magenta Write-Host $starttime = Get-Date $filename = $patchfile.basename Start-Process $filename Start-Sleep -seconds 20 $proc = get-process $filename $proc.WaitForExit() $finishtime = get-date Write-Host Write-Host "Patch installation complete" -foregroundcolor green Write-Host ################## ##Start Services## ################## Write-Host "Starting Services Backup" -foregroundcolor yellow Set-Service -Name "SPTimerV4" -startuptype Automatic Set-Service -Name "IISADMIN" -startuptype Automatic ##Grabbing local server and starting services## $servername = hostname $server = get-spserver $servername $srv2 = get-service "SPTimerV4" $srv2.start() $srv3 = get-service "IISADMIN" $srv3.start() $srv4 = get-service "OSearch15" $srv5 = get-service "SPSearchHostController" ###Ensuring Search Services were stopped by script before Starting" if($srch4srvctr -eq 2) { set-service -Name "OSearch15" -startuptype Automatic $srv4.start() } if($srch5srvctr -eq 2) { Set-service "SPSearchHostController" -startuptype Automatic $srv5.start() } ###Resuming Search Service Application if paused### if($srchctr -eq 2) { Write-Host "Resuming the Search Service Application" -foregroundcolor yellow $ssa = get-spenterprisesearchserviceapplication $ssa.resume() } Write-Host "Services are Started" -foregroundcolor green Write-Host Write-Host Write-Host "Script Duration" -foregroundcolor yellow Write-Host "Started: " $starttime -foregroundcolor yellow Write-Host "Finished: " $finishtime -foregroundcolor yellow Write-Host "Script Complete"
After you have the .ps1 file, save that .ps1 and the files you downloaded for the cu, usually a couple of uber files and an executable, into the same directory on your server. (e.g. c:\updateFolder)
If you don’t have the CU downloaded yet, here’s a link to TK’s blog – I recommend the November 2016 CU for SharePoint 2013; but, you’ll always want to check for any regressions and apply to a non-prod environment first.
Next, open PowerShell and navigate to the directory where you saved the .ps1 file, the CU exe file, and the other files (e.g. cd c:\updateFolder).
Make sure the Execution policy in PowerShell, is set to unrestricted (e.g. c:\updateFolder\Set-ExecutionPolicy unrestricted)
Call the .ps1 file (c:>\updateFolder\ .\CUInstall.ps1)
If prompted to allow, go ahead and allow all by pressing A, or Y
(If you have more servers in the farm, you should go to them and run the script, same options as this server)
When you run the PowerShell it will give you the option to stop search and other services, definitely pick this option.
Do not close the window, let it run until the script is completed.
VERY IMPORTANT: At the end of the script if the patch requires a restart, do NOT restart, until the script has had an opportunity to restart the services and finish.
When prompted by the installer to restart, like so many other things in life, “Just Say No”
When the script finishes you’ll see Script Complete.
After the script completes go ahead and restart the server after all the servers in the farm have got to this point.
Run this script in parallel on other servers in the farm, obeying the same restart rules.
After all servers have received the CU, and restarted for good measure, and not before, go ahead and run psconfig either from the wizard or from Powershell, sequentially.
PSConfig.exe -cmd upgrade -inplace b2b -wait -cmd applicationcontent -install -cmd installfeatures -cmd secureresources -cmd services -install
One word of advice, I gleaned from reading posts by Stefan Gobner, if using the command line, err powershell, err psconfig.exe not psconfiggui.exe, make sure you use the above, as just running Psconfig.exe -cmd upgrade -inplace b2b -wait -force will not update the files in the _app_bin directory. Something to keep in mind. So, if you use the gui, then you don’t have to worry about those files getting updated because it triggers the Install-SPApplicationContent cmdlet. Hope that helps.