List All SharePoint Site Request Access Emails In A Web Application

When a SharePoint site is created, by default the creator’s email address is automatically populated into the “Manage Access Requests”. However, sometimes the creator isn’t the site owner, and doesn’t handle the day-to-day access requests for the site.

The script below will go through all sites and site collections within a designated web application and list the site title, url, and Access Request email.

If you’d like to spit out an inventory CSV file with the URL and number of characters, just use the Out-File Cmdlet:

FindAccessEmail | Out-File -filepath C:\wherever\AccessRequestEmails.csv
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
 
#Starting web app
$site = "http://sharepoint.company.com"
 
# Function: FindAccessEmail
# Description: Go through a target web application and list the title, url and access request email.
function FindAccessEmail
{
	$WebApps = Get-SPWebApplication($site)
	foreach($WebApplication in $WebApps)
	{
	    foreach ($Collection in $WebApplication.Sites)
	    {
	       foreach($Web in $Collection.AllWebs)
	        {
				$siteDetails = $Web.title+'#'+$Web.url+'#'+$Web.RequestAccessEmail 
	            write-host $siteDetails
				Write-Output $siteDetails
	        }
	    }
	  }
}
#Run Script!
FindAccessEmail

PowerShell Script To Find and Extract Files From SharePoint That Have A URL Longer Than 260 Characters

If you’re here, it can only mean one thing: Your users have created a folder and filename path in SharePoint that is so long that they’re now getting errors, and they can’t edit the document in Office applications. Like a burrowing parasite, the office document document has gone deeper and deeper into a convoluted folder structure until the URL exceeds the SharePoint limit of 260 characters.

It’s called Longurlitis, and while painful, it is curable.

Take this (not a real world) example:

http://sharepoint.company.com/Documents/Dave%20Documents/My%20Administrator%20Told%20Me%20To%20Use/
Metadata%20but%20what%20does%20he%20know/I’ll%20show%20him/
You’ll%20take%20these%20folders%20away%20from%20my%20cold%20dead%20hands/
Mwahahahahahahahahahahahahahahahahahaha/
Dave’s%20Word%20Document%20With%20Meeting%20Minutes%20From%201992%20
About%20That%20Upcoming%20Millenium%20Bug%20No%20I%20Can’t%20Get%20Rid%20Of%20These/
Meeting%20Minutes%20June%20Fourteenth%201992%20FINAL%20VERSION%20DRAFT%20v482.doc

Ouch, that hurt my everything.

Now when the user tries to do anything with this file, you get this:

The URL for this file is too long for the application. A temporary copy of this file will be opened on your computer. You must save this copy as a new file.
Every time this error appears, a SharePoint administrator sheds a tear.

This issue has been discussed at fairly great length a number of places, and by SharePoint heavyweights like Joel Oleson.

The problem is fairly straightforward when it’s only one or two files, but what do you do when this isn’t a one-off, but a full-on infestation of Longurlitis? I recently came across over 700 files with Longurlitis in an old site that’s being decommissioned. After running the SharePoint Site Extraction script, I found a number of files missing. The reason being is that the script’s BinaryWriter chokes on the insane URL length.

To that end I’ve created the script below that finds all files in a given site that with a URL that exceeds 260 characters. You can also download all of the files by un-commenting the designated line. Also if you’d like to spit out an inventory CSV file with the URL and number of characters, just use the Out-File Cmdlet like so:

FindLongPaths.ps1 | Out-File -filepath C:\wherever\LongFiles.csv

