# Wednesday, March 18, 2009

It looks like the SharePoint team is slowly catching up to what the community has had for years in various guises on CodePlex, but I’ve a good feeling that sometime in the future, the community will finally be able to relax and get back to real work as official support will surpass even the best of the open source offerings (optimistic? we’ll see). Here’s the feature set for the current CTP:

(These are features added in v1.3 which were not available in v1.2 or v1.1)

· Support for developing and deploying on 64 bit (x64).

  • New menu commands within Visual Studio
    • Package - package the solution but does not deploy.
    • Retract - retracts and deletes the active solution from SharePoint.
    • Quick Deploy
      • Copy to 12 - copies template files, modules to the 12 Hive.
      • Copy Binarie(s) - deploys only the assemblies.
      • Copy Both
      • Recycle Application Pool
      • Attach to IIS Worker Processes
  • WSP View Improvements (Create New Feature)
    • Allows specify feature scope (Web, Site, Web Application, Farm)
    • Allows creation of a feature receiver
    • Option to automatically create elements.xml with new feature
    • Elements can be dragged from one feature to another
  • Build Commands Updates
    • Package command added to Visual Studio IDE and command line.
    • Retract command added to Visual Studio IDE and command line.

1) Command line operation is as follows:
devenv.exe <Project.csproj or Solution.sln and other usual flags> /deploy Debug
devenv.exe <Project.csproj or Solution.sln and other usual flags> /deploy Debug /package
devenv.exe <Project.csproj or Solution.sln and other usual flags> /deploy Debug /retract
Note that with the /package and /retract flags the /deploy flag is required.  

  • CTRL-F5 no longer launches the debugger. Use F5 to launch the debugger. CTRL-F5 will just launch the web browser and show the SharePoint site.
  • SharePoint Solution Generator Enhancements
    • Export from publishing sites. Note that round tripping of generated sites is not supported for anything but the simplest of sites. Instead some editing may be required.
  • Correct VB and C# Inconsistency Correction
    • VB VSeWSS projects no longer use VSeWSS as the root namespace
  • New Item Templates for RootFiles
    • Create a <RootFiles> item from template.
  • Web Part Item Template Improvements
    • Allows selection of deployment model to the global assembly cache (GAC) or to the \BIN directory. For /BIN deployment a simple Code Access Security permissions set is provided.
  • Easier Web Part Project Item Rename
    • Detect web part rename and modify dependent files
  • Support for deploying dependant assemblies added as a reference with CopyLocal=true.
    • VSeWSS now checks for any "CopyLocal=true" reference and incorporates this binary in the manifest.  The binary is added to the manifest with a DeploymentTarget matching the first binary found in the manifest, usually the project target binary.  Subsequent changes to "CopyLocal", or removing a binary altogether will correctly be cleaned up when rebuilding the manifest (either through WSP view or through a deployment command).  Changes to the DeploymentTarget can be made by editing the manifest.
  • Improved solution validation during full deployment
  • Validation Logging
    • Adding the element <add key="IfLog" value="true" /> to the <appSettings> node of your web.config will turn on validation logging. Logging occurs during a full deployment from a VSeWSS project and can be used for diagnostic purposes. Note: The log location will be noted on the build output window."
  • Conflict resolution dialog when deploying from within Visual Studio
    • Duplicate Features: If a feature with the same name as a feature you are trying to deploy is already on the server a dialog will give you the choice of uninstalling the existing feature first. If the feature was deployed via WSP the entire solution is retracted. If the feature was manually installed it will be deactivated then uninstalled.
    • Duplicate Site Definition Folders: Site definition folder is the same as 12/Templates/SiteTemplates or the WebTemp folder already exists. The option to delete the deployed folder is available.
    • RootFiles and Templates: If there is a RootFile or Template with the same name the option to delete the files first is given.
    • Solutions: If a solution with the same name exists on the server (possibly unique solution IDs) the option is given to retract and delete the existing solution.
  • The List Definition from Content Type template now allows for the creation of a List Definition Event Receiver.

Grab it from the Microsoft Download Center.

posted on Wednesday, March 18, 2009 10:48:40 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] Trackback
# Sunday, December 14, 2008

Now this is cool. I’ve always wanted to try out TDD, but as I’m primarily a SharePoint developer, a lot of the time my code is written on my laptop running XP, so I can’t actually test anything since SharePoint won’t install there. The folks at Bamboo Solutions came up with some clever hacks to get WSS 3.0 and MOSS running on Vista, but it’s a bit of a heavyweight solution, especially when you consider this:

Typemock are offering their new product for unit testing SharePoint called Isolator For SharePoint, for a special introduction price. it is the only tool that allows you to unit test SharePoint without a SharePoint server. To learn more click here.

The first 50 bloggers who blog this text in their blog and tell us about it, will get a Full Isolator license, Free. for rules and info click here.

Unfortunately the competition is actually over, but it’s still worth a peek!

posted on Sunday, December 14, 2008 6:58:36 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] Trackback
# Monday, November 03, 2008

I’ve been performing the “resolution” listed in this article since I first discovered the problem, but never ever did I think it was a “feature?” I was sure that I was just the unluckiest person alive and was always working with some dodgy permissions configuration of the 12 hive, but lo and behold, no. This is just the way it’s meant to be.

Anyone else think this is just pure madness? By default any forms you create in Visual Studio have a managed component. Hitting F5 to run deploy/debug won’t ever do the work for you either. Why isn’t this mentioned anywhere in any sort of official capacity? Anybody?


