When working with SharePoint on-premises you may occasionally get strange issues which you can’t fix directly with just an IISReset. A lot of blogs including mine start troubleshooting with a few default steps. These steps cleans your environment and may resolve the issue without having to dig in to the ULS logs. I’ve recently seen an issue for the first time where farm solutions weren’t deploying to all SharePoint servers in the farm which prevented a successful installation of a third party program. After doing the same troubleshooting steps again manually I decided to create a script that will do all initial troubleshooting steps automatically for all servers in my SharePoint farm.

The script is built in sections so each section can be run separately or you can run the whole script to do everything (it will do a few things more than once but this is needed to be able to use individual sections). The script will do the following troubleshooting steps in order:

– Restart SharePoint Timer Service and the SharePoint Administration Service on all servers
– Verifying and starting Microsoft SharePoint Foundation Timer services on all servers
– Clear SharePoint configuration cache on all servers
– IISReset on all servers

Restart SharePoint Timer Service and the SharePoint Administration Service

The most common step is to restart these two services should there be a problem with timer jobs not running or failing. You can go to each server in your farm manually or connect to another computer using services.msc but you can also use the below section to restart these services on all servers in your farm.

Function Restart-SPServices{
    Write-Host -f gray "---------------------------------------------------"
    Write-Host -f DarkGreen "Restarting SharePoint Timer and Administration Service on all servers"
    Write-Host -f gray "---------------------------------------------------"
    Write-Host ""
    
    #Add sharepoint pssnapin
    if ( (Get-PSSnapin -Name microsoft.sharepoint.powershell -EA "SilentlyContinue") -eq $null )
    {
        Add-PsSnapin microsoft.sharepoint.powershell
    }
    
    $SPServers = get-spserver | ? { $_.Role -ne "Invalid"}
    
    foreach ($SPServer in $SPServers)
    {
        try{
            write-host -f Cyan "Stopping SharePoint timer service on $($SPServer.name)..."
            Get-Service -Name SPTimerV4 -ComputerName $SPServer.name | Stop-Service -Force
            $service = Get-Service -Name SPTimerV4 -ComputerName $SPServer.name | Set-Service -Status Stopped
            while ($service.Status -eq "Running"){
                Write-Host "Waiting for service to stop on server $($SPServer.name)..."
                $service = Get-Service -Name SPTimerV4 -ComputerName $SPServer.name
                Start-Sleep 3
            }
            write-host -f green "SharePoint timer service stopped on $($SPServer.name)..."
        }
        catch{
            write-host -f red "Error occurred stopping SharePoint timer service on $($SPServer.name);$($_.Exception.Message)"
        }

        try{
            write-host -f Cyan "Stopping SharePoint Administration service on $($SPServer.name)..."
            Get-Service -Name SPAdminV4 -ComputerName $SPServer.name | Stop-Service -Force
            $service = Get-Service -Name SPAdminV4 -ComputerName $SPServer.name | Set-Service -Status Stopped
            while ($service.Status -eq "Running"){
                Write-Host "Waiting for service to stop on server $($SPServer.name)..."
                $service = Get-Service -Name SPAdminV4 -ComputerName $SPServer.name
                Start-Sleep 3
            }
            write-host -f green "SharePoint Administration service stopped on $($SPServer.name)..."
        }
        catch{
            write-host -f red "Error occurred stopping SharePoint Administration service on $($SPServer.name);$($_.Exception.Message)"
        }
    }

    foreach ($SPServer in $SPServers)
    {
        try{
            write-host -f Cyan "Starting SharePoint timer service on $($SPServer.name)..."
            Get-Service -Name SPTimerV4 -ComputerName $SPServer.name | Stop-Service -Force
            $service = Get-Service -Name SPTimerV4 -ComputerName $SPServer.name | Set-Service -Status Running
            while ($service.Status -eq "Stopped" -or $service.Status -eq "starting"){
                Write-Host "Waiting for service to start on server $($SPServer.name)..."
                $service = Get-Service -Name SPTimerV4 -ComputerName $SPServer.name
                Start-Sleep 3
            }
            write-host -f green "SharePoint timer service started on $($SPServer.name)..."
        }
        catch{
            write-host -f red "Error occurred starting SharePoint timer service on $($SPServer.name);$($_.Exception.Message)"
        }

        try{
            write-host -f Cyan "starting SharePoint administration service on $($SPServer.name)..."
            Get-Service -Name SPAdminV4 -ComputerName $SPServer.name | Stop-Service -Force
            $service = Get-Service -Name SPAdminV4 -ComputerName $SPServer.name | Set-Service -Status Running
            while ($service.Status -eq "Stopped" -or $service.Status -eq "starting"){
                Write-Host "Waiting for service to start on server $($SPServer.name)..."
                $service = Get-Service -Name SPAdminV4 -ComputerName $SPServer.name
                Start-Sleep 3
            }
            write-host -f green "SharePoint administration service started on $($SPServer.name)..."
        }
        catch{
            write-host -f red "Error occurred starting SharePoint administration service on $($SPServer.name);$($_.Exception.Message)..."
        }
    }
}
Restart-SPServices

