Jeroen Derde's Blog

My Software Engineering Universe

SharePoint communication sites begin rollout to Office 365 customers

clock June 29, 2017 01:51 by author Jeroen Derde

User Profile Service Permissions affects on MySite experience

clock January 9, 2014 18:17 by author Jeroen Derde

While researching MySite Permissions I found the following table online that I think will be nice to Blog for future reference. The table describes how the combination of User Profile Service permissions influence the Users experience in the MySite.

User Licence Enforcement SharePoint 2013

clock October 1, 2013 03:30 by author Jeroen Derde

User licenceenforcement zorgt ervoor dat er licentie "usage data" wordt gelogd, en toegang tot mogelijkheden die niet binnen de geconfigureerde licentievorm vallen wordt geblokkeerd. Deze functionaliteit staat standaard uit bij installatie van SP2013 en moet expliciet worden aangezet. ULE mogelijkheden werken alleen met een Claims Based omgeving.Om ULE toe te passen kunnen er Active Directory Security Groups worden aangemaakt waaraan vervolgens een licentie categorie wordt gekoppeld. Een licentie categorie kan ook aan een formsbasedrole of een claim worden gekoppeld.

Alle mogelijke categorieën zijn (beschikbaar op basis van installatie):

  • Standard – Delivers the core capabilities of SharePoint, including basic Search functions and Communities platform
  • Enterprise – Provides all the Standard Cal features, including the following Enhanced Search, Business Solutions (Access Services, InfoPath Services), and Business Intelligence (Excel services, PerformancePoint Services, and Visio Services)
  • Project – Access to Project Server that is installed within the SharePoint farm
  • DUET – Allows interoperability with SAP applications
  • OfficeWebAppsEdit (WAC) – Access to Office Web App 

Implementatie voorbeeld:

Er kan aan verschillende Security Groups in het AD, waar in totaal alle gebruikers van een bedrijf in aanwezig zijn, een licentie categorie gekoppeld worden. Door de licentie catagorie“Standard” aan deze security groups te hangen, krijgen alle gebruikers alleen toegang tot de functionaliteiten die vallen onder de Standard CAL van SharePoint. Voor Office Web Apps moet de categorie “WAC” aan dezelfde groep worden toegekend.

User Experience:

Als een gebruiker alleen toegang heeft tot de Standard CAL functionaliteiten, en hij komt op een pagina waar Enterprise CAL features worden gebruikt (zoals bijvoorbeeld het Content Search webpart), dan zal run-time de Enterprise feature niet getoond worden. Bij dit webpart zal in de pagina een melding wordengegeven aan de gebruiker: “Sorry, we couldn’t find your license to use this feature.”

Naast het afdwingen van Webpartsworden ook in de Webpart Gallery mogelijkheden weggenomen als dit onder de geconfigureerde licentie voor de gebruiker noodzakelijk is. Als de gebruiker een Standard CAL heeft, dan zullen de Enterprise CAL webparts ook niet getoond worden, en is het niet mogelijk voor de gebruiker ze toe te voegen aan een pagina.


Logging loopt via de Usage and Health data collection in Central Admin. Iedere keers als de gebruiker toegang tot SharePoint vraagt wordt dit gelogd in de Usage Data. SharePoint houd een cache bij (in de Distributed Cache) om tijdelijk logging data in op te slaan, voor het geval dezelfde gebruiker nogmaals toegang vraagt tot SharePoint. Hiermee wordt voorkomen dat de logs vollopen met toegangsmeldingen van dezelfde gebruiker. De cache wordt 24 uur vastgehouden waarna hij wordt opgeschoond, en dezelfde gebruiker opnieuw gelogd zal worden.

Note: Whether user license enforcement is enabled or not, usage data is logged about which features a user accesses and which licenses they have. 

Note: If user license enforcement is disabled, then the log entries are simply mapped to the installed SKUs which are standard or enterprise.  So, a user accessing a SharePoint deployment that has the Enterprise CAL will be logged as an Enterprise CAL user.  If a user accesses a SharePoint deployment with the Standard CAL, then log entries will contain the Standard CAL for that user.  Only standard and enterprise are logged in this case.