Managed code may not be executed if an InfoPath 2007 workflow form is deployed as a feature for a workflow

SYMPTOMS

Consider the following scenario. A Microsoft Office InfoPath 2007 workflow form contains managed code. The form is deployed as a feature for a workflow. In this scenario, the managed code may not be executed.

CAUSE

This issue occurs because a compiled DLL becomes part of the InfoPath form template (XSN) file when you create managed code behind an InfoPath form. Microsoft Office Forms Services does not extract a DLL by expanding the XSN file when the XSN file is installed by using the features functionality.

RESOLUTION

To resolve this issue, copy the compiled DLL to the same folder to which your feature XSN file was deployed.

http://support.microsoft.com/kb/930894/en-us

posted on Monday, November 03, 2008 4:51:58 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] Trackback

One thing I’ve noticed about the SharePoint callback-based Activities in Workflow is that they are extremely flakey if you try to reference the member variable reference for the owning Activity directly instead of casting the “sender” argument in the event handler itself. You have a SharePoint SetState Activity, for exmaple, along with the corresponding MethodInvoking hook and I don’t mean the State Machine transition Activity, but rather the SharePoint-specific Activity that lets you override the Workflow’s overall state string using the <ExtendedStatusColumnValues> metadata in Workflow.xml. In my case, I use the MySetState_MethodInvoking hook to set the state at runtime depending on several conditions. If I try to set properties on the workflow's MySetState member variable directly like this:

private void MySetState_MethodInvoking(object sender, EventArgs e) {
    this.MySetState.State = SPWorkflowStatus.Max + 2;
}

This just plainly doesn’t work reliably. It doesn’t throw any exceptions, in fact it looks to work just fine, except the state is not changed. The same seems to go for any other of the SharePoint interfaces that involve callbacks. In my experience, they just don’t work most of the time especially if the workflow dehydrates before the callback is invoked. This leads me to think that there are some quirky interactions going on internally that somehow cause the workflow to ignore your attempts to change anything, perhaps due to the workflow getting rehydrated after you have made the changes, or who knows. All I know is that if you want this stuff to work reliably, ALWAYS CAST THE SENDER to your target Activity before attempting to manipulate the owning Activity. Using the member variable is just flakey. If anyone has any information on this, let me know. This works reliably:

private vid MySetState_MethodInvoking(object sender, EventArgs e) {
    ((SetState)sender).State = SPWorkflowStatus.Max + 2;
}

Anyway, have fun.

posted on Monday, November 03, 2008 10:45:31 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] Trackback
# Tuesday, September 30, 2008

This is just a post containing all the issues I’ve run into over the last six months while working with MOSS Workflows, InfoPath and Visual Studio 2008/VSTO 3.0. I’ve been using these tools in this combination for a while now, but it’s only the last six months where I decided to take a note every time I ran into something. Don’t get me wrong though. This is more of a post aimed at helping others in their quest for abdominal hull-integrity while working with these tools, not attacking the toolset. Ultimately, the Office Suite and the corresponding tools are working together better than ever before, but unfortunately with large teams working relatively independently you’re just going to get these kind of problems. To be brutally honest, I think VSTO 3.0 is a saddle-sore on the otherwise supple and leathery hide of Visual Studio 2008 and the disparity in their respective product quality is way too pronounced to be ignored.

Anyway, I’m not going to make much attempt to explain each case for non-SharePoint people, but if you’re involved in this area, you’ll know where I’m coming from. The following list contains Glitches and Gotchas.

Glitches

First though, the Glitches, in no particular order. These are the lovingly hand-crafted defects and “product quality issues” that will first cause your stomach muscles to contract somewhat, then violently spasm so hard that that first loop of intestine will pop out to nestle amongst the fat cells and veins in the fleshy meadow of your lower-epidermis. Don’t say I didn’t warn you.

Publish an Installable Form Template (requires Visual Studio)

vs2008-vs-not-installed-properly

If you try to publish a form as "an installable template (requires visual studio)" from within Visual Studio 2008 (even with sp1), VSTO, in its infinite wisdom tries to use visual studio 2005 devenv.exe executable to do it! And it fails spectacularly 'cos it's not installed, or if it is installed it's part of some vs-shell install for some other office app like office macros IDE, or Internet Explorer’s “script debugger” shell for example.

vs2008-infopath-vs2005

Publishing a Form to an explicitly-included Managed Path

Trying to publish a form to a SiteCollection sitting on an explicitly-included managed path fails with "getting the site content type columns failed." Workaround? Don’t publish forms to Managed Paths. It’s b0rked.

“An exception occurred during loading of business logic” - Publishing XSNs with CodeBehind to SharePoint

If you perform a cursory search for the title, you’ll find lots of herniated VSTO users having issues with this. InfoPath Forms Services on MOSS Enterprise is a fickle beast; a beast that will have you tucking those intestinal loops back into your torso with a pencil before you can say “FileNotFoundException, whuh?”

XSN files are actually CAB files. When Forms Services loads them up to be rendered into Browser Forms, it has to load the embedded DLL into memory. It has an extremely hard time doing this sometimes. Particularly when you store your XSN files in a subdirectory under your workflow feature, say like one called Forms. It appears that the form loads ok, but Forms Services is looking for the DLL in the root of your feature. Even sometimes if you have the XSN in the root of your feature, it still won’t find and extract/load the embedded DLL. The only way to avoid this it appears is to manually extract the DLL and place it in the root of the feature yourself after you have deployed the workflow solution.

