Add SSO apps with Powershell MOSS 2007 aka strange powershell syntax

27 February 2011 roelhans Geen reacties

The setting
At the moment I am working for a client that has quite a lot of applications that require SSO in SharePoint 2007 to function in their Intranet. If you need to know what SSO in SharePoint 2007 is, please follow this link. In a big enterprise it is important to create reusable stuff for development, test, acceptance and production environments. This is where my friend Powershell comes in. Powershell scripting provides the opportunity to reuse script and settings in those environments in a repeatable way. So I decided to go and script to create the desired SSO applications.

I assume some familiarity with Powershell and the SharePoint Object Model here. The namespace Microsoft.SharePoint.Portal.SingleSignon contains the desired properties and methods to create the SSO applications in SharePoint 2007. So first thing we do is create a reference:

[System.Reflection.Assembly]::LoadWithPartialName
("Microsoft.SharePoint.Portal.SingleSignon")

So now we have a reference and I thought everything would be straightforward. I looked up the SDK and figured I needed to create an array of ApplicationField and create an ApplicationInfo object. Feed that to the AddApplication method and hey presto all is done. Oh no….no.no.no. So I went to work in PowerGui, which has Intellisense. So I get to the ApplicationField by typing:

$field1 = new-object Microsoft.SharePoint.Portal.SingleSignon.Application.ApplicationField("foo", $true)

All I got was this error saying that ApplicationField cannot be found. Hmmm it is there according Visual Studio and the SDK. So i tried just by typing in the PowerShell console:

$field1 = new-object Microsoft.SharePoint.Portal.SingleSignon.Application
$fied1 | Get-Member

The problem
Hmm ApplicationField appears to be missing. It is a type in the type Application type. Googled a bit around, talked a bit with my coworkers. Fired up Reflector. Using Reflector I noticed the plus sign in the namespace.

reflector showing the nested type

reflector showing the nested type

Turns out it is a nested type and as PowerShell uses reflection in the reference you must also create the object on a nested type with a plus sign. So the correct code is:

$field1 = new-object Microsoft.SharePoint.Portal.SingleSignon.Application+ApplicationField("foo", $true)

The solution
Hey presto it worked! In the namespace there are quite some members that are nested types. The finished script looks like this:

(I’ve added the code here as the long code lines will not properly wrap. If you know a fix please let me know.)
code_sso_powershell

# Load a bunch of assemblies that are needed for creating the sso apps
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Portal.SingleSignon")

Write-Host "Creating SSO application" -ForegroundColor Green
[xml]$config = Get-Content settings.xml

# create an array of appfields
# note the plus syntax in the constructor
$field1 = new-object Microsoft.SharePoint.Portal.SingleSignon.Application+ApplicationField($config.xml.appinfo.appfield1.value, [System.Convert]::ToBoolean($config.xml.appinfo.appfield1.mask))
$field2 = new-object Microsoft.SharePoint.Portal.SingleSignon.Application+ApplicationField($config.xml.appinfo.appfield2.value, [System.Convert]::ToBoolean($config.xml.appinfo.appfield2.mask))
$field3 = new-object Microsoft.SharePoint.Portal.SingleSignon.Application+ApplicationField($config.xml.appinfo.appfield3.value, [System.Convert]::ToBoolean($config.xml.appinfo.appfield3.mask))
$field4 = new-object Microsoft.SharePoint.Portal.SingleSignon.Application+ApplicationField($config.xml.appinfo.appfield4.value, [System.Convert]::ToBoolean($config.xml.appinfo.appfield4.mask))
$field5 = new-object Microsoft.SharePoint.Portal.SingleSignon.Application+ApplicationField($config.xml.appinfo.appfield5.value, [System.Convert]::ToBoolean($config.xml.appinfo.appfield5.mask))
[Microsoft.SharePoint.Portal.SingleSignon.Application+ApplicationField[]]$appfields = ($field1, $field2, $field3, $field4, $field5)

# create the application info data

# set the type of the application
switch ($config.xml.appinfo.grouptype) {
"Individual" {$appType = [Microsoft.SharePoint.Portal.SingleSignon.Application+ApplicationType]::Individual}
"Group" {$appType = [Microsoft.SharePoint.Portal.SingleSignon.Application+ApplicationType]::Group}
default {Write-Error "Could not determine type of the application"}
}

# to overwrite or not
switch ($config.xml.appinfo.disposition) {
"overwrite" {$appCreationDisposition = [Microsoft.SharePoint.Portal.SingleSignon.Application+ApplicationCreationDisposition]::Overwrite}
"new" {$appCreationDisposition = [Microsoft.SharePoint.Portal.SingleSignon.Application+ApplicationCreationDisposition]::CreateNew}
default {Write-Error "Could not determine overwrite or create new sso application"}
}

$appinfo = New-Object Microsoft.SharePoint.Portal.SingleSignon.Application+ApplicationInfo($config.xml.appinfo.name, $config.xml.appinfo.name,$appType, $config.xml.appinfo.email)
[Microsoft.SharePoint.Portal.SingleSignon.Application]::AddApplication($appinfo, $appfields, $appCreationDisposition)

Note that I use an XML file to supply the settings. The xml file looks as follows:

<xml>
<appinfo grouptype="individual" disposition="overwrite" name="myid2" displayname="myid2" email="roelhans@tsunami.nl">
<appfield1 value="test1" mask="false"></appfield1>
<appfield2 value="test2" mask="false"></appfield2>
<appfield3 value="test3" mask="false"></appfield3>
<appfield4 value="test4" mask="false"></appfield4>
<appfield5 value="test5" mask="false"></appfield5>
</appinfo>
</xml>

