Tag Archives: PowerShell

Automating a tedious task: Testing SharePoint page performance

Here’s a quick and dirty PowerShell script that hits a supplied SharePoint-related URL and outputs the correlation ID so you can check the ULS logs to further investigate why the page took longer than expected to load.

The script takes three parameters:

  1. SharePointUrl: The URL to test. Can be a SharePoint site collection, site, list, library, page. A resource in SharePoint.
  2. numTries: The number of times to try hitting the URL. Default is 1000
  3. unnaceptableTime – how long you deem is “too long” — milliseconds (i.e. 1000 = 1 second)

When you run the script, it will try connecting to the SharePoint site repeatedly and output attempts that take too long.

When SharePoint receives requests from users, it times how long it takes to process the request and returns this time in the SPRequestDuration HTTP header (in milliseconds). This script compares the returned SPRequestDuration to the unacceptableTime parameter and if the request took longer, it will output the SPRequestGUID which you can then use with Merge-SPLogFile to pull the ULS logs for the request.

param (
	
	$SharePointUrl = "https://yoursharepoint.example.com/demo/TypicalSharePointSite/SitePages/SomePageToTest.aspx",
	
	# Number of times to try hitting the page
	$numTries = 1000,
	
	# Number of milliseconds we'll say is too long for the page to return
	$unacceptableTime = 8000	
)

$timesTooLong = 0

# Repeat the number of times specified by $numTries
for ($i = 0; $i -lt $numTries; $i++) {

	# Build our URL to query SharePoint
	# We're going to abuse the rev parameter to trick our session into not caching the results from each query
	$requestUri = $SharePointUrl + "?rev=$i"
	
	# Issue our request to the fine SharePoint Server
	$Request = Invoke-WebRequest -Uri $requestUri -UseDefaultCredentials
	
	# The request took too long so send out the details
	if ([int]$Request.Headers["SPRequestDuration"] -gt $unacceptableTime) {
	
		Write-Output "$($Request.Headers["SPRequestGuid"]) $($Request.Headers["SPRequestDuration"])ms $requestUri"
		
		$timesTooLong++
	
	}
	
	
}

Write-Output "$timesTooLong request(s) took longer than $($unacceptableTime)ms"
Share Button

Clear the Configuration Cache in a SharePoint 2010, 2013, or 2016 farm

Here is a script that will clear the SharePoint Configuration Cache on all servers in the farm. This is a more compact script than the one I previously released.

Simply copy to one of the servers and run in an elevated PowerShell window. The script will determine where the configuration cache is stored on all servers in the farm, stop the timer services, clear the cache, reset the counter, and start the timer services again.

This script is provided as-is.

<#
.SYNOPSIS
Clear the Configuration Cache in a SharePoint 2010, 2013, or 2016 farm
  
.DESCRIPTION
Clear-SPConfigCache.ps1 will:
 1. Stop the SharePoint Timer Service on all servers in the farm
 2. Delete all xml files in the configuration cache folder on all servers in the farm
 3. Copy the existing cache.ini files as a backup
 4. Clear the cache.ini files and reset them to a value of 1
 5. Start the SharePoint Timer Service on all servers in the farm

Clear-SPConfigCache.ps1 will work in either single-server and multi-server farms.

Run in an elevated SharePoint Management Shell

Author: Jason Warren

.LINK
 http://jasonwarren.ca/ClearSPConfigCache ClearSPConfigCache.ps1
 
.EXAMPLE
 .\Clear-SPConfigCache.ps1
 
.INPUTS
None. Clear-SPConfigCache.ps1 does not take any input.

.OUTPUTS
Text output that describes the current task being performed.

#>


Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction Stop
$farm = Get-SPFarm
$ConfigDB = Get-SPDatabase | where {$_.Name -eq $Farm.Name}

# Configuration Cache is stored in %PROGRAMDATA\Microsoft\SharePoint\Config\[Config ID GUID]
# %PROGRAMDATA% is C:\ProgramData by default, it is assumed it's in the same location on all servers in the farm
#	i.e. if it's X:\ProgramData on one server, it will be X:\ProgramData on the others
# We'll be connecting via UNC paths, so we'll also change the returned DRIVE: to DRIVE$
$ConfigPath = "$(($env:PROGRAMDATA).Replace(':','$'))\Microsoft\SharePoint\Config\$($ConfigDB.Id.Guid)"

# Stop the timer service on all farm servers
$TimerServiceName = "SPTimerV4"
foreach ($server in $farm.TimerService.Instances.Server) {
	Write-Output "Stopping $TimerServiceName on $($server.Address)..."
	$service = Get-Service -ComputerName $server.Address -Name $TimerServiceName
	Stop-Service -InputObject $service -Verbose
} # Foreach server


$TimeStamp = Get-Date -Format "yyyymmddhhmmssms"

# Clear and reset the cache on each server in the farm
foreach ($server in $farm.TimerService.Instances.Server) {

	Write-Output $server.Address
	
	# build the UNC path e.g. \\server\X$\ProgramData\Microsoft\SharePoint\Config\00000000-0000-0000-0000-000000000000
	$ServerConfigPath = "\\$($server.Address)\$($ConfigPath)"
	
	# Delete the XML files
	Write-Output "Remove XML files: $ServerConfigPath..."
	Remove-Item -Path "$ServerConfigPath\*.xml"
	
	# Backup the old cache.ini
	Write-Output "Backup $ServerConfigPath\cache.ini..."
	Copy-Item -Path "$ServerConfigPath\cache.ini" -Destination "$ServerConfigPath\cache.ini.$TimeStamp"
	
	# Save the value of "1" to cache.ini
	Write-Output "Set cache.ini to '1'..."
	"1" | Out-File -PSPath "$ServerConfigPath\cache.ini"

	Write-Output ""
	
} #foreach server

