Friday, 12 February 2010

Best Practice List Development in SharePoint

I had the honour of speaking on the subject of best practice SharePoint list development at last weekend’s SharePoint Saturday event held in Perth, Western Australia but I want to take this discussion one step further. I’m therefore creating this post to point to my slide deck from the event and as an index for follow-on, detailed posts about some of the items I had to gloss over. There’s precious little out there, in a single location, on the subject of list development guidelines and I’m hoping to change that. If you want to contribute what you feel is a best practice I’ve missed or challenge one of the practices I do have listed, please comment and join the discussion.

Slides are available here: Best Practices for Developing SharePoint Lists (PowerPoint | PDF)

Here are the two key resources I cite in the presentation:

Wednesday, 10 February 2010

YSlow Configuration “Use a Content Delivery Network (CDN)”

The westernaustralia.com site is served to users all over the world from the most remote city in the world: Perth, Western Australia. In other words, we target users in core markets across Australasia, Europe, and North America and while we expect a consistent homepage load time below ten seconds in all cases, Perth to New York, Perth to London, and, really, Perth to anywhere equates to high latency, congestion, and poor response times. Couple that with SharePoint, a rich, interactive site design, and an excessive number of page requests and you'll begin to appreciate why we chose to serve the site across Akamai's content delivery network.

I'll describe the setup in detail someday but for now, I've finally managed to convince YSlow the site is being served using a CDN; while we use better tools for global performance measurement (Gomez), seeing a low grade—in part because the hundred-odd requests were perceived to be served without a CDN—was starting to get me down ;) YSlow is a great plugin for analysing your site in Firebug but it's grading system can be a bit tough.

The YSlow FAQ will tell you how to configure the plugin to acknowledge the use of a CDN by setting a extensions.yslow.cdnHostnames preference. I won't repeat those details here but will expand on how the string value might be configured to tell YSlow a CDN is in use—whether you’re telling the truth or not. It’s surprisingly simple.

In our particular case, www.westernaustralia.com is a CNAME to an Akamai URL so telling YSlow to use akamai.com as a CDN doesn’t make sense and YSlow isn’t smart enough to figure things out on its own. Since www.westernaustralia.com is implicitly its own CDN, configuring the the extensions.yslow.cdnHostnames value as westernaustralia.com sorts everything out. I had to restart Firefox (3.5.x) and reload the page for things to take effect.

If you’re not using a CDN and want to turn off this particular component of your grade (or at least make it an “A”), simply add your own URL; regardless of whether you’re actually using a CDN, YSlow will think you are.

SharePoint 404: The resource cannot be found

If a page element is missing—either a user control hasn’t been deployed or something else that needs to be in place for the page to compile dynamically is awol—you might be the proud owner of a 404 even though the page itself does exist.

HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly.

After setting the SafeMode element’s CallStack element true in web.config, turning off CustomErrors, and setting the debug=”true” attribute on the compilation element, you’re possibly looking at a beautiful ASP.NET error message with no stack trace and not a lot to go on.

Well here’s a trick: view source on the error page and and scroll down below the closing HTML tag. Behold the stack trace! It should tell you exactly where to look for the problem.

Tuesday, 9 February 2010

westernaustralia.com Relaunch and Other Website Recent Activities

If you’ve been following the progress of the westernaustralia.com website over the years, you’ll already know the site was one of the first in Australia to be launched on the MOSS 2007 platform and has been consistently voted as one of the top fully branded SharePoint sites in the world ever since. Having worked on the site since the get-go and as the current technical lead for the project, I’m the proud owner of the site’s programmatic aspects; today I’m tickled pink to tell you, the SharePoint community, about yesterday’s launch of the new Tourism Western Australia brand, Experience Extraordinary, and, more specifically, the brand’s impact on the westernaustralia.com website.

At the moment we’re working with the Digital Marketing team on a two (or three phase) approach (depending on how you look at it) to implement the new brand. The first phase unfolded in August last year and involved the neutralisation of the preceding brand’s elements (The Real Thing) while the latest creative design agency, Host, was appointed. Phase 1 of the new brand implementation kicked off in the dev team a little over three weeks back and involved making the Photoshop mockups provided by Host into a living website. This work focused largely on the page banners (vibrant imagery, the tab, and extra height), the navigation, the background colour (trust me—everything is more complicated than you might think at first glance with wa.com!), what we call the ePostcards element, and the footer elements.

Here’s a picture of what I think is a visually stunning website and a vast improvement over its predecessor:

