donderdag 25 juli 2013

SharePoint Inventory

People who are busy with SharePoint migrations know that it is useful to first perform an analysis of the content. There are some tools to help you but most of them aren’t free. At this moment I’m busy with creating an inventory of a SharePoint 2007 and I’ve automated it in a console application. The console application can also be used on a SharePoint 2010 version.

My console application “SharePointContentInventory” generates a xml of al the sitecollections, sites, lists and workflows with their properties.

For business users is a xml not readable so I have also written a Windows Forms Application that generates a treeview of the xml. If you click on a treeviewnode the properties are shown in the right pane of the application.

maandag 17 juni 2013

SharePoint 2013: Show title row in searchcenter

I was asked to integrate the top navigation in the search master page of SharePoint 2013. After some searching on the internet I found this great blog post:


http://www.estruyf.be/blog/display-the-title-row-top-navigation-in-the-search-centers-of-sharepoint-2013/

When working with the new search centers in SharePoint 2013, the first thing that you will notice is that the title row is different compared with for example a standard Team Site. Standard SharePoint 2013 Title Row Standard SharePoint 2013 Title Row Search Center Heading - Title Row is Hidden Search Center Heading - Title Row is Hidden

SharePoint 2013 Branding tips

It’s time to take a deep dive into the SharePoint 2013 branding. My research on the internet stopped very quickly on the blog from Eric Overfield. After reading his blog I noticed some important branding tips:

  • s4-notdlg from SharePoint 2010 changed to ms-dialogHidden in SharePoint 2013:

In a custom branding project you add a new container element, such as a new header, navigation block or footer to your System (default) Master Page. This element then appears in dialogs even through we do not want it to.

Solution:

SharePoint 2013 template for Photoshop

Previously I announced the photoshop template for SharePoint 2010. Now I can also give you the photoshop template for SharePoint 2013. There is nothing easier than start with a template if you want to create a new branding for your SharePoint 2013.
You can download it here
Enjoy it! Glimlach

woensdag 24 april 2013

SharePoint 2010 Alerts

How to send daily alerts immediately in SharePoint 2010?
If you create new daily alert and want to see whether it will work or not it is not very convenient to wait 24 day until SharePoint will sent them next time. In this post I will show how to trigger summary alerts and send them when you need.
When you add a new daily alert on a list or something a new row is added to the SchedSubscriptions table into the SharePoint content database. The most important columns in this table are NotifyTime and NotifyTimeUNC. In these columns stores SharePoint the time when next time daily alert for particular list will be send.
Step 1: Get the id of the daily alert that you want to modify
SELECT * FROM SchedSubscriptions
Step 2: Copy the Id and execute the following SQL query:
declare @s datetime
declare @u datetime
set @s = CAST('2013-04-24 10:00:00.000' as datetime)
set @u = CAST('2013-04-24 07:00:00.000' as datetime)

update dbo.SchedSubscriptions
set NotifyTime = @s, NotifyTimeUTC = @u
where Id = '. . .'
Notice that the NotifyTimeUNC = NotifyTime minus 3 hours.
After that wait some time. Exact time of waiting depends on the Recurring Schedule of the Immediate Alert timerjob.

dinsdag 19 maart 2013

SharePoint 2010: Show lync presence in custom webpart

My customer asked for a contact details webpart with the feature if the contact is available on Lync or not. It isn’t difficult to get the contact details from a user profile in contrast to get the lync presence. I spend a few hours to get how it works in SharePoint 2010 and finally I found this blog post of Martin Kearn. With a little bit of fine tuning I rewrote the function to let it work with the UserProfile property instead of a SPFieldUserValueCollection.

maandag 11 maart 2013

SharePoint 2010 Contact Details WebPart

A customer asked me to write a webpart to have the possibility to show contact details of a user based on the userprofile. Someone told me that this webpart could be useful in other projects too. I reviewed my code an made it generic so it can be used in every SharePoint 2010 where are userprofiles present. It’s also expanded with localization. The webpart is available in English, Dutch and French.

woensdag 6 februari 2013

Add webparts to pages via PowerShell

This week I created some webparts. Those webparts must be added to more than 1000 pages in SharePoint. It’s an awful job to do it manually, so I created a script in PowerShell that do the job for me Glimlach

