Jeroen Derde's Blog

My Software Engineering Universe

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 https://eoffice928-public.sharepoint.com/ and added the first blogpost: https://eoffice928-public.sharepoint.com/Lists/Posts/Post.aspx?ID=2

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: http://www.mpspartners.com/2012/02/SharePointTaxonomyFieldandTheobjecthasbeenupdatedbyanotherusersinceitwaslastfetched/



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: http://contoso.com
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.
 
Batchfile
echo off
SET URL="http://contoso.com"
SET WEBPARTTOADD="Related Documents"
SET ZONEID="Zone1"

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

pause
Now we can start on the AddWebParts.ps1 file.
Create the input params
Param($siteUrl,$WebPartsToAdd,$ZoneId);
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"
			continue;
		}

		# 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)
			{
				continue;
			}

			#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
			}
			else
			{

				#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 ")"
				}
				else
				{
					Write-Host "Page is of invalid layout (" $pubPage.Layout.Name "). Skipping."
					continue;
				}

				Write-Host "starting page processing -----"
				# Checking out page
				$page.File.CheckOut()

				$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.";
						continue;
					}

					# 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
					$index++;
				}

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

				# Check the page in and Publish if required
				$page.File.CheckIn($checkInMessage);
			
				if($page.ParentList.EnableMinorVersions -eq $true)
				{
					$Page.File.Publish("Published");
				}
				
				Write-Host "page done"
			}
		}

	$web.AllowUnsafeUpdates = $allowunsafeupdates;

	# Dispose of the web
	$web.Dispose();
	}
}
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"
			break;
		}
	}

	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;
break; 
}
}

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

$webPartCollection.Delete($webPartStorageKey);
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];

try
{
# 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); 
}
catch
{
Write-Host "An error occurred. Unable to add webpart " $webPartListItem.Title;
Write-Host $_.Exception.ToString();
}
[System.Web.HttpContext]::Current = $null
$wpManager.Dispose();


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

InsertWebPartInWebPartZone $siteUrl $WebPartsToAdd $ZoneId

Stop-Transcript




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>
--update--
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
 
 


PublishingWebControls:EditModePanel

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

Example:

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

Update
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"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
 <xsl:template match="/">
  <xmp><xsl:copy-of select="*"/></xmp>
 </xsl:template>
</xsl:stylesheet>

 

 



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
[Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges( 
{
     $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:
http://social.msdn.microsoft.com/Forums/en-AU/sharepoint2010general/thread/8ce468ec-096b-4ad2-a1e9-0bfb93cecf95

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

Param([string]$site0=http://mysharepoint, 
[string]$list0="My List",
[string]$itemKey0="Item Key",
[string]$linkUrl0=http://newlink,
[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

http://support.microsoft.com/kb/2512804/en-us

11 March Sharepoint  Foundation CU Hotfixes

http://support.microsoft.com/kb/2475880/en-us

28 April Sharepoint Server CU

http://support.microsoft.com/kb/2512800/en-us



Microsoft Country Partner of the Year

clock April 21, 2011 19:58 by author Jeroen Derde

 At e-office we have been working hard at baking our Microsoft cake this year

Lets just say we are pretty serious about our baking skills.
To put the cherry on top we are submitting a great case to the anual Microsoft World Partner Conference in LA.



Check-LookupColumn PowerShell

clock April 14, 2011 01:08 by author Jeroen Derde

Today I had some issues with a Lookup Column in SP2010.

When using my Admin account I was able to edit an Item and select a value. When using my normal useraccount (with contribute rights on bot lookuplist an list) I wasn't able to select anything, and SP2010 showed an empty dropdown.
Looking at the column properties in SharePoint everything looked OK, but using SP Designer the properties where empty.
Figuring this just might be something other then a rights issue, I wrote a little PowerShell function to check the settings of my Column.

 

Function Check-LookupColumn($webURL, $listName, $columnName, $lookupListName)
{
 $web = Get-SPWeb $webURL
 $list = $web.Lists[$listName]
 $column = $list.Fields[$columnName]
 $lookupList = $web.Lists[$lookupListName]
 
 
 write-host "lookupweb              : " $column.LookupWebId.ToString() 
 write-host "should be equal to web : " $web.ID.ToString() 
 write-host "lookuplist             : " $column.LookupList.ToString() 
 write-host "should be equal to list: " $lookupList.ID.ToString()
}

Turned out that during the migration from one environment to the other, the references of the lookup column had not been updated.
The Admin account had sufficient rights on both environments, so it worked for that account. my user account on the other hand was not available in the source environment, so no sigar.
After updating the column with the right GUID's everything works again.

Wish I had seen this before writing my onw script Laughing, but the script to fix the lookup column can be found at: http://get-spscripts.com/2011/01/fixing-blank-lookup-columns-in.html



New job at e-office

clock April 9, 2011 00:23 by author Jeroen Derde

April 1st I started my new job at e-office.  e-office focusses on Human software, and does this using Microsoft, IBM and Google technology.
Human sofware can be seen as 'messaging', 'collaboration', 'enterprise 2.0', 'unified communications', 'user experience' and 'mobile'.
It does however not stop at the technology, because at e-office we believe that people and organisations are an equal part of the equation.

I've joined the SharePoint team at e-office, and I'm already very excited about the upcoming projects that I have seen.

You can follow e-office on:

twitter: http://twitter.com/#!/e_office_com

facebook http://www.facebook.com/group.php?gid=109382118015

linked-in: http://www.linkedin.com/groups?mostPopular=&gid=145232

 




Month List

Calendar

<<  May 2013  >>
MoTuWeThFrSaSu
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar

Sign in