PowerShell: Cast Object Type

If you load an CSV file with import-csv you will end up with an object of type System.Management.Automation.PSCustomObject. It’s an array.

In such a case I liked to use such an imported file or especially the imported data with the correct object type.

Therefore I created an generic “cast” function in generic PowerShell that can be used for casting with other types.

See the following PowerShell script. The function “Get-CastedObject” takes to parameters:
1) the source array
2) the result object type as string

In the following sample the script creates a CSV file and reads the content of the file during the next run. After loading the data the objects of the array will be “casted” to the correct data type.

Therefore the cast function looks for the “property” object members and tries to assign them to the new created object of the expected result type.

I’m sure there are several opportunities for improvements. Please let me know!

$outfile = C:tempcast-test.csv

Add-Type @’
public class ResultObj
{
public string Test1 = “”;
public string Test2 = “”;
public bool   Test3 = false;
public int    Test4 = 0;
}
‘@

function Get-CastedObject
{
param(
[Parameter(Mandatory
=$true)] [object]$inputObject = $null,
[Parameter(Mandatory
=$true)] [string]$resultType = $null)

if($inputObject -isnot [System.Management.Automation.PSCustomObject] ) {
return $null
}

if($resultType -eq $null ) {
return $null
}

$resultObject = new-object $resultType

$inputObject |gm | ? {$_.MemberType -eq NoteProperty } |% {
Invoke-Expression $(`$resultObject.+$_.Name+ = `$inputObject.+$_.Name )
}

$resultObject
}

$ErrorActionPreference = Continue

if( @(get-childitem $outfile).count -gt 0 )
{
$global:imp = (Import-Csv -Delimiter ; -Path $outfile )
}

$l = @();

$imp | % {$l = $l + (Get-CastedObject $_ ResultObj)  }

$r = New-Object System.Random

for($i=0;$i -lt 10;$i++ ){
$obj = New-Object ResultObj
$obj.Test1 = Test + $l.Count.ToString()
$obj.Test2 = ([System.DateTime]::Now).ToString(HH:mm:ss)
$obj.Test3 = &{if( ($r.NextDouble())-lt 0.5 ) {$true }else {$false } }
$obj.Test4 = [int]$r.Next()
$l = $l + $obj
}

del $outfile -ErrorAction SilentlyContinue
$l |Export-Csv -Delimiter ; -Path $outfile -Encoding utf8 -Force -NoTypeInformation

Please notice my disclaimer in the right sidebar!

Project Server 2010: Error Message “Could not retrieve enterprise global template. Please contact your administrator.”

 

After renaming my SharePoint 2010 from an old to a new URL I could not longer access any project from this server.

The error message looked like this:

“Could not retrieve enterprise global template. Please contact your administrator.”

I could solve the problem by removing the existing Project Server Account connections in the registry:

HKEY_CURRENT_USERSoftwareMicrosoftOffice14.0MS ProjectProfiles<[1..n] project server connections as sub keys>

Before that I copied the URL from the “Path” value under the registry key.

Then I recreated the Project Server Account by using Microsoft Project’s tool.

 

Please notice my disclaimer in the right sidebar!

FileNotFoundException while developing an external SharePoint application

If you develop a SharePoint Application with Visual Studio 2010, e.g. a Console Aplication, you may get an FileNotFoundException.

For example in this code (program.cs):

namespace DemoConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
           SPSite site = new SPSite("http://sharepoint.local");  //<<--- FileNotFoundException
           SPWeb web = site.RootWeb;
           //your code here

        }
    }
}

I’ve maked the line of code where you may receive the exception.

I solved the problem by setting the platform target in the project settings: Go to “project settings”, select “Build” tab, set “Platform target” setting to the architecture of your platform. I always use “x64” there. – After that the exception is gone.

Activate Claim Based Authentication afterwards with PowerShell

You can active Claim Based Authentication for a SharePoint Web App afterwards if you missed that at creation time.

Use this PowerShell script:

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
[System.Reflection.Assembly]::LoadFile($Env:CommonProgramFiles+"Microsoft SharedWeb Server Extensions14ISAPIMicrosoft.SharePoint.dll") | out-null

$webapp = Get-SPWebApplication "http://<sharepoint server>/"
write-host "Current: " $webapp.UseClaimsAuthentication
$webapp.UseClaimsAuthentication = $true
$webapp.Update()

$webapp.ProvisionGlobally()

write-host "    New: " $webapp.UseClaimsAuthentication

Enable CollectSPRequestAllocationCallStacks with PowerShell

I got this message in the ULS log:

An SPRequest object was not disposed before the end of this thread. To avoid wasting system resources, dispose of this object or its parent (such as an SPSite or SPWeb) as soon as you are done using it.  This object will now be disposed.  Allocation Id: {646667A7-73BC-4DDD-B0FB-6EDFC315CCE7}  To determine where this object was allocated, set Microsoft.SharePoint.Administration.SPWebService.ContentService.CollectSPRequestAllocationCallStacks = true. 