Code Snippet
  1. Add-PSSnapin Microsoft.SharePoint.PowerShell
  2. Start-SPAssignment -Global    # This cmdlet takes care of the disposable objects to prevent memory leaks
  3.  
  4. function AddCustomWebPart($web,$page,[string]$webpart_nameSpace,[string]$webpartTitle,[int]$index)
  5. {
  6.     $comment = $webpartTitle + " WebPart Added"
  7.  
  8.     $webpartmanager=$web.GetLimitedWebPartManager($page.Url,  [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
  9.     
  10.     $wpsOnPage = $webpartmanager.WebParts | % { $_ }
  11.     foreach($wp in $wpsOnPage)
  12.     {
  13.         if($wp -ne $null)
  14.         {
  15.             if($wp.Title -eq $webpartTitle)
  16.             {
  17.                 Write-Host "webpart " $wp.Title " exists on page. "
  18.                 $webpartmanager.DeleteWebPart($webpartmanager.WebParts[$wp.ID]);
  19.             }
  20.         }
  21.     }
  22.     
  23.     $webpart = new-object $webpart_nameSpace
  24.     $webpart.ChromeType = [System.Web.UI.WebControls.WebParts.PartChromeType]::Default;
  25.     $webpart.Title = $webpartTitle
  26.     $webpart.Width = "300px"
  27.     
  28.     $webpartmanager.AddWebPart($webpart, "RightColumn", $index);    
  29. }
  30.  
  31. function CheckInAndPublishPage($comment)
  32. {
  33.     " Checking in page"
  34.     $page.CheckIn($comment)
  35.  
  36.     # Publish
  37.     if($page.listItem.ParentList.EnableMinorVersions -eq $true -and $publishingPage.ListItem.File.MinorVersion -ne 0)
  38.     {
  39.             " Publishing"
  40.             $page.listItem.File.Publish($comment)
  41.     }
  42.  
  43.     # If moderation is being used handle the approval    
  44.     if ($page.listItem.ParentList.EnableModeration)
  45.     {
  46.  
  47.         $modInformation = $page.listItem.ModerationInformation
  48.         
  49.         " Moderation on, Current Status: " + $modInformation.Status
  50.  
  51.         # Check for pending approval
  52.         if($modInformation.Status -ne [Microsoft.SharePoint.SPModerationStatusType]::Approved)
  53.         {
  54.             " Approving"
  55.             $page.ListItem.File.Approve($comment)
  56.         }
  57.     }
  58. }
  59.  
  60. $webUrl = "http://intranet/sites/subweb/"
  61. $web = Get-SPWeb $webUrl
  62.     
  63. $list = $web.Lists["Pagina's"]
  64. Write-Host $list.Title
  65. $pages = $list.Items
  66.  
  67. foreach($item in $pages)
  68. {
  69.     $page =  [Microsoft.SharePoint.Publishing.PublishingPage]::GetPublishingPage($item)
  70.     Write-Host "Page Url: " $item.Url
  71.     Write-Host "Page ContentType: " $item.ContentType.Name
  72.     
  73.     $page.CheckOut()
  74.         
  75.     AddCustomWebPart $web $page "SharePoint.Intranet.WebParts.Bijlagen" "Bijlagen" 3
  76.     AddCustomWebPart $web $page "SharePoint.Intranet.WebParts.ProcesbeschrijvingBijlagen" "Procesbeschrijving bijlagen" 4
  77.     
  78.     CheckInAndPublishPage("Bijlage webparts toegevoegd.")
  79. }
  80.  
  81. # Clean up
  82. $web.Close()
  83.  
  84. Write-Host Done.
  85.  
  86. # Add an empty line
  87. Write-Host ""
  88.  
  89. # Clean up
  90. Write-Host "Cleaning up..."
  91. Stop-SPAssignment -Global
  92. Remove-PsSnapin Microsoft.SharePoint.PowerShell
  93.  
  94. Write-Host "Press any key to continue ..."
  95. $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

Isn’t it wonderful? The script also check if the webpart is already on the page or not. If it’s already added than it will be deleted and added again to respect the order of the webparts. For some reason SharePoint doesn’t respect the order.

If someone knows why SharePoint ignores the order of the webparts feel free to let me know.

dinsdag 8 januari 2013

SPListItemCollection with Linq

I like to use linq to find, sort, .. items in a list quick and easily, but it’s a pain to convert a SPListItemCollection into a generic list. Today I wrote a class that do the conversion for me easily.

Code Snippet
  1. public class SPListItemCollectionAdapter : List<SPListItem>
  2.     {
  3.         private SPListItemCollection _listItemCollection;
  4.  
  5.         /// <summary>
  6.         /// Get a generic list of SPListItems and convert it
  7.         /// </summary>
  8.         /// <param name="listItemCollection">SPListItemCollection collection of items</param>
  9.         public SPListItemCollectionAdapter(SPListItemCollection listItemCollection)
  10.         {
  11.             _listItemCollection = listItemCollection;
  12.  
  13.             Refresh();
  14.         }
  15.  
  16.         /// <summary>
  17.         /// Convert a SPListItemCollection into a generic list
  18.         /// </summary>
  19.         private void Refresh()
  20.         {
  21.             this.Clear();
  22.  
  23.             foreach (SPListItem item in _listItemCollection)
  24.             {
  25.                 this.Add(item);
  26.             }
  27.         }
  28.     }

Now you can use the class above like:

Code Snippet
  1. private SPListItemCollectionAdapter GetItems(SPList list, string query)
  2.         {
  3.             SPQuery q = new SPQuery();
  4.             q.Query = query;
  5.  
  6.             return new SPListItemCollectionAdapter(list.GetItems(q));
  7.         }

The only thing you need to do is declare a variable of the type SPListItemCollectionAdapter and create a new one.

Isn’t it easy?