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)