Looping through SPList items


Now this is something I’m guilty of time and time again. Within my PowerShell scripts I quite often query SharePoint lists and loop through them in the following way…

$site = New-Object Microsoft.SharePoint.SPSite( $url )
$web = $site.OpenWeb()
$list = $web.List

for ( $i = 0; $i < $list.Items.Count; $i++) {
   SPListItem listItem = activeList.Items[i];

What I should be doing is this…

SPListItemCollection items = SPContext.Current.List.Items;

for(int i=0;i<100 && i<items.Count;i++) {
  SPListItem listItem = items[i];



For whatever reason, sometimes you just can’t upgrade the installed version of PowerShell on a server. In this case, I wanted to make use of the Invoke-SqlCommand command.

The most simple way around this limitation is to add a module to the server that includes a command that performs the same function.

See this post for a command that can be cut and pasted into a new PowerShell module file and easily accessed from your own scripts.


XSL and dumping XML


When you’re attempting to construct an XSL template its always helpful to know the structure of the XML you’re transforming. When working with lists in SharePoint, this isn’t always obvious.

One quick solution is simply to dump the XML to the page so you can review it.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<xsl:copy-of select="*"/>


Bulks inserts and SSIS


SQL Server Integration Services (SSIS) really isn’t my thing. I like to get my hands dirty with code. But every now and then (not often enough for me to remember anything of what I’ve previously done) I have to bite the bullet and open an SSIS package in Visual Studio.

Today has been one of those days.

The goal of the package was simple: to import the contents of two CSV files from a network share into two database tables on a SQL Server. After a day of struggling to reason why I was getting various “Access is denied” and “The file … does not exist” error messages, I finally discovered this blog post that helped to clear the mist.

Bingo! I now have a package with two Sequence Containers with green execution results.

The final SSIS package

Creating SharePoint alerts via CSOM

Development, Server Administration

I’m posting this as a useful reminder. It outlines how alerts can now be created via CSOM.

New SharePoint CSOM version released for SharePoint Online – February 2017

The included code sample is in C#, but I’ve translated it to PowerShell – which suits my administrative needs better.

[System.Reflection.Assembly]::LoadWithPartialName( "Microsoft.SharePoint.Client" ) | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName( "Microsoft.SharePoint.Client.Runtime" ) | Out-Null

# Set variables
$path = "C:\Temp\Usernames.txt"

$url = "https://xxxxxx.sharepoint.com/sites/help"

$list = "My List"

$title = "$list (Auto-subscribed)"

# Prompt the administrator to log in
$credential = Get-Credential -Credential $null

# Create a connection to SharePoint Online
$context = New-Object Microsoft.SharePoint.Client.ClientContext( $url )
$context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials( $credential.UserName, $credential.Password )

# Retrieve the targeted web
$web = $context.Web

$context.Load( $web )

# Loop through the provided usernames and create a new alert for each one
$usernames = Get-Content -Path $path

foreach ( $username in $usernames )
    $user = $context.Web.EnsureUser( $username )

    $alert = New-Object Microsoft.SharePoint.Client.AlertCreationInformation
    $alert.List = $context.Web.Lists.GetByTitle( $list )
    $alert.AlertFrequency = [Microsoft.SharePoint.Client.AlertFrequency]::Daily
    $alert.AlertTime = ( Get-Date ).AddDays( 1 )
    $alert.AlertType = [Microsoft.SharePoint.Client.AlertType]::List
    $alert.AlwaysNotify = $false
    $alert.DeliveryChannels = [Microsoft.SharePoint.Client.AlertDeliveryChannel]::Email
    $alert.Status = [Microsoft.SharePoint.Client.AlertStatus]::On
    $alert.Title = $title
    $alert.User = $user
    $alert.EventType = [Microsoft.SharePoint.Client.AlertEventType]::All
    $alert.Filter = "1"

    $guid = $user.Alerts.Add( $alert )



SharePoint’s People Picker Error

Development, Server Administration

Since the roll out of Internet Explorer 10, our users were having trouble whenever they attempted to give someone access to their SharePoint 2010 area via the Grant Permissions dialog. Whenever they clicked the Browse icon, they’d receive a “An unexpected error has occurred” message.

One solution that seemed to solve this issue was to add the domain of the SharePoint site into the browser’s Compatibility View Settings – but that would effect all sites using the domain (including non-SharePoint sites).

While researching the issue I found a suggestion that it could be corrected by appending a META tag to one of the MasterPages.

Normally I wouldn’t dare edit one of the SharePoint core files, but as this was effecting so many users and we’ll be migrating to SharePoint 2013 in the near future, the benefits outweighed the risks.

  1. Browse to C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS and locate the pickerdialog.master file.
  2. Immediately after the opening HEAD tag, insert the following line: <meta http-equiv=”X-UA-Compatible” content=”IE=EmulateIE8″ />

The changes appear to have resolved the issue completely.

Hiding Disqus Comments


While the Disqus commenting system may be fine for standard post types, sometimes clients don’t wish to use them on specific custom post types. Previously (c. 2013), the following code worked for me…

add_filter( 'the_content' , 'dsq_comments_template_remove' );

function dsq_comments_template_remove( $content ) {
	global $post;

	if ( function_exists( 'dsq_comments_template' ) && 'post' != get_post_type( $post ) ) {
		remove_filter( 'comments_template', 'dsq_comments_template' );
	return $content;

Now I have to use this code:

add_filter( 'comments_template' , 'dsq_comments_template_remove', 1 );

function dsq_comments_template_remove( $file ) {
	if ( 'question' == get_post_type() ) {
		remove_filter( 'comments_template', 'dsq_comments_template' );

	return $file; 

Source: How to Disable Disqus on Custom Post Types in WordPress

Value does not fall within the expected range


The following code, which was supposed to update the “Current” Composed Look, was throwing a “value does not fall within the expected range” error each time I ran it.

SPWeb web = properties.Feature.Parent as SPWeb;
SPList gallery = web.GetCatalog(SPListTemplateType.DesignCatalog);

if (gallery != null)
    SPQuery q = new SPQuery();
    q.RowLimit = 1;
    q.Query = "<Where><Eq><FieldRef Name='DisplayOrder'/><Value Type='Number'>0</Value></Eq></Where>";
    q.ViewFields = "<FieldRef Name='DisplayOrder'/>";
    q.ViewFieldsOnly = true;

    SPListItemCollection items = gallery.GetItems(q);

    foreach (SPListItem item in items)
        item["MasterPageUrl"] = web.MasterUrl;


After a lot of head scratching, it boiled down to the ViewFieldsOnly property which, which I had left set to true. Doh! Updating the property to false corrected the error.

See: SPQuery.ViewFieldsOnly property

SharePoint 2013: Focus on Content


SharePoint 2013 has introduced a small Focus on Content icon to the ribbon bar which, for the MasterPages that support it, will show and hide portions of the page when clicked. This can be useful for hiding non-essential page elements.

When the icon is clicked, JavaScript will do two things:

  1. It creates a cookie, so the selection is remembered the next time the page is visited.
  2. It adds a new ms-fullscreenmode class to the page’s BODY tag.

So, via CSS, we can decide which elements of the page should be hidden via the Focus on Content functionality.

.ms-fullscreenmode #nonessentialcontent { display: none; }