Note: I had to use a character other than a comma for the CSV output, because it’s possible and likely that the same users who are creating these files are also putting commas in the filename. Because the hash character (#) is forbidden in SharePoint URLs, it works well for delimiting the output.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
 
#Where to Download the files to. 
$destination = "C:\Wherever"
 
#The site to extract from. Make sure there is no trailing slash.
$site = "http://sharepoint.company.com/site"
 
# Function: DownloadLongFiles
# Description: Downloads all documents with a URL > 260 characters
# Variables
# $folderUrl: The Document Library to Download
function DownloadLongFiles($folderUrl)
{
    $folder = $web.GetFolder($folderUrl)
 
    foreach ($file in $folder.Files) 
	{
		$encodedURL = $file.url -replace " ", "%20"
		$FullURL = $site+'/'+$encodedURL
	    $URLWithLength = $FullURL+'#'+$FullURL.length
		$Filename = $file.Name
		$Downloadpath = $destination+'\'+$Filename
		if ($FullURL.length -ge 260)
		{
			#Uncomment the line below to download the files.
			#HTTPDownloadFile "$FullURL" "$Downloadpath"
			Write-Host $FullURL
			Write-Host $destination
 
			Write-Host $URLWithLength
			Write-Output $URLWithLength
		}
 
	}
}
 
# Function: DownloadSite
# Description: Calls DownloadLongFiles recursiveley to download all documents with long file names in a site.
# Variables
# $webUrl: The URL of the site to download all document libraries
function DownloadSite($webUrl)
{
	$web = Get-SPWeb -Identity $webUrl
 
	foreach($list in $web.Lists)
	{
		if($list.BaseType -eq "DocumentLibrary")
		{
			DownloadLongFiles $list.RootFolder.Url
			#Download files in folders
			foreach ($folder in $list.Folders) 
			{
    			DownloadLongFiles $folder.Url
			}
		}
	}
}
 
# Function: HTTPDownloadFile
# Description: Downloads a file using webclient
# Variables
# $ServerFileLocation: Where the source file is located on the web
# $DownloadPath: The destination to download to
 
function HTTPDownloadFile($ServerFileLocation, $DownloadPath)
{
	$webclient = New-Object System.Net.WebClient
	$webClient.UseDefaultCredentials = $true
	$webclient.DownloadFile($ServerFileLocation,$DownloadPath)
}
 
#Download Site Documents + Versions
DownloadSite "$site"

SharePoint PowerShell Script to Monitor SharePoint Availability

A little while ago on Reddit I read a post on the SharePoint Subreddit about monitoring a SharePoint 2010 environment. The #1 comment was from a user mentioning that since his fellow administrators hadn’t set up System Center Operations, he’d created a bunch of PowerShell scripts to monitor various aspects of SharePoint.

Since we also don’t use SCOM, I decided I’d write my own small script to monitor SharePoint to make sure it’s available from a basic level: just by checking to see if it’s possible to download the various site collection’s home page via HTTP, or if there are text that result from typical errors (“Troubleshoot issues with Microsoft SharePoint Foundation” for example). If the HTTP download fails, or common error text is found, shoot off an email to the admin(s). I’ve configured this script to run every 10 minutes on our farm; you may want to adjust this based off your SLA’s, governance, and experience.

Now, keep in mind that this is no-frills monitoring, canary in the coal mine type stuff. It’s not going to tell you what is wrong, but it will tell you that your clients are most probably having connection issues with SharePoint, and that aghem, you may want to look into that before the inevitable flood of “hey is SP down?” tickets and emails come your way.

#*=============================================
#* Script Name: Check SharePoint Status
#* Author: Nik Craik
#*=============================================
#* Purpose: Monitor SharePoint 2010 for errors
# and availability. If an error or problem
# is detected on a site, send an email to
# administrators.
#*=============================================
 
#Send an Email if an Error is encountered
function sendMail($site){
#SMTP server name
$smtpServer = "mail.yourserver.com"
 
#Creating a Mail object
$msg = new-object Net.Mail.MailMessage
 
#Creating SMTP server object
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
 
#Email structure
$msg.From = "sharepoint@yourserver.com"
$msg.ReplyTo = "sharepoint@yourserver.com"
$msg.To.Add("sharepointadmin@yourserver.com")
$msg.To.Add("sharepointadmin2@yourserver.com")
$msg.Priority = [System.Net.Mail.MailPriority]::High
$msg.subject = "ALERT: "+$site+" IS UNAVAILABLE"
$msg.body = "The SharePoint site collection $site is unavailable. Please have an administrator review the problem."
 
#Sending email
$smtp.Send($msg)
}
 
#Try to download the home page of a given site collection, if fails, send email
function checkIfSiteUp($url){
#Create a new web client object with the current credentials
$webclient = new-object System.Net.WebClient
$webClient.UseDefaultCredentials = $true
 
#Attempt to download site's home page, if fails, send email
try {
$page = $webclient.DownloadString($url)
$errorPage = $page.Contains("Troubleshoot issues with Microsoft SharePoint Foundation.")
$serverError = $page.Contains("Server Error")
$configDBOffline = $page.Contains("Cannot connect to the configuration database.")
if ($errorPage -or $serverError -or $configDBOffline) {
sendMail($url)
}
}
catch {
sendMail($url)
}
}
 
#Array of SharePoint Sites
$shptWebs = @("http://intranet",
"http://othersite",
"http://onemoresite")
 
#Execute for all SharePoint Sites
foreach ($web in $shptWebs)
{
checkIfSiteUp($web)
}