wacom homepage 4 Experience Extraordinary Phase 1

Phase 2 holds still more secrets but you can bet we’ll be making all the middle bits fit with the rest of the changes. One of the challenges we’ll be facing is getting the home page weight down from a whopping 1750KB and 100 requests. Stunning, certainly, but our CDN of choice (Akamai) allows us to get away with this sort of monkey business.

In addition to all the glam, we also took the opportunity to overhaul the heading infrastructure. This subsystem is designed to give content editors the ability to upload new banner images and all of the corresponding display data required to render the Flash banner. The Flash banner itself was built by Host from our previous banner and it takes as a parameter an XML file providing all the information it needs to display the banner images, text, links, and colours.

Obviously this data is stored in a list to which the FlashBanner.cs web part communicates at render time. Like I say, nothing in wa.com is as it first appears and one of the more complex requirements was allowing a subsite to override the banners displayed for for it and its children (in effect to support the major subsections of the site such as the destinations). Apart from simply walking up the site hierarchy recursively until a banner list is found, we then needed interrogate the list and emit an XML file acceptable to the banner; the URL to the file is finally cached with a dependency on the file itself.

Interestingly, this was one of the first times we started using event receivers on the banner lists to invalidate the cache when a banner is added, edited, or deleted; this keeps the content editors happy and productive and is one less of those annoying “is my banner cached in the browser cache | Akamai | reverse proxy| application cache | output cache | blob cache?” questions ;)

I’ll also point out we’re using a simple custom list for this instead of a picture library or custom list derived from a picture library. The previous version of this list was in fact a custom picture library but it suffered from broken thumbnails (which we now know how to fix) and proved rather cumbersome to use in practice (no reordering, a difficult view, etc). The move away from the picture library wasn’t, in retrospect, necessarily a great decision but it was probably the best decision at the time and came with considerable deliberation. The one major problem with the current approach is banner images must be uploaded separately to a real picture library and then referenced from the list; this is a bit of a double-up and disconnects the image itself from its metadata. As our understanding of list development and the peculiarities of these other list types increases, we may revisit this approach.

Also at a technical level, we recently move the site from our old IBM BladeCenter kit running Windows Server 2003 x86, MOSS 2007 SP1 (not even the Infrastructure Updates—gasp!), .NET 3.0, and a non-clustered SQL Server 2005 x86 database server. Everything was virtualised on ESX 4.0. We actually had three of these farms: one in prod, one in DR, and one for authoring; as content deployment never worked for the site, this meant a daily backup and restore of the content database from authoring to production and corresponding switch to or from DR (with DR actually being treated as a standby prod environment). That must have really sucked for our admin who had did that essentially manual task every business day since launch in May 2007. What. A. Drag.

From that setup, we moved to what was briefly the bees knees: Windows Server 2008 x64, MOSS 2007 SP2 + June 2009 CU, .NET 3.5 SP1, and a clustered SQL Server 2008 x64 database environment. Everything is still virtualised on ESX 4.0 and the entire setup is mirrored in DR. We’ve finally done away with the authoring farm so content editors are editing content in the production farm (we’re working towards a tiered security design and approval workflows, by the way, but our content editors have been working with the environment for years now and are mature in their understanding of how not to break the site ;). So no more daily content deployments and those of us in the dev team can finally start working with .NET 3.5 and LINQ.

For more on how we run the site, check out my Perth SharePoint User Group presentations and videos (things have changed but not that much):

http://blog.mediawhole.com/2009/02/how-we-do-wcm-at-tourism-wa-im-speaking.html

http://blog.mediawhole.com/2009/03/presenting-at-next-sharepoint-user.html

If you’ve read this far, you deserve the chance to win a prize. Want the opportunity to take an extraordinary taxi ride around the state of Western Australia? If so, check out the “brand activation” microsite: http://www.extraordinarytaxiride.com.au/

Note: I am employed by Tourism WA as a contractor working for Diversus. Mediawhole, mediawhole.com, and this blog are not associated directly with Tourism Western Australia or the westernaustralia.com website. The information provided above  is published independently as a member of the public and does not reflect the views of Tourism Western Australia or Diversus. Please consult a Tourism WA representative for more information about its brand, campaigns, and websites.

Friday, 22 January 2010

Buying a laptop? Make sure it supports VT

