Friday 22 May 2009

Windows Memory Limits

Different versions and architectures of Windows support different limits on memory. http://msdn.microsoft.com/en-us/library/aa366778.aspx concisely describes those differences from Windows 2000 onwards.

Thursday 21 May 2009

SharePoint on SharePoint – Under the Hood

The SharePoint Team Blog just announced they’ve launched the www.microsoft.com/sharepoint site on SharePoint itself with a large sprinkling of Silverlight. The post mentions the use of the publishing feature and SEO optimisation so I thought it would be interesting to see if I could find any really cool, secret WCM optimisations. I’m disappointed and can’t suggest modelling your own internet-facing MOSS site on this site :-(

  • Looking at the site URL alone I can tell this is a MOSS site: /pages/default.aspx. I was hoping to see the /pages directory magically vamoosed from the URL and I’d hardly say Default.aspx is SEO-friendly.
  • The total page weight, according to YSlow, is 538.5KB, which translates into a load time of 13.81s from Western Australia and a grade of F (despite waiting for the Silverlight banner to load the page load time didn’t feel too bad but reloading with an unprimed browser cache was sluggish but I have little doubt they’re running off a CDN)
  • The JavaScript and CSS aren’t minified and both init.js and core.css are loaded in their entirety.
  • The number of resources requested by the page is significant and there’s been no apparent effort to merge CSS and JS files
  • The page viewstate equates to 62KB of the overall page weight while another 68KB pertains to inline Silverlight load script stuff

The single neat-o thing about this site (let’s say apart from its content and this is a technical blog) is the way hitting the Login link or trying to hit /_layouts/settings.aspx redirect to the Live login form. It would be interesting to know if they’re actually using Passport authentication on this site.

Sunday 17 May 2009

Run an internal URL hashing/redirect service with Google Short Links

Google Labs recently made the Google Short Links application available to the Google Apps platform. Short Links is a promising little feature that enriches the Apps system by allowing you to shortcut and/or hash URLs and serve those redirects directly from your Google Apps domain. As a useless example, checkout http://go.mediawhole.com/blog ;-)

Like most things with Google Apps when you’re running your own domain name, setting up is simply a matter of picking one or more hostnames and a creating a corresponding CNAME entry in your DNS server (see my post on how to get setup—it’s easy, I promise!). The choice of hostname is arbitrary; in my case I chose http://go.mediawhole.com and http://bookmarks.mediawhole.com. If you do add multiple hostnames note you still only have a single collection of short links. My line of thinking is to use go.mediawhole.com for public-facing redirection and bookmarks.mediawhole.com for private use.

In addition to creating short, hashed URLs for use in Twitter and other space-constrained applications (print articles/ads/etc), you can also create friendly URLs that may be easier for your visitors to remember. As an example, http://go.mediawhole.com/michael will redirect you to my Blogger profile. Short Links handles both internal and external links (links pointing to pages on your own domain and pages on external domains).

Link administration is simple through the UI: as you might expect, all you have to do is specify the short link and paste in the target URL; alternatively, just pop in the target URL and Google will generate a new hash. You can also make individual short links public or keep them private—presumably for use only by your logged on users. Obviously you need to be careful about deleting a link once it’s been created and published as redirection will be removed for that link and your users won’t end up where they expect—a nice enhancement would include the ability to configure a default short link for cases like this.

Google being Google you can of course search your short links and viewing the list of short links you’ve configured will specify a usage count for each link—providing some rough analytics.

Saturday 16 May 2009

Starting with SharePoint for Administrators

Whether you’re a newbie admin holding together a one man shop or a seasoned technical veteran, when you find yourself lumped with rolling out Windows SharePoint Services 3.0 and/or MOSS 2007 do yourself a favour and read this brief white paper on some of the more important considerations:

The above paper is about twenty pages and it’s a quick read that should help you step forward on the right foot. If nothing else, each of the topics presented links to additional TechNet and MSDN material and the paper is a valuable index from that perspective.

Like it or not, effective administration is pivotal to the success of the entire project from the very beginning right through the support phase and beyond; seemingly harmless mistakes made during the initial install can lead to major long-term problems. Like everyone else “doing SharePoint”, generic Windows/SQL Server/ASP.NET experience will get you started but you’ll still be faced with a very steep learning curve, depending on what you’ve been asked to accomplish. Bear in mind the SharePoint paradigm will not always sit right with conventional experience and may clash with existing corporate IT policies. SharePoint will challenge and frustrate you on many different levels, while at times seeming to throw common sense out the window.

Re-learning everything you know now isn’t strictly necessary to build a SharePoint environment :-) but the size and power of the SharePoint ecosystem does require a massive, sustained learning effort that will increase your professional maturity very quickly.

