SharePoint 2013 RTM Availability

Using .NET 4 with SharePoint 2013

A while ago, I wrote an article about performing operations parallel with SharePoint 2010 (.NET 3.5). –> Execute code in multiple threads (even with SharePoint)

Since I am not the only guy with this kind of “problems”, others are writing about SharePoint and .NET. Especially .NET 4.5 and SharePoint 2013.

Stephane Eyskens hat posted a nice 6-post series about .NET within SharePoint 2013.

If you stumble across more great resources, please leave a comment.

Getting an “Object reference not set to an instance of an object” when accessing the User Profile Service via Code

This is one of the posts which shall remind me about something. And may help others as well.

Coding against the User "Profile Service Application requires Connection Permissions for the executing user account!

From the beginning. I wrote a console application which leverages the User Profile Store. Every time I created a new instance of the UserProfileConfigManager class, an exception was thrown:

Object reference not set to an instance of an object

at Microsoft.Office.Server.Administration.UserProfileApplicationProxy.get_ApplicationProperties()
at Microsoft.Office.Server.Administration.UserProfileApplicationProxy.get_ILMMachineName()
at Microsoft.Office.Server.UserProfiles.UserProfileConfigManager.Initialize(UserProfileApplicationProxy userProfileApplicationProxy, Guid partitionID)
at Microsoft.Office.Server.UserProfiles.UserProfileConfigManager..ctor(SPServiceContext serviceContext)
at ITaCS.UserProfileManager.GetUserProfileServer() in D:\Data\Development\tfs02\ITaCS\Components\UserProfileProperties\UserProfileProperties\UserProfileManager.cs:line 49
asf

Fiddling with Reflector and creating the object with Reflection didn’t help. The solution was much easier. Just grant the executing account, which was my user who executes the console application, Connection Permissions to the User Profile Store Service Application (UPS).

image

image

That’s it.

One other thing. If you are running your SharePoint with local accounts, you might not be able to verify a domain account. In that case, you can tell the people picker to use a domain account instead of the service account (which is a local account and does not have permissions in the active directory). See Configure People Picker (SharePoint Server 2010) and  Multi Forest/Cross Forest People Picker peoplepicker-searchadcustomquery.

What is the _layouts/15/start.aspx in SharePoint 2013

SharePoint 2013 immediately redirects you to an application page start.aspx when you call a website.

If you’ve ever wondered why, keep on reading…image

image

The pictures will also look familiar to you. So what happened? Why the start.aspx?

The start.aspx inherits Microsoft.SharePoint.ApplicationPages.MDSStartPage. That page simply looks, if the SPContext.Current.Site.CompatibilityLevel is above 14. If not, it’ll redirect to web.Url. That is the behavior, we know from previous versions of SharePoint.

Additionally it adds some caching information to the Response, and loads a JavaScript called… start.js. That file contains a method $_global_start, which is executed after the file has been loaded. There are some steps the JavaScript executes. Next I’ll try to tell you what the most important steps are.

The arrow basically shows what happens if a user requests a page, where the new logic has been implemented.

image

Next, I will write a little bit about each step. Don’t expect an in-deep explanation. This is just an overview to satisfy the first curiosity.

The Start.js

Show “Working on it…” either full-size for a newly called page, or a smaller one on the right side

But who calls the script? The answer is: the mighty masterpage.