The following PowerShell script will do that for me – and you 🙂

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
[System.Reflection.Assembly]::LoadFile($Env:CommonProgramFiles+"Microsoft SharedWeb Server Extensions14ISAPIMicrosoft.SharePoint.dll") | out-null

# Get Content Service of the farm
$contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService

# Display and change the setting of property "CollectSPRequestAllocationCallStacks"
write-host "Current: " $contentService.CollectSPRequestAllocationCallStacks 
$contentService.CollectSPRequestAllocationCallStacks = $true
$contentService.Update()

write-host "    New: " $contentService.CollectSPRequestAllocationCallStacks 

Add web.config Modification with PowerShell (SPWebConfigModification)

Here is a script I used to add some web.config modifications with PowerShell. In this case I want to add a custom authentication provider. – The following script I used for setup purpose.

# Load SharePoint PowerShell PSSnapIn and the main SharePoint .net library
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$sharePointDLL = $ENV:CommonProgramFiles+("Microsoft SharedWeb Server Extensions14ISAPIMicrosoft.SharePoint.dll")
[System.Reflection.Assembly]::LoadFile($sharePointDLL) | out-null

# Show Farm BuildVersion to ensure the SharePoint .net library is loaded
$localFarm = [Microsoft.SharePoint.Administration.SPFarm]::Local
$localFarm.BuildVersion

# store some settings and objects in variables
$webapp = [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup($url)
$farmServices = @($webapp.Farm.Services | where-object { $_.TypeName -eq "Microsoft SharePoint Foundation Web Application" } )[0]
$assembly = "MyAuthenticationProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxx"

# Remove old web.config modifications of MyAuthenticationProvider
$oldMods = @();
$webapp.WebConfigModifications | where-object { $_.Owner -eq "MyAuthenticationProvider" } | foreach-object { $oldMods = $oldMods + $_}

$oldMods | foreach-object{ $webapp.WebConfigModifications.Remove($_) }

# update the Web Application and apply all existing web.config modifications - this executes the "remove" actions from above
$webapp.Update()
$farmServices.ApplyWebConfigModifications()

# New web.config modifications for MyAuthenticationProvider
$myModification1 = new-object "Microsoft.SharePoint.Administration.SPWebConfigModification"
$myModification1.Path = "configuration/system.web/membership/providers"
$myModification1.Name = "add[@name='MyAuthenticationProvider'][@type='MyAuthenticationProvider.MyMembershipProvider, " + $assembly + "']"
$myModification1.Sequence = 0
$myModification1.Owner = "MyAuthenticationProvider"
$myModification1.Type = 0           #for the enum value "SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode"
$myModification1.Value = "<add name='MyAuthenticationProvider' type='MyAuthenticationProvider.MyMembershipProvider, " + $assembly + "' />"
$webapp.WebConfigModifications.Add($myModification1)

$myModification2 = new-object "Microsoft.SharePoint.Administration.SPWebConfigModification"
$myModification2.Path = "configuration/system.web/roleManager/providers"
$myModification2.Name = "add[@name='MyAuthenticationProvider'][@type='MyAuthenticationProvider.MyRoleProvider, " + $assembly + "']"
$myModification2.Sequence = 0
$myModification2.Owner = "MyAuthenticationProvider"
$myModification2.Type = 0           #for the enum value "SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode"
$myModification2.Value = "<add name='MyAuthenticationProvider' type'MyAuthenticationProvider.MyRoleProvider, " + $assembly + "' />"
$webapp.WebConfigModifications.Add($myModification2)

# Update the Web Application and apply all exisiting web.config modifications including the new from above

$webapp.Update()
$farmServices.ApplyWebConfigModifications()

Please notice my disclaimer in the right sidebar!

“TaxonomyPicker” failed to load – Error in Event Viewer

After updating the SharePoint Foundation 2010 Server of our company to SharePoint Server 2010 I got this error in the Event Viewer:

Load control template file /_controltemplates/TaxonomyPicker.ascx failed: 
Could not load type 'Microsoft.SharePoint.Portal.WebControls.TaxonomyPicker' 
from assembly 'Microsoft.SharePoint.Portal, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'.

I could solve this error by re-enabling the corresponding feature using this PowerShell script:

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
[System.Reflection.Assembly]::LoadFile($Env:CommonProgramFiles+"Microsoft SharedWeb Server Extensions14ISAPIMicrosoft.SharePoint.dll") | out-null
Get-SPWebApplication -IncludeCentralAdministration | get-spsite | foreach-object { enable-spfeature "73ef14b1-13a9-416b-a9b5-ececa2b0604c" -force -url $_.Url -Verbose }

Note: The first to lines of the script enable are “standard lines of code” for me. They enable SharePoint PowerShell support if you use the Script without “SharePoint 2010 Management Shell”.