Applications

Using non-CLS compliant types in PowerShell

Not all classes in the SharePoint API are CLS-compliant types.  While using a language like C#.NET it does not matter since the .NET framework knows how to work with these classes.  Working in PowerShell is a completely different story.  PowerShell does not differentiate between the various cases of names of objects, properties, or methods.  This can become apparent rather quickly when, for example, you want to change the maximum site collections allowed in a content database by using a PowerShell script.  This may seem like a relatively simple task since the SPContentDatabase type has a property called MaximumSiteCount of type int32, right?

The problem is that the SPContentDatabase has two methods for the id property (ID and Id) making it non-CLS compliant – PowerShell can’t differentiate between ID and Id.  As soon as an instance of an SPContentDatabase is referenced, you will get an ugly message like:

$siteCol.ContentDatabase.MaximumSiteCount = 1
The field/property: "Id" for type: "Microsoft.SharePoint.Administration.SPContentDatabase" differs only in case from the field/property: "ID". Failed to use non CLS compliant type.

The way that you have to work around this issue is to get a handle to the type’s property using reflection and then invoke the SetValue() method.

$maxProp = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("MaximumSiteCount")
$maxProp.SetValue($siteCol.ContentDatabase, 1, $null)

If you want to get the property value:

$returnVal = $maxProp.GetValue($siteCol.ContentDatabase, $null)

To invoke a method of the non-CLS compliant type you must get a handle to the method instance and use Invoke.  The following example gets a reference to a method that has multiple overrides and gets the instance of the method that takes no parameters.

$update = [Microsoft.SharePoint.Administration.SPContentDatabase].GetMethod("Update", @())
$update.Invoke($newSite.ContentDatabase, "instance,public", $null, $null, $null)

If you want to get the instance of a method that uses parameters, you must get the handle to the method using an array of types that match the signature of the overridden method.  The following example gets the instance of a method that takes a Boolean parameter.

$boolType = [System.Boolean]
$typeArray = , $boolType
$trueArray = , $true
$update = [Microsoft.SharePoint.Administration.SPContentDatabase].GetMethod("Update”, $typeArray)
$update.Invoke($newSite.ContentDatabase, "instance,public", $null, $trueArray, $null)

To complete this example, below is the snippet of PowerShell script that will set parameters on an SPContentDatabase and update it.

$warnProp = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("WarningSiteCount")
$warnProp.SetValue($newSite.ContentDatabase, 0, $null)

$maxProp = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("MaximumSiteCount")
$maxProp.SetValue($newSite.ContentDatabase, 1, $null)

$update = [Microsoft.SharePoint.Administration.SPContentDatabase].GetMethod("Update", @())
$update.Invoke($newSite.ContentDatabase, "instance,public", $null, $null, $null)

7 Comments

  1. Marco March 1, 2010
  2. George Bonney March 13, 2010
  3. Florian April 27, 2010
  4. Raymond Mitchell October 27, 2010
  5. Matthias Weh February 16, 2012
  6. Bill S December 19, 2012
  7. Bill S December 19, 2012

Leave a Reply

x

We use cookies to ensure the best possible experience on our website. Detailed information on the use of cookies on this site is provided in our Privacy and Cookie Policy. Further instruction on how to disable our cookies can be found there.