Note: If user license enforcement is enabled, then access to unlicensed features will be logged as ‘unlicensed’.  If a user belongs to more than 1 CAL group, a seperate log entry will be added for each CAL pertaining to the user.  As well, user CAL and device CAL information will be included so that a user’s name that is attempting to access the feature, along with their IP address.


Voorbeeld powershell voor koppelen securitygroup aan Enterprise CAL

$a = New-SPUserLicenseMapping -SecurityGroup "CORP\Enterprise Client Access License" -License Enterprise
Add-SPUserLicenseMapping -Mapping $a 

 Beschikbare PowerShellCmdLets

1. Get-SPUserLicensing

2. Enable-SPUserLicensing

3. Disable-SPUserLicensing

4. Get-SPUserLicense

5. Get-SPUserLicenseMapping

6. New-SPUserLicenseMapping

7. Add-SPUserLicenseMapping

8. Remove-SPUserLicenseMapping


De beschikbare categorieën in de Farm kunnen bijvoorbeeld opgevraagd worden aan de hand van het volgende Powershell Commando: Get-SPUserLicense


Figuur 1- Voorbeeld beschikbare categorieën in SharePoint Demo omgeving

NOTE: Het is ook mogelijk om een koppeling te maken voor een specifieke WebApplicatie in SharePoint

NOTE: User License Enforcement can be used to compliment blended CAL scenarios (such as serving Enterprise and Standard CALs within a single-server farm), but does not enable compliance.  In addition the MAP toolkit can be implemented for reporting purposes.


SharePoint Online V15 on Office 365

clock July 19, 2012 02:39 by author Jeroen Derde

Creates a Office365 Preview environment today using a VM running windows 8 and office 2013 (just for the fun of it).

Changed the public website and added the first blogpost:

Next blogpost I will be wrting from Word 2013, lets hope it works.

SharePoint TaxonomyField and “The object has been updated by another user since it was last fetched”

clock April 11, 2012 23:22 by author Jeroen Derde

Got this error after creating some taxonomy fields and then importing them into Visual Studio using CKSDev. If I then tried to connect a term to the taxonomy field the error occured.

 (“The object has been updated by another user since it was last fetched”)

This did not happen at first, but only after removing my Development Site Collection, and then deploying again from Visual Studio to a new clean sitecollection.

The error was thrown because there was a version number specified in the field xml of the taxonomy field. More detailed information can be found at:

Adding WebParts and a customised CQWP webpart to a page using powershell

clock November 11, 2011 11:45 by author Jeroen Derde
Update thanks to Japser Beerens:
if ($page.File.Level -eq [Microsoft.SharePoint.SPFileLevel]::Checkout)

 changed to

if ($page.File.CheckOutType.value__ -ne 2) #2 = SPCheckOutType.None

because first statement would fail if checked-out by someone else. 

This post will descibe what you need, and what to watch out for when you are planning to add webparts to a publishing page using powershell. Scroll down and skip the plumbing part for the good bits.
First of all: get PowerGUI (or PowerGui for visual studio using the extension gallery) this will make your life a whole lot easier.
Lets start with the information we have and create a batchfile. This is not required, but makes life a lot easier when you want to execute your powershell script multiple times, or have to deal with a Sys-Op that does not know any powershell.

The case: we would like to add webparts to multiple zones on publishing pages of a portal.
We have a site we want to add webparts to:
In the webpart gallery we have a custom webpart (CQWP) with the title: "Related Documents"
This webpart needs to be added to the webpartzone with zoneid called "zone1" in all pages that have a certain pagelayout.
We create a batchfile and set all the parameters we need.
PS: The script is capable of putting multiple webparts into a single zone.
echo off
SET WEBPARTTOADD="Related Documents"

powershell.exe -command .\AddWebParts.ps1 '%URL%' '%WEBPARTTOADD%' '%ZONEID%'