Just borrowed a colleague’s Toshiba M300/Intel Core2 Duo Mobile Processor P7350 laptop only to find the CPU doesn’t support VT (or the Intel Virtualization Technology/hardware-assisted virtualisation) required by Hyper-V and VMware; I was planning to use this laptop for Hyper-V-based demos. Rats.

The laptop in question is only six months old and otherwise nicely equipped with 4GB of RAM and a 320GB hard drive so it’s a shame about this niggle… back to Virtual PC and 32-bit for me I suppose—how quaint!

Which leads me this mental note: when buying a laptop go to extreme lengths to determine whether the CPU offers VT and do some Googling to determine whether it can actually be enabled in the BIOS (apparently the various manufacturers can disable/enable VT at their discretion).

In the P7350 case, Intel’s technical data was incorrect on publication—originally specifying support for VT. If you’ve actually got one of these and are reading this post, sorry mate—hope you weren’t planning to do too much 64-bit virtualisation!

Wednesday, 20 January 2010

SharePoint 2007 Slipstreamed Installer

I hadn’t noticed previously but Microsoft released slipstreamed SP2 installers (x86 and x64) at the end of 2009:

http://www.microsoft.com/downloads/details.aspx?FamilyId=3015FDE4-85F6-4CBC-812D-55701FBFB563&displaylang=en

http://www.microsoft.com/downloads/details.aspx?familyid=2e6e5a9c-ebf6-4f7f-8467-f4de6bd6b831&displaylang=en

Makes life a little bit easier so you don’t have to do the slipstreaming yourself. Apparently previous installers will not work with Windows Server 2008 R2.

Saturday, 16 January 2010

Manage Active Directory Users and Groups with PowerShell

With a new dawn and the SharePoint 2010 beta upon us, I figured it was finally time to a) dip my toes into the PowerShell pool and b) learn how to automate the creation of users, groups, organisational units, and other objects within Active Directory. In the PS case, it still seems like an unnecessary evil and, between all the other things on my “TO LEARN” list, it hasn’t been a high priority; that said, it seems to work and I kind of, sort of, maybe just like it. We’ll see… On the automation front, I figured I’ll probably blow away more than my fair share of development environments before my time is up so I might as well make creating the darned things a little bit easier and more repeatable.

My search for information along these lines quickly led me to Quest’s ActiveRoles Management Shell for Active Directory—a set of PowerShell commandlets. The download is free and if you grab it I’d also strongly suggest you pull down the admin guide as well—it’s comprehensive and includes examples. To install, run the .msi and finish the wizard with the defaults.

From there you’ll need to add the related snap-in in a PS window as follows:

Add-PSSnapin Quest.ActiveRoles.ADManagement

The first thing I wanted to create was a user object and this was reasonably straightforward. Be warned some of the commandlets take a lot of arguments, the names of which don’t always correspond to the UI you see in the AD Users and Computers snap-in: password is –UserPassword, for example, and Job Title is simply –Title. Here’s the command I used:

new-QADUser -name 'Bob' -ParentContainer 'OU=DirtyWords,DC=spdev,DC=mediawhole,DC=com' -SamAccountName 'Bob' -UserPassword 'TH1Smis1s' -FirstName 'Bob' -DisplayName 'Bob' -UserPrincipalName 'bob@spsdev.mediawhole.com' -Title CEO

This creates the user but new-QADUser doesn’t allow you set all of the things I want to using the standard parameters. In my case, I also want to set the account to never expire. To do this, I used the set-QADUser commandlet as well, which seems to let you get to much more detail:

set-QADUser 'CN=Bob,OU=DirtyWords,DC=spdev,DC=mediawhole,DC=com' -PasswordNeverExpires $true

Next I created a new group using the new-QADGroup commandlet:

new-QADGroup -ParentContainer 'OU=DirtyWords,DC=spdev,DC=mediawhole,DC=com' -name 'Managers' -samAccountName 'Managers' -grouptype 'Security' -groupscope 'Global'

…before adding my new user to my new group with the add-QADGroupMember commandlet:

add-QADGroupMember -identity 'CN=Managers,OU=DirtyWords,DC=spdev,DC=mediawhole,DC=com' -member 'CN=Bob,OU=DirtyWords,DC=spdev,DC=mediawhole,DC=com'

This last exercise proved somewhat troublesome as the examples in the admin guide and specific documentation about the –member parameter indicated I could supply ‘spsdev\Bob’ in place of the string above I ended up using successfully. The error message was fairly explicit about this:

Add-QADGroupMember : Cannot resolve directory object for the given identity: 'spsdev.mediawhole.com\bob'.