Just start Windows PowerShell as administrator on a server in the SharePoint farm.

Copy and paste the above script to PowerShell

The SharePoint timer and administration service have been restarted on all servers in the farm.

Verifying and starting Microsoft SharePoint Foundation Timer services

The Microsoft SharePoint Foundation Timer service should be enabled on each SharePoint server in the farm. This service is not the same as the windows service and it is only retrievable using PowerShell. Disabled services could result in solutions not being deployed to all servers or errors installing third party software.

Function Start-SPFoundationServices{
    Write-Host -f gray "---------------------------------------------------"
    Write-Host -f DarkGreen "Verifying and starting Microsoft SharePoint Foundation Timer service on all servers"
    Write-Host -f gray "---------------------------------------------------"
    Write-Host ""
    
    if ( (Get-PSSnapin -Name microsoft.sharepoint.powershell -EA "SilentlyContinue") -eq $null )
    {
        Add-PsSnapin microsoft.sharepoint.powershell
    }
    
    $SPServers = get-spserver | ? { $_.Role -ne "Invalid"}
    
    foreach ($SPServer in $SPServers)
    {
        $serviceInstances = $SPServer.ServiceInstances    
        foreach($serviceInstance in $serviceInstances){
            if ($serviceInstance.TypeName -eq "Microsoft SharePoint Foundation Timer")
            {
                try{
                    write-host -f Cyan "Verifying Microsoft SharePoint Foundation Timer service on $($SPServer.name)..."
                    if($serviceInstance.status -eq "Disabled")
                    {
                        write-host -f cyan "Microsoft SharePoint Foundation Timer service is $($serviceInstance.status) on $($SPServer.name)..."
                        write-host -f cyan "Starting all disabled timer service instances in the farm..."
                        $farm  = Get-SPFarm
                        $disabledTimers = $farm.TimerService.Instances | Where-Object {$_.Status -ne "Online"}
                        if (!$disabledTimers)
                        {
                            foreach ($timer in $disabledTimers)
                            {
                                $timer.Status = [Microsoft.SharePoint.Administration.SPObjectStatus]::Online
                                $timer.Update()
                                write-host -f green "Started $($timer.Server.Name) successfully"
                            }
                        }
                    }
                    else{
                        write-host -f green "Microsoft SharePoint Foundation Timer service is $($serviceInstance.status) on $($SPServer.name)..."
                    }
                }
                catch{
                    write-host -f red "Error occurred verifying or starting the Microsoft SharePoint Foundation Timer service on $($SPServer.name);$($_.Exception.Message)..."
                }
            }
        }
    }
}
Start-SPFoundationServices

Just start Windows PowerShell as administrator on a server in the SharePoint farm.

Copy and paste the above script to PowerShell

The Microsoft SharePoint Foundation Timer Service will be started should it be disabled.

Clear SharePoint configuration cache on all servers

The SharePoint configuration cache is in the application data folder on all SharePoint servers in the farm. Normally it should be C:\Documents and Settings\All Users\Application Data\Microsoft\SharePoint\Config\{GUID} where GUID is the id of the SharePoint configuration database. You will most likely need to run this step when you receive issuers like “An update conflict has occurred, and you must re-try this action” during solution deployment or running the SharePoint Configuration Wizard. This folder consists of many .XML files and only 1 .ini file which should be the same across all SharePoint servers in the same farm. The script will first stop all SharePoint timer services, then delete the .XML files, afterwards reset the cache.ini to 1 and lastly start the SharePoint timer services again.