Now we can start on the AddWebParts.ps1 file.
Create the input params
Set the pagelayoutfilenames we want to add the webparts to, and we know the zoneid exists on.
This is required because the (very)LimitedWebpartManager does not allow us to check if a webpartzone exists in a page!
If the zone does not exist, SharePoint will just put the webpart in the first zone it can find.
$AllowedPageLayouts = "ArticleLeft.aspx","ArticleLeft.aspx";

Add the sharepoint powershell snapin

Add-PSSnapin Microsoft.SharePoint.PowerShell

With all the plumbing done we can start on actually doing something.
function InsertWebPartInWebPartZone($siteUrl, $WebPartsToAdd, $webPartZone)
	# Create a new instance of the site. 
	$site = Get-SPSite (New-Object System.Uri($siteUrl)); 

	# Iterate trough all the pages
	foreach($web in $site.AllWebs)
		Write-Host "==============================="
		Write-Host "Currently parsing" $web.Title;
		Write-Host "==============================="

		#check if we are in a publising web
		if( ! [Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($web) )
			Write-Host "Web is not a publishing web, skipping"

		# Retrieve the pages library
		$pagesLibrary = $web.Lists["Pages"];
		$allowunsafeupdates = $web.AllowUnsafeUpdates
		$web.AllowUnsafeUpdates = $true

		# Iterate through all pages
		foreach($page in $pagesLibrary.Items)
			#check for null
			if($page -eq $null)

			#check if page is checked out already
			#if ($page.File.Level -eq [Microsoft.SharePoint.SPFileLevel]::Checkout)
			if ($page.File.CheckOutType.value__ -ne 2) #2 = SPCheckOutType.None
				Write-Host $page.Url "is Checked-Out already. Skipping

				#check if page is a publising page and if it is of allowed pagelayouts to change
				$pubPage = [Microsoft.SharePoint.Publishing.PublishingPage]::GetPublishingPage($page)
				if( ($pubpage -ne $null) -and ($AllowedPageLayouts -contains $pubPage.Layout.Name))
					Write-Host "Page is of valid layout, processing page (" $page.Name ")"
					Write-Host "Page is of invalid layout (" $pubPage.Layout.Name "). Skipping."

				Write-Host "starting page processing -----"
				# Checking out page

				$index = 0;
				foreach($webPartToAdd in $WebPartsToAdd)
					# Retrieve the webpart from the webpartgallery
					$webPart = GetWebPartFromGallery $site $webPartToAdd;
					if($webpart -eq $null)
						Write-Host "Unable to retrieve $webPartToAdd to insert. Skipping.";

					# Check if the page already contains this webpart, if so, remove it
					RemoveWebPartFromPage $page $webPart.Title;

					# Add or re-add the webpart to the page in the specified zone
					AddWebPartToPage $page $webPart $webPartZone $index;

					# Update the index

				# Build up the message
				$checkInMessage = "This page is checked in by the Add WebPart Script";

				# Check the page in and Publish if required
				if($page.ParentList.EnableMinorVersions -eq $true)
				Write-Host "page done"

	$web.AllowUnsafeUpdates = $allowunsafeupdates;

	# Dispose of the web
In the previous function we called several functions, in the next section we will outline these functions 
  • GetWebPartFromGallery
  • RemoveWebPartFromPage
  • AddWebPartToPage

Get WebPartFromGallery reads a webparts XML definition. It reads the definition from the webpartgallery and finds the webpart based on the webpart name.

function GetWebPartFromGallery($site, $webPartName)
	Write-Host "Getting " $webPartName " from gallery."
	# Get the rootweb (and get the webpart gallery)
	$web = $site.OpenWeb();
	$webPartGallery = $web.Lists["Web Part Gallery"]

	if($webPartGallery -eq $null)
		Write-Host("Unable to retrieve Webpartgallery");

	$webpart = $null;
	foreach($wp in $webPartGallery.Items)
		#find the webpart we are looking for
		if($wp.Title -eq $webPartName)
			$webpart = $wp;
			Write-Host "Webpart found in gallery"

	if($webpart -eq $null)
		Write-Host("Unable to retrieve webpart: $webPartName");

	return $webpart;
The next two functions do all the heavy lifting in this script (the good stuff).
The first function allows us to rerun the script multiple times. This is allows us to make changed to a webpart, upload it to the gallery and replace the existing webparts with new ones on all pages.
It searched the page for a webpart with a certain title. if the webpart is found on the page, the webpart will be removed. After that the second (add) function will be called.
The second function adds the webpart that was read from the gallery onto the page into the specific zone.
Both functions contain a section (needs refactoring :) ) thats sets the HTTPContext. This is the part of the functions that is very interesting, and basically the reason for writing this blogpost.
This code was added, because when we are instantiating webparts that contain URL's (like the CQWP contains an XslItemLink, XslMainLink or XslHeaderLink ) The properties of the webpart class are used to set the values in the webpart object.
These URL properties internally call makeserverrelative and that uses the HTTP context. However, because we are running inside of powershell, these is no HttpContext. This problem does not occur with the standard SharePoint webparts I tested, because the XML definition of these webparts does not contain any URL properties. But when trying to put the customised CQWP (related documents) on the page, I got an error. After a lot of debugging manually creating a HTTPContext was the solution because of the reason stated above.
I hope this information will save someone a lot of time.
#Remove webpart based on Webpart title
function RemoveWebPartFromPage($page, $webPartTitle)
#make sure the page is checked-out
if ($page.File.Level -ne [Microsoft.SharePoint.SPFileLevel]::Checkout)
Write-Host $page.Url " is not Checked-Out. Cannot remove webpart from the page.";
return $false;