Some strange things I’ve observed about Forms Services on MOSS Enterprise:

  • Uploading a codebehind-XSN  file via central admin automatically extracts dll/pdb into feature directory but...
  • Deploying a codebehind-XSN with  workflow feature does not extract dll/pdb.
  • Upgrading a codebehind-XSN with central admin creates new subdir in feature folder, modifies feature.xml to point to it but does not extract the form's codebehind dll/pdb into new subdir either.

These seem to be some rather serious looking issues to me.

VSTO Designer ToolPane Content Shrinks

Occasionally the Design ToolPane in VS2008/VSTO inexplicably changes size, with the contents of it being set at about 1cm wide.b0rked-vsto-toolpane

A restart of Visual Studio or close/reopen of the project usually fixes this.
Workflow Designer Screws Up Layout of Nested States

The workflow designer in VS 2008 (even sp1) will screw up the formatting of nested states in a state machine workflow - they get randomly offset to the left or right so they are half occluded by the containing state. Yay.

Views ToolPane Is Blank For a Form that has Views

Views created in infopath sometimes do not appear in vs2008 project built around that imported XSN. Weirdly, the toolpane is completely white/blank. A restart of Visual Studio or close/reopen of the project usually fixes this.

Manipulating Files In “InfoPath Form Template” Project Folder Is a Bad Idea

Deleting/modifying/renaming a file in the "infopath form template" meta-folder in Visual Studio 2008 does not fix the reference in the manifest.xsf file. The form is then impossible to open until you fix the references within the manifest by closing the form designer and opening the XSF with the XML handler through a right-click. Why does VSTO even let you modify embedded resources if it won’t update the manifest for you?

The magical secondary DataSource ItemMetadata.xml

The secondary DataSource (for receive data) ItemMetadata.xml has _two_ ways of being added as a resource - the second way (prompted at end of import). You can either add it as a resource when you initially point VSTO/InfoPath at it, or if you don’t do it then you get a second chance at the end of import to add it as a resource. This is confusing.

Converting an embedded DataSource to site-relative format and placing into a  Data Connection Library can leave the required field "Title" empty

This enforces the UDCX files to be permanently checked out - trying to update the title field by hand does not work - it remains blank at every attempt to change it when done directly or via bulk edit DataGrid view. It sometimes exclaims that the files are checked out to another user even though they are plainly checked out to me. Worst of all, only *I* can use the InfoPath form that uses this DataSource so it’s starts out a looking like “it works for me” issue.  Anyone else cannot use the form - DataSource loading fails - ULS log says "root element is missing" - after much debugging, it appears that anyone (apart from me the author) attempting to download the UDCX file gets a 0 length file - you can test this by getting the poor user to try to download the UDCX from the connection library. This is because only an author of a checked-out file can read it. 

Hacky Fix: Remove ReadOnly attribute from the list-level UDCX content type and mark the Title column as optional, then check-in the connections. Title be damned!

This all started when I enabled Versioning for the connection library before converting my data sources. Not sure if that’s relevant.

BDC randomly losing ServerContext while inside Event Receiver triggered from Workflow context

The TLS slot for the resource provider SqlSessionProvider sometimes ends up being null on the Event Receiver's thread. If you’re not following me, you probably don’t need to understand this any further.

Gotchas

These are not so much glitches are they are things that can trip you up and/or be considered “non-obvious” behavioural quirks. While they may give you an upset tummy, you are not going to be trussed up in a Spigelian torso-bangle any time soon.

A Workflow Continually Spawns New Instances of Itself

When you have a workflow added to a document library and the workflow updates the list item when it is running, a new workflow will spawn once the .Update() method is executed on the list item. To update the item without having a new worklfow started, use .SystemUpdate(). Duh.

"The database returns an error. Failed to enable constraints." When InfoPath DataBinds

Changing the query directly in a UDCX file inside a data connection library may cause "The database returns an error. Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints" errors from live InfoPath forms because the data source schema in InfoPath no longer matches (especially if you increase the length of a returned field) - after you change the UDCX, you must go through the "manage data connections" and choose "modify" for that connection and go through the wizard without changing anything. This will cause InfoPath to re-sync the schema.

How The Hell Can I Render The Form Version On The Form Itself?

Tip: insert form version with the expression: substring-before( substring-after( /processing-instruction()[local-name(.) = "mso-infoPathSolution"], 'solutionVersion="'), '"')

I can’t remember where I got this, I didn’t write it myself. Thanks to the original author.

Why Can’t SharePoint Find My Forms for my Workflow?

The Form URN will change if you don't name your form exactly as you did (e.g. accept the default) in "file > form properties" when publishing it with the publishing wizard.

Why Can’t My Workflow Forms Find My Data Connections?

Site relative data connections stored in a data connection library work fine for InfoPath published forms bound to a content type in a site; also form security will stay at domain. But they can’t be found if these same forms are used in a workflow. Use “centrally managed” data connections instead.

Why Does Visual Studio Put Referenced DLLs Bound For the GAC Into My InfoPath XSN?

If you reference other feature projects in the same solution that deploy into GAC, be sure that they exist in the GAC before building the InfoPath project's XSN - if they are not in the GAC, they will be copied into the XSN by default. Duh.

How Do I Uninstall My Workflow I was Debugging In Visual Studio?

Workflow features deployed via vs2008 F5/start debugging have no obvious means of being "undeployed." you must use VSTO 1.0 PowerTools "Feature Sweeper" to remove it; this is a dependency for workflow forms registered in central admin.

Why Are The TaskProperties Hashtables So Weird?

