For anyone thats interest I’ve got my slides from my South East Asia SharePoint Conference presentation on “The Modern Art of Taming Software Developers” available here. The slides don’t have everything I talk about so if you’re interested in finding out more, follow me on twitter (@christomich82) and I’ll let you know when the next conference I’ll be presenting at is.
South East Asia SharePoint Conference Presentation
Posted by Chris on November 11, 2011
Posted in Uncategorized | Leave a Comment »
The SharePoint ‘Tacklebox’
Posted by Chris on October 23, 2011
The other day I was talking to one of my clients and I was trying to explain what SharePoint is exactly and why projects delivering them tend to fail. Like most others, they had been sold on the collaborative power that SharePoint introduces into an organisation and how it was the be all and end all of online delivery of content, collaboration, business intelligence, search etc. After a little search in my head for the best analogy I could think of, I settled on comparing it to a fisherman’s tackle box.
When I was much younger my dad bought this fantastic fishing tackle box. It’s one of those boxes that when you pulled back the lid there would be all these multilevel compartments that could be folded out and had millions of little drawers to hold all kinds of different fishing tackle. My dad had filled it up with all kinds of different hooks, sinkers, floaters, leaders, etc. By having everything at our disposal it meant that we would be prepared for any fishing environment.
Now just because we had purchased a complete kit with all the equipment any fishing pro would have at his disposal did not make everyone in my family a pro. In most cases I had no clue what the thing did or when or how it should even be used. Context is a major part of fishing, just like in a SharePoint project. Knowing what the functional use for the accessory is does not mean you know the environment or situation in which to use it. For example, can you have a guess as to what the following equipment is and when it’s typically used?
If you didn’t manage to guess it, its a fish bite alarm. To some this may seem pointless because you’d be asking the question “wouldn’t you know that you have a fish by the fact its trying to rip the rod out of your line?” and you’d be correct in some circumstances but there are times when you may have multiple lines or the kind of fish you’re fishing for requires a more subtle technique meaning the bite is quite hard to detect without some kind of aid. SharePoint is no different; there is a time and a place for all its components.
When you install SharePoint, you aren’t installing a tool with the knowledge and wisdom of a thousand grey haired developers. What you’re installing is a tool of immeasurable pain toolbox of components commonly used in the development of a variety of web based applications. Just like fishing, we need to know the environment we’re in. We need to know whether it is an intranet site, internet site, collaborative portal, document management portal, or records management portal (just to mention a few) that we’re building. We also need to have an understanding of the IT / businesses processes and procedures in place as these are likely to affect the kinds of solutions and the paths we choose for customisation.
Judging the success/failure of a SharePoint project is also much like fishing, we judge it on the level of user engagement we attract. The less user engagement, the more likely we’ve totally missed the needs of the business. The more we understand the business needs as the business views it (I’m glaring at those developers who think they know the business better than the business knows itself) before we undertake the development of the project then the higher level of user engagement we’ll receive.
The ultimate point in all of this is that SharePoint alone won’t get the level of user engagement sought after by organisations. There is a level of maturity and understanding required by implementers around both the needs of the business and the business goals that are to be achieved. These need to be understood long before you decide upon SharePoint as the platform. It’s for this reason that many SharePoint projects fail. SharePoint can deliver on the promises of collaboration, portal, business intelligence, business processes, content management, and search. What it can’t deliver and doesn’t promise to deliver is that these tools will be used properly by the SharePoint ‘fisherman’ and that any users will be successfully ‘caught’.
Posted in Development | Tagged: Governance, MOSS 2007, SharePoint, SharePoint 2010 | Leave a Comment »
Shameless Conference Plug
Posted by Chris on October 9, 2011
I’ve been accepted to present on SharePoint governance and finding goal alignment at the SharePoint Conference Asia 2011 in Singapore so here is my shameless plug to come to my session.
I’ll be discussing various techniques we’ve used to find goal alignment within an organisation as this has been a critical success factor in all the SharePoint deployments my consultancy has undertaken. In particular I’ll explore one of the biggest factors we’ve noted as being a hurdle to finding this goal alignment which is the way most organisations have been structured.
If you’re going to be in the area in November on the 8 – 9 and are interested in coming you can find out more here http://www.sharepointconference.asia/sea/2011/solutionpages/default.aspx.
Posted in Uncategorized | Leave a Comment »
MOSS World (parody of Gary Jule version of Mad World)
Posted by Chris on March 19, 2011
My colleague and a few other SharePoint gurus came up with this gold. I think it aptly sums up the feelings of most SharePoint Consultants that inherit projects. Enjoy.
Posted in General, SharePoint | Tagged: SharePoint | Leave a Comment »
Follow-up on ‘Can’t Find .NET Framework Class Methods’
Posted by Chris on January 14, 2011
Ok so after figuring out why the PowerShell ISE wasn’t loading the appropriate .NET Framework I added the registry key to enforce that .NET Framework v4.0 always loaded – bad idea. When you do this it means that the .NET Framework v4.0 will be loaded instead of the .NET Framework version you selected for that particular Visual Studio project. This results in a variable array of ‘could not be resolved because it has a higher version’, ‘type or namespace could not be found’, and ‘predefined type is defined in multiple assemblies in the global alias’ warnings and errors.
To get yourself back to a usable state, delete the registry keys out. Below are the commands that will let you do this from the commandline.
reg delete hklm\software\microsoft\.netframework /v OnlyUseLatestCLR reg delete hklm\software\wow6432node\microsoft\.netframework /v OnlyUseLatestCLR
Posted in Uncategorized | Leave a Comment »
PowerShell ISE Can’t Find .NET Framework Class Methods
Posted by Chris on January 9, 2011
So I have started a new love affair with PowerShell and have started developing more and more things using it as it means I don’t have to bother with the UI, compiling or deployment – which for SOME situations is perfect. But today I came across an interesting problem while trying to load some .NET Framework classes.
I was attempting to call a method on the .NET Framework object I instantiated and found that the Dispose method that was mentioned on MSDN was being reported by PowerShell ISE as “Method invocation failed because [System.Security.Cryptography.RSACryptoServiceProvider] doesn’t contain a method named ‘Dispose’”.
After a bit of scratching my head I decided to look back at version v1.1 of the .NET Framework documentation to see if the Dispose method was present and guess what… it wasn’t. I went through the versions and found that it hadn’t been added till v3.5 of the .NET Framework. So after doing a few quick searches on Google I managed to find out on this post that by default the PowerShell ISE is loading an older version of the framework (presumably v2.0/v3.0) and that there are two ways to fix this.
- Using the following lines, edit the registry so that the .NET Framework loaded systemwide will be .NET Framework 4.0. WARNING: Use with Caution. See here for why
reg add hklm\software\microsoft\.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1 reg add hklm\software\wow6432node\microsoft\.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1
- Adding the following configuration to the ‘$psHome\powershell_ise.exe.config’ file. This will load the .NET Framework 4.0 for only the PowerShell ISE.
<?xml version="1.0" encoding="utf-8"?> <configuration> <startup> <supportedRuntime version="v4.0.20826" /> </startup> </configuration>
Either method will work but personally I just use the registry modification as it saves me the hassle with any future applications.
Posted in PowerShell | Tagged: .NET, Powershell | 2 Comments »
Invalid Terms in Managed Metadata Field
Posted by Chris on January 7, 2011
Recently I came across the problem where the terms inside managed metadata fields in a list become invalid after migrating a site. Even after re-linking the term sets to which the managed metadata fields were assigned, the values for each of the items were invalid. The stupid thing is when I went to edit the field the name would be found straight away in the term store and it was just a matter of clicking on the term again and saving and all would be fine.
After some investigating I found out that the IDs that were being referenced by the items had changed during the migration and thus needed to be updated. Obviously going through 4 columns on over 100+ items wasn’t going to be productive so I wrote up a powershell script to go through each item, find the appropriate term in the term store and update it with the new ID.
Before you use the script you will also need to go through and reconnect the managed metadata fields to the appropriate term sets. I did try to add this functionality into the script itself but unfortunately it appears as though only the GUIDs are stored inside the field meaning I have no idea which term set to use without having access to the original server. If you run the script in ‘test’ mode, it will flag if a field is currently connected to an invalid term set so this will help you narrow down which fields need to be updated.
Update: I’ve setup a CodePlex site at http://sptermstoreutilities.codeplex.com/ where you can download the following script.
Below is the code for the script but I recommend running it in test mode first and making sure that you aren’t receiving any peculiar errors or exceptions. From the SharePoint 2010 Management Shell, use it as so (by the way, I called my script ReloadTermSets.ps1 so just rename that part to whatever you call the script) -
.\ReloadTermSets.ps1 -web “http://localhost” -test -recurse
web – This is the web address to use.
test – This uses a ‘test’ mode that will output lines detailing found fields and the values found for them in the term store and won’t save the items.
recurse – This flag will cause the script to recurse through all child sites.
DISCLAIMER: Use the following script/advice at your own risk! By using/viewing/distributing it you accept responsibility for any loss/corruption of data that may be incurred by said actions. Myself and any contributors to this site accept no liability for any damage that may occur from the use of this information or any advice provided.
param
(
[string]$web = "",
[switch]$recurse,
[switch]$test
)
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Taxonomy")
function UpdateTaxonomyFields
{
param
(
[string]$webAddress = "",
[switch]$recurse,
[switch]$test
)
$web = Get-SPWeb $webAddress
$taxonomySession = Get-SPTaxonomySession -Site $web.Site
$taxonomyType = [Type]::GetType("Microsoft.SharePoint.Taxonomy.TaxonomyField, Microsoft.SharePoint.Taxonomy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c", $true)
foreach ($list in $web.Lists)
{
try
{
foreach ($field in $list.Fields)
{
$query = New-Object Microsoft.SharePoint.SPQuery
$listItems = $list.GetItems($query)
if ($field.GetType() -eq $taxonomyType)
{
Write-Host "Entering List '", $list.Title, "' Located At:", $list.DefaultViewUrl, "On Field:", $field.Title
if (-not $field.IsTermSetValid)
{
Write-Host "Current Term Set Invalid:", $field.TermSetId, " Field Name:", $field.Title
}
foreach ($item in $listItems)
{
$currentTerms = $item[$field]
if (-not [string]::IsNullOrEmpty($currentTerms))
{
$newTerms = New-Object Microsoft.SharePoint.Taxonomy.TaxonomyFieldValueCollection $field
if ($test)
{
Write-Host "Term Replacement Starting"
}
foreach ($term in $currentTerms)
{
Write-Host $term
$fullTermLabel = $term.Label
$lastIndexOfTermSeparator = $fullTermLabel.LastIndexOf(":")
$termLabel = $fullTermLabel.Substring($lastIndexOfTermSeparator + 1)
$existingTerms = $taxonomySession.GetTerms($termLabel, $false)
if ($existingTerms.Count -gt 1)
{
if ($test)
{
Write-Host "Found Terms"
}
$termIsFound = $false
$matchedTerm = ""
foreach ($foundTerm in $existingTerms)
{
$foundTermPath = $foundTerm.GetPath().Replace(";", ":")
if ($foundTermPath -eq $fullTermLabel)
{
Write-Host "Matching Term Found Found Term:", $foundTermPath, "Full Term:", $fullTermLabel
$termIsFound = $true
$matchedTerm = $foundTerm
}
}
if (-not $termIsFound -and $test)
{
Write-Host "No exact term found"
}
elseif ($termIsFound)
{
Write-Host "Replacing Term:", $fullTermLabel, "New Term:", $matchedTerm.GetPath()
$termValueAsString = "-1" + ";#" + $matchedTerm.GetPath() + [Microsoft.SharePoint.Taxonomy.TaxonomyField]::TaxonomyGuidLabelDelimiter + $matchedTerm.Id.ToString()
Write-Host $termValueAsString
$termValue = New-Object Microsoft.SharePoint.Taxonomy.TaxonomyFieldValue $termValueAsString
$newTerms.Add($termValue)
}
if ($test)
{
Write-Host "End of Found Terms"
}
}
elseif ($existingTerms.Count -le 0)
{
Write-Host "Term For Item '", $item.Id, "' At List '", $list.Title, "' Located At", $list.DefaultViewUrl, "Has No Matching Term"
}
else
{
if ($test)
{
try
{
Write-Host " Old Term:", $term.Label, "New Term:", $existingTerms[0].GetPath()
}
catch
{
Write-Host "Error Occurred Full Term Label:", $fullTermLabel, "| Term Label:", $termLabel, "| Found Terms Count:", $existingTerms.Count
}
}
else
{
Write-Host "Replacing Term:", $fullTermLabel, "New Term:", $existingTerms[0].GetPath()
$termValueAsString = "-1" + ";#" + $existingTerms[0].GetPath() + [Microsoft.SharePoint.Taxonomy.TaxonomyField]::TaxonomyGuidLabelDelimiter + $existingTerms[0].Id.ToString()
Write-Host $termValueAsString
$termValue = New-Object Microsoft.SharePoint.Taxonomy.TaxonomyFieldValue $termValueAsString
$newTerms.Add($termValue)
}
}
}
try
{
if ($test)
{
Write-Host "Term Replacement Finished"
}
else
{
if ($field.AllowMultipleValues)
{
$field.SetFieldValue($item, $newTerms)
$item.Update()
}
elseif ($newTerms.Count -gt 0)
{
$field.SetFieldValue($item, $newTerms[0])
$item.Update()
}
}
}
catch [System.Management.Automation.ExtendedTypeSystemException]
{
Write-Host $_.Exception.ToString()
}
}
else
{
Write-Host "Item Is Empty:", $item.Id, $item.Title
}
}
}
}
}
catch [System.Management.Automation.ExtendedTypeSystemException]
{
Write-Host $_.Exception.ToString()
}
}
if ($recurse)
{
foreach ($childWeb in $web.Webs)
{
if ($test)
{
Write-Host "Child Web:", $childWeb.Url
}
UpdateTaxonomyFields -webAddress $childWeb.Url -test:$test -recurse:$recurse
}
}
}
UpdateTaxonomyFields -webAddress $web -test:$test -recurse:$recurse
Posted in PowerShell, SharePoint | Tagged: Powershell, SharePoint, SharePoint 2010 | 8 Comments »
Mixing MOSS 2007 x86 and x64 in a Farm
Posted by Chris on November 1, 2010
The question arose today for me whether you can add an x64 SharePoint MOSS 2007 to an x86 SharePoint MOSS 2007 farm and the short answer is yes you can. I imagine that as this situation works you can also add an x64 SharePoint WSS 3.0 server to an x86 SharePoint WSS 3.0 farm as MOSS is built off the WSS 3.0 code base anyway.
I can’t seem to find anything online that says you shouldn’t although if anyone can enlighten the best practices on whether to do it or not, I’d very much like to hear the reasoning.
Posted in SharePoint | Tagged: Configuration, SharePoint, WSS 3.0, x64, x86 | Leave a Comment »
SQL Management Studio Problem Connecting to WSS 3.0 Database
Posted by Chris on October 19, 2010
Today I came across the following error (which I have encountered many a time previously) but I totally forgot how I resolved it the last time. I hit the error most typically when I’m accessing a WSS 3.0 deployment using the Windows Internal Database. I’ve also encountered it when I access some SQL Server deployments.
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified) (Microsoft SQL Server)
I feel absolutely stupid for continuously hitting this same issue and forgetting how I resolved it previously so I’ve decided to write a quick blog post on steps to follow next time it happens (this assumes I remember that I blogged about the issue).
- If its a local Windows Internal Database you’re accessing, make sure you’re accessing the right address. So many times I’ve assumed the address is going to be localhost/MICROSOFT##SSEE when in fact the address you need to be accessing is \\.\pipe\MSSQL$MICROSOFT##SSEE\sql\query. This has tripped me up so many times its embarrassing.
- If you’re absolutely sure you got the right address, check TCP/IP and Named Pipes have been enabled for the SQL Server instance. You can do this by doing the following steps on the machine hosting the SQL Server instance.
- Go to the Start Menu -> All Programs -> Microsoft SQL Server 2005/2008 -> Configuration Tools -> SQL Server Configuration Manager.
- Once the Sql Server Configuration Manager has loaded, check under SQL Native Client 10.0 Configuration (32bit) -> Client Protocols and SQL Native Client 10.0 Configuration -> Client Protocols that TCP/IP and Named Pipes are both enabled.
- Check the protocols allowed, for the instance you wish to access, under the SQL Server Network Configuration section. Again make sure that TCP/IP and Named Pipes are enabled.
- You will need to restart the SQL Server instance if you’ve had to make any of the changes above.
These two steps are usually the only steps I need to perform before I realise whats wrong. I’ll add more steps if I come across any other things that trip me up in the future or if anyone else has any to contribute.
Posted in SharePoint | Tagged: SharePoint, SQL, WSS 3.0 | 3 Comments »








