Thursday, 20 May 2010

Disable the Output Cache Programmatically with PowerShell

Restoring a content database from a production environment to a development machine for dev purposes can sometimes get a little bit interesting.

Our production environments generally have output caching enabled for performance reasons(see /_Layouts/sitecachesettings.aspx in your own environment) but developing or troubleshooting an issue in dev normally requires output caching be disabled to you can view the results of your work. Of course the output cache settings are stored within the site collection so using a production backup will normally bring the output cache setting along with everything else.

Of course you can manually disable output caching but that means remembering to do so. As our attach process is scripted in a batch file for repeatability and automation purposes, I recently added a step to disable the output cache programmatically. To do this, I wrote a little PowerShell script and call it from the batch file:

Param($Url)

write-host "User must be a site collection administrator or have full control within web application policy!"

[System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint”)
[System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint.Publishing”)

$cacheSettings = new-object Microsoft.SharePoint.Publishing.SiteCacheSettingsWriter($Url);
$cacheSettings.EnableCache = $false;

$cacheSettings.Update();

The script takes a single named parameter (Url) which specifies the site collection URL. As you can see, I'm working with the SiteCacheSettingsWriter class to set the EnableCache property to false before sending through an Update() command; of course the same thing can easily be accomplished in C#.

I call the script like so from my batch script:

powershell "& ./DisableOutputCache.ps1 -Url http://dev-moss"

I've parameterised this script since I restore content databases from multiple sites and didn't want the URL hard-coded.

As per my note, the account used to execute this script must be a site collection owner or have rights configured the web application policy or you'll encounter an access denied error.

 

How to supply named arguments to a PowerShell script

Calling a parameterised PowerShell script from a batch file or command window using name parameters is pretty easy, just flag each paramater name and supply a value like so:

powershell.exe "& ./MyScript.ps1 -MyParam1 'MyValue 1' –MyParam2 MyValue2"

Note I’ve wrapped MyValue1 in single quotes because of the space; the single quotes are stipped off the argument when it’s presented to the script.

MyScript.ps1 would use the parameters like so:

Param($MyParam1, $MyParam2)
write-host $MyParam1
write-host $MyParam2

The Param statement declares the formal parameters accepted by the script and must be the first executable line of code in the script. The parameters can now be used like any other variable, as demonstrated by the two write-host calls.

Disclaimer: I’m a PowerShell rookie! 

Building SharePoint 2010 Solutions with Visual Studio 2010

[Update: a video recording of this presentation is now available here]

I’m presenting the second of tonight’s Perth SharePoint User Group sessions:

Building SharePoint 2010 Solutions with Visual Studio 2010

Description:

SharePoint 2010 development is now a first class citizen with a new level of tool support in Visual Studio 2010. This session will demonstrate the basics steps to create a SharePoint project, configure a solution package, and create and work with project items like features and the new visual web part. Debugging, LINQ to SharePoint, and considerations for working with stand-alone applications will also be discussed.

Target Audience: Developers

Hope to see you there and don’t forget to register (for catering purposes) if you’re planning to attend: http://perthsharepointmay2010.eventbrite.com/

Thursday, 6 May 2010

How to merge Hyper-V snapshots to a parent .vhd

Jason Neurohr has a detailed, illustrated post on the subject of merging Hyper-V snapshots to a parent .vhd, leaving you with a single .vhd file you can run without having to worry about the snapshots. I found Jason’s post excellent and the steps described worked like a charm the first time I had to do this (while I didn’t persist, I found exporting a VM with snapshots from the Hyper-V R2 console just wasn’t working—the snapshots weren’t exported as expected).

The merge process is actually quite simple and I’m therefore reproducing just the relevant details from Jason’s post for my own future benefit:

  • Backup the parent .vhd and all snapshot disks (.avhd)
  • Change the extension for all snapshot differencing disks from .avhd to vhd
  • Within the Hyper-V MMC, select the Edit Disk… option
  • On the Locate Disk screen, locate the snapshot disk to be merged
  • Select the Merge option and then the To the parent virtual hard disk option
  • Finish the wizard and create a new virtual machine using the merged disk

If multiple snapshots exist, merge the most recent snapshot into the parent disk and work in reverse snapshot date order all the way back to the parent.

Tuesday, 4 May 2010

Hassles installing Office 2010

Had a painful time trying to get Office 2010 Professional Plus (MSDN RTM) installed in a Windows Server 2008 R2 environment. Attempting to run a customised install including Outlook, Word, Excel and PowerPoint died repeatedly after seemingly getting two thirds of the way through:

Error 1935. An error occurred during the installation of assembly component {89EDD3A9-944B-3257-8484-D6EB6A00DDF5}. HRESULT: 0x80070BC9.

The event log wasn’t any more helpful.

In the end, installing each application one-by-one—although tedious—did the trick.

Wednesday, 28 April 2010

Using validation groups in ASP.NET always posts back

A weird little annoyance I’ve only just noticed is that using validation groups with the ASP.NET validators always results in a postback on form submission and client-side validation doesn’t intervene. Oddly enough, client-side validation does engage when tabbing between fields.

As much as I love the ASP.NET validators and the validation framework for simple scenarios, its limitations are significant when it comes to anything more significant.

Peter Blum, here I come!

IE8 dev toolbar disable script menu grayed out

The Disable –> Script menu option in the IE dev toolbar has baffled me for a while now: sometimes it’s enabled, sometimes it’s disabled (as in grayed out and unselectable), and whenever I need to use it I can’t. I’ve also noticed some of the tabs (namely Script and Profiler) occasionally disappear—easily solved by restarting IE—so I’ve put down the Script menu issue to bugginess.disable script IE8 dev toolbar Thankfully the IE(6/7) Dev Toolbar download page makes clear that “Some menu items are unavailable (grayed out) when running Internet Explorer in Protected Mode on Windows Vista.” I’m running Windows Server 2008 R2 with User Access Control intact and, sure enough, opening IE by right-clicking the IE icon and selecting Run as administrator enables the Script option.

With the IE dev toolbar now built into IE8 and IE being the defacto intranet/corporate browser that it is, I can see why this would be locked down for non-admins; I suppose you don’t want those pesky information workers and power users hacking your corporate forms. What a hassle though.

.

Thursday, 22 April 2010

Failure trying to synch web application and A duplicate site ID was found

If you’re shunting SharePoint content databases around between environments using the stsadm deletecontentdb and addcontentdb commands, you may find a couple of new errors in your events logs:

Failure trying to synch web application {guid}, ContentDB {guid}  Exception message was A duplicate site ID {guid}(http://yoursite) was found. This might be caused by restoring a content database from one server farm into a different server farm without first removing the original database and then running stsadm -o preparetomove. If this is the cause, the stsadm -o preparetomove command can be used with the -OldContentDB command line option to resolve this issue.

followed by:

A runtime exception was detected. Details follow.
Message: A duplicate site ID {guid}(http://yoursite) was found. This might be caused by restoring a content database from one server farm into a different server farm without first removing the original database and then running stsadm -o preparetomove. If this is the cause, the stsadm -o preparetomove command can be used with the -OldContentDB command line option to resolve this issue.

After restoring a production content database to my dev environment, I was finding these two errors every hour on the dot.

Importantly—and despite what this error message notes as a possible cause—Todd Carter details why you shouldn’t be using stsadm preparetomove in a modern (post-IU) SharePoint environment. It seems like preparetomove actually fixed up some GUIDs before a detach/attach operation and it’s still documented with no warnings on Technet but hey, there’s something to be said for collective community wisdom when it comes to Sharepoint ;)

The problem itself seems to lie with SharePoint’s inability to update database IDs during the detach/attach process and (possibly) the fact the content database consumes an SSP. I’m a bit unclear on how the Infrastructure Update may have addressed this but at the end of the day I just want a clean event log and stable environment.

To correct this problem and clear both error messages, I ran the following stsadm command:

stsadm –o sync –DeleteOldDatabases 0

Despite it’s name, the DeleteOldDatabaes parameter doesn’t delete databases, only the “old records corresponding to these databases.” The zero value instructs the command to delete all records that have not been synchronized for the specified number of days. For a report of what might be cleaned up, run stsadm –o sync –ListOldDatabases 5 first.

Monday, 19 April 2010

How to do a test TFS 2008 migration to TFS 2010

Planning an evaluation (or trial) migration/upgrade from TFS 2008 to TFS 2010 seems to be a rather confusing affair; with most Google results still referring to the beta or RC, I haven’t come across many definitive guides pertaining to the RTM release. I haven’t spend any time with the TFS beta either and have never migrated a TFS install so the entire process is new to me. A throwaway install would therefore be required—preferably one that doesn’t impact the production 2008 install!

Most importantly, remember the tfsconfig import is a destructive command. Just stop and think before you do anything—or at least back up your existing databases! Also, a disclaimer: there may be other ways to accomplish the same thing using the upgrade wizard (at install time?? as an in-place upgrade??) but I didn’t follow up this option since I wanted to maintain the existing TFS 2008 environment; it may be worthwhile investigating in your case.

In short, I want to use my existing TFS 2008 data in a clean 2010 environment while the 2008 environment ticks along until the real migration can be scheduled.

So, step-by-step:

1. Install and configure TFS 2010 in a test environment; make sure everything’s working—create a test project collection and project, dill around with it for while, etcetera.

2. Backup the following databases from the data tier running your TFS 2008 environment:

  • TfsIntegration
  • TfsBuild
  • TfsWarehouse
  • TfsWorkItemTracking
  • TfsWorkItemTrackingAttachments
  • TfsVersionControl
  • TfsActivityLogging

3. Restore the 2008 backups via SQL Server Management Studio to the data tier in your TFS 2010 environment. In my case the 2008 database names were different than the 2010 database names so no name clashes occurred.

IMPORTANT NOTE: Do not follow this advice in production. You’ll likely want to point the tfsconfig import command at your old production server and, if not, there are safer ways to go about the database restore process.

4. Navigate to C:\Program Files\Microsoft Team Foundation Server 2010\Tools in a command window and kick off the import, which will effectively importing from your 2010 environment to your 2010 environment (if pointed to a production server, this process is destructive!):

tfsconfig import /sqlinstance:dev-tfs /collectionName:Imported /confirmed

It took this command 208 steps to do its thing.

Much to my surprise, the TFS 2008 databases restored previously were gone when I next checked in SQL Server Management Studio! Gasp!

5. Open Visual Studio and connect to your new team project(s).

6. Brian Harry also suggests changing the GUID of the migrated database for Beta 2; in my experience, the changeserverid command completed successfully after a warning that I shouldn’t be doing this to “a set of Team Foundation Server databases that have no application tiers configured” but the subsequent registerdb command failed with the following:

TF246017: Team Foundation Server could not connect to the database. Verify that the server that is hosting the database is operational, and that network problems are not blocking communication with the server.

This is a single-server environment with the command being run locally and the database itself is seemingly happy so I doubt a communication problem. At any rate, the mighty Google is silent on this problem and the environment seems kaput—revert, revert! I won’t explore this further as this step isn’t required for a real migration but I suppose it could be related to step 5 where I access the new environment; maybe I should have run these two commands first?

Brian also advises disabling SharePoint and Reporting Services via the Admin Console but I have yet to do that.

Update: After upgrading, we came across an issue where changesets that were previously merged "came back to life" in the merge candidate screen in VS 2010/TFS 2010. This KB article describes the problem and a hotfix is available to correct it. I'm not sure what the official MS stance is on this hotfix but you might want to apply it just in case.

Thanks to http://www.devh.de/post/Team-Foundation-Server-2010-Beta-2-Import-finally.aspx for the Beta 2 steps.

TFS 2010 Install and Western Australia Timezone Error (tf255356)

The TFS 2010 install is reportedly a walk in the park by comparison with previous versions so I thought it would be fun to give it a spin as we prepare to move from TFS 2008 to the latest and greatest.

First of all, if you’re doing a test install (or any kind of install, for that matter), the TFSInstall.chm guide included in the root of the installation media has a very well-documented process for installing both SQL Server 2008 and TFS. Unlike previous guides I’ve attempted to wade through, this one is actually quite a light read and presents just the information required to get up and running.

Apart from installing Windows Server 2008 R2 with Analysis Services and Reporting Services, I also installed SQL Server 2008 and SP1 before dropping into the TFS installer; the installer will add .NET 4, the Web Server (IIS) feature, WSS 3.0 if required, and SQL Server 2008 Express if required. I reused existing service accounts on the domain for SQL Server and TFS and created a new service account for Reporting Services. Some other bits were left to run as Network Service.

When installation completes, the configuration wizard kicks off. I went with the advanced option since I didn’t want to install SharePoint. 

The entire process was a smooth experience until I ran into an old nemesis for those of us opposed to daylight saving here in Western Australia:

tf255356 Error occurred while executing servicing step Create Warehouse for component TfsWarehouse during Install: The supplied DateTime represents an invalid time.  For example, when the clock is adjusted forward, any time in the period that is skipped is invalid.

This is interesting because the push for daylight savings was defeated a while back and the latest timezone updates were reported to be installed on my new R2 machine.

Luckily Andreww posted a work around on the connect issue: change the timezone from (UTC +8:00) Perth to (UTC +8:00) Tapei (where daylight savings is also not observed and Windows recognises the fact…). Before I could continue I had to delete both the TFS_Configuration and TFS_Warehouse databases as they were created before this problem cropped up.

All good from there… configuration completed successfully. But groan nonetheless, Microsoft!