One other commandlet I haven’t yet managed to get working is the new-QADObject commandlet to create a new OU:

new-QADObject -ParentContainer 'DC=spsdev,DC=mediawhole,DC=com' -type 'organizationalUnit' -NamingProperty 'ou' -name 'Dirty Words'

This command fails on the type parameter with;

New-QADObject : A referral was returned from the server…

+ CategoryInfo          : NotSpecified: (:) [New-QADObject], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException,Quest.ActiveRoles.ArsPowerShellSnapIn.Powers
hell.Cmdlets.NewObjectCmdlet

I’ll probably look back at this post one day after figuring this one out and laugh at my lack of understanding but for now it’s got me stumped.

 

Tuesday, 12 January 2010

Can’t start Hyper-V VM after Windows Server 2008 R2 upgrade

Oh the tedium… Having used Windows Server 2008 R2 for a while, I was keen to upgrade the Hyper-V host environment supporting my dev infrastructure from RTM to R2. R2 seems faster and more refined; I was also wanting to play with the latest version of the System Center Virtual Machine Manager—which requires R2.

The upgrade process went smoothly once I figured out the installer would eventually present me with the upgrade option after telling it to install the Windows Server 2008 R2 Standard (Full Installation) option; this was briefly confusing to me  since I didn’t want to do a full installation! I shut down all my VMs properly beforehand and everything seemed pretty much good (I did have to recreate the one VM I normally auto-start but luckily I was able to reuse the .vhd itself and the machine came back to life with little hassle).

Today, however, I went to create a new VM but was unable to start it post-creation. Clicking start popped up a message telling me the VM could not initialize and Hyper-V could not create or access saved state file. The physical location of my VMs hadn’t changed but I read this error message as a permissions issue—but where to start?! The only thing I had to go on was that I was creating the new VM on another volume.

Fortunately Jevgenij Martynenko saved the day for myself and others in this forum post with the old trick of granting access to the root of the drive. I remember having to do this for ASP.NET back in the day for some reason…

Anyway, as per the instructions, I granted ‘Authenticated Users’ ‘List folder / read data’ permission to the root of my E:\ drive, setting the scope drop down to This folder only. I did not replace all child object permissions as apparently that causes more problems.

Starting the new VM was successful after this change.

Windows Server 2008 R2 Scratch Disk

When building out a new VM I’ve occasionally created a second disk for holding non-system files and temporary data; this disk is easy to blow away every so often and saves the hassles of defragging and compressing.

I recently built a Windows Server 2008 R2 VM and created a system drive and secondary drive in Hyper-V manager before installing the OS. During the OS installation process, I created a new partition and noticed—but thought nothing of—the fact the installer didn’t nag me about creating a reserved system partition as well.

Carrying on my merry way, I eventually found the secret system reserved partition on my “scratch” disk (d:\) when I went to format what I expected was a completely unallocated disk. Bummer—I’m not clear on the ramifications of simply deleting this reserved partition but it currently means dragging around an additional 6GB of D: drive and being unable to blow away my scratch disk.

Saturday, 9 January 2010

I’m Speaking at SharePoint Saturday Perth this February

How exciting—our very first SharePoint Saturday event in Perth! A BIG shout out to Jeremy Thake for organising the venue, speakers, sponsors, prizes, and everything else! The speaker line-up looks fantastic and the sessions cover a range of topics so I reckon this is going to be a great day.

In addition to attending the event, I’ll also be presenting on the subject of SharePoint list development. Here’s the official blurb for my talk:

Lists are key to understanding the power of the SharePoint platform and provide core data storage and management facilities in a SharePoint environment. Lists can be customised to suit custom requirements but doing so isn’t always straightforward.

Learn how to create, deploy, manage, and interact with SharePoint lists in this jam-packed session. Discussion will cover the pros and cons of using SharePoint lists before focusing on methods for creating and deploying lists between environments in a repeatable manner; techniques for working with lists and data using the SharePoint API with also be demonstrated.

Existing experience with the SharePoint UI, a cursory knowledge of content types, and ASP.NET development experience is recommended but not assumed.

If there’s anything you’d like me to cover in particular please drop me a line or post a comment below. If all goes well I’ll also be recording the session so feel free to make a request or post a question even if you’re unable to attend in person.

Finally, Diversus are sponsoring the event and their package includes a JVC video camera to be given away—thanks guys!!!

Diversus - Perth SharePoint Development