Albert Jan Schot
 

SharePoint 2007 to 2010 upgrade issue with navigation

03

Aug

Upgrading a SharePoint 2007 to a SharePoint 2010 environment and all options you have is something that is handled quite well on the web, personally i love this post on how to do it, but there are several other posts out there making it pretty easy. However I ran into a ‘small’ bug upgrading.

I have a SharePoint farm containing some info, and a Dutch language pack, thus I recreated the same environment as a SharePoint 2010 containing a Dutch language pack, and using a database upgrade. And as you can see in the picture below, there are no errors, and adding the content DB went well as expected.

addcontentdb 

However, the results when looking at in the browser where kind of sad:

Foutmelding menu

After a long search on the web someone mentioned turning off and on the Publication Infrastructure for SharePoint, turning it of resolved the issue, but turning it on again instantly returned it. So I found myself struggling with the issue for another day not being able to find the exact bug, but nice fix.

Apparently the Menu control expects a /paginas library that contains the pages, but it isn’t there, so it throws an error, since I didn't want to change my farm to much I created a small PowerShell scripts that would fix the error.

The result is a working site:

Werkend menu

Script 1 – Creating Libraries 

  1: [Void][System.Reflection.Assembly]::LoadWithPartialName
  2:   ("Microsoft.SharePoint")
  3: [Void][System.Reflection.Assembly]::LoadWithPartialName
  4:   ("Microsoft.SharePoint.Publishing")
  5: 
  6: function CheckaWeb($rootweb)
  7: {
  8:   #Step 1 Check For Lists
  9:   $list = $rootweb.Lists[$from];
 10:   if($list -ne $null) {createList $rootweb $list}
 11:   
 12:   #Check for subwebs
 13:   if($rootweb.Webs -ne $null)
 14:   {
 15:     # Recursive Call To SubWeb
 16:     foreach($web in $rootweb.Webs)
 17:     {
 18:        CheckAWeb $web
 19:     }
 20:   }
 21: }
 22: 
 23: 
 24: function createList ($web, $list)
 25: {
 26:   Write-Host -ForegroundColor Green 
 27:           " Found a web containing a PageList on url" $web.Url 
 28:   
 29:   $web.Lists.Add("Paginas", 
 30:             "Automatisch gegenereerde bibliotheek voor 
 31:              SharePoint 2010 upgrade", 101)
 32: }
 33: 
 34: 
 35: Write-Host ""
 36: Write-Host -ForegroundColor Green 
 37:     "Fix Dutch SharePoint 2010 Upgrade Script v1.0 - Albert-Jan Schot "
 38: Write-Host -ForegroundColor Green 
 39:     "contact appie@tamtam.nl"
 40: Write-Host ""
 41: 
 42: $site=new-object Microsoft.SharePoint.SPSite('http://restore.sp2010.dev')
 43: $from = "Pagina's"
 44: 
 45: Write-Host -f Blue " "
 46: 
 47: CheckaWeb $site.Rootweb $true  
 48: 
 49: Write-Host " "
 50: Write-Host -f Blue "Done checkin webs"
 51: Write-Host " "

Albert-Jan Schot schreef

Comments (0)

Albert-Jan Schot

Moving a DocumentSet through code - pt1

20

Jul

One of the new features in SharePoint 2010 are the so called DocumentSets, a sort of folders-like option that allows you to manage multiple documents as they where a set, setting global metadata or capturing versions and downloading multiple documents. Since those options sounds pretty cool I recon it’s going to be a much used option within SharePoint 2010, however once you created a DocumentSet moving it around can be pretty hard, by default there are a few ways to move around your environment:

  • You can move items around in the Explorer view of your libraries, and doing so with a DocumentSet results in the copying of a folder, losing all metadata for your DocumentSet (and as you might have noticed once you set the ContentType back to DocumentSet it still shows as a folder).
  • On the other hand you can use the “send-to” option you get, but that will results in the sending of a ZIP package, still losing the information as it seems. 
  • The only way by default moving around works, is by using the Site Content and Structure.

So we decided to check if we could manage it through code. In this first part there will be some PowerShell examples on how to move a DocumentSet and where you might find yourself trying to do so, in the next part there will be some focus on how to move the DocumentSet through the ribbon, including all the metadata of it.

According to TechNet a DocumentSet is a special type of folder, and checking out MSDN shows that the the DocumentSet object does not have any options to move it to another location. The export function results in a packaged file (zip), but importing is a crime, and so far i didn't get that to work.

  1: $moveFromUrl = "aSiteUrl"
  2: $newfolder = $site.OpenWeb().GetFolder("aFolderUrl")
  3: 
  4: $movefromList=$site.OpenWeb().GetList($moveFromUrl)
  5: 
  6: $docSet = [Microsoft.Office.DocumentManagement.DocumentSets.DocumentSet]
  7:   ::GetDocumentSet($newfolder)  
  8: $compressedFile = $x.Export()
  9: 
 10: $compressedFile.GetType() 
 11: 
 12: $docsetID = [Microsoft.SharePoint.SPBuiltInContentTypeId]::DocumentSet
 13: $targetFolder = $movefromList.RootFolder
 14: $targetFolder.GetType()
 15: $user = $site.OpenWeb().EnsureUser("aUser")
 16: $user.GetType()
 17: 
 18: $properties = new-object System.Collections.Hashtable
 19: $properties.Add("DocumentSetDescription", "Description")
 20: 
 21: $z = [Microsoft.Office.DocumentManagement.DocumentSets.DocumentSet]
 22:   ::Import($compressedFile, "DocsetRestore", $targetFolder, 
 23:   $docsetID, $properties, $user);

Results in a nice error telling me nothing.

  1: IsPublic IsSerial Name                 BaseType                                                                           
  2: -------- -------- ----                 --------                                                                           
  3: True     True     Byte[]               System.Array                                                                       
  4: True     False    SPFolder             System.Object                                                                      
  5: True     False    SPUser               Microsoft.SharePoint.SPPrincipal                                                   
  6: 
  7: Exception calling "Import" with "6" argument(s): "DocID: Site prefix not set."
  8: At :line:94 char:76
  9: + $z = [Microsoft.Office.DocumentManagement.DocumentSets.DocumentSet]
 10:   ::Import <<<< ($compressedFile, "Docset1Backup", $targetFolder, 
 11:   $docsetID, $properties, $user);
 12: 

 

So I came up with a new approach, it is a Folder with a ContentType set to it, so I used the folder ‘MoveTo’ and updated the ContentType of the folder back to a ‘DocumentSet’, that lead to the same error I would do that through the browser, it still was a folder, without the DocumentSet welcome page set to it. After some debugging I found out that there was a field that differs between a folder and a DocumentSet: HTML File Type. So i made some changes and was able to move a DocumentSet with PowerShell. Below you can find the code, where you can see how we update the folder,in pt2 there will be some more info on how you can do so with a nice custom ribbon command, and also move all custom fields.

  1: param([string]$moveFromUrl, [string]$moveToUrl, [string]$moveItem)
  2: 
  3: [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") 
  4: 
  5: ##########################################################################
  6: ###                                                                    ###
  7: ###                            Functions                               ###
  8: ###                                                                    ###
  9: ##########################################################################
 10: 
 11: function checkItemToMove ([Microsoft.SharePoint.SPList]$movefromList, [Microsoft.SharePoint.SPList]$movetoList, [string]$moveItem)
 12: {
 13:   $docsetID = [Microsoft.SharePoint.SPBuiltInContentTypeId]::DocumentSet
 14:   [Microsoft.SharePoint.SPFolder]$docsetToMove = $null 
 15:   
 16:   foreach($docset in $movefromList.Folders)
 17:   {  
 18:     if($docset.ContentType.ID.ToString().StartsWith($docsetID.ToString()) -and $docset.Name -eq $moveItem) 
 19:     {
 20:       $docsetToMove = $docset.Folder
 21:       $docsetContentTypeId = $docset.ContentType.Parent.Id
 22:       break;
 23:     }       
 24:   }
 25:   
 26:   if($docsetToMove -ne $null -and $docsetContentTypeId -ne $null) 
 27:   {
 28:     Write-Host -ForegroundColor Green "Found a docset: " $docsetToMove.Name " Lets move it"
 29:     moveDocSet $docsetToMove $movetoList $docsetContentTypeId
 30:   }
 31:   else {  Write-Host -ForegroundColor Red "No document set of desired name found:" $moveItem }
 32: }
 33: 
 34: function moveDocSet ([Microsoft.SharePoint.SPFolder]$docset, [Microsoft.SharePoint.SPList]$movetoList, [string]$docsetContentTypeId)
 35: {
 36:   $moveurl = $movetoList.RootFolder.ToString() + "/" + $docset.Name  
 37:   
 38:   $docset.MoveTo($moveurl)
 39:   
 40:   #retrieve it at new location
 41:   [Microsoft.SharePoint.SPFolder]$newDocset=$site.OpenWeb().GetFolder($moveurl)
 42:   if($newDocset.Exists)   
 43:   {
 44:     #update it so it is a doc set and set CT right
 45:     $newDocset.Item["ContentTypeId"] = $docsetContentTypeId
 46:     $newDocset.Item["HTML File Type"] = "SharePoint.DocumentSet" 
 47:     #TODO update all custom fields .. 
 48:     $newDocset.Item.Update()
 49:   
 50:     Write-Host -ForegroundColor Green " Docset moved succesfully ... parteh "
 51:   }
 52:   else {Write-Host -ForegroundColor Red " Failed moving the docset or setting ... "}
 53: }
 54: 
 55: ##########################################################################
 56: ###                                                                    ###
 57: ###                           /Functions                               ###
 58: ###                                                                    ###
 59: ##########################################################################
 60: 
 61: Write-Host ""
 62: Write-Host -ForegroundColor Green "Move DocSet Script v1.0 - Albert-Jan Schot "
 63: Write-Host ""
 64: 
 65: if($moveFromUrl -eq $null -or $moveFromUrl -eq "") {Write-Host -ForegroundColor Red "No folder to move from"; Exit}
 66: if($moveToUrl -eq $null -or $moveToUrl -eq "") {Write-Host -ForegroundColor Red "No folder to move to"; Exit}
 67: if($moveItem -eq $null -or $moveItem -eq "") {Write-Host -ForegroundColor Red "No DocumentSet name set"; Exit}
 68: 
 69: #Retrieves the desired objects
 70: $site=new-object Microsoft.SharePoint.SPSite($moveFromUrl)
 71: 
 72: [Microsoft.SharePoint.SPList]$movefromList=$site.OpenWeb().GetList($moveFromUrl)
 73: [Microsoft.SharePoint.SPList]$movetoList=$site.OpenWeb().GetList($moveToUrl)
 74: 
 75: #Move a docset
 76: checkItemToMove $movefromList $movetoList $moveItem 

 

There is one remark, if you try to move a DocumentSet this way to a library that does not have all the ContentTypes available that are used in the DocumentSet you will have a problem with the Version. If all ContentTypes are available it will take the version history of the DocumentSet and move it, if the ContentTypes aren’t available it will try to copy the version history, but if you try to display it, it will fail, giving a field not present error, so keep that in mind.

Albert-Jan Schot schreef

Comments (0)

Albert-Jan Schot

Create a custom group in the SharePoint Ribbon

20

Jul

Creating custom ribbon commands is all inline with the SharePoint User Experience, and thus something you should keep in mind whenever you are developing for SharePoint 2010.  However I found myself in need of creating a new group within an existing tab and stumbled upon the next MSDN article, however a minor detail is that you cannot add a CommandUIHanlder without a CommandAction. So in order to get the script working you have to delete the line with Command="EnableCustomGroup" and the line with <CommandUIHandler Command="EnableCustomGroup" />.

Leaving you with a script like you can find below to create a custom group:

  1: <?xml version="1.0" encoding="utf-8"?>
  2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  3:   <CustomAction 
  4:     Id="Ribbon.WikiPageTab.CustomGroupAndControls" 
  5:     Location="CommandUI.Ribbon" 
  6:     RegistrationId="100" 
  7:     RegistrationType="List">
  8:     <CommandUIExtension>
  9:       <CommandUIDefinitions>
 10:         <CommandUIDefinition 
 11:           Location="Ribbon.WikiPageTab.Groups._children">
 12:           <Group 
 13:             Id="Ribbon.WikiPageTab.CustomGroup" 
 14:             Sequence="55" 
 15:             Description="Custom Group" 
 16:             Title="Custom Group" 
 17:             Command="EnableCustomGroup" 
 18:             Template="Ribbon.Templates.Flexible2">
 19:             <Controls Id="Ribbon.WikiPageTab.CustomGroup.Controls">
 20:               <Button
 21:                 Id="Ribbon.WikiPageTab.CustomGroup.Controls.CustomButton1" 
 22:                 Command="CustomButtonCommand1" 
 23:                 Image16by16="/_layouts/images/FILMSTRP.GIF" 
 24:                 Image32by32="/_layouts/images/PPEOPLE.GIF" 
 25:                 LabelText="" 
 26:                 TemplateAlias="o2" 
 27:                 Sequence="15" />
 28:             </Controls>
 29:           </Group>
 30:         </CommandUIDefinition>
 31:        </CommandUIDefinitions>
 32:       <CommandUIHandlers>
 33:         <CommandUIHandler Command="EnableCustomGroup" />
 34:         <CommandUIHandler Command="CustomButtonCommand1" 
 35:           CommandAction="javascript:alert('Hello, world!');" />
 36:       </CommandUIHandlers>
 37:     </CommandUIExtension>
 38:   </CustomAction>
 39: </Elements>

Albert-Jan Schot schreef

Comments (0)

Albert-Jan Schot

SharePoint 2010 Search Page and the UIVersionedContent control

27

May

The default SharePoint 2010 Search center has a nice predefined results page for you, containing a nice set of WebParts. However if you create a Search Center you can see that returning to your site is a pretty hard task. So today someone asked me if we could make a page-layout exactly like the default search results page, allowing them to create resultpages anywhere in their portal. That being said, the only thing I had was the SharePoint Designer, luckily for me it was a 2010 project :).

So first thing I did was copying the default WelcomeLinks.aspx pagelayout, since that page has no left sidebar, next thing was to simply copy the table structure to the page and tweaking it a bit. However after checking it in, and publishing it, I got stuck with an unknown error. After some debugging my logs shows the error:

Exception No parameterless constructor defined for this object.

After some more debugging it seems that one of the WebParts on the default search page got an invalid property, so after deleting all the WebParts, leaving me with an empty page with nothing but some WebPartZones I checked it in, and published it again. Just to bring me the next error:

Unknown server tag 'SharePoint:UIVersionedContent'.

For some reason the WelcomeLinks.aspx is allowed to use the UIVersionedContent, but as soon as you ‘customize’ it, you aren’t anymore. Adding the next line will do the trick:

<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

After that you’re good to go, and you will have a nice SearchResults look-a-like pagelayout.

Result:

SearchResults.zip (2.08 KB)

Albert-Jan Schot schreef

Comments (0)

Albert-Jan Schot

SDN 18 may 2010 : PowerShell and SharePoint

26

May

Last week I gave a presentation on PowerShell and SharePoint. The main focus was on showing the cool stuff from PowerShell and giving an introduction into new possibility’s it has for both developers and admins. More on the event itself can be found on: http://www.sdn.nl/SDN/SDNEvent/SDNEventMei2010/tabid/160/Default.aspx (Dutch).
For those who are interested the slides and code examples can be found here:

PowerShell.ppt (164 KB)
PowerShellDemos.zip (4.54 KB)

Both are in Dutch.

Albert-Jan Schot schreef

Comments (0)

Albert-Jan Schot
Page 1 of 2 in the SP2010NL category Next Page