At a minimum, beware administering SharePoint will cover:

  • Windows Server
  • Active Directory
  • IIS
  • ASP.NET
  • SQL Server
  • XML
  • SharePoint farm management
  • SharePoint Designer

From there, a “standard” WSS/MOSS rollout can involve:

  • Integration with LOB applications
  • Virtualisation
  • SAN management
  • Backup and restore
  • Content deployment
  • Load balancing
  • High availability
  • Database clustering
  • Reverse proxies/caches and content delivery networks
  • Security
  • SSL certificate management and distribution
  • Kerberos
  • Code access security
  • XSL, CSS, Javascript, C#, TSQL
  • Solution deployment
  • Remote debugging
  • Performance overhauls
  • Antivirus
  • SMTP
  • Exchange
  • InfoPath Forms
  • Excel
  • Office applications (Word, PowerPoint, Outlook, Project)
  • [Your technology here]
  • [This space for rent in 2010]
  • [What did I miss?!?]

I’ve watched great admins balk at the overheads and oddities required of a SharePoint deployment, moving through the various phases of shock (ignore), denial (disbelief), anger (hate), depression (confusion), and finally acceptance (hope—SP1?!, resignation). If you’re moving through one of these phases or have come out the other end (or you’ve already deployed SharePoint and are starting to realise what’s involved), read this paper.

Friday 15 May 2009

Blocking SharePoint Designer from Accessing Your Site

In a recent TechEd discussion panel comment, my favourite SharePoint MVP Eric Shupps mentions the ability to block SharePoint Designer from connecting to a SharePoint server and modifying content.

Why is SharePoint Designer a bad thing?

  • It’s free; every man and his dog can download it, potentially install it, and potentially break your sites
  • It can potentially be used against production—which if you follow a regimented deployment process is all wrong as changes can be made any ol’ time
  • It customises (or ghosts, if you prefer) pages thereby severing the link between the artefacts you’ve conscientiously built into a solution package and featurised;  uncustomising these artefacts may not be possible, depending on the changes that were made, or you’ll need another way to fix things up.
  • Artefacts created by SPD are created in the content database and can’t be moved easily between environments (eg. from dev to UAT to prod)
  • It modifies your files and injects stupid attributes that only it cares about
  • It’s buggy and it sucks and crashes and it’s too complicated for business analysts and too wrong for developers and it’s FrontPage rebranded and so on.

Eric’s comment got me digging and I found this new tool on CodePlex that installs a feature allowing admins and content editors to disable access to a site using SPD. Although a site definition can be altered directly to limit access by SPD this won’t affect existing sites, can’t be unlimited at any point in the future using any obvious mechanism, and is all a bit weird.

No SharePoint Designer is implemented as an HTTP Handler so it doesn’t touch the content database or much of anything. It’s still early days but definitely a “watch this space” kind of effort.

An alternative tool uses AD groups to limit access and this approach uses group policy to simply block SPD from running (and this MSDN blog entry is comprehensive if nothing else!).

Resources:

http://www.msteched.com/online/view.aspx?tid=efa154e2-6c06-4a76-ab3c-e9d71ebf0ff2
http://nospd.codeplex.com/
http://support.microsoft.com/default.aspx/kb/940958
http://blogs.msdn.com/sharepointdesigner/archive/2008/11/25/locking-down-sharepoint-designer.aspx

Thursday 7 May 2009

Collapsing multiple using statements

Multiple, nested using statements are extremely common when developing against the SharePoint API to ensure the various objects at work are disposed of correctly:

using (SPSite site = new SPSite ("http://server")){
using (SPWeb web = site.OpenWeb())
{
str = web.Title;
}
}

Under the hood, the CLR transforms both using statements into two try/finally blocks—one nested inside the other—where the relevant object is disposed in each finally block. Handy but these multiple using blocks still leave the code that does all the real work of your application indented far into the page. Add some if statements, loops, or RunWithElevatedPrivileges calls and you’re halfway across.

To clean up ever so slightly, the two using blocks in the example above can actually be combined or stacked with a single block (a single set of braces and a single level of indentation):

using (SPSite site = new SPSite ("http://server"))
using (SPWeb web = site.OpenWeb())
{
str = web.Title;
}

The end result is the same at the MSIL level: two try/finally blocks nested one inside the other (check ildlasm.exe) but you regain one level of indentation.

System.Random not so random in a loop

When you need to generate a random number System.Random comes to mind:

int randomNumber = new Random ().Next ();

All well and good but did you know new Random () actually generates a sequence of random numbers and Next () simply returns the next random number in the sequence? The Random class could have been named more accurately as RandomSequence but I digress…. One more thing, did you know the random sequence is generated using a seed value and that if you specify the same seed value when constructing a new Random object you’ll get the same sequence of random numbers? And finally: did you know if you don’t specify a seed value, the seed value is initialised using the system clock which naturally “has finite resolution.”

If you answered no to all of the above and you need a random number go read the doco. If you’re an attentive reader, you’ll read this:

…using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers.

Which sucks because that’s exactly what happens if you use the above code in a loop on a machine that can execute that loop more than once before the clock ticks over. If that happens, the same seed value will be use and calling Next () on the new Random object will return the same value it did last time.

The easiest way to work around this is to instantiate your Random object outside the loop and then call Next () on that instance in the body of the loop:

Random randomSequence = new Random ();

for (int i = 0; i < 10; i++)
{
randomSequence.Next ();
}

If that doesn't suit, consider passing the Random constructor a seed value that increments with each iteration of the loop (the MSDN documentation suggests there may be performance implications if you create a new Random object repeatedly so watch out).

For what it’s worth, today we were dealing with this exact problem in the context of an anonymous method passed to the List<T>.Sort () delegate. The IComparer<T>.Compare () method supplied to Sort () only accepts two parameters (those to be compared).

int Compare( T x, T y)

As a developer, it’s easy to assume the anonymous method only has access to its parameters. In actual fact, variables in the “outer scope” are captured and made available to the delegate until the delegate referencing the anonymous method itself goes out of scope and become eligible for garbage collection:

The local variables and parameters whose scope contain an anonymous method declaration are called outer or captured variables of the anonymous method.

Read more about closures if you're interested...

What this means is that our anonymous method can access the Random instance declared in the outer scope:

Random randomSequence = new Random ();

list.Sort
(
delegate (string x, string y)
{
return x == y ? 0 : randomSequence.Next (-1, 1);
}
);

There’s some extra stuff going on here because the result returned must conform to the IComparer<T> interface in that it must return –1, 0, or 1 but the code in bold calls out the use of the outer variable within the anonymous method.

Wednesday 6 May 2009

Can’t Minimise a Full Screen Remote Desktop Connection

Ever get stuck in a full-screen RDP session where the little yellow bar isn’t pinned and just won’t slide down?

Control + Alt + Break will restore the window.

Tuesday 5 May 2009

Creating child sites under a Publishing Portal

Every time I create a new site collection I regularly forget to enable the use of different site templates below the top-level site. Invariably that means I’m limited to using the Publishing Site with Workflow template—fine for most of what I do despite the “with Workflow” bit adding extra hassle but I usually end up thinking you can’t create sites using other templates a child sites below a Publishing Portal.

Well that’s just silly—the extra site templates simply need to be made available through Site Settings –> Page layouts and site templates. Select the individual templates you want to make accessible or select Subsites can use any site template and you’re off. No features to activate in one of four different locations, no config to change, easy unless your memory is like sieve.

Ps. Zabi has posted a nice visual walkthrough showing you exactly how to make this change.

Choosing the right MOSS site template