ExtendedProperties Hashtables leaves root XML fields as keys, and nested xml as my:schema formatted XML for Hashtable values. Strangely, the Workflow API has a public XmlToHashtable method on a utility class, but not the inverse to pull it back out of ExtendedProperties. Duh.

Where The Hell Did The Form Publish Menu Disappear to?

You cannot publish the InfoPath form unless you have the designer open, even though you can only have one form per project and you might just have a single project in the solution. This is annoying when your forms are large and sluggish to open.

Why do some VS SharePoint Activities have a User (string) property and others a UserID (int) property?

I wish I knew. This is just another silly design (in)decision. All SPUsers in SharePoint have both a Login (string) and a PrincipalID (int). If you want to set the Logging Activity’s UserId (int) to the id of a person who performed a Workflow Modification User (string), you have to convert, persist and expose these properties yourselves before you can bind to an activity using the designer. Duh.

I use a method like this:

id = Contact.FromName(executor, this.workflowProperties.Web).PrincipalID;
Why is Visual Studio 2008  SP1’s Workflow Designer Host still such a dog?

You and thousands of other people would love to know the answer. IMHO, it’s too complex to have been written in Managed Code (e.g. C#). It should have been native C++ from day one. All that synchronizing intellisense, XOML and the visual designer is just too much for it. God help you if you throw in any real-time refactoring tools on top of that.

Summary

Despite all this moaning, SharePoint in conjunction with Visual Studio 2008 is a powerful combination. Nothing to be sniffed at all; I actually love it (most of the time.)

Have fun.

posted on Tuesday, September 30, 2008 2:19:44 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Tuesday, August 12, 2008

It’s getting harder to post useful scripting tips for PowerShell these days as there are so many talented hardcore scripting bloggers around. My day to day is job is not system/network/server administrator; I’m a .NET developer, having started the C# habit about eight or nine years ago with the early CLR 1.0 beta. So, from here on in, I’ve decided that a better direction for me to take from now on is that of a PowerShell developer,  as opposed to a scripter. There are very few (if any?) dedicated PowerShell developer blogs around, and so I figured I should try to fill that gap as best I can. I have a not insignificant amount of experience writing providers, cmdlets and other widgety bits, so it’s a good time to share my experiences. Of course, my way is not “the” way, so please reply with your own experiences/advice/mocking/whatever. ;-)

That said, I am not eschewing scripting altogether – I have some stuff in the pipeline (har-har) concerning areas I’m interested in, like eventing and jobs/remoting.

posted on Tuesday, August 12, 2008 10:03:20 AM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Thursday, June 12, 2008

Just a quick one for the frustrated searchers out there. If you've recently installed the SP1 beta for Visual Studio 2008 (or just the 3.5 sp1 beta alone), and you find that you have serious difficulty using SharePoint Designer 2007 against a remote instance of SharePoint running in a VM (or a physical machine) that doesn't have the SP1 Beta bits, you know what to do. My SPD would refuse to load the master page from my virtualized SharePoint instance until I had installed .NET 3.5 SP1 Beta onto the virtual machine also. Just so you know!

posted on Thursday, June 12, 2008 1:41:52 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [1] Trackback
# Wednesday, March 05, 2008

Discovered while playing around with the new SPUserToken class and associated goodness that is the new impersonation APIs in WSS 3.0 / SPS 2007. from Reflector:

public static void SetApplicationCendentialKey(SecureString password)
{
    SPCredentialManager.CreateApplicationCendentialKey(password);
}

Ouch! how did that get past QA? there are only five methods on the class - looks like it was a late night for whomever wrote these bits. Unless I'm very much mistaken, shouldn't that read Credential?

microsoft.sharepoint.spsecurity.setapplicationcendentialkey

posted on Wednesday, March 05, 2008 7:50:44 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] Trackback
# Friday, February 29, 2008
Someone on the PowerShell usenet group asked if it was possible to interact with SharePoint lists through our favourite little shell. Marco Shaw responded and put the pressure on by saying this was my bag of tricks. Who am I to say otherwise? so lets take a look at the recipe.
posted on Friday, February 29, 2008 10:11:39 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] Trackback
# Thursday, February 14, 2008

My last post got me thinking about the problems experienced when trying to write culture aware software. Yeah, I know it was actually me that was unaware of the culture, but this time it's about the software end of the deal; in particular, the recently updated Microsoft Business Data Catalog Definition Editor for Microsoft's popular SharePoint 2007 server. If you read some of the comments on the blog, you'll see that various people (using a non US English version of Windows) have installed it and have come across a problem where the tool cannot find the local security group called "Builtin\Users." Oops. In the world of cutting-edge technology, people often install software that doesn't match the installed language of their O/S. The fact of the world is that all major symbolic computer languages are based around English, and the most popular software gets written in English first. Here in Quebec, Canada, French is the primary language with English coming second (Canada is officially bilingual - although most of the country only speaks English). Localization of software takes a fair amount of time. It's not just translating a resources file - there are hot-keys to reassign (the Bold shotcut in French MSWord is CTRL+G for example, bold being Gras in French) dialog boxes to resize, labels and controls to reposition etc. Some languages are more verbose than others and end up with text that won't fit. However, there are things you do to avoid certain problems -- lets take the issue above as an example.

Logins and Group names are just an abstraction in the Windows security subsystem. These things are actually represented by value called a SID ( system.security.principal.securityidentifier ). No matter what version of Windows you use, the SIDs for built-in accounts and groups are the same:

First using an en-US system:

  1. PS > $acc = new-object System.Security.Principal.NTAccount "Users" 
  2. PS > $acc.Translate( [System.Security.Principal.SecurityIdentifier] ).value  
  3. S-1-5-32-545 

and a French (fr-FR) system:

  1. PS > $acc = new-object System.Security.Principal.NTAccount "Utilisateurs" 
  2. PS > $acc.Translate( [System.Security.Principal.SecurityIdentifier] ).value  
  3. S-1-5-32-545 

As you can see, the SID is the same: S-1-5-32-545. An example of this is shown below - a simple If-Elevated function that takes two Scriptblocks: the first is executed if the user is running as an administrator, the second is running if the user is just a plain well, user:

  1. # Usage:  
  2. #  
  3. # If-Elevated { .. admin code .. } { "sorry, need admin" }   
  4. #  
  5.  
  6. function If-Elevated {  
  7.   param(  
  8.     [scriptblock]$AsAdmin = $(Throw "Missing 'as admin' script"),  
  9.     [scriptblock]$AsUser= $(Throw "Missing 'as user' script")  
  10.   )  
  11.    
  12.   $identity = [security.principal.windowsidentity]::Getcurrent()  
  13.   $principal = new-object  security.principal.windowsprincipal $identity 
  14.   $adminsRole =  [system.security.principal.securityidentifier]"S-1-5-32-544" 
  15.                   
  16.   if ($principal.IsInRole($adminsRole)) {  
  17.     & $AsAdmin 
  18.   } else {  
  19.     & $AsUser 
  20.   }  
  21. }  
So ok, it doesn't have localized messages, but at least it will execute correctly on other locales ;-) Have fun.
posted on Thursday, February 14, 2008 6:36:06 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] Trackback
# Wednesday, January 30, 2008

Some weeks ago, I started a new contract for a pretty monstrous MOSS (Microsoft Office SharePoint Server) 2007 project. The thing is, this is my first pure Francophone environment since I first came to Canada four years ago. As the agency is part of the Canadian Government -- and located in Quebec -- most of the software installed is the French version. The keyboards are fr-ca, Windows is French, and yep, SharePoint is installed in French. It's proving quite difficult to find my way around as the translations are not really comparable. Sometimes they are not even close. It's worse though, because a lot of the idioms are France-French, not Quebec-French. As Quebecers (and confused French people) will tell you, it can be quite a different language sometimes.

Today, it got a lot worse.

I found myself having to define a calculated column - that is to say, a cell in a list that performs calculations based on other cells in the row. You've got the usual SUM, AVG etc functions available. Only except this time I don't. After several frustration attempts, I discovered that the scripting language itself has been translated into French. At first my reaction was incredulity - what is the point of that? They don't translate C# for other cultures, so why do that? Surely this kind of functionality is aimed at power users, like Excel users! they don't translate the Excel formulas in other locales of Office?!

Except they do.

Merde.

posted on Wednesday, January 30, 2008 10:29:20 PM (Eastern Standard Time, UTC-05:00)  #    Comments [1] Trackback
# Wednesday, October 24, 2007

Someone on the newsgroup ran into an issue whereby a instance of a non CLS Compliant type was fed to PowerShell's default formatter. The type in question had two properties with the same name, but in different casing. I'm pretty much just going to carbon-copy the qestion and answer here as I feel this is worth preserving in the annals of blogdom.

> I am in the process of writing a script to document SharePoint
> installations.  When I try to get information about the content database
> I get this error.

> "out-lineoutput : 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."

> Here is some of the PowerShell Script that I am using