Function Clear-SPConfigurationCache{
    Write-Host -f gray "---------------------------------------------------"
    Write-Host -f DarkGreen "Clearing SharePoint configuration cache on all servers"
    Write-Host -f gray "---------------------------------------------------"
    Write-Host ""
    
    if ( (Get-PSSnapin -Name microsoft.sharepoint.powershell -EA "SilentlyContinue") -eq $null )
    {
        Add-PsSnapin microsoft.sharepoint.powershell
    }

    #Retrieving database GUID and build the path
    $farm = Get-SPFarm
    $ConfigDB = Get-SPDatabase | where {$_.Name -eq $Farm.Name}
    $ConfigPath = "$(($env:PROGRAMDATA).Replace(':','$'))\Microsoft\SharePoint\Config\$($ConfigDB.Id.Guid)"

    #Stop all SharePoint timer services
    $SPServers = get-spserver | ? { $_.Role -ne "Invalid"}

    foreach ($SPServer in $SPServers)
    {
        try{
            write-host -f Cyan "Stopping SharePoint timer service on $($SPServer.name)..."
            Get-Service -Name SPTimerV4 -ComputerName $SPServer.name | Stop-Service -Force
            $service = Get-Service -Name SPTimerV4 -ComputerName $SPServer.name | Set-Service -Status Stopped
            while ($service.Status -eq "Running"){
                Write-Host "Waiting for service to stop on server $($SPServer.name)..."
                $service = Get-Service -Name SPTimerV4 -ComputerName $SPServer.name
                Start-Sleep 3
            }
            write-host -f green "SharePoint timer service stopped on $($SPServer.name)..."
        }
        catch{
            write-host -f red "Error occurred stopping SharePoint timer service on $($SPServer.name);$($_.Exception.Message)..."
        }
    }

    #Clear cache on all servers
    foreach ($SPServer in $SPServers)
    {
        try{
            write-host -f Cyan "Starting to clear the configuration cache on $($SPServer.name)..."
            $ServerConfigPath = "\\$($SPServer.name)\$($ConfigPath)"

            write-host -f cyan "Count current number of .xml files..."
            $OldXMLnumber = (Get-ChildItem $ServerConfigPath | Where-Object{$_.name -like "*xml*"}).count

            write-host -f Cyan "Deleting all .XML files on $($ServerConfigPath)..."
            Remove-Item -Path "$ServerConfigPath\*.xml"

            write-host -f Cyan "Updating cache.ini file on $($ServerConfigPath)..."
            "1" | Out-File -PSPath "$ServerConfigPath\cache.ini"

            write-host -f green "Cleared configuration cache successfully on $($SPServer.name)..."
        }
        catch{
            write-host -f red "Error occurred clearing the configuration cache on $($SPServer.name);$($_.Exception.Message)..."
        }
    }

    #Start all SharePoint timer services
    $SPServers = get-spserver | ? { $_.Role -ne "Invalid"}

    foreach ($SPServer in $SPServers)
    {
        try{
            write-host -f Cyan "Starting SharePoint timer service on $($SPServer.name)..."
            Get-Service -Name SPTimerV4 -ComputerName $SPServer.name | Stop-Service -Force
            $service = Get-Service -Name SPTimerV4 -ComputerName $SPServer.name | Set-Service -Status Running
            while ($service.Status -eq "Stopped" -or $service.Status -eq "starting"){
                Write-Host "Waiting for service to start on server $($SPServer.name)..."
                $service = Get-Service -Name SPTimerV4 -ComputerName $SPServer.name
                Start-Sleep 3
            }
            write-host -f green "SharePoint timer service started on $($SPServer.name)..."
        }
        catch{
            write-host -f red "Error occurred Starting SharePoint timer service on $($SPServer.name);$($_.Exception.Message)..."
        }
    }

    #Waiting for cache to be rebuild
    foreach ($SPServer in $SPServers)
    {
        try{
            write-host -f Cyan "Waiting for cache to be rebuild on $($SPServer.name)..."
            $ServerConfigPath = "\\$($SPServer.name)\$($ConfigPath)"

            write-host -f cyan "Count current number of .xml files..."
            $NewXMLnumber = (Get-ChildItem $ServerConfigPath | ?{$_.name -like "*xml*"}).count

            while($NewXMLnumber -lt $OldXMLnumber)
            {
                Write-Host -f gray "Recreating XML files on $($SPServer.name): $NewXMLnumber of $OldXMLnumber completed..."
                Start-Sleep 5
                $NewXMLnumber = (Get-ChildItem $ServerConfigPath | ?{$_.name -like "*xml*"}).count
            }

            if($NewXMLnumber -eq $OldXMLnumber) {Write-Host -f green "Cache has been successfully rebuild on $($SPServer.name)..."}
        }
        catch{
            write-host -f red "Error occurred waiting for rebuilding the configuration cache on $($SPServer.name);$($_.Exception.Message)..."
        }
    }
}
Clear-SPConfigurationCache

Just start Windows PowerShell as administrator on a server in the SharePoint farm.

Copy and paste the above script to PowerShell

IISReset on all servers

The one that most likely resolve your issues will be the IISReset which will clear the cache of all application pools. The below section will reset it on all servers in the SharePoint farm.

Function Start-IISReset{
    Write-Host -f gray "---------------------------------------------------"
    Write-Host -f DarkGreen "Running IISReset on all servers in the SharePoint farm"
    Write-Host -f gray "---------------------------------------------------"
    Write-Host ""
    
    if ( (Get-PSSnapin -Name microsoft.sharepoint.powershell -EA "SilentlyContinue") -eq $null )
    {
        Add-PsSnapin microsoft.sharepoint.powershell
    }
    
    $SPServers = get-spserver | ? { $_.Role -ne "Invalid"}
    
    foreach ($SPServer in $SPServers)
    {
        try{
            write-host -f Cyan "Resetting IIS on $($SPServer.name)..."
            invoke-command -computername $SPServer.name -scriptblock {cd C:\Windows\System32\; ./cmd.exe /c "iisreset"}
            write-host -f Green "Resetted IIS successfully on $($SPServer.name)..."
        }
        catch{
            write-host -f red "Error occurred verifying or starting the Microsoft SharePoint Foundation Timer service on $($SPServer.name);$($_.Exception.Message)..."
        }
    }
}
Start-IISReset

Just start Windows PowerShell as administrator on a server in the SharePoint farm.

Copy and paste the above script to PowerShell

Putting them together

We have four functions now which I’ve saved to a .ps1 file which can be downloaded below or copy/paste the above sections. Just remove or use the 4 lines of code to start each function you want:

Restart-SPServices
Start-SPFoundationServices
Clear-SPConfigurationCache
Start-IISReset

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.