Looping through SPList items

Development

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];
   htmlWriter.Write(listItem["Title"]);
}

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];
  htmlWriter.Write(listItem["Title"]);
}

XSL and dumping XML

Development

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="/">
<pre>
<xsl:copy-of select="*"/>
</pre>
</xsl:template>
</xsl:stylesheet>

Simples!

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 )
$context.ExecuteQuery()


# 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 )

    $user.Update()

    $context.ExecuteQuery()
}

Falling foul of SharePoint SSL

Server Administration

Recently, despite ensuring the SSL certificates within Internet Information Services (IIS) were updated ahead of their expiry, I fell foul of the hidden certificate within SharePoint 2013’s Security Token Service. In my defence, this is a certificate not mentioned within IIS or the Central Administration site. Its one of those lovely settings that can only be seen, analysed, and amended via PowerShell commands. Once you know/remember its there, its relatively straight forward to update.

$path = "C:\certificate.pfx"
$password = "thepassword"

$certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $path, $password, 20

Set-SPSecurityTokenServiceConfig -ImportSigningCertificate $certificate

certutil -addstore -enterprise -f -v root $certificate

iisreset

net stop SPTimerV4
net start SPTimerV4

See: Replace the STS certificate for the on-premises environment

 

Migrating Lists from SharePoint 2010 to SharePoint 2013

Server Administration

While waiting for a purchase order for Sharegate to be approved, I needed to quickly migrate content of an old SharePoint 2010 list to our new SharePoint 2013 farm. Out of the box this isn’t straight forward, and Microsoft recommend a complete backup, move and upgrade approach for the entire content database. Time-wise, this wasn’t an option and seemed overkill for a single list.

In the past I’ve experimented by writing a PowerShell script to export the list’s content to a .CSV file and it’s attachments into folders, and then another script to suck it back into the destination site.

Before heading down that route again, I searched for a different approach and found the Fast & Cheap method documented by Vlad Catrinescu.

It basically involves:

  1. Exporting the list from SharePoint 2010 via the Backup and Restore option within Central Administration.
  2. Changing the extension of the resulting files from .cmp to .cab, and extracting their contents.
  3. Amending the versions stated within the SystemData.xml file from 14.0.x.x to 15.0.x.x
  4. Repackaging them back into a .cab file via CapPack.
  5. Changing the extension from .cab back to .cmp
  6. Importing the list into SharePoint 2013 via PowerShell.
Import-SPWeb -Identity http://mysharepointsite -Path \\temp\SharePointList.cmp -IncludeUserSecurity -Verbose

It seems to have worked like a charm!

SharePoint 2013 and IE11 Support

Server Administration

Very odd. Even though I’ve been using Internet Explorer 11 and SharePoint 2013 together for some time, this morning, when I created a new Site Collection and added a Calendar, it wasn’t rendering as it should and many links were broken.

After a little research,  it seems that IE11 doesn’t work out-of-the-box with SharePoint 2013 and boils down to an inconsistency with the X-UA-Compatible meta tag.

To overcome this, I added a new URL rewrite rule into IIS that spoofs the User Agent of the visitor’s browser, forcing the SharePoint page to be rendered correctly. No Compatibility View required.

Using the Content Query web part in SharePoint without activating the Publishing feature

Server Administration

You can use the Content Query web part within a SharePoint site without activating publishing feature (which you may want to do as activating the feature introduces and changes a lot of options):

  1. Go to the Web Part Gallery within an existing publishing site
  2. Export the ContentQuery.webpart file and upload it to the Web Part Gallery of the destination site
  3. Copy the three .XSL documents (Header, ItemStyle, ContentQueryMain) from the XSL Style Sheets folder within the Style Library and transfer them to the destination site

SharePoint 2013 & PerformancePoint

Server Administration

Note to self: Instead of banging your head for two days trying to resolve the issue of PerformancePoint reports not displaying. When you see a “Failed to Sql Query data XEvent collector on sqldbserver…” message within the log files, first ensure that the SharePoint farm account has been granted the serveradmin role upon the SQL server.

See: Failed to Sql Query data XEvent collector on sqldbserver. The error is Object reference not set to an instance of an object. And other SQL related errors in SharePoint 2013