Upgrade SharePoint 2013 after installing Patches or CU
I wrote this script to provide several options that have helped me successfully run PSConfig upgrades.
This script will do the following:
This script will do the following:
- Start IIS in case it is stopped (could be stopped while installing patches)
- Run any pending admin service jobs
- Clear the local configuration cache
- Provide a menu of 3 options for upgrade:
- Simple
- Advanced
- Stuck at 10% progress during a previous run
- Initialize Resource Security
Here is the PowerShell script:
#region INFO
########################
#### INFORMATION ###
########################
<#
.SYNOPSIS
This script will attempt to run good actions to ensure the successful upgrade of SharePoint.
.DESCRIPTION
Uses the PSConfig.exe application
.EXAMPLE
.\Upgrade_PSConfig_PatchLevel.ps1
.LINK
Open this link for any issues observed during the upgrade as reported in the logs:
https://technet.microsoft.com/en-us/library/cc262967(v=office.15)
.NOTES
File Name :
Author : Eric Jochens
Tags : sharepoint, upgrade
#>
#endregion
#region FUNCTIONS
#######################
#### FUNCTIONS ####
#######################
function ChoiceMenu-Upgrade
<#
.SYNOPSIS
This will implement a popup menu for choices you give the operator.
.EXAMPLE
ChoiceMenu-Upgrade
#>
{
Begin
{
#Title bar of popup:
$title = "Upgrade SharePoint"
#Question displayed above choices:
$message = "What type of upgrade process do you want to run?"
}
Process
{
#Choices:
$simple = New-Object System.Management.Automation.Host.ChoiceDescription "&Simple", "PSConfig.exe -cmd upgrade -inplace b2b -force"
$advanced = New-Object System.Management.Automation.Host.ChoiceDescription "&Advanced", "PSConfig.exe -cmd upgrade -inplace b2b -force -cmd applicationcontent -install -cmd installfeatures"
$10Percent = New-Object System.Management.Automation.Host.ChoiceDescription "&10Percent", "Run if the process got stuck at 10% before."
$cancel = New-Object System.Management.Automation.Host.ChoiceDescription "&Cancel", "This will cancel the prompt and not run any actions."
#Settings:
$options = [System.Management.Automation.Host.ChoiceDescription[]]($simple,$advanced,$10Percent)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)
}
End
{
Return $result
}
}
function ChoiceMenu-Upgrade2013Workflow
<#
.SYNOPSIS
This will implement a popup menu for choices you give the operator.
.EXAMPLE
ChoiceMenu-Upgrade2013Workflow
#>
{
Begin
{
#Title bar of popup:
$title = "Workflow 2013 Upgrade"
#Question displayed above choices:
$message = "Is the 2013 Workflow system installed on this farm?"
}
Process
{
#Choices:
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Upgrade the 2013 workflow activities"
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Ignore 2013 workflow as it is not installed"
#Settings:
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)
}
End
{
Switch ($result)
{
0
{
Write-Host "Initiating the 2013 Workflow upgrade procedure." -f Cyan
#(To copy workflow activities installed on the SharePoint host to an instance of the Workflow Service)
#get the Workflow Service Address:
$wfProxy = Get-SPWorkflowServiceApplicationProxy
$wfURL = $wfProxy.GetWorkflowServiceAddress((Get-SPSite -Limit 1 -WarningAction SilentlyContinue))
#Copy the activities:
$cred = [System.Net.CredentialCache]::DefaultNetworkCredentials
Copy-SPActivitiesToWorkflowService -WorkflowServiceAddress $wfURL -Credential $cred -Force $true
}
1
{
Write-Host "Skipping the 2013 Workflow upgrade procedure." -f Cyan
}
}
}
}
Function Clear-SharePoint-ConfigurationCache-LocalServer
<#
.SYNOPSIS
This function will clear the configuration cache on the current SharePoint server.
.DESCRIPTION
This will:
(1) Stop the timer service
(2) Delete all the xml files in the configuration cache folder
(3) Change the count in the cache.ini file to 1
(4) Start the SharePoint Timer Service
(5) Report that the xml files have been rebuilt
.EXAMPLE
Clear-SharePoint-ConfigurationCache-LocalServer
#>
{
Begin
{
$StartTime = Get-Date
Write-Host "Start Time:" $StartTime
$DateStr = $StartTime.ToString("yyyy-MM-dd_HHmm")
Write-Host "Clear the SharePoint Configuration Cache on this server" -f Cyan
Write-Host "Stopping the SharePoint Timer Service" -f Cyan
$timerV4 = Get-Service -Name SPTimerV4
If($timerV4.Status -ne "Stopped")
{
Stop-Service $timerV4
}
Start-Sleep -Seconds 2
If($timerV4.Status -eq "Stopped")
{
Write-Host "SharePoint Timer Service is stopped" -f Green
}
}
Process
{
$configDB = Get-SPDatabase | ?{$_.Type -eq "Configuration Database"}
[String]$confidDbId = $configDB.Id.Guid
$cacheDirectory = Get-ChildItem -Path "c:\ProgramData\Microsoft\SharePoint\Config" -Filter $confidDbId
$cacheIni = Get-ChildItem -Path $cacheDirectory.FullName -Recurse -Include "cache.ini"
[Int]$cacheIniCountStart = Get-Content -Path $cacheIni.FullName
Write-Host "cache.ini integer content in Configuration Cache folder is:" $cacheIniCountStart
[Array]$xmlFiles = @()
[Array]$xmlFiles = Get-ChildItem -Path $cacheDirectory.FullName -Recurse -Include "*.xml"
[Int]$xmlActualFileCountStart = $xmlFiles.Count
Write-Host "xml file count in Configuration Cache folder is:" $xmlActualFileCountStart
[Array]$xmlFiles = @()
[Array]$xmlFiles = Get-ChildItem -Path $cacheDirectory.FullName -Recurse -Include "*.xml"
While($xmlFiles.Count -ne 0)
{
Write-Host "Deleting" $xmlFiles.Count "xml files..." -f Cyan
ForEach($xmlFile in $xmlFiles)
{
Remove-Item -Path $xmlFile.FullName -Force
}
[Array]$xmlFiles = @()
[Array]$xmlFiles = Get-ChildItem -Path $cacheDirectory.FullName -Recurse -Include "*.xml"
}
Clear-Content -Path $cacheIni.FullName
While((Get-Content -Path $cacheIni.FullName) -ne 1)
{
Write-Host "Setting cache.ini contents to 1" -f Cyan
Set-Content -Path $cacheIni.FullName -Value "1"
}
}
End
{
Write-Host "Starting the SharePoint Timer Service" -f Cyan
$timerV4 = Get-Service -Name SPTimerV4
If($timerV4.Status -ne "Running")
{
Start-Service $timerV4
}
While($timerV4.Status -ne "Running")
{
Write-Host "Timer Service is:" (Get-Service -Name SPTimerV4).Status
Start-Sleep -Seconds 3
}
If((Get-Service -Name SPTimerV4).Status -eq "Running")
{
Write-Host "SharePoint Timer Service is running" -f Green
}
#Wait for the XML file count to be correct
[Int]$timeElapsed = 0
Write-Host "Waiting for the xml file count to reach the right count..."
While((Get-ChildItem -Path $cacheDirectory.FullName -Recurse -Include "*.xml").Count -ne $xmlActualFileCountStart)
{
Write-Host "Time-Elapsed:" $timeElapsed "seconds"
Start-Sleep -Seconds 5
$timeElapsed = $timeElapsed + 5
}
Start-Sleep -Seconds 3
#test to see that xml file count and the contents of cache.ini are what we started with:
[Int]$cacheIniCountEnd = Get-Content -Path $cacheIni.FullName
[Array]$xmlFiles = @()
[Array]$xmlFiles = Get-ChildItem -Path $cacheDirectory.FullName -Recurse -Include "*.xml"
[Int]$xmlActualFileCountEnd = $xmlFiles.Count
If($cacheIniCountEnd -eq $cacheIniCountStart)
{
Write-Host "cache.ini has the same number!" -f Green
}
Else
{
Write-Host "cache.ini has changed!" -f White -b Red
Write-Host "cache.ini start :" $cacheIniCountStart
Write-Host "cache.ini end :" $cacheIniCountEnd
}
If($xmlActualFileCountEnd -eq $xmlActualFileCountStart)
{
Write-Host "XML files are the right count!" -f Green
}
Else
{
Write-Host "XML file count has a different count!" -f Red
Write-Host "XML file count start:" $xmlActualFileCountStart
Write-Host "XML file count end :" $xmlActualFileCountEnd
}
$EndTime = Get-Date
$TimeToComplete = $EndTime - $StartTime
Write-Host ("Script Complete")
Write-Host ("End Time : " + $EndTime)
Write-Host ("Total Elapsed : " + $TimeToComplete.Minutes + " min " + $TimeToComplete.Seconds + " sec")
[System.GC]::Collect()
}#end
}#function
#endregion
#region SCRIPT
####################
##### Script #####
####################
#System Variables
$StartTime = Get-Date
Set-Location -Path "C:\"
Clear-Host
Write-Host "Start Time: " $StartTime
$DateStr = $StartTime.ToString("yyyy-MM-dd_HHmm")
Add-PSSnapin Microsoft.SharePoint.PowerShell -EA 0
Get-SPProduct | Format-Table -Autosize
$wwwService = Get-Service "W3SVC"
If($wwwService.Status -ne "Running")
{
$wwwService.start()
}
Else
{
Write-Host "The IIS service is running" -f Green
}
Write-Host "This next section can fail and that is okay, it will try to run any stalled admin jobs" -f Green
net stop SPTimerV4
Start-SPAdminJob -Verbose
net start SPTimerV4
#Clear and rebuild the local configuration cache as this can cause issues with upgrades
Clear-SharePoint-ConfigurationCache-LocalServer
#initiate the function to open a menu and choose the upgrade script to run:
$choiceUpgrade = ChoiceMenu-Upgrade
Switch ($choiceUpgrade)
{
0
{
Write-Host $title ": Running the Simple upgrade process." -f Cyan
PSConfig.exe -cmd upgrade -inplace b2b -force
ChoiceMenu-Upgrade2013Workflow
}
1
{
Write-Host $title ": Running the Advanced upgrade process." -f Cyan
PSConfig.exe -cmd upgrade -inplace b2b -force -cmd applicationcontent -install -cmd installfeatures
ChoiceMenu-Upgrade2013Workflow
}
2
{
Write-Host $title ": Running the Stuck at 10% upgrade process." -f Cyan
PSConfig -cmd upgrade -inplace b2b -wait -cmd applicationcontent -install -cmd installfeatures -cmd secureresources
# -WAIT = No timer job so the upgrade happens in real time in the psconfig process.
# -FORCE = Removes all existing upgrade jobs incase a timer job is stuck.
ChoiceMenu-Upgrade2013Workflow
}
3
{
Write-Host $title ": Canceled." -f DarkYellow
}
}#switch
#this was added for a farm to fix an issue where the Managed Metadata service was no longer connected to the site collection.
Initialize-SPResourceSecurity
$EndTime = Get-Date
$TimeToComplete = $EndTime - $StartTime
Write-Host -Message ("Script Complete.")
Write-Host -Message ("End Time : " + $EndTime)
Write-Host -Message ("Total Elapsed: " + $TimeToComplete.Minutes + " min " + $TimeToComplete.Seconds + " sec")
#endregion
Comments
Post a Comment