# set the current httpcontext, needed for contentquerywebparts webparts that use the 
 # xslitemlink, xslmainlink or xslheaderlink property
 # else makeserverrelative url will fail, because there no context
 if ($null -eq [System.Web.HttpContext]::Current)
     $sw = New-Object System.IO.StringWriter
  $resp = New-Object System.Web.HttpResponse $sw
  $req = New-Object System.Web.HttpRequest "", $web.Url, ""
  $htc = New-Object System.Web.HttpContext $req, $resp
  #explicitly cast $web to spweb object else sharepoint will 
  #see it as a PSObject, and AddWebpart wil fail
  $htc.Items["HttpHandlerSPWeb"] = $web  -as [Microsoft.SharePoint.SPweb]
  [System.Web.HttpContext]::Current = $htc

$webPartCollection = $page.Web.GetWebPartCollection($page.Url,[Microsoft.SharePoint.WebPartPages.Storage]::Shared);
$webPartStorageKey = $null;
foreach($wp in $webPartCollection)
$webpart =  $wp -as [Microsoft.SharePoint.WebPartPages.WebPart];
if($webpart.Title -eq $webPartTitle)
$webPartStorageKey = $webpart.StorageKey;

if($webPartStorageKey -eq $null)
return $false;

return $true;

# Adds the desired webpart to the page
function AddWebPartToPage($page, $webPartListItem, $webpartZoneId, $index)
Write-Host "Adding" $webPartListItem.Name " to " $page.Name;

if ($page.File.Level -ne [Microsoft.SharePoint.SPFileLevel]::Checkout)
Write-Host $page.Url "is not Checked-Out. Cannot add webpart to the page.";
return $false;