#Start the timer service on all farm servers
foreach ($server in $farm.TimerService.Instances.Server) {
	Write-Output "Starting $TimerServiceName on $($server.Address)..."
	$service = Get-Service -ComputerName $server.Address -Name $TimerServiceName
	Start-Service -InputObject $service -Verbose
	
}
Share Button

Get a list of SharePoint sites that allow anonymous authentication

For administrators who manage (usually) public-facing SharePoint farms, it’s good to keep tabs on the sites that allow anonymous users. Configuring anonymous access is a multi-step process — there are web application settings, site settings, and permissions. Although there is a lot of configuration, it’s easy to see which sites allow anonymous authentication using the SPWeb.AnonymousState site-level flag. Using this property we can write a short PowerShell script to list out all the sites in the farm and display whether or not they allow anonymous authentication.

SharePoint 2013 and SharePoint 2010

For SharePoint 2010, SharePoint 2013, and presumably future versions of SharePoint, getting this list is simple using the Get-SPSite cmdlet which can be used to list every site collection in the farm:

$sites = Get-SPSite -Limit All
foreach ($site in $sites) {
	$site.AllWebs | Select Url, AnonymousState
}

The output will look like something like this:

Url                                         AnonymousState
---                                         --------------
http://example.com                                 Disabled
http://example.com/searchcenter                    Disabled
http://example.net                                      On
http://example.net/About                                On
http://example.net/Careers                              On
http://example.net/Contact                              On
http://example.net/Search                               On

SharePoint 2007

If you have PowerShell installed on a server in the farm (you really should), you can use PowerShell to build this handy report just it takes a bit more effort:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local
$websvcs = $farm.Services | where -FilterScript {$_.GetType() -eq [Microsoft.SharePoint.Administration.SPWebService]}
$webapps = @()
foreach ($websvc in $websvcs) {
	foreach ($webapp in $websvc.WebApplications) {		
		foreach ($site in $webapp.Sites) {
		
			$Site.AllWebs | Select Url, AnonymousState
		
		}
    }
}

The output will look look the same as with later versions of SharePoint:

Url                                          AnonymousState
---                                          --------------
http://example.com                                 Disabled
http://example.com/searchcenter                    Disabled
http://example.com/sites/Example                         On
http://example.com/sites/Example/Site1                   On
http://example.com/sites/Example/Site1/SubSite           On

(HT to Gary Lapointe for the code to get the web applications in a SharePoint 2007 farm using PowerShell: Getting an SPWebApplication object using PowerShell.

Share Button

New-SPEnterpriseSearchServiceApplication : Value cannot be null.

Got this exception when creating a search service application in a multi-server farm:

New-SPEnterpriseSearchServiceApplication : Value cannot be null.

Parameter name: indexLocation

Found the resolution in this TechNet forum post: SharePoint 2013 (RTM) Powershell New-SPEnterpriseSearchApplicationService error about non-existent “indexlocation” parameter ??

The solution in my case wasn’t the accepted answer, rather the answer from iftvio suggesting to start the search and query service instances. This answer was counter-intuitive to me because I was running the script from a server that wasn’t part of the search topology.

Let me explain.

New-SPEnterpriseSearchServiceApplication

In this particular farm, I had the search components dedicated to a specific server. I was running the script from another server in the farm. In my scripts I start the search and query instances on the servers specified in a configuration file. Since the server I was running the scripts from wasn’t a search server it wasn’t in the list of servers on which to start the service instances. It turns out though, that New-SPEnterpriseSearchServiceApplication expects these service instances to be running on the current server.

To start the instances, use Start-SPEnterpriseSearchServiceInstance and Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance

In the end my topology is what I expected, I just stopped the service instances once I was done configuring search.

Summary: When running New-SPEnterpriseSearchServiceApplication make sure the server is running the search and query service instances.

Share Button

Link Roundup 1

Here are some interesting links I’ve come across. Consider this a test of a future recurring feature.

A lot happened at the SharePoint Conference 2014 last week. I wasn’t there, though between Yammer and Twitter it felt like Vegas here in the -20C land that is Canada.

Looking for session slides from SharePoint Conference 2014? Check out the external Yammer’s uploaded files! Videos and demos should be realeased in about a month.

Lots of great videos from SPC14 over at channel9

Rackspace released the very addictive Fanatiblaster game based on their fantatical support. I know it’s totally based on real life because every SharePoint administrator carries a dart gun to shoot folders and SharePoint sites. One of the neat things about it is @ShareP911 will tweet out anytime someone beats the high score.

If you’re using CredSSP for PowerShell remoting, know that on Windows versions earlier than Windows Server 2012 R2 and Windows 8.1 that the server you connect to stores your username and password in plain text! Check out Accidental Sabotage: Beware of CredSSP over at PowerShell Magazine

Did you know you can now get SharePoint ULS logs from SharePoint Online using CSOM?

Creating a new Office Web Apps farm on Windows Server 2008 R2 SP1 throws an exception “New-OfficeWebAppsFarm : The operation failed. The server did not meet the following prerequisites: – Windows Update KB2592525 must be installed.” Then, when you try to install the update you get the error “This update is not applicable to your computer.” To resolve this wonderful trick to logic, check out this great post courtesy of Markus Nöbauer: Office Web Apps Server – KB2592525 Installation failed

Share Button