Archive for the 'Technical' Category



SharePoint 2010 Managed Metadata or Choice Column?

Interestingly enough this is a conversation I have independently had recently with two customers. How do you decide whether to use a choice column or a managed metadata column in SharePoint 2010?

Hopefully you have a properly defined Information Architecture (if not give me a shout J) and you are using content types effectively, preferably defining them in a content type hub and pushing them out through the managed metadata service. Note that this works fine with choice fields as well as managed metadata fields.

You may want to use a choice field when

  • You only have a smallish (say less than 100) items to choose from and they are not arranged hierarchically
  • You do not want to use the filtered views of libraries that are available with managed metadata
  • You want to create a “one off” column for a particular library, and have no requirement now or in the future to share that classification across other libraries
  • You want users to have a dropdown rather than the picker in the UI
  • You want to be able to set values in the datasheet view (you can’t do this with managed metadata)

When either are acceptable I tend to favour managed metadata as it is more powerful and flexible – unless one of the bottom two above is an absolute requirement.

Ian

Back to PointBeyond web site

Finding Duplicate Documents in SharePoint using PowerShell

This script looks through all documents stored in a SharePoint site collection and finds duplicate files based on document contents rather than document names. This script has been written for SharePoint 2010 but should find duplicate documents in SharePoint 2007 as well with very little modification.

Over time, it is quite possible the same document will be uploaded to numerous SharePoint libraries. Keeping track of duplicate content spread across multi libraries can be practically impossible.

Building on the article here http://blog.codeassassin.com/2007/10/13/find-duplicate-files-with-powershell/ that details duplicate checking on fileshares, the following PowerShell script scans all your document libraries with a site collection for duplicate content by calculating an MD5 hash of the file contents. The script groups identical hashes and produces a list of all duplicated files, detailing the full url to item and the file name.

To run the script, copy the contents to notepad and save as a .ps1 file on one of your SharePoint servers. Then launch a PowerShell console and run the ps1 file.

Output to console showing duplicate files

PowerShell Console Output

The function returns the full path of all duplicated content.

This information could be piped back into SharePoint, or exported to Excel for analysis. You could even set this as a recurring job. In a future article, I will package this functionality into a timer job feature.

At present, the script stores all results in memory while it is running. If you are running this over a large site collection this may not scale very well. It may be worth streaming the results into a SQL table or similar. Also, at present this script will only evaluate content on a site collection basis but could be scoped to a web application or a whole farm if required.

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

function Get-DuplicateFiles ($RootSiteUrl)

{

$spSite = Get-SPSite -Identity $RootSiteUrl

$Items = @()

foreach ($SPweb in $spSite.allwebs)

{

Write-Host “Checking ” $spWeb.Title ” for duplicate documents”

foreach ($list in $spWeb.Lists)

{

if($list.BaseType -eq “DocumentLibrary” -and $list.RootFolder.Url -notlike “_*” -and $list.RootFolder.Url -notlike “SitePages*”)

{

foreach($item in $list.Items)

{

$record = New-Object -TypeName System.Object

if($item.File.length -gt 0)

{

$fileArray = $item.File.OpenBinary()

$hash = Get-MD5($fileArray)

$record | Add-Member NoteProperty ContentHash ($hash)

$record | Add-Member NoteProperty FileName ($file.Name)

$record | Add-Member NoteProperty FullPath ($spWeb.Url + “/” + $item.Url)

$Items += $record

}

}

}

}

$spWeb.Dispose()

$duplicateHashes = $Items | Group-Object ContentHash | Where-Object {$_.Count -gt 1}

foreach($duplicatehash in $duplicateHashes)

{

$duplicateFiles += $Items | Where-Object{$_.contentHash -eq $duplicatehash.Name}

$duplicateFiles += “————————————————————”

}

}

return $duplicateFiles |Format-Table FullPath

}

function Get-MD5($file = $(throw ‘Usage:Get-MD5[System.IO.FileInfo]‘))

{

$stream = $null;

$cryptoServiceProvider = [System.Security.Cryptography.MD5CryptoServiceProvider];

$hasAlgorithm = New-Object $cryptoServiceProvider

$stream = $file;

$hashByteArray = $hasAlgorithm.ComputeHash($stream);

return [string]$hashByteArray;

}

Get-DuplicateFiles(<your sharepoint site>)

Back to PointBeyond Website

Fix for Reminders not Displaying in Outlook 2010

Seems that quite a few people have reported that the popup reminder window in Outlook 2010 has stopped appearing. It started happening for me after applying Office 2010 Service Pack 1.

I checked the Outlook 2010 advanced settings and tried the steps detailed in http://support.microsoft.com/kb/286166 but no joy. Note that this article does not apply to Outlook 2010, but I thought it’s worth a go.

So I am using Office Online (BPOS). Here is what fixed it for me.

  1. Shut down Outlook.
  2. Go to the “Microsoft Office Online Services Sign In” tool.
  3. Click on the Options tab.
  4. Click on “Reconfigure my desktop applications.”

     

  5. Click “Next” through all the wizard pages.

Outlook now opens and starts downloading all of your content. Alerts now work again.

Back to the PointBeyond web site

Migrate Managed Metadata Service Database

Recently I came across the situation where I wanted to migrate the Managed Metadata Service database from one farm to another. Many differing solutions were mentioned on the interweb however I decided to just backup and restore the Managed Metadata database from old to new farm and see what happened. The new farm already had a Managed Metadata Service instance but had not been configured with any terms. I was also migrating a content database which had a few Managed Metadata columns and lots of items referencing the terms. I was therefore a little anxious as to whether my migrated content would display the migrated terms and if it would be possible to re-sync everything following migration or whether there might be some GUIDs that would not match. It turns out not to be so bad. Below are the steps taken to achieve this.

Backup the Managed Metadata database in old farm

Restore the Managed Metadata database in new farm overwriting the existing one

Give the account you are using db_owner permissions to the restored database

Open Central Admin and navigate to the Manage Services on Server section

Ensure that the Managed Metadata Web Service is started

Perform an IISRESET

In Central Admin navigate to the service applications page

Click on the Managed Metadata Service Application row (not the link through to the management screen)

Click on Administrators in the ribbon

Ensure that the account you are using is listed with Full Control

Click through to the Managed Metadata Service Application management page

In the Term Store Administrators section, add the account you are using

Click Save

Restore the content database

Log into the site of the restored content database

Go to Site Settings -> Site Columns where our Managed Metadata columns are listed

For each Managed Metadata column click through to the column settings page and re-link the term set anchor. You should see all migrated term sets

Your migrated content should now be showing the correct terms and you should be able to modify these values.

 

Back to PointBeyond web site

PowerShell CSV and Array Handling

Am continuing to be impressed by PowerShell. Working with CSV files and arrays is a breeze.

Take a look at this CSV (fruit.csv)

 

Fruit, Colour, Shape

Apple, Red, Round

Banana, Yellow, Curved

Kiwi, Green, Oval

 

We can get this into an array in Powershell with a single line

$fruit = Import-Csv “fruit.csv”

Then take a look at our array:

Want a row in the array, selecting by ID?

Or how about a single element, selecting the row by ID?

Or get a row where the shape is Oval?

Or get an element in the row, in this case the name of the fruit?

More SharePoint blogs coming up I promise…

Ian

Back to PointBeyond web site.

Should I use SharePoint for my Business Application?

SharePoint can be a great platform for delivering business applications. There are many examples such as vacation requests, purchase order requests, starters and leavers, training tracking and booking, sales tracking, contract management, timesheets, expenses, etc. These applications can often be built quickly and easily by leveraging the built in capabilities of SharePoint, Microsoft tools such as InfoPath and SharePoint Designer, or third party products. Using SharePoint as a business application platform can potentially bring the following benefits:

  • A single place for users to go to do and find things
  • Lower licence cost compared to point solutions
  • Removed or reduced need for (expensive) developers
  • Reduced costs through the replacement of legacy applications

So you may say that’s great – from now on let’s build all our business applications in SharePoint! It’s better for users and it’s going to cost less time and money, right? Well unfortunately and perhaps unsurprisingly it’s not as simple as that. Certain applications are more suited to being built in SharePoint than others. So when faced with a requirement for a business application, how do you decide whether or not SharePoint is the right choice?

To help with this I have devised a SharePoint suitability checklist as follows:

Business Application SharePoint Suitability Checklist

Question

Notes

How complex is the requirement, and are there existing products available?

We aren’t going to build a finance package from scratch on SharePoint (I hope), but we may integrate SharePoint to one.

What is the likely load and data volume?

SharePoint 2010 scales pretty well but it isn’t the best choice for very heavy loads and data volumes. We probably wouldn’t use it to manage ticket sales for the Olympics.

Are we constrained by time and/or money?

If these aren’t problems, then we could build exactly what we want, rather than accept possible constraints imposed by SharePoint.

Have we factored in licencing costs?

It may be quicker to custom develop something than to purchase a large number of licences. However it is important to consider the long term here as the total cost of custom developments (and ongoing maintanence) could easily end up outstripping licence costs.

Does the SharePoint toolset align with what we need to do?

In other words, can we make it do what we want it to do?

Are we flexible about the way an application works?

Do we have the flexibility within the business to accept any constraints imposed by SharePoint?

Are we fussy about how it looks?

If we’re planning to use out of the box SharePoint, or tools such as InfoPath, Excel Services, etc then there are going to be constraints on appearance, that the business needs to accept.

How capable/sensible are our users?

How much do we trust our users. If they are able to do silly things, will they do them? Will they be comfortable interacting with an application built on SharePoint?

Are we sure about long term complexity?

The SharePoint toolsets may allow us to get up and running quickly now, but is our application going to get much more complex, and beyond the capabilities of the toolsets in the future? We don’t want to have to start again from scratch.

Will it comply with our change management/deployment process?

Do the mechanisms available to release and update our application meet our requirements for change management?

 

I am sure that there are other items that could be added so comments and feedback welcome.

Ian

Back to PointBeyond web site.

SharePoint 2010, Network Load Balancing (NLB), Unicast or Multicast, and VMWare Virtual Machines

Many organisations are running multiple web front end servers in their SharePoint farms, and using Windows Network Load Balancing (NLB) to balance requests across those servers.

One important decision is whether or not to use NLB in unicast or multicast mode. In normal (physical machine) scenarios either should work fine, and the decision will depend on your network setup. For example unicast mode requires two NICs in each server.

However as I discovered this week, unicast mode will not work correctly with VMWare virtual machines. Full details are contained in the VMWare knowledge base article: Microsoft NLB not working properly in Unicast Mode.

My conclusion is if you want to load balance between multiple VMWare virtual server web front ends you can either:

  • Use NLB in multicast mode
  • Use NLB in unicast mode and follow the steps detailed in the article above
  • Purchase hardware load balancer(s) and use them instead of NLB – this is the best option really, but obviously some cost involved

Ian

Back to PointBeyond web site

PowerShell to create SharePoint groups

The PowerShell code below creates 3 SharePoint groups within a subsite using the examples of the standard SharePoint Owners, Members, and Visitors groups and assigns the relevant permissions level to each. It will also configure the groups to allow any member to edit the membership and show how to add users into the newly created groups. In this example we will ensure that the subsite has unique permissions and will contain only the 3 groups stated above.

Using the SharePoint Management Shell enter the following…

###### Get the web object that requires the new groups

$web = Get-SPWeb http://site/subsite

###### If the web object is currently inheriting permission then break the inheritance

if ($web.HasUniquePerm -eq $false)
{
$web.BreakRoleInheritance($true, $true)
}

###### Remove unnecessary groups/users from the site permissions
for ($i = $web.RoleAssignments.Count – 1; $i -ge 0; $i–)
{
$web.RoleAssignments.Remove($i)
}

###### Create the new groups

# Owner Group
$web.SiteGroups.Add(“$web Owners”, $web.Site.Owner, $web.Site.Owner, “Use this group to grant people full control permissions to the $web site”)
$ownerGroup = $web.SiteGroups["$web Owners"]
$ownerGroup.AllowMembersEditMembership = $true
$ownerGroup.Update()

# Members Group
$web.SiteGroups.Add(“$web Members”, $web.Site.Owner, $web.Site.Owner, “Use this group to grant people contribute permissions to the $web site”)
$membersGroup = $web.SiteGroups["$web Members"]
$membersGroup.AllowMembersEditMembership = $true
$membersGroup.Update()

# Visitors Group
$web.SiteGroups.Add(“$web Visitors”, $web.Site.Owner, $web.Site.Owner, “Use this group to grant people read permissions to the $web site”)
$visitorsGroup = $web.SiteGroups["$web Visitors"]
$visitorsGroup.AllowMembersEditMembership = $true
$visitorsGroup.Update()

###### Add users to group as required

$user1 = $web.Site.RootWeb.EnsureUser(“domain\ownerusername”)
$ownerGroup.AddUser($user1)

$user2 = $web.Site.RootWeb.EnsureUser(“domain\memberusername”)
$membersGroup.AddUser($user2)

$user3 = $web.Site.RootWeb.EnsureUser(“domain\visitorusername”)
$visitorsGroup.AddUser($user3)

###### Create a new assignment (group and permission level pair) which will be added to the web object

$ownerGroupAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($ownerGroup)
$membersGroupAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($membersGroup)
$visitorsGroupAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($visitorsGroup)

###### Get the permission levels to apply to the new groups

$ownerRoleDefinition = $web.Site.RootWeb.RoleDefinitions["Full Control"]
$membersRoleDefinition = $web.Site.RootWeb.RoleDefinitions["Contribute"]
$visitorsRoleDefinition = $web.Site.RootWeb.RoleDefinitions["Read"]

###### Assign the groups the appropriate permission level

$ownerGroupAssignment.RoleDefinitionBindings.Add($ownerRoleDefinition)
$membersGroupAssignment.RoleDefinitionBindings.Add($membersRoleDefinition)
$visitorsGroupAssignment.RoleDefinitionBindings.Add($visitorsRoleDefinition)

###### Add the groups with the permission level to the site

$web.RoleAssignments.Add($ownerGroupAssignment)
$web.RoleAssignments.Add($membersGroupAssignment)
$web.RoleAssignments.Add($visitorsGroupAssignment)

$web.Update()
$web.Dispose()

 

Back to PointBeyond web site

SharePoint UK User Group Southampton 19 May

What a great evening the user group meeting turned out to be on Thursday. The dev focussed theme was popular and pulled in a good size audience, regulars and also some new faces.

Martin Hatch kicked off the evening with a great session on Sandbox solutions, and clearly explained what they were and how they work. Martin also looked at full trust proxies and solution validators, and kept us entertained with numerous demos. Picture below of Martin in action, with Visual Studio open and a demo of solution validators.

Next up was Paul Beck, with an excellent session on CRUD operations using LINQ to SharePoint. Again this session included lots of demos and Paul explained and showed the use of SPMetal. Paul’s talk followed on nicely from Martin’s. Here is Paul in action, again deep into Visual Studio.

After these two sessions we took an interval and made the most of the bar that literally adjoins the lecture theatre at Southampton University. We are so lucky to have a great venue – how many other user groups have not only a proper lecture theatre for presentations, but also a very nice bar right next door? What more could you want!

Then suitably refreshed we returned for the last session of the evening, from Chris McKinley and Darren White from Twynhams School. The duo lived up to their billing of “an entertaining and informative session” (no pressure). They showed some code for creating dynamic icon bars, and also a dynamic theme picker that stored settings in a SharePoint list. For anyone who didn’t want to look at code there was also the chance to complete a Sudoku puzzle, but perhaps the best bit of the session was the “name that hex code colour” competition!

The Twynhams guys also very kindly brought along loads of memory sticks to give away. Finally we gave away a copy of Windows 7 Ultimate Edition and lots of books very kindly provided by Apress.

That rounded off the evening nicely, so thanks again to our speakers, Martin, Paul , Chris, and Darren, to Apress for providing the books, to Twynhams for providing the memory sticks, and to Southampton University.

That will be it for Southampton meetings now until September, when the theme will be real world “This is how we did it” presentations. I’ll be encouraging first time speakers and there will be some shorter slots available, so if you’ve done some interesting stuff with SharePoint now is your chance to tell us about it! Just get in touch or leave a comment on this blog if you would like to speak.

Have a great summer everyone!

Ian

Integrating CRM 2011 with SharePoint 2010 for Document Storage

You can now configure Dynamics CRM 2011 to store documents in SharePoint. The integration is fairly simplistic, using an IFrame under the bonnet, but it is nevertheless effective. These instructions show you how to set it up technically, but the configuration that is correct for you will depend on your situation.

For the instructions below I used a locally hosted instance of SharePoint Server 2010, and an instance of CRM 2011 online.

Installing the Dynamics CRM 2011 List Component

Download the component from

http://www.microsoft.com/downloads/en/details.aspx?FamilyID=23c0f351-8694-4d92-9ddf-34a949aec6a7&displayLang=en

In SharePoint 2010 Central Administration, go to Manage Web Applications, select the web application you wish to use and click on “General Settings”. Set Browser file handling to permissive for the web application:

Navigate to the folder where you downloaded CRM2011-SharePointList-ENU-amd64.exe, and double-click it.

In the Open File – Security Warning dialog box, click Run.

To accept the license agreement, click Yes.

Select a folder to store the extracted files, and click OK.

The following files are extracted:

AllowHtcExtn.ps1

crmlistcomponent.wsp

Open your browser.

In the address bar, type the URL of the site collection on which you want to install the Microsoft Dynamics CRM List component.

Click Site Actions, and then click Site Settings.

Under Galleries, click Solutions.

On the Solutions tab, in the New group, click Upload Solution.

Click Browse, locate the crmlistcomponent.wsp file, and then click OK.

Click close.

Make sure that the Sandboxed Code Service is running:

On the Solutions tab, in the Commands group, click Activate.

This did not work for me. To get the solution to activate the following procedure was needed (from http://blogs.msdn.com/b/sharepointdev/archive/2011/02/08/error-the-sandboxed-code-execution-request-was-refused-because-the-sandboxed-code-host-service-was-too-busy-to-handle-the-request.aspx)

On the server, click Start | Administrative Tools | Services.

On the Services dialog, scroll to SharePoint 2010 User Code Host.

Note the full user name in the Log On As column. You will need this information later.

Open SharePoint Management Shell.

Enter the following at the command prompt, including all punctuation.

(Get-SPManagedAccount –Identity “username”).Sid.Value

Replace username with the name you obtained above. E.g., CorpDomain\ServiceAccount

This will return the user’s SID (Security ID), which you will use in a later step.

Open the registry editor and navigate to:

HKEY_USERS\SID you obtained earlier\Software\Microsoft\Windows\CurrentVersion\WinTrust\Trust Providers\Software Publishing

Be sure the State key value is set to 0x00023e00.

Restart the sandboxed host service on all servers on which it is to run. It cannot hurt to do an iisreset as well.

Another known cause is that SharePoint is trying to check for certificate revocations at crl.microsoft.com. You can redirect these attempts by adding the following line to the end of the hosts file located at C:\Windows\System32\drivers\etc:

127.0.0.1 crl.microsoft.com

This must be done on all servers running the sandboxed host service. Then restart the service on all these servers. It cannot hurt to do an iisreset as well.

Add .htc extension to the list of the allowed file types

The steps mentioned here are required only if you are using Microsoft SharePoint Server 2010 (On-Premises).

You must be a SharePoint administrator or a farm administrator to be able to do the following steps:

Copy the AllowHtcExtn.ps1 script file to Microsoft SharePoint Server 2010.

In the Windows PowerShell window or in the SharePoint Management Console, run the command: AllowHtcExtn.ps1 <Web Application URL>

Example: AllowHtcExtn.ps1 http://mywebapplication

Configuring the connection

You can now go into CRM in Outlook (or the browser based version) and click on “Settings” then “System”, then “Document Management”.

From here you can set up the mapping between SharePoint in one of two ways. The easy way (shown below) creates a folder hierarchy for you, based on CRM entity types and names.

If you wish to though, you can set explicit mappings for each CRM entity through to a specific SharePoint location.

Which of these is correct for you will depend on how you intend to use SharePoint and the amount of documentation that you anticipate storing.

Now when you go to an entity in CRM you can click on documents in the left panel and interact with your documents in a SharePoint library, all from within CRM.

Note: To get Outlook integration to work it may be necessary to add the CRM web site to “Trusted Sites” in Internet Explorer.

Back to PointBeyond web site

« Previous PageNext Page »



Follow

Get every new post delivered to your Inbox.