# Get the webpartmanager
$wpManager = $page.Web.GetLimitedWebPartManager($page.Url,[System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared);

# Get the webpart's xml
$errorMsg = "";
$xmlReader = New-Object System.Xml.XmlTextReader($webPartListItem.File.OpenBinaryStream());
$webPart = $wpManager.ImportWebPart($xmlReader, [ref]$errorMsg) -as [Microsoft.SharePoint.WebPartPages.WebPart];

# set the current httpcontext, needed for contentquerywebparts webparts that use the 
# xslitemlink, xslmainlink or xslheaderlink property
# else makeserverrelative url will fail, because there no context
if ($null -eq [System.Web.HttpContext]::Current)
    $sw = New-Object System.IO.StringWriter
$resp = New-Object System.Web.HttpResponse $sw
$req = New-Object System.Web.HttpRequest "", $web.Url, ""
$htc = New-Object System.Web.HttpContext $req, $resp
#explicitly cast $web to spweb object else sharepoint will 
#see it as a PSObject, and AddWebpart wil fail
$htc.Items["HttpHandlerSPWeb"] = $web  -as [Microsoft.SharePoint.SPweb]
[System.Web.HttpContext]::Current = $htc

# Add webpart to the page
$wpManager.AddWebPart($webPart, $webpartZoneId, $index); 
Write-Host "An error occurred. Unable to add webpart " $webPartListItem.Title;
Write-Host $_.Exception.ToString();
[System.Web.HttpContext]::Current = $null

return $true;
I always start a Transcript before executing the script.

InsertWebPartInWebPartZone $siteUrl $WebPartsToAdd $ZoneId


Add the source parameter to SharePoint links

clock October 5, 2011 20:46 by author Jeroen Derde

Let say we have a publishing page, and we create a link on that publishing page to the NewForm of a List.
Aftre the user created the listitem we would like to go back to the page the user clicked the link, in stead of the list overview page.
When you want to return to the page you came from, sharepoint uses a QueryString Parameter called "source".
Microsoft was even kind enough to provide us with al small javascript function to automatically add this parameter to a Link.
In a content editor webpart u can use
<A onclick="GoToLink(this);return false;" href="/feedback/_layouts/listform.aspx?PageType=8&ListId={B0EF9608-FC48-401E-9343-4EDDF4585131}&RootFolder=">new feedback</A>
If however you are in a Publishing page Content Field, SharePoint is kind enough to strip all javascript from the contents.
So you will have to manually add the source parameter for that link.
GoToLink is located in the core.js


clock October 1, 2011 02:56 by author Jeroen Derde

Found out today that the behaviour of the PublishingWebControls:EditModePanel changed between MOSS2007 and SP2010.

Apparently,now in SP2010, you need the EditItem Permission to be able to see what is in an EditModePanel even if the PageDisplayMode attribute is set to "Display".

So basically it works like a SPSecurityTrimmedControl


<SharePoint:SPSecurityTrimmedControl PermissionsString="EditListItems" runat="server"> 

This behaviour has been changed back to 2007 behaviour as of SP1 for Sharepoint 2010

XSL for Raw Search XML of SharePoint search results

clock September 27, 2011 20:36 by author Jeroen Derde

I keep losing this really handy xsl for displaying the raw search result XML in SharePoint. Blogging it for future reference :).

<xsl:stylesheet version="1.0"
 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
 <xsl:template match="/">
  <xmp><xsl:copy-of select="*"/></xmp>



Missing Search Refinement Webpart in SP2010 Site Collection

clock September 14, 2011 00:32 by author Jeroen Derde
When you upgrade to Microsoft SharePoint Server 2010, some of the new SharePoint Enterprise Search Web Parts are missing from the Web Part gallery for upgraded site collections.
The following are the missing Web Parts:
  • Refinement Panel
  • Related Queries
  • People Refinement Panel
  • Dual Chinese Search
This topic describes how you can add these Web Parts to the Web Part galleries of the upgraded site collections.
Another post about this with more detailed problem information

Powershell RunWithElevatedPrivileges

clock September 13, 2011 20:46 by author Jeroen Derde
     $site = get-spsite "http://localhost/nonfarmadminsitecollection" 

$elevatedSite = new-object Microsoft.SharePoint.SPSite([Guid]$site.ID,$site.SystemAccount.UserToken)

Lenovo W510 Windows 7 install

clock July 23, 2011 02:09 by author Jeroen Derde

Today I waisted some time installing Windows 7 on my new Lenovo W510.

It has 2 HDD's so I could not use a win7 DVD. No problem there.
Borrowed a USB stick from a collegue (Thnx Jan) and downloaded this little tool. This allows you to copy an ISO of Windows7 to a USB drive and install it from there.