The script does some magic to the Url. I’ll check for updates, which have to be loaded an passed to the client and modify the Url (inserts _layouts/15/start.aspx). If you want to take a closer look on what the script does, set a Breakpoint with e.g. Firebug on the line “function AsyncDeltaManager$_navigate(url, anchorName, bUpdatehash) {“ and reload a page.

The v5.master

SharePoint 2013 brings a new masterpage, which is called v5.master. That masterpage contains a control of type StartScript.

<SharePoint:StartScript runat="server" />

The TagPrefix SharePoint reflects the namespace Microsoft.SharePoint.WebControls. So lets look into the class.

The StartScript WebControl

If the current Page is of type DeltaPage, the class adds some JavaScript to the Page.

To shorten up here as well: If there is a hash in the Url (#), the script will tell the AsyncDeltaManager (from start.js) to hook up to the submit event and tell it where it needs to redirect in case of a postback.

That’s basically all the WebControl is doing.

The DeltaPage

The DeltaPage inherits System.Web.UI.Page. It decides, whether to render the full page, or just a delta. This is called the “Minimal Download Strategy”. There are already some interesting posts about this available. SharePoint 2013 – Introduction to the Minimal Download Strategy (MDS) or Minimal Download Strategy in SharePoint 2013

protected override void Render(HtmlTextWriter writer)
{
    if (this.RenderDelta)
    {
        this.RenderForRenderDelta(writer);
    }
    else
    {
        this.RenderToBase(writer);
    }
}

RenderDelta will look if the current page is the StartPage (that means there is no Page on which to depend)  or if SPContext.Current.Web.EnableMinimalDownload has not been enabled. RenderForRenderDelta add “pageStartRedirect” to the response. I won’t go into the details of this, because I simply haven’t looked into it deep enough for a blog post.

Summary

This image should visualize the steps.

image

Please keep in mind, that this post is written with a research on SharePoint 2013 preview!

There are plenty more features which I’d like to take a deeper look into. Let’s hope I find the time to do so 🙂

Start / Stop SharePoint Services via PowerShell

If you have installed SharePoint on your workstation, you might want to start the services only in case of active development. Otherwise the services consume memory and other resources.

The PowerShell script in this post will allow you to easily start and stop all required services for a local SharePoint Installation.

image

It will detect if you’ve installed SharePoint 2007/WSS, SharePoint 2010 or SharePoint 2013. Just copy the code below to a file, name it StartStopSharePoint.ps1 (yes, very creative :-)) and call it from a PowerShell (you don’t need the SharePoint Management PowerShell).

$SharePointV3Services = ('SQLSERVERAGENT','MSSQLSERVER','W3SVC','SPWriter','SPTrace','SPTimerV3','SPAdmin','OSearch','DCLoadBalancer','DCLauncher')
$SharePointV4Services = ('SQLSERVERAGENT','MSSQLSERVER','W3SVC','SPSearch4','OSearch14','SPWriterV4','SPUserCodeV4','SPTraceV4','SPTimerV4','SPAdminV4','FIMSynchronizationService','FIMService','DCLoadBalancer14','DCLauncher14')
$SharePointV15Services = ('SQLSERVERAGENT','MSSQLSERVER','W3SVC','SPSearchHostController','OSearch15','SPWriterV4','SPUserCodeV4','SPTraceV4','SPTimerV4','SPAdminV4','FIMSynchronizationService','FIMService','DCLoadBalancer15','DCLauncher15')

$Services = $SharePointV3Services
$version = 12
# check for SharePoint 2010
$hive = get-ItemProperty "hklm:\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0"
if ($hive -eq $null)
{
    if ((get-ItemProperty "hklm:\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\15.0" SharePoint).SharePoint -eq 'Installed')
    {
        $version = 15
        $Services = $SharePointV15Services
    }
}
else
{
    if ((get-ItemProperty "hklm:\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0" SharePoint).SharePoint -eq 'Installed')
    {
        $version = 14
        $Services = $SharePointV4Services
    }
}

Write-Host -ForegroundColor Green 'SharePoint Version' $version 'found'
Write-Host -ForegroundColor Yellow 'Press'
Write-Host -ForegroundColor Green '1' -NoNewline
Write-Host -ForegroundColor Yellow ' to start SharePoint Services'
Write-Host -ForegroundColor Green '2' -NoNewline
Write-Host -ForegroundColor Yellow ' to stop SharePoint Services'
Write ''

function StartSharePoint($Services)
{
    Write-Host -ForegroundColor Yellow ('Starting ' + $Services.Length + ' services')
    foreach ($serviceName in $Services)
    {
        $service = Get-Service $serviceName -ErrorAction SilentlyContinue 
        if ($service)
        {
            $startMode = (get-wmiobject win32_service | where-object {$_.Name -eq $serviceName}).StartMode
            if (($service.Status -ne 'Running') -and ($startMode -ne 'Disabled'))
            {
                Write-Host -ForegroundColor Green ('Starting "' + $service.DisplayName + '"')
                Start-Service $serviceName
            }
        }
        else
        {
            Write-Host -ForegroundColor Red ('Service "' + $serviceName + '" does not exist')
        }
    }
}

function StopSharePoint($Services)
{
    Write-Host -ForegroundColor Yellow ('Stopping ' + $Services.Length + ' services')
    for($i = ($Services.Length - 1); $i -gt -1; $i--)
    {
        $serviceName = $Services[$i]

        $service = Get-Service $serviceName -ErrorAction SilentlyContinue 
        if ($service)
        {
            $startMode = (get-wmiobject win32_service | where-object {$_.Name -eq $serviceName}).StartMode
            if ($service.Status -ne 'Stopped')
            {
                Write-Host -ForegroundColor Green ('Stopping "' + $service.DisplayName +'"')
                Stop-Service $serviceName -force
            }
            else
            {
                Write-Host -ForegroundColor Green ('"' + $service.DisplayName + '" is already stopped')
            }
        }
        else
        {
            Write-Host -ForegroundColor Red ('Service "' + $serviceName + '" does not exist')
        }
    }
}

function UserInput($strMsg, $intStyle)
{
  #$strMsg: Message displayed on the console sreen
  #$intStyle: User Input Style:
    #1 = Read-Host (Multiple characters, require to press Enter);
    #2 = $host.ui.rawui.readkey() (Single character, do not require to press enter)
  switch($intStyle)
  {
    1 { $strInput = Read-Host $strMsg ; $host.ui.rawui.foregroundcolor = $Global:fgColor ; return $strInput }
    2 { Write-Host $strMsg; $strInput = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown"); return $strInput}
  }
}

$userInput = UserInput "Enter Choice" 2
switch ($userInput.VirtualKeyCode)
{
    49 { StartSharePoint($Services) }
    50 { StopSharePoint($Services) }
    default { Write-Host -ForegroundColor Red 'Press "1" or "2"' }
}

Hint: In case you haven’t set the Script-Execution-Policy yet, you will be prompted to do so. –> Using the Set-ExecutionPolicy Cmdlet

Happy Coding!

BrandMySharePoint.de

Soeben ist ein neues Community-Portal online gegangen. Auf diesem Portal bin auch ich als Autor für Artikel vertreten. Mehr Werbung möchte ich jetzt erst einmal nicht machen 🙂 Schaut es euch einfach mal an.

www.brandmysharepoint.de

Was erwartet Euch auf diesem Portal?

Wir starten zunächst mit zwei Rubriken: Artikel und Shots. Die Artikel befassen sich mit allen möglichen Themen rund um das Design. Dabei werden nicht nur die klassischen (Web-)Designer angesprochen, sondern auch Entwickler, IT-Pros oder einfach nur „SharePoint-Interessierte“. Zu finden werden sein Codebeispiele, Anleitungen, Screenshots oder Erfahrungsberichte aus unterschiedlichen Projekten.

Die Shots veranschaulichen, welche Möglichkeiten und Ansätze es gibt, die SharePoint-Oberflächen zu gestalten, anzupassen oder grafisch komplett „umzubiegen“. Hier veröffentlichen wir regelmäßig Screenshots von diversen SharePoint-Portalen, möchten Euch aber vor allem einladen, eigene Beispiele beizusteuern.

Für die Zukunft haben wir noch mehr geplant…

Caching objects with HttpRuntime

I won’t go into the arguments for using a caching mechanism or not. This post is simply an example for an easy way to cache data.

So if you want to store some object in the cache, you can do so very easy.

var localizedString = Caching.EnsureObject(resourceName,
                                           () => GetOperation(parameter));

As you can see, it really doesn’t matter what type of object the cache will store.

class Caching
{
   private static readonly TimeSpan Duration = new TimeSpan(1, 0, 0);

   /// <summary>
   /// return cached value, or add and return from cache
   /// </summary>
   /// <typeparam name="T"></typeparam>
   /// <param name="cacheKey"></param>
   /// <param name="getObject"></param>
   /// <returns></returns>
   internal static T EnsureObject<T>(string cacheKey, Func<T> getObject)
   {
      var value = HttpRuntime.Cache[cacheKey];
      if (value != null)
      {
         return (T) value;
      }

      value = getObject.Invoke();

      if (value != null)
      {
         var expiration = DateTime.UtcNow.Add(Duration);
         HttpRuntime.Cache.Insert(cacheKey, value, null, expiration, Cache.NoSlidingExpiration);
      }
      return (T) value;
   }

Adjust the duration, or pass it as parameter. Additionally you could pass another delegate for Exception-Handling. This example is meant as a reminder to think about caching again…

Error in SharePoint Search

I’ve had the error message “The SharePoint item being crawled returned an error when requesting data from the web service.   (0x80042616)” when I tried to crawl a SharePoint WebApplication. The search crawler account had access to a site by a WebApplication policy. But somehow, that didn’t work.

After removing and re-adding the account policy on the WebApplication, the search crawled my content again.

Hopefully this post can help others as well.

Execute code in multiple threads (even with SharePoint)

Since SharePoint 2010 uses .NET 3.5, you can not use the fancy new functions from .NET 4 🙂

So if we need e.g. multi-threaded execution of code, we’ll need to write the code ourselves. But, as you can see, this really isn’t so hard. The basic idea behind this solution of executing code parallel in threads, is that you have an IEnumerable<T> of some kind. This can be a List, or any other IEnumerable.

So let us for example take a list of Guids, which are the IDs of all SPWebs in a SiteCollection. Then we are iterating each web, and write the itemCount of all lists to the Console.

class ParallelExecutionTest
{
   private static int _overallItemCount;
   private static readonly object Lock = new object();

   public static void AddItemCount(int itemCount)
   {
      lock (Lock)
      {
         // only let one thread write to the setter 
         _overallItemCount += itemCount;
      }
   }

   public static void CountListitemsInAllWebs(string siteUrl)
   {
      using (var site = new SPSite(siteUrl))
      {
         // perform the method/action on any web in the sitecollection 
         site.AllWebs.Select(w => w.ID).EachParallel(webId =>
         {
            CountListitems(site.ID, webId);
         }, Environment.ProcessorCount);
         Console.WriteLine("Overall Itemcount: " + _overallItemCount);
      }
   }

   private static void CountListitems(Guid siteId, Guid webId)
   {
      // use new instances for each web 
      using (var site = new SPSite(siteId))
      using (var web = site.OpenWeb(webId))
      {
         var itemCount = web.Lists.Cast<SPList>().Sum(list => list.ItemCount);
         Console.WriteLine("Web {0} has {1} items in all lists.", web.Title, itemCount);
         AddItemCount(itemCount);
      }
   }
}

That doesn’t look too complicated, does it? The little method EachParallel is all it takes for running the code in multiple threads. You have to decide if your code can run parallel, and if makes sense!

Note: Remember that SharePoint will most likely not work, if you access the same objects in multiple threads. So to be safe, create new instances of SharePoint objects in each Thread!

The sample above will create as much threads, as your system has CPUs. On my notebook with i7 and HyperThreading in 8 threads. And here comes the point to remember. Think carefully about the pitfalls on running your code parallel. Here are some drawbacks, compared to the sequentiell execution:

  • Overhead for creating new SharePoint objects (calls to the SQL server)
  • Additional load on the SQL server by querying more data simultaneously (think about a 4 processor server board with x cores and HyperThreading)
  • Possibly more load on the local SharePoint server by writing logfiles
  • Exception handling. With sequential code you can abort. Multiple threads keep running

Enough for now. Lets look at the Extension method which makes all this possible.

public static class Extensions
{
   /// <summary> 
   /// Enumerates through each item and start the action in a new thread 
   /// </summary> 
   /// <typeparam name="T"></typeparam> 
   /// <param name="enumerable"></param> 
   /// <param name="action"></param> 
   /// <param name="maxHandles">e.g. Environment.ProcessorCount</param> 
   public static void EachParallel<T>(this IEnumerable<T> enumerable, Action<T> action, int maxHandles)
   {
      // enumerate the passed IEnumerable so it can't change during execution 
      var itemArray = enumerable.ToArray();
      var count = itemArray.Length;

      if (count == 0) return;
      if (count == 1)
      {
         // if there's only one element, just execute 
         action(itemArray.First());
      }
      else
      {
         // maxHandles must not be greatet than the count of actions, or nothing will be done 
         if (maxHandles > count) maxHandles = count;
         var resetEvents = new ManualResetEvent[maxHandles];

         for (var offset = 0; offset <= count / maxHandles; offset++)
         {
            EachAction(action, maxHandles, itemArray, offset, resetEvents);
            // Wait for all threads to execute 
            WaitHandle.WaitAll(resetEvents);
         }
      }
   }

   private static void EachAction<T>(Action<T> action, int maxHandles, IEnumerable<T> itemArray, int offset, ManualResetEvent[] resetEvents)
   {
      int i = 0;
      foreach (var item in itemArray.Skip(offset * maxHandles).Take(maxHandles))
      {
         resetEvents[i] = new ManualResetEvent(false);

         ThreadPool.QueueUserWorkItem(data =>
         {
            var index = (int)((object[])data)[0];
            try
            {
               // Execute the method and pass in the enumerated item 
               action((T)((object[])data)[1]);
            }
            catch (Exception ex)
            {
               // Exception handling 
               Console.WriteLine(ex.ToString());
            }

            // Tell the calling thread that we're done 
            resetEvents[index].Set();
         }, new object[] { i, item });
         i++;
      }
   }
}

All items in the IEnumerable are iterated. If there is free slot, the action will be executed in a new thread. There is no guarantee, that the code is executed in the same order, as the items in your IEnumerable. Here is an examples of IDs in an array, and the execution order:

Order in ListExecution order
03
16
27
31
44
50
62
75

Summary: Depending on your code, and its requirements, multiple threads can be a good way to improve the speed of you code. It even can be a life-saver (thx Christopher!) for very long running operations. Take your time to think about it, before you implement the “little” change to your code to run in multiple threads!

One last word. I mentioned .NET 4 at the beginning. Here is a sample.

var ids = new List<int> { 0, 1, 2, 3, 4, 5 }; 
ids.AsParallel().ForAll(id => { Console.WriteLine("Id: " + id); });

Nice, ain’t it?

Major Update to the Fileserveraccess Web Part

In 2008 I’ve released a Web Part, which enables your users to access files on your fileservers through SharePoint. Original post. This Web Part has been downloaded many times. With this new version, I’ve tried to deal with the most asked questions (like Kerberos), which will make the Web Part easier to use. Naturally new features have been implemented, to get you to upgrade to the new version.

With this release, the Web Part requires SharePoint Foundation / Server 2010. For the users who are still using WSS V3, please stick to the old version, or upgrade your farm 🙂

First some screenshots, so you know what I am talking about.

image

imageimage

Features

  • Download files from your fileservers via SharePoint
  • Download a folder with all containing files as zip-file
  • Upload files to a fileserver
  • Delete files from a fileserver
  • View the file properties
  • By default, the fileserver path has to be UNC. Local paths are not allowed, so a user cannot enter C:\ to access e.g. the web.config or other files on the local server
  • Multilanguage

Of coarse the access to the files is security trimmed. Meaning that if your users would not be able to access files with their logon from their client, they won’t be able from the Web Part!

Requirements

For authorization against the fileserver, the credentials of the currently logged on user is used. For SharePoint (and any other application as well), it is necessary to configure the WebApplication which is hosting the Web Part to use Kerberos instead of NTLM. Otherwise a server cannot pass the user credentials forward to a second server. This is called the “Double-Hop problem”. To get a glimpse about the topic, take a look at an article I wrote some time ago. Configuring Kerberos for SharePoint. That post has been written for SharePoint V3! But thereimage are plenty of Kerberos Guides out there for SP 2010. And a whitepaper from Microsoft: Configuring Kerberos Authentication for SharePoint 2010 Products http://technet.microsoft.com/en-us/library/ff829837.aspx

If you do not configure Kerberos for the WebApplication, the Web Part will detect that, and show a notification in the properties section.

A small sidenote: If you are going to use local paths (meaning a folder on your SharePoint server), you can continue using NTLM. 

Another good starting point for Kerberos-Troubleshooting can be found here: http://blogs.msdn.com/b/friis/archive/2009/12/31/things-to-check-when-kerberos-authentication-fails-using-iis-ie.aspx

Configuration

image

To use the WebPart, you’ll need to at least configure a path. Files – and subfolders – from that path will be shown.

Additionally, there are some properties, which modify features of the Web Part.

The Paging size defines, how many files are displayed on one page. With the next three checkboxes, you can allow files to be downloaded as zip, allow files to be uploaded and to be deleted.

I recommend to leave the caching activated. Deactivate only, if you have specific reasons, because there will be more todo for your SharePoint server and fileserver.

Using a local path as source

In case you want to use a local path as source for the Web Part, you have to allow the path to be used. To do so, follow the steps below.

  1. locate the feature.xml file ("C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\FEATURES\FileserverAccess\Feature.xml")
  2. Edit the file in your favorite editor
  3. Look for the property with the key “AllowLocalPaths” and modify the value to correspond to the driveletter you wish to use
    image
    Replace “Driveletter” with e.g. “C”. You can specify more than one drive letters. In that case use a “;” as divider
  4. Save the feature.xml
  5. Restart your IIS (iisreset)

Remember that you’ll need to modify the file on all of your FrontEnd SharePoint Servers! After an upgrade of the Web Part, the file has to be modified again. If you do not allow local drives, the Web Part will show an error.

image

This version is compatible to the old version. So you can simply upgrade the solution and benefit of the new features!

Download the new version for SharePoint 2010 (Foundation and Server): RH.FileserverAccess.wsp

Download the old version for WSS V3 / MOSS 2007: RH.FileserverAccess.wsp

Update March 2012

  • I did not get the Web Part working in my claims based authentication test-environment. Additionally, the Web Part properties will show the current user and authentication method. If you see Negotiate, your environment is set up correctly (for classic authentication).

imageimage

  • Another small update, which prevented the upload from working in Chrome

Das neue Jahre bringt neue Aufgaben

Nach fast 8 Jahren bei der Firma Net at Work, startet für mich ein neues Kapitel. Auch auf diesem Wege möchte ich mich noch einmal bei allen Kollegen und Kunden für die Zusammenarbeit bedanken.

Ab heute hat es mich beruflich nach Berlin verschlagen. Dort habe ich bei der ITaCS angedockt. Ich freue mich auf neue Projekte und Herausforderungen.

Ach ja. Ich wünsche allen Lesern ein Frohes Neues Jahr!

Update: WarmupScript

A long time ago, I posted a program which will hit all your sites. With parameters you can specify to hit all sites within a sitecollection.

image

This program has been updated. You can not omit a start Url, and specify “Farm” as parameter. This way, all sites in all sitecollections in all webapplications in all… 🙂 will be warmed up.

The warmup will use a HttpRequest to query all homepages. It will not hit every page in the pages libraries, but hitting each web is sufficient for most scenarios.

One thing to mention. If you want to warmup your Central Administration, you’ll have to call the program with the Url, as the CA will not be included in the webapplication enumeration of a SharePoint farm.

Usage:

WarmupSharePoint http://your.server.url [AllSites] – will hit one site only, unless the AllSites parameter is specified. Then all sites will be dealed with.

WarmupSharePoint Farm – iterates through all sitecollections and hit all sites within

Download the program
Download the sourcecode

What to know about the feature folder

One of the first things I used to tell guys new to SharePoint development is: Never ever name the folder of your feature “Feature1”. If you create a solution with WSPBuilder, or did some time ago with VS 2008, you have to rename the folders immediately!

image

This is how a typical SharePoint project looks like, if you create features. I guess most of us have used the mighty WSPBuilder (http://wspbuilder.codeplex.com) for developing with SharePoint.image

After building the VS solution and creating a WSP package with WSPBuilder, the wsp contains two folders. They reflect the names, we defined in VS.

 

 

Now lets take a look at the same features in a Visual Studio 2010 SharePoint Solution.

image

It almost looks the same as a WSPBuilder solution in VS 2008.

The features have been created by right-clicking on the Features folder in the Solution Explorer. This is important.

In many places VS uses tokens to replace strings with certain solution specific values like the assembly name. You can take a look at the tokens here: Replaceable Parameters

If we look at the wsp again, we notice the difference. Visual Studio 2010 hasimage added the solution name as prefix to the feature folders. Great. Thank you Microsoft. Now we can name our feature folders e.g. after the scope. (Site, Web, Webapplication of Farm), and do not have to worry about duplicate names.

The magic of this can be seen, if we take a look at the properties of the feature folders.

image

Conclusion: VS 2010 is a great improvement to us SharePoint developers. We don’t have to know all the places where it helps, but it can’t hurt, either. I hope this article brings a little light to the magic 🙂

Use Powershell ISE for SharePoint 2010

To be able to use the ISE for SharePoint, you can configure it to load the SharePoint cmdlets automatically.

Scot Hillier wrote a great article about it. Read “Setting up PowerShell ISE for SharePoint 2010”.

If you only want to use the SharePoint cmdlets once, you can register them with this two lines:

If ((Get-PSSnapIn -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null )
{ Add-PSSnapIn -Name Microsoft.SharePoint.PowerShell }

SharePoint 2010 and HTML5

“v5.master” is a simple HTML5 master page designed for SharePoint 2010. It makes good use of the amazing new features of both HTML5 and CSS3, including CSS3 media queries. The master page is extremely simplistic in nature, and is truly meant to serve as a framework for building your own SharePoint 2010 customizations.

Here comes some good news for SharePoint and HTML 5. If you want to build your masterpage for HTML 5, you can: http://kyleschaeffer.com/sharepoint/v5-responsive-html5-master-page/

Thank you, Kyle!

Updates for SharePoint 2010 Products, changed update strategy!

The latest updates can be found on this technet website: http://technet.microsoft.com/en-us/sharepoint/ff800847

I was looking for the August 2011 updates. They are not released yet. But I found an interesting text on the page:

The packaging of cumulative updates changed as of August 31, 2011. The following packages are provided for cumulative updates:

  • SharePoint Foundation 2010
  • SharePoint Foundation 2010 + SharePoint Server 2010
  • SharePoint Foundation 2010 + SharePoint Server 2010 + Project Server 2010

As a result of the new packaging, it is no longer necessary to install the SharePoint Foundation cumulative update and then install the SharePoint Server cumulative update.

That’s great news! Thank you Microsoft!

Mastering your Hyper-V R2 Core Server

If you like – and use – Hyper-V is out of scope of this post. So let’s assume you have a Hyper-V core installation, as it is free and works great 🙂

Microsoft® Hyper-V™ Server 2008 R2 is a stand-alone hyper-visor based virtualization product which includes Live migration.

Download: http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=3512 (about 1GB)

OK. That was the marketing part.

Many people have great respect for a server, which has no GUI. At least not the way we know “Windows Servers”.

Well, at least for managing your VMs, there are some tools out there. One of them is the PowerShell Management Library for Hyper-V, available on CodePlex. It will give you great control over VMs on your server. And… it has a GUI (kind of), which can be started with “Show-HyperVMenu”:

image

Starting, Stopping and changing the configuration is now possible, without using the Hyper-V Management Console.

The module for PowerShell can be installed by calling a batch file. It works smooth, and does what is needed to manage Hyper-V via PowerShell.

get-command -module HyperV will show all available commandlets. As always (with PowerShell), a get-help commandname shows some help for the commandlet.

Update July 2012

The command for showing the GUI above is “Show-HyperVMenu”

StaticName != InternalName

Recently I was trying to fetch a SPField from a SPWeb object. I had SharePoint 2010, so I decided to use the new SPFieldCollection.TryGetFieldByStaticName() Method.

image

You can imagine how surprised I was, that I couldn’t get the field I was looking for. What do we learn? Well, the StaticName of an SPField is not necessarily the InternalName!

Here is a link to the MSDN about SPField.StaticName: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfield.staticname.aspx

Watch out for ContentTypeBindings

If you don’t know ContentTypeBindings, take a short look at: http://msdn.microsoft.com/en-us/library/aa543598.aspx

“Content type binding enables you to provision a content type on a list defined in the onet.xml schema.”

So we can assign content types to newly created lists. That’s cool 🙂  The ContentTypeBinding feature can, of coarse, contain multiple content types which are bound to multiple lists. Like this:

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   <ContentTypeBinding 
      ContentTypeId="0x0100yourGuid" 
      ListUrl="Pages" />
   <ContentTypeBinding 
      ContentTypeId="0x0100anotherGuid" 
      ListUrl="Pages" />
   <ContentTypeBinding 
      ContentTypeId="0x0100yetAnotherGuid" 
      ListUrl="Lists/YourList" />
</Elements>

There is however, a limitation! Do not configure more then one ContentTypeBinding feature for a newly created page! You will get a save conflict Exception, when you provision a new web.

If you are curious how the feature gets referenced, take a look at this page: Understanding Onet.xml files

<Configurations>
   ...
   <Configuration ID="0" Name="Default">
      <Lists>
         ...
      </Lists>
      <Modules>
         <Module Name="Default" />
      </Modules>
      <SiteFeatures>
         ...
      </SiteFeatures>
      <WebFeatures>
         <!-- a ContentTypeBinding feature -->
         <Feature ID="6BB8BC13-987F-4668-9A63-E42F1CC03C44" />
         <!-- do NOT add another ContentTypeBinding feature! -->
         <Feature ID="CFAF8323-0CC5-4426-A33D-5B6A0AD72F96" />
      </WebFeatures>
   </Configuration>
   ...
</Configurations>