Of course it is pretty easy to add multiple settings in the xml file and have powershell read each appinfo node with a foreach-object loop. I’ll leave that one to you the reader however.

Conclusion
I hope you find this post insightful on how to set up SSO applications in SharePoint 2007. I suppose that this will also work in SharePoint 2010, I have not tested it however and there might be cmdlet out there that does this hard work for you. I also hope it has saved you some time on the strange syntax in PowerShell for nested types.

For now: happy scripting!

Categorieën:Geen rubriek, powershell Tags:

Sharepoint Timer Jobs and Microsoft Enterprise Library

18 September 2009 roelhans Geen reacties

I had a problem at one of my projects with a Sharepoint Timer Job. It was running fine for a while but after two months it started throwing errors. The code that creates sharepoint sitecollections is relying on the Enterprise library for things such as exception handling.

Since the unit test and web application ran fine I had not checked that the timer job processed the exceptions correctly. Turned out that exceptions did not get logged because the timer jobs run on their own context rather than in context of a webapplication. Hence the web.config settings for the Enterprise library could not be loaded. The unit tests have their own app.config but where would you place such settings for a SPTimer job?

Turns out it is pretty easy! Since the SPTimer job runs in context of the owstimer.exe in the bin directory of the Sharepoint 12 Folder you can add your own config settings file. If you already had a unit test in VS.NET with a correct app.config, then just copy that one to the Sharepoint 12/BIN folder, rename it to owstimer.exe.config and hey presto all your Enterprise Library settings will now load correctly. Remember to copy it to all Sharepoint servers where the timer job is running.

Thanks to Henk Drent and http://www.thesug.org/Blogs/mossmania/archive/2007/12/19/Using_a_Config_File_for_Windows_SharePoint_Services_Timer_Jobs.aspx.aspx for helping out on this one!

Moving Sharepoint farm databases from one db server to another

30 April 2009 roelhans 1 reactie

A client of the company I work for asked my collegue Ron (@ronlagerwaard) to move all sharepoint databases for two Sharepoint 2007 farms from a SQL Server 2005 db to a new SQL Server 2008 db. The procedure described in the Word document at http://www.microsoft.com/downloads/details.aspx?FamilyID=65686896-c171-46a8-a95f-54f43ad79952&displaylang=en did not work for him.

I had to do this for Sparked, the company I work for as we had a problem with our new SQL 2005 install so I had some experience with the difficulties involved. I tried a backup at farm level and then restore the backup on the newly created farm after detaching the farm and creating a new firm using psconfig.exe. Did this not work for me as the timer job for the backup restore never ran. This left me with the painful recreation of all config and webapplications by hand. It worked but it took a long time and is probably not workable for a big farm.

Ron came up with the alternative of using stsadm -o renameserver. Now I checked the documentation and it wasn’t exactly clear that this is used for the database server renaming. Turns out it was a great idea and it worked like a charm except for the index and search server settings messing up. We were able to fix that as well and here is the procedure we followed:

  1. server 1: create backup of all databases that are to be moved
  2. server 2: make sure that all accounts used for db access and rights as used on server exist on this server
  3. server 2: restore all databases on this server, making sure that right are correctly set
  4. Stsadm –o renameserver -oldservername server1 -newservername server2
  5. Reboot sharepoint and take all moved sharepoint databases offline on server 1
  6. stsadm -o osearch -action stop
  7. stsdm -o osearch -action start -role index
  8. Edit SharedService provider and provide the index settings
  9. reboot server
  10. Recrawl all content

This worked very well for us. There are some alternatives: Gary Lapointe on using sql alias as an alternative:

http://stsadm.blogspot.com/2008/06/moving-databases-easy-way.html.

Categorieën:Geen rubriek Tags:, , ,

Access denied when editing a task in Sharepoint Designer workflow

15 February 2009 roelhans 2 reacties

One of my collegues called me as she had a problem with a Sharepoint Designer Workflow. Three of the five workflows had a problem. When you logged in as a user and tried to edit the workflow task Sharepoint was throwing an access denied error.

I had a look and told here to restore rights inherintance. Unfortunately this did not solve the problem. So it was time to have another look. Nothing I could see was out of the usual in the workflows nor in the permission settings (task list, workflow history list etc). Even assigning full control to all users did not help. In this case: Google is your friend! Googled it and came up with this

Turns out that if you add a workflow with Sharepoint Designer, assign tasks to users in that workflow and add users afterwards, the rights are not properly set for those new users. Solution is to republish the workflow through Sharepoint Designer. Even if you publish to c: the workflow will run fine with proper rights afterwards. I am not sure if this is a bug or by design…

Categorieën:Geen rubriek Tags:

How to get TFS to build WSP with WSPBuilder

11 February 2009 roelhans 2 reacties

I usually use Subversion plus CruiseControl.NET and WSP Builder for automatic builds of WSP files for the Sharepoint DEV and TEST environments. Recently I have started a project for a customer that uses Team Foundation Server (TFS). Of course I wondered how to set up the same. Lo and behold it got twitted. So here is the link: http://blog.brianfarnhill.com/2008/12/30/how-to-get-tfs-to-automate-your-wsp-builds-with-wspbuilder/. Thanks @waldekm for bringing it to attention!

The thing that really shines for me is in step six: referencing if you have no MOSS installed on the build server. I have always used the first approach; dump the referenced dll in the GAC. I did not know about the possibilty of adding an extra reference path in the build project for TFS. Much more elegant than dumping it on the GAC.