After copying the windows7 files to the USB drive I was ready to get started. So I put the drive in the side USB ports of the W510 and gor started. 30 minutes and lots of error messages later I decided to BING it.

It turns out you cannot install the laptop with a external  USB drive (or USB dvd player) on any but the rear usb.
I guess that this port is on another controller that is supported by default and the side (USB 3.0) ports are on another controller that is not.

Just thought I would put it out there for everyone else  

Link Tools (Ribbon) Remove Link does not delete link

clock July 18, 2011 20:38 by author Jeroen Derde

The issue occurs on a publishing site that has a contenttype containing a Publishing Hyperlink (SPFieldLink).
Inserting a link with the Link Tools Tab of the ribbon works fine, but removing the link after it has been set does not.
Found a post on Stackoverflow that describes the issue in detail:

For quick reproduction: (steps and testing by M. Siepel)

  • Create a Publishing Portal site
  • Create a column of type Publishing Hyperlink 
  • Add the column to de Welcome Page contenttype
  • Navigate to the Press Releases page 
  • View information -> Edit
  • Add a link to the newly created column and save the page
  • Open it again, remove the link (the link is visually removed, it even says: Click here to add a new Hyperlink)
  • Save the page again
  • Now open the page again. 
  • In our situation, the message 'Click here...' is gone, and if you view the source our original link is still there, but there is no text inside it.

I did some testing on it and these are the results:

  • It occurs on dev and prod server with a custom solution installed
  • It occurs on a server with no custom solution installed (clean install)
  • It also occurs on the 'Adventure Works' site (both on a clean install and on a server with custom solution) 
  • It occurs both when creating a sitecolumn of type Publishing Hyperlink through API and UI
  • When viewed with firebug the 'deleted' link is still in the href property, but the text property is empty
  • Tested on IE/FF
  • When viewing with Sharepoint Manager 2010, the link is still in de DB (with no text property as stated above)
  • It happens on Dutch and English sites.

A little more time on the Bing machine resulted in finding a post from M Siepel on the Microsoft forums:

Basicly it states that the bug can be reproduced consistently and it has been reported to the product team. Lets hope this will be fixed in the next CU.

Someone already created a powershell fix, but that is not really end-user friendly. I will update this post

[string]$list0="My List",
[string]$itemKey0="Item Key",
[string]$desc0="New description",
[string]$toolTip0="New Tooltip") $site = Get-SPSite($site0) $rootWeb = $site.rootWeb $lists = $rootWeb.Lists $list = $lists[$list0] $items = $list.Items $listItem = $items | Where-Object {$_.Name -eq $itemKey0} $linkUrl = $listItem["Link Url"] $linkUrl.NavigateUrl = $linkUrl0 $linkUrl.Description = $desc0 $linkUrl.ToolTip = $toolTip0 # this is the trick - set the object back to listItem $listItem["Link Url"] = $linkUrl $listItem.Update()


Visio 2010 XSD

clock June 6, 2011 23:28 by author Jeroen Derde

About a week ago Microsoft published the XML Schema Definition (XSD) files for the Microsoft Visio 2010 XML Drawing (.vdx) format. This schema is also known as DatadiagramML.
This should make it alot easier to use the visio file to generate code based in the visio file.

The DatadiagramML Schema for Visio 2010 consists of three .XSD files:

  • visio.xsd is the core schema used by Visio 2003 and later
  • visio12.xsd is the set of extensions used by Visio 2007 and later
  • visio14.xsd is the set of extensions used by Visio 2010

More information about the schema is available in the Visio 2010 XML Schema Reference on MSDN.

Cumulative Update SharePoint 2010 April

clock May 12, 2011 22:59 by author Jeroen Derde

I missed these when they where released

28 April Sharepoint  Foundation CU

11 March Sharepoint  Foundation CU Hotfixes

28 April Sharepoint Server CU

Month List


<<  August 2017  >>

View posts in large calendar

Sign in