> [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
> $site = New-Object Microsoft.SharePoint.SPSite("http://localhost")
> $site.ContentDatabase

> It is the final line that is giving me the error.  I can get other
> properties without error.  Can someone enlighten me on this error
> message and let me know if there is a way to work around it.

> Thanks
> Jerry

Hi Jerry,

This is a tricky one for people very new to powershell without any real experience of the .NET framework. One of the rules of a so-called "CLS compliant type" (cls = common lanaguage specification) is that you should not expose any public members that only differ in casing. The SPContentDatabase type has two properties, "Id" and "ID." This is perfectly legal in C# since case in important in that language and the compiler sees them as different as chalk and cheese. However, in VB.NET, case is not important and as such it [vb] has no native mechanism to differentiate between the two. The same goes for PowerShell's grammar. So, how do we get around this?

First, you grab a handle to the method directly by asking for it from the Type itself:

PS> $idMethod1 = [Microsoft.SharePoint.Administration.SPContentDatabase].getmethod("get_ID")

and for the second version,

PS> $idMethod2 = [Microsoft.SharePoint.Administration.SPContentDatabase].getmethod("get_Id")

Note the differing case for get_Id and get_ID. Btw, Properties like ID in .NET are actually served by special accessor methods prefixed with get_ and set_, hence the prefixes. Next, you need a way to invoke those methods on the instance itself: this is done by using the Invoke method on the MethodInfo object representing the method itself. You pass the instance to the Invoke method telling it that the method is "instance" (e.g. not static/shared) and "public" and it will call that method for you on the instance, returning the value, if any.

PS> $result = $idMethod1.Invoke($site.ContentDatabase, "instance,public", $null, $null, $null)

I know from the SharePoint documenation, that this property returns a guid. Also, due to another oversight, Posh does not know how to format Guids, so you must call ToString() on the result to get the value back or you'll be greeted by a blank line from powershell's formatter.

PS> $result.ToString()
1ade149d-2049-4668-b555-4b7be9374c65

Bizarrely, these two properties return the same guid, but hey, I'll let someone from the sharepoint team answer that one. Anyway, you should have enough information here to extract the properties that you need.

So, that's the interesting portion out of the way. Another way to do this might be to create a custom view for the SPContentDatabase type omitting the duplicated property and use the Update-FormatData cmdlet to activate it. This may not work though, as the non-cls compliancy issue may rear it's ugly head before posh's formatter gets this far.

Hope this helps,

- Oisin / x0n.

posted on Wednesday, October 24, 2007 4:18:50 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Tuesday, August 14, 2007

I got tired of typing add-pssnapin blah, especially with Quest's AD snap-in's longer than usual name so I came up with a little script that enumerates registered snap-ins, and lists a simple numbered menu showing those that are not already loaded into memory. You just type the number and hit enter to load it. Enter on an empty line exits the script. Yeah, it's brain-dead, but hey, I think I was brain-dead to continually type long commands in every single session to load stuff ;-) 

UPDATE 2007-08-16: I was even more braindead than I realised - I copied up a broken version without the $notloaded array. Ooops. Fixed.

  1. write-progress "Enumerating Snapins" "Registered..."
  2. $snaps = get-pssnapin -r
  3.  
  4. write-progress "Enumerating Snapins" "Loaded..."
  5. $loaded = get-pssnapin | % {$_.name}
  6. $notloaded  = @()
  7.  
  8. write-progress "Enumerating Snapins" "Complete." -Completed # glitchy
  9.  
  10. $i = 0; "";
  11.  
  12. foreach ($snap in $snaps) {
  13.         if (-not($loaded -contains $snap.name)) {
  14.                 Write-Host -fore cyan -nonewline "${i}) "
  15.                 write-host -fore green $snap.name
  16.                     $notloaded  += $snap
  17.                 $i++
  18.         }
  19. }
  20.  
  21. if ($i -eq 0) {
  22.         Write-Warning "Any eligible snapins are already loaded."
  23.         exit;
  24. }
  25.  
  26. $i--;
  27. Write-Host -fore yellow "<enter> to quit"
  28.  
  29. do {
  30.         write-host -nonewline "Load 0 - ${i}: ";
  31.         $choice = [console]::readline()
  32.         if ($choice -and ($choice -lt 0) -or ($choice -gt $i)) {
  33.                 Write-Warning "'${choice}' is out of range!"
  34.                 continue;
  35.         }
  36.         if ($choice) {
  37.                 "loading $($notloaded[$choice].name) ..."
  38.                 add-pssnapin $notloaded[$choice]
  39.         }
  40. } while ($choice)


Just pop it into a function or a ps1 script.

You'll notice how when this is run from a clear screen, the progress bar disappears, then suddenly reappears and the first few menu items are hidden. This is a bug in the powershell.exe host. Vote on it here:

https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=291380&SiteID=99

 

posted on Tuesday, August 14, 2007 4:05:06 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [2] Trackback
# Tuesday, June 12, 2007

I like to see myself as a competent SharePoint developer having worked with it since beta 1 on various large scale projects, but it always bothered me that there were large swathes of it on which I was no expert, primarily due to one thing: CAML. It disgusts me - in fact, my brain downright rejects it. Every time I have to create some markup for a simple SPQuery, I have to look pull out the SDK reference material. CAML for me symbolizes everything bad that came out of the 1998-2001 "XML revolution," where absolutely everything had to be xml/xslt driven, where all wisdom concerning the separation of presentation and data disappeared in a puff of <smoke />.

It's not often that you see a new technology and you just "get it." No thinking required; instant grokkage. I thought I "got" LINQ, but it wasn't until today that I truely got it. So, I'm not sure if this qualifies as a "straw" as per the metaphor used in the title, perhaps a full-on hulking haybale would be more apt. Enter Bart de Smet's savegely impressive LINQ to SharePoint project on CodePlex. No more of the nausea-inducing verbosity that is CAML; just plain old C# 3.0.

posted on Tuesday, June 12, 2007 10:36:10 AM (Eastern Daylight Time, UTC-04:00)  #    Comments [1] Trackback
# Friday, January 05, 2007

So, happy new year everyone (read: both of you reading this blog) -- fyi, there's a powershell v1.0 binary compatible build of my SharePoint PSProvider up on codeplex now. I also filled out the Wiki with some information that was sorely lacking.

http://www.codeplex.com/PSSharePoint

posted on Friday, January 05, 2007 3:00:46 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] Trackback
# Saturday, November 04, 2006

As a sign that I'm trying to ramp up development (especially getting a MOSS 2007 layer working), I've snagged me a spot on the codeplex for this code. Feel free to ask for features, provide ideas, critique whatever on the forums provided. I'm also working on an ArchivePSProvider which will allow navigation of Zip and Tar files as hierarchical stores as well as providing some pipe-friendly cmdlets for tar/gzip/zip, e.g.  get-childitems -inc *.log | out-tar | out-gzip

posted on Saturday, November 04, 2006 8:40:42 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] Trackback
# Friday, October 20, 2006

No changes. Too busy at work. Argh. However, it now works with PS RC2. Argh.

(old binary removed) - latest version always at:
http://www.codeplex.com/PSSharePoint

I'm also trying to finish off zip, gzip, tar and bzip2 cmdlets along with an experimental tar/zip provider. Stay tuned, if you've got nothing better to do and a few months to spare. Honestly though, I hope to finish them before the end of the month. There's a warm bed waiting for them up on the CodePlex I'm told...

posted on Friday, October 20, 2006 3:52:28 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Thursday, May 25, 2006

Just released SharePoint SDKs; these look quite meaty -- The wss one weights in at nearly 34MB, compressed.

Windows SharePoint Services V3: SDK

This SDK contains conceptual overviews, programming tasks, samples, and references to guide you in developing solutions based on Microsoft® Windows® SharePoint® Services (version 3).
 
SharePoint Server 2007: SDK

The Microsoft Office SharePoint Server 2007 (Beta) SDK contains conceptual overviews, programming tasks, code samples, and references to guide you in developing solutions based on Microsoft® Office SharePoint® Server 2007.
 

I've also just installed the fresh Beta 2 releases on a virtual machine, so I'll be looking forward to porting my PowerShell SharePoint provider to v3...
posted on Thursday, May 25, 2006 12:15:59 AM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Friday, May 12, 2006

Hmm, I just realised that RC1 and RC1 Refresh have different build numbers and are not binary compatible. Here's another drop built for rc1 refresh, 1.0.9567.0:

(old binary removed) - latest version always at:
http://www.codeplex.com/PSSharePoint

posted on Friday, May 12, 2006 1:44:05 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Friday, April 28, 2006

Just some minor fixes, and the obvious API changes needed to be RC1 compatible. Source has been pushed the the MSH Community Extensions Workspace. For those of you who just want to play, you can get the latest binary at the bottom of this entry. Installation has changed slightly:

PS c:\temp> InstallUtil Nivot.PowerShell.SharePoint.dll
...
PS c:\temp> Add-PSSnapin Nivot.PowerShell.SharePoint
PS c:\temp> New-PSDrive wss SharePoint
http://mywss/
PS c:\temp> cd wss:
PS wss:\>

Apart from some minor refactoring, I've added some more actions to allow copy/move/delete between users/roles/groups and webs. Here's an example of how easy it is to define the operations for adding and removing users to a SPWeb using my generics-based provider model:

// add SPUser and place in Reader role by default
RegisterAdder<SPUser>(
    new Action<IStoreItem>(
        delegate(IStoreItem item) {
            SPUser user = (SPUser)item.NativeObject;
            NativeObject.Roles["Reader"].AddUser(user);
        }
    )
);

// remove SPUser
RegisterRemover<SPUser>(
    new Action<IStoreItem>(
        delegate(IStoreItem item) {
            SPUser user = (SPUser)item.NativeObject;
            NativeObject.Users.Remove(user.LoginName);
        }
    )
);

The above code allows the following to work:

   PS wss:\subweb> copy ..\!roles\contributor\username .

where . represents wss:\subweb, an SPWeb object.

Have fun!

Build RC1 Only, NOT RC1 Refresh -- for latest version see homepage 
Download: Nivot.PowerShell.SharePoint-0.51.zip (40.94 KB)

(edit: minor bug found -- v0.51 update)

posted on Friday, April 28, 2006 1:12:10 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Sunday, April 09, 2006

...released to GotDotNet's MSH Community Extensions run by Monad MVP Blogger, Keith Hill.

posted on Sunday, April 09, 2006 1:20:16 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Wednesday, April 05, 2006

So, another drop for you today:

It now supports infinitely complex paths, and copy/move/delete:
 
e.g.
 
     # clear all alerts for the 'username' found in the contributor role
   remove-item wss:\site\subsite\!roles\contributor\username\!alerts\*
 
   # make the cross-site group 'crosssitegroup' part of the administrator role
   copy !groups\crosssitegroup  !roles\administrator\
 
   # upgrade perms for 'crosssitegroup' from reader to contributor
     move !roles\reader\crosssitegroup !roles\contributor
 
Of course, wildcards work too, so let loose!
 
pseudo containers (will tab complete, but not show up in get-childitems):
 
   !alerts, !groups, !roles, !lists, !users
 
When in the context of certain containers, only a subset of these will appear. For example, when in the user container, only !groups and !alerts are available
 
containers:
 
   user, group, role, list
 
leaf:
 
  alert, listitem
 
I've implemented a handful of what I call "adders" and "removers" to allow basic copy/move/delete functionality between different types of compatible (and incompatible) paths. So, what do I mean by "incompatible?" For example, it is currently possible to do:
 
   move-item \!users\oisin \!roles\contributor\
 
So, what happens is the user oisin gets copied to the contributor role (ok) and then is removed from the source (not ok). In sharepoint terms, this makes oisin a contributor, and then removes him from the site users -- which also removes him from contributors :)
 
Since I plan to release the source when I get to a reasonable beta level, I don't want any dirty hacks. I'm taking the time to architect the copy/move/remove path rules properly, so as to give back a solid, reusable framework to the community.
 
Use with:
 
   installutil.exe nivot.monad.sharepoint.dll
   add-mshsnapin nivot.monad.sharepoint
   new-drive <drivename> sharepoint <url>    ( e.g. new-drive wss: sharepoint http://localhost/ )
 

(old binary removed) - latest version always at:
http://www.codeplex.com/PSSharePoint

posted on Wednesday, April 05, 2006 12:31:49 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Thursday, March 30, 2006

Update April 8th: for latest version -- see home page http://www.nivot.org/

This was a lot of pain; but through a combination of Lutz Roeder's Reflector, MDBG and tinkering, I've got a functioning NavigableCmdletProvider derived SharePoint provider working:

  • only supports Drive-Qualified operation at the moment
  • no support for copy,delete or move, yet.
  • each web exposes pseudo container paths of !Alerts, !Groups, !Lists, !Roles, !Users
  • no format-types xml included yet, so directory display is a little messy

This initial release only supports running on the same server as sharepoint, meaning you'll need to install 2.0 framework and Monad 3.1 onto your sharepoint box. Just extract the DLL and run the following commands to get started:

MSH C:\Monad\Snapins> c:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe MshSharePointProviderSnapin.dll
...
MSH C:\Monad\Snapins> add-mshsnapin nivot.monad.providers
MSH C:\Monad\Snapins> new-drive wss sharepoint
http://wss.server.com
MSH C:\Monad\Snapins> cd wss:
MSH wss:\>

So, from here you can use cd or set-location and hit tab to cycle through the pseudo containers and subwebs. Once inside, e.g. wss:\subsite\!roles, you can type dir to enumerate all SPRole items. Alerts, Groups, Lists, Roles and Users are treated as containers. Alert, Group, List, Role and User are leaf nodes. I'm extending this to treat a List and a User as a container too to expose their collections (List.Items) and (User.Alerts) as further containers. Currently, only simple paths are supported, some examples:

\!alerts\alerttitle
\subweb\!roles
\subweb\!users\username
\subweb\subweb2\


Complex nested paths will be in the next release, e.g.

\subweb\!users\username\!alerts\alerttitle

Currently, it does support not SPS; you can map a drive to the root of a portal, but you will experience some weird behaviour. I plan to incorporate support for that in the future.

The next release will support copy, move and delete semantics between containers. It will also support complex paths. Post any ideas, feature requests and/or anything you feel might a bug or just done wrong. I'm working on a list of concrete features for my next post.

Have fun!

( for latest version, see homepage )

posted on Thursday, March 30, 2006 5:38:24 PM (Eastern Standard Time, UTC-05:00)  #    Comments [3] Trackback
# Wednesday, March 22, 2006

For me, the Microsoft Command Shell (MSH) has to be the most exciting thing to come out of Microsoft for years; yes, I'm a command line whore, but proud of it. In the *nix world I used ksh and when I ended up working a lot with DOS, 4DOS was my trusty companion. Up until recently 4DOS's 32bit successor, 4NT, was my main workhorse in the nt4/2000/xp world, but it's slowly losing ground now to MSH.

I've been working a lot with SharePoint Products & Technologies 2003 the last few years, and I've increasingly found myself writing little c# console apps to perform menial work like batch uploads into lists, mass user management/migrating, site cloning etc. I actually started to sit down and write a shell which was christened SPSH (pronounced speh-shell -- e.g. special, geddit!) which was going to work like NETSH with command contexts etc; NETSH is pretty nice, it feels like very much like IOS. Then I discovered MSH and the Cmdlet Provider model and I saw the light

Made in Express entrant

So, I'm announcing my work on a SharePointProvider which I expect to have ready in about 6 weeks from now in it's first release form. I'm about 2 weeks into it now. Incidentally, since I'm developing it with the unbelievably cool -- and free -- Visual Studio Express, I've entered the project for the "Made in Express" Contest. It'd be nice to get the $10k, but I'm doing this for fun already and to help ease my workload (and yours too if you decide to use it). Imagine being able to do this:

MSH C:\monad\snapins> new-drive wss sharepoint http://intranet

Name       Provider      Root                    CurrentLocation
----       --------      ----                    ---------------
wss        nivot.mona...
http://intranet

MSH C:\monad\snapins> cd wss:
MSH wss:\> cd subsite\!Users
MSH wss:\subsite\!Users> copy * ..\!roles\contributor

Anyhow, the list of things you can do is endless once the provider is in place. Check all users in a site collection against AD to see if they locked out their accounts? easy. Copy users from one site to another? easy. Downgrade all contributors from a particular domain to reader? easy.

Also, you'll be able to copy files from one document library to another while preserving metadata, optionally creating the source schema in the destination if the document libraries do not match.

And finally, if you don't want to wait for me before you get scripting SharePoint, take this in:

MSH c:\monad> [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

GAC    Version        Location
---    -------        --------
True   v1.1.4322      C:\WINDOWS\assembly\GAC\Microsoft.SharePoint\11.0.0.0__71e9bce111e9429c\Microsoft.SharePoint.dll

MSH c:\monad> $site = new-object Microsoft.SharePoint.SPSite("http://intranet")
MSH c:\monad> $site.ID.toString()
d5dfb76b-fd15-4666-b9f1-93f2ae617086

Exciting times!

posted on Wednesday, March 22, 2006 12:32:35 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] Trackback
# Thursday, March 16, 2006
You get "Cannot complete this action" when updating/editing a Hyperlink field ( URL ) in a Links list programmatically.
posted on Thursday, March 16, 2006 10:07:51 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] Trackback
# Tuesday, January 10, 2006
Faulting application w3wp.exe, version 6.0.3790.1830, stamp 42435be1, faulting module stswel.dll, version 11.0.6568.0, stamp 42e17544, debug? 0, fault address 0x0009310c.

This is something I fell victim about 18 months ago, pre-SP1 for Windows SharePoint Services, and I'd forgotten about until the recent release of SP2 for both WSS and SPS. By the time I had resolved the problem and discussed it with the Microsoft Escalation Engineer we had standing by, SP1 was already in testing. It was said that a "fix" may not make that service pack. So, it was worked around and was duly forgotten until now -- the release of SP2 -- and so I decided to see if it had been "fixed."
posted on Tuesday, January 10, 2006 5:10:56 PM (Eastern Standard Time, UTC-05:00)  #    Comments [2] Trackback