Sunday, January 22, 2012

SharePoint Summit 2012

I am very pleased and honored to be speaking at the SharePoint Summit 2012. This unmissable event will take place on 16, 17 and 18 April 2012 in Fairmont Le Château Frontnac, Quebec City, Quebec. Please visit http://www.sharepointsummit.org for more details.

My conference will address the Sharepoint solution development and deployment processes. The development approaches, development best practices and the best ways to administer the SharePoint solutions will be among the topics I will talk about.  

You can register for the event here.

I look forward to meeting you there.

Monday, October 17, 2011

SharePoint 2010 : How to add rating to a list using PowerShell


Rating an item of a list is one of the new features of SharePoint 2010. Lately I was asked how  to  add this feature programmatically to the Page list of a publishing site. First, I was expecting to find a sort of SPList.EnableRating property or something like that. There is no such a thing. 

Via the UI, on the list settings page, you just have to click the Ratings settings link and then select YES.  When you enable Ratings on a list, SharePoint adds two columns to the content type(s) you choose : AverageRatings and RatingCount

Finally, after some readings and few searches, here is how I made it using PowerShell :

First, we have to activate a site scoped  feature called Ratings with ID 915c240e-a6cc-49b8-8b2c-0bff8b553ed3 :

Enable-SPFeature -Identity Ratings -Url http://SiteCollectionUrl 

Then, we add the two columns to the content type(s) of the list :


 [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")  
 $site = New-Object Microsoft.SharePoint.SPSite("http://SiteCollectionUrl")  
 $web=$site.OpenWeb()  
 if ($web -ne $Null)  
 {  
       $AverageRating=$web.Fields[[System.Guid]"5a14d1ab-1513-48c7-97b3-657a5ba6c742"]  
       $RatingCount=$web.Fields[[System.Guid]"b1996002-9167-45e5-a4df-b2c41c6723c7"]  
       $PagesList=$web.lists["Pages"]  
       if ($PagesList -ne $Null)  
       {  
             Write-Host " Processing List : " $PagesList.Title  
             $ct=$PagesList.ContentTypes["Page"]  
             If ($ct -ne $null)  
             {  
                   Write-Host " Adding Rating columns to content type : " $ct.name  
                   $AverageRatinglink = new-object Microsoft.SharePoint.SPFieldLink $AverageRating  
                   $RatingCountLink = new-object Microsoft.SharePoint.SPFieldLink $RatingCount  
                   $ct.FieldLinks.Add($AverageRatinglink)  
                   $ct.FieldLinks.Add($RatingCountLink)  
                   $ct.update()                
             }  
       }  
 }  
 $web.Dispose()  

Hope this helps 

Sunday, April 25, 2010

SharePoint 2007 : The incremental crawl never ends!

This is the second time my crawl sticks on indexing files. It shows that it has been crawling for 85 hours. To solve this problem, the first time, I remember, I had to restart the SharePoint services and initialize the index. This time, I do not know how that happened but I found out that on one WFE no SharePoint service was running! So, I started all needed services. When I went back to my Search settings, I found that the stuck crawl has ended. I launched an incremental crawl for all my content sources. Every thing has worked as expected. I am glad I did not have to reinitialize my index this time. I have more than 100000 items in it. It would take me hours to reconstruct it. I tested my search and it is working fine.

Hope this helps.

Saturday, March 6, 2010

System.InvalidOperationException: This access control list is not in canonical form and therefore cannot be modified


In this post I want to share a solution for a problem that may occur when you want to copy pages or sites from a location to another inside a site collection, using the content and structure 'copy' option. You may receive this error :
System.InvalidOperationException: This access control list is not in canonical form and therefore cannot be modified.


At System.Security.AccessControl.CommonAcl.ThrowIfNotCanonical()
At System.Security.AccessControl.CommonAcl.RemoveInheritedAces()
At System.Security.AccessControl.CommonSecurityDescriptor.SetDiscretionaryAclProtection(Boolean isProtected, Boolean preserveInheritance)
At System.Security.AccessControl.ObjectSecurity.SetAccessRuleProtection(Boolean isProtected, Boolean preserveInheritance)
At Microsoft.SharePoint.Deployment.DataFileManager.<>c__DisplayClass1.<CreateDirectoryAsProcessAccount>b__0()
At Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)
At Microsoft.SharePoint.Deployment.DataFileManager.CreateDirectoryAsProcessAccount(String strDir, Boolean allowCurrentUserWriteAccess)
At Microsoft.SharePoint.Deployment.SPExport.AutoGenerateDataFolder()
At Microsoft.SharePoint.Deployment.SPExport.Run()
At Microsoft.SharePoint.Publishing.Internal.DeploymentWrapper.Copy(String[] sourceSmtObjectIds, String destSmtObjectId)
At Microsoft.SharePoint.Publishing.Internal.WebControls.CopyObjects.Copy()
At Microsoft.SharePoint.Publishing.Internal.WebControls.CopyObjects.DoWork()
At Microsoft.SharePoint.Publishing.Internal.LongRunningOperationJob.<>c__DisplayClass16.<ThreadEntryPoint>b__11()
At Microsoft.Office.Server.Diagnostics.FirstChanceHandler.ExceptionFilter(Boolean fRethrowException, TryBlock tryBlock, FilterBlock filter, CatchBlock catchBlock, FinallyBlock finallyBlock)
The problem is that the ACL for the 'Windows\temp' directory is corrupted and therefore, the accounts WSS_WPG and WSS_ADMIN_WPG have no access to the folder to put temporary stuff. 

The solution is to redefine the ACL:


  1. Right-Click on the folder Windows\temp
  2. Click on the Security tab
  3. Click on the Advanced button
  4. Ensure that the account WSS_ADMIN_WPG as the full control permission
  5. Ensure that the account WSS_WPG has the Read & execute permission.
  6. Select both 'Allow inheritable permissions...' and 'Replace permission entries...'
  7. Click OK. 
A 1000 thanks for my colleague Frédéric Lévesque the 'Security guy' for helping troubleshooting the issue.

Hope this helps.

Saturday, February 27, 2010

Extracting SSP user profiles in a xml file

Have you ever wanted to get all user profiles in one listing, especially that in the SSP UI, profiles are displayed in a paginated list? If you happen to have thousands of users then expect to have hundred of pages. The SSP user profiles list is not very intuitive that's why I developed a console application to get all users in a single xml file that I can sort an filter as I wish. Here is the code :




Imports System.Text
Imports System.IO
Imports System
Imports Microsoft.SharePoint
Imports System.Xml
Imports System.Web
Imports Microsoft.Office.Server
Imports Microsoft.Office.Server.UserProfiles

Module SSPUserProfiles

    Sub Main()
        EnumUserProfiles()
    End Sub
    Private Sub EnumUserProfiles()
        Try
            Using Site As New SPSite("http://ServerName")
                Dim siteContext As ServerContext = ServerContext.GetContext(Site)
                Dim ProfileManager As New UserProfileManager(siteContext)
                ' Open a new XML file stream for writing
                Dim stream As IO.FileStream
                stream = File.OpenWrite("UserProfiles.xml")
                Dim writer As XmlTextWriter = New XmlTextWriter(stream, Encoding.UTF8)

                ' Causes child elements to be indented
                writer.Formatting = Formatting.Indented

                writer.WriteProcessingInstruction("xml", "version=""1.0"" encoding=""utf-8""")
                writer.WriteStartElement("UserProfiles")
                writer.WriteAttributeString("Count", ProfileManager.Count.ToString)
                For Each Userp As UserProfile In ProfileManager
                    
                    writer.WriteStartElement("UserProfile")
                    writer.WriteAttributeString("AccountName", Userp("AccountName").Value.ToString())
                    writer.WriteAttributeString("PreferredName", Userp("PreferredName").Value.ToString())
                    If Userp("WorkEmail").Value IsNot Nothing Then
                        writer.WriteAttributeString("E-Mail", Userp("WorkEmail").Value.ToString())
                    End If
                    writer.WriteEndElement() 'UserProfile
                Next
                writer.WriteEndElement() 'UserProfiles
                ' Flush the writer and close the stream
                writer.Flush()
                stream.Close()
            End Using
        Catch exp As Exception
            Console.WriteLine(exp.Message)
        End Try
    End Sub
End Module




For a full list of user profiles properties, please read Anne Stenberg's Blog.

Hope this helps.

Tuesday, January 5, 2010

SharePoint log viewer

Finally, I had some time to develop a tool that I always wanted. A tool that will let me go trough the SharePoint log (where unfortunately I spend lot of time) with ease to find the information I want. Actually it is very simple : It is a small windows application that read the text log file, convert it to a xml file and then, bind it to DataGridView where it can be filtered By :

- Time stamp
- Process
- Area

- Category
- Level of severity


You can find it on CodePlex at : http://mosslogviewer.codeplex.com. It is still a beta version but many ideas are coming.

Your feedback is welcome.

Enjoy!

Tuesday, December 8, 2009

Document icons missing in the search results

This week I had mounted a new server. When I configured Search I found that the documents icons (all types of documents) do not show in the search results page. When it comes to documents icons we always have to check the ...\12\TEMPLATE\XML\DocIcon.xml. The problem was that the file had two instances of the pdf mapping key and the gif file name which is in the mapping value had a blank space in it. I deleted one instance, corrected the gif file name and performed an IISRESET. After that, the icons displayed fine.

To summarize here is what I did :

- Verify that there are no double mapping keys
- Check the icons file names
- IIS reset or recycle the pools

Hope this helps someone.