It’s a bit old now but Todd Baginski has posted some really great resources about the differences between the various OOB MOSS site templates.

http://www.toddbaginski.com/blog/archive/2007/06/29/which-wss-3.0-moss-2007-site-template-is.aspx

Creating a new Article on a SharePoint Wiki site Results in a File Not Found Error

I haven’t played with the OOB MOSS 2007 site templates for a while and after someone at work asked about MOSS blog capabilities I decided a refresher was in order. As you may have read we run a successful wiki in the office, hosted on the MediaWiki platform; we briefly ran a MOSS wiki on our intranet but it didn’t really take off and it looked like rubbish. With that baggage, I wanted to have a good hash around a clean wiki site and see how it compares with MediaWiki.

New web application –> new site collection –> Wiki Site

…success and straight into it, ignoring all of the rather verbose SharePoint UI text. Wiki site created and I create a forward link from the default article to create my first page. Enter an article name and some dummy text and Save…

File Not Found

Thanks MOSS for another great error message—it must have found something because viewing the Wiki library I see my article listed. That said, this behaviour was easily repeated and I had nothing of interest in the event log. Google didn’t return much either until I stumbled upon an unrelated post suggesting a trusty old IISRESET. In my haste and being fatigued, I realised I’d forgotten to reset IIS—as instructed by SharePoint after creating my new web app. And behold problem solved. I can create wiki articles to my heart’s content—IISRESET always has been and always will be a god among men in my eyes.

And yeah, the MOSS blog stuff I thought is pretty good (comparing with Blogger) and the wiki bits are a bit simplistic but adequate with a nicer WSIWYG editor than MediaWiki’s (I really like the Incoming Links bit). Next steps: make the blog look like www.westernaustralia.com… keep your eyes peeled!

Monday 4 May 2009

SharePoint SP2 Upgrade Fails: The B2B upgrader timer job failed

Update: Be sure to checkout the comments for additional suggestions.

Upgrading to WSS SP2 from a relatively clean, MOSS 2007 SP1 + December Cumulative Updates environment went smoothly over the weekend but upgrading my day-to-day “MOSS 2007 SP1 + a selection of hot fixes” dev environment to WSS SP2 failed at step 8 of the configuration wizard with:

An exception of type Microsoft.SharePoint.PostSetupConfiguration.PostSetupConfigurationTaskException was thrown.  Additional exception information: Failed to upgrade SharePoint Products and Technologies.

Naturally, it’s not like the configuration wizard would tell me this without forcing me into the log file; no, it assumes I’m a sweet, niaive administrator with  a penchant for colourful UIs and lollypops. Even the event log simply points to the wizard log file. God forbid it present the underlying exception in the wizard UI—I’m guessing anyone dealing with SharePoint on a daily basis isn’t going to freak out when faced with a stack trace. Anyway, into the logs and search for capital ERR and there I find the source of the failure—or at least as close as I’m going to get:

The B2B upgrader timer job failed

I tried all the usual wizard tricks to no avail:

  • psconfig -cmd upgrade -inplace b2b -force (failed at step 3 with the same exception but apparently the log file is more detailed)
  • Followed up my WSS install with the MOSS install
  • Browsed through KB944267
  • Restarted and stopped the administration service, the timer service, IIS
  • Cleared the file system cache as described in KB939308 
In the end I'm a complete gimp: after backing up my VM before starting this exercise, I inadvertently fired up an older copy to which I attempted my SP2 install. Moving across to my current SP1+ VM allowed me to successfully install SP2. What gives? Service packs are cumulative so I should have also been successful with my older copy, which was pre-SP1; in fact I should be able to go RTM to SP2.

Despite being a gimp, I learned a few very important lessons today:

  • Always, always, always test a service pack or updates release on a non-production, non-critical environment (and backup your content database and other bits before you start in production)
  • It's fun to be first but if you're risk averse, it's probably a good idea to let others go first and blog their workarounds before diving in (there's a dearth of information about the problem I encountered as it applies to SP2 and none of the SP1 suggestions from a year ago worked in my environment)
  • The SharePoint Products and Technologies Configuration Wizard doesn't log much of any value