Wednesday, September 19, 2012

Force an update of Web Analytics


With the service Web Analytics in SharePoint 2010 you can either see statistics reports in Central Administration or retreive information from it to display on your pages. There is one big drawback. The statistics are updated only once a day, and this cannot be changed anywhere in Central Administration. To check what the current settings of your Web Analytics service application, use the following Power Shell command:

PS> Get-SpWebAnalyticsServiceApplication -identity "web analytics service application"

By default the start time of the report consolidation is "Daily at 02:00". It is possible to change the time when the update is made with the following Power Shell command:

PS> Set-SpWebAnalyticsServiceApplication -identity "web analytics service application" -ReportConsolidationStartTime 12

This will change the start time of the report consolidation to "Daily at 12:00". Note that the number, 12 in my example, must be an integer value between 1 and 23. I haven't tried this myself yet, but this should mean that in theory you could write a Power Shell script, or something, that runs every half hour and pushes the start time forward one hour. This should force the report consolidation to run every hour instead of once each day. But to get up to one hour old statistics is usually not good enough, but it's the best you can do with the Web Analytics service. Too bad.

Yet another day in SharePoint paradise...

Profile import in 2010 cannot filter on AD-groups

The other day I was doing some configuring on a brand new SharePoint 2010 farm at a customer. My task was to configure the profile import just as their old SharePoint 2007 farm was configured. Easy peasy...not.

I started the user profile synchronization service, created a new connection to their AD, made the first synchronization and got no profiles at all. Then I remembered that the profile synchronization service account  must have replication directory changes permission. This sounds worse than it actually is and is fixed by following this TechNet article, http://technet.microsoft.com/en-us/library/hh296982.aspx#RDCdomain. After that the profile database was populated correctly.

Then I just had to create a filter for a handful of AD-groups. In SharePoint 2007 this was done by adding a LDAP-filter to the connection. In the filter you define what should be included/excluded in the synchronization. In SharePoint 2010 this is no longer a valid option. Instead you define one or more exclusion filters. First of all, to limit the filter to just being an exclusion filter is really stupid. The other setback is that it's not possible to filter on AD-groups any more, just AD-parameters! I found this official blog post to confirm this, http://blogs.msdn.com/b/spses/archive/2011/05/31/sharepoint-2010-profile-sync-inability-to-import-users-based-on-group-membership.aspx.

The story ends with a custom profile database clean-up job, which is a story in itself, and a slightly unhappy customer. I find some comfort in the fact that I'm not alone, http://donalconlon.wordpress.com/2011/04/26/fun-with-filters-user-profile-synchronization-somebody-shoot-me-now/.

Yet another day in SharePoint paradise...

WSS_UsageApplication proxy stopped

All of a sudden the web analytics reports on one of my development servers was not updating properly. I followed this http://technet.microsoft.com/en-us/library/ff453926.aspx but could not find anything wrong. Then I noticed that the service application proxy to the usage application was in status "Stopped". Since there is no way of restarting application proxies in Central Administration my first thought was to remove Web Analytics from the farm and recreate it again. Luckily I found this blog post before I started tearing things down, http://tristanwatkins.com/index.php/fixing-the-usage-and-health-data-collection-sa/. I ran the following Power Shell commands and after that the application proxy was in status "Started" again:

PS> $sap = Get-SPServiceApplicationProxy | where-object {$_.TypeName -eq “Usage and Health Data Collection Proxy”}
PS> $sap.Provision()

Yet another day in SharePoint paradise...

Tuesday, July 17, 2012

SharePoint 2013 is here!

Finally! During the spring we here in Sweden we got July 20 as the date for the beta release. Almost a month later it is here.

Download SharePoint Server 2013 preview: http://technet.microsoft.com/en-us/evalcenter/hh973397
Download SharePoint Foundation 2013 preview: http://www.microsoft.com/en-us/download/details.aspx?id=30345

It will take some time to download the files. In the meantime it is a good idea to have a look at the training videos.

SharePoint 2013 IT pro traning videos: http://technet.microsoft.com/en-US/sharepoint/fp123606
SharePoint 2013 Developer training videos: http://msdn.microsoft.com/en-US/sharepoint/fp123633

It will be interesting if to see I can run the server since the hardware requirements has shot through the roof, http://technet.microsoft.com/library/cc262485(office.15)?ocid=fwlink#hwforwebserver. I "only" have 16 GB RAM, which also is maximum. I'll probably have to ask my boss for a new computer.

Yet another day in SharePoint paradise...

Friday, July 13, 2012

Replace New Page menu item for publishing sites

Back in SharePoint 2007 when you created a new publishing page in a publishing site you got to a page where you had to enter a title and choose a page layout.


In 2010 you just get a pop-up where you enter the name of the new page.


The new page will get the "default" page layout. If you want to change the layout, which is true in a lot of cases, you have to do that in the ribbon menu after the page has been created. Thank you Microsoft, but this is not how anyone wants to work with their publishing pages. Thankfully there is hope. There is a page in the layouts-folder called CreatePage.aspx, which is the exact same page as in 2007!


So now you, of course, want to hide the old New Page menu item with a HideCustomAction element and add a new menu item with a CustomAction element which just points to CreatePage.aspx. Well... Unfortunately Microsoft has cut some corners implementing the three menu items you get when you enable the publishing feature, i.e. New Page, New Document Library and Manage Content and Structure. Instead of adding them as three independent custom actions they have created one custom action and added the menu items in code behind. This makes it impossible to hide one of the three since all are registered with the same Id.

The solution to this madness is to create a new custom action and change the action for the New Page menu item via the object model in the code behind.

Oh, and another thing. It is impossible to add the new custom action in the exact same spot as the old New Page menu item since Microsoft does not expose the property MenuGroupId in the custom action xml, http://msdn.microsoft.com/en-us/library/ms460194.aspx. So we have to add our new custom action in code behind.

Here is my CustomAction element:

  <CustomAction
    Id="SharePoint.Paradise.CustomActions.NewPage"
    Location="Microsoft.SharePoint.StandardMenu"
    GroupId="SiteActions"
    Rights="AddListItems"
    ControlAssembly="$SharePoint.Project.AssemblyFullName$"
    ControlClass="SharePoint.Paradise.CustomActions.NewPage">
  </CustomAction>

Here is the code behind for the custom action:

namespace SharePoint.Paradise.CustomActions
{
    public class NewPage : WebControl
    {
        // Hide the old "New page" menu item
        // Menu items for the publishing feature is not added properly so we can hide them in Elements.xml with HideCustomAction, thank you Microsoft
        protected override void OnPreRender(EventArgs e)
        {
            ToolBarMenuButton menu = ToolBarMenuButton.GetMenuControl(this);
            MenuItemTemplate item = menu.GetMenuItem("wsaCreatePage");
            if (item != null)
            {
                menu.MenuControl.HiddenMenuItems.Add(item);
            }
        }
        
        // Add a the new "New page" menu item
        // MenuGroupId in not exposed to Elements.xml so we can add "New page" in the same location as the old one, thank you Microsoft
        protected override void CreateChildControls()
        {
            MenuItemTemplate item = new MenuItemTemplate();
            item.Text = HttpContext.GetGlobalResourceObject("wss", "siteactions_createpage", CultureInfo.CurrentUICulture).ToString();
            item.Description = HttpContext.GetGlobalResourceObject("wss", "siteactions_createpagedesc", CultureInfo.CurrentUICulture).ToString();
            item.ImageUrl = SPContext.Current.Web.Url + "/_layouts/images/crtpage.gif";
            item.MenuGroupId = 200;
            item.Sequence = 100;
            item.ClientOnClickNavigateUrl = SPContext.Current.Web.Url + "/_layouts/CreatePage.aspx";

            this.Controls.Add(item);
        }
    }
}

Yet another day in SharePoint paradise...

Move a document into a document set

Document set is a new feature in SharePoint 2010. It is very neat to be able to group documents together with metadata, workflows, etc. Just one small thing. There is no way to move existing documents into document sets. I recently had to come up with a solution to this for a customer and I found this gem after some searching, http://gilleslauwers.wordpress.com/2011/05/31/move-a-file-to-a-document-set/.

I changed two things to make the solution perfect.

1. Added {SiteUrl} to options.url in Elements.xml to make it work for site collections with a managed path:

options.url = '{SiteUrl}/_layouts/Sam.MoveToDocumentSet/ChooseDocumentSet.aspx?ListId={ListId}&amp;ItemId={ItemId}';

2. Changed the CAML query to display all document sets, even those of custom content types:

query.Query = "<Where><Eq><FieldRef Name='FSObjType' /><Value Type='Lookup'>1</Value></Eq></Where>";

I would rather develop features that does something customer specific than do this, which should be included in the product.

Yet another day in SharePoint paradise...

True is false, but TRUE is true

I had the craziest idea the other day. What if I write "True" or "true" instead of "TRUE" for boolean properties that should be true in my Elements.xml. I have always written "TRUE" because that's what everyone does. I hadn't given it much thought before, so I just went bezerk and wrote "True".

To my biggest suprise the property became false.

It apperas that the only true true is TRUE. I would very much like to have a chat with the retard that wrote the parser for boolean properties in SharePoint.

Yet another day in SharePoint paradise...