When software attacks!

Thoughts and musings on anything that comes to mind

9. December 2011 20:16
by Rik Hepworth
0 Comments

Streaming video to XBOX 360 from Windows Home Server 2011

9. December 2011 20:16 by Rik Hepworth | 0 Comments

This one threw me for a while and I could find nothing specific on the web. I wanted to use my Xbox 360 to watch video streamed from my Windows Home Server. Streaming is switched on by default, I hear you say. Why, yes it is, but each time I tried to connect the Xbox I received an error.

The solution? Enable the Guest account on the server. Do this with care – revoke it’s access to everything except the folders you want to stream unless you want to allow read access to everything on the server.

Once Guest was enabled and the access rights were applied the whole thing worked like a charm.

7. December 2011 12:51
by Rik Hepworth
1 Comments

Displaying a SharePoint 2010 library on a page in a different site within the same site collection

7. December 2011 12:51 by Rik Hepworth | 1 Comments

One of our customers contacted us the other day with a problem. They wanted to put a view of a document library that was located in the top level site of a site collection onto the landing pages of all the second level sites in that collection. The customer had consulted the internet hive mind and found a blog post with instructions which had been diligently followed and yet whenever a user clicked ‘New’ on the ribbon bar an error occurred.

After a bit of poking and prodding on my local test system I not only replicated the fault but also found the cure. Since none of the other sites on the internet that I found mentioned this, I thought I’d better write it up for the world.

 

The screenshot below shows you our goal. The ‘Main Site Shared Documents’ web part actually points to a document library that is in the site above the one we are in.

Group Site with external document library web part

Step 1: Export the original list web part with SharePoint Designer 2010

In order to place the view we need on our page we need a web part. To get that we have to edit the page of the view of our document library in SharePoint designer.

Navigate to the view of your document library and in the ribbon part choose ‘Modify In SharePoint Designer (Advanced) from the drop down ‘Modify View’ menu.

modify view in designer

 

Once you have the page open in SharePoint Designer, you need to select the XsltListViewWebPart that is showing the contents of the library.

xsltlistviewwebpart

With the web part selected you will be able to switch Designer’s ribbon to the Web Part tab and choose ‘To File’ from the Save Web Part panel. Saving to the Site Gallery won’t work – I tried and SharePoint complained every time I added the web part to a page.

When you save the web part SharePoint Designer will throw up a dialog box:

export web part question

You need to answer ‘Yes’ to this question because we want the web part to always point at our target document library, no matter where we use it.

save web part to file

Step 2: Add the web part to your page

Edit your target page and add a web part to your intended zone. When the web part panel comes up, you will see ‘Upload a Web Part’ in small text beneath the Categories panel and clicking that will expand the control to give you a file browser.

Browse to the web part you saved from SharePoint Designer and then Upload the file. The web part picker will close at this point. Don’t panic!

upload a web part

Go through the steps to add a web part again and this time in the Categories panel you will have a new item at the top called Imported Web Parts. Select that and your web part will appear in the list so you can add it to the page.

add an imported web part

Step 3: Change the toolbar setting on the web part

This is the important bit! When you add the new web part to your page everything appears to work fine. Documents from the document library open fine and clicking the ‘Add a new document’ link will open the upload dialog as they should. However, if you use the ribbon bar then you will notice very quickly that it is not the correct ribbon bar for the library – the items on the New menu will be wrong (if you have custom content types that’s easier to spot!) and trying to use the buttons will cause errors.

The solution to this conundrum turned out to be straightforward – simply change the toolbar setting of the web part. If you choose ‘Full Toolbar’ or ‘Show Toolbar’ you will see the erroneous behaviour; choose ‘Summary Toolbar’ or ‘No Toolbar’ and all will work fine.

broken menu with web part settings

The setting shown above on the web part will give you a broken menu (the other web part on the page is a calendar, so I get appointments!)

working menu with web part settings

The setting shown above works just fine.

12. May 2011 18:05
by Rik Hepworth
2 Comments

Making SharePoint 2010 search pages work with a proper master page

12. May 2011 18:05 by Rik Hepworth | 2 Comments

If you talk to those who know me about my pet hates in SharePoint, the search pages will come up every time. It’s not that I hate search itself – that’s great, but the minimal.master is just plain annoying. It makes the search centre a black hole into which you can fall but not navigate out of – there’s no navigation and the portal site connection doesn’t work.

I’ve been meaning to get search working with a real master page (step forwards, v4.master) for a while and never got around to it. However, I needed to fix it for a demo and having done so I thought I’d document the steps involved for the world.

To set the scene, here are some screenshots of the default Enterprise Search Centre pages:

default searchcentredefault searchresultsdefault peopleresults

If you climb into site settings and change the Site Master Page to v4.master, this is what you get:

v4 master search page

That’s not very usable, is it. Moreover, if you click the breadcrumbs/portal site connection icon in the top bar you see the following:

v4 master search page with search box

That’s just barking mad, frankly. However, it does give us a solid clue as to how we go about fixing the page.

Step 1: Fix the layout pages

I had a rummage around the search centre’s masterpage folder and found the cause of our problems. Some bright spark decided to use the PlaceHolderTitleBreadcrumb as the content area to put the search box in. That speaks more about the structure of the minimal.master page than the search layout pages, to be fair. It is most definitely not where it should be, however.

Using SharePoint Designer, open your Search Centre SharePoint site and look in the _catalogs\masterpage folder. In there you will see three page layouts: SearchMain.aspx, SearchResults.aspx and ReopleSearchResults.aspx.

sharepoint designer masterpages highlighted

Let’s do SearchMain first – the site landing page. Right-click the file and choose Edit File in Advanced Mode

Step 1a: Move the search box to the right place

Find the line that reads:

<asp:Content ContentPlaceHolderID="PlaceHolderTitleBreadcrumb" runat="server">

You want to cut the markup that is inside that content placeholder:

<SharePoint:UIVersionedContent UIVersion="3" runat="server">
<ContentTemplate>
<div style="height:100%; width:100%;padding-left: 18px; padding-top: 50px; padding-bottom: 10px;">
<center>
<div style="width: 510px">
<SPSWC:ListBoundTabStrip ID="Tab" runat="server" PersistQueryString="true" CSSClassNamePrefix="ms-sctab" ListName="<%$Resources:Microsoft.Office.Server.Search,SearchCenterOnet_SearchCenterListName%>" ResourceIdforListName="$Resources:Microsoft.Office.Server.Search,SearchCenterOnet_SearchCenterListName" UnselectedTabTrimLength="-1"></SPSWC:ListBoundTabStrip>
<div style="padding-top: 0px">
</ContentTemplate>
</SharePoint:UIVersionedContent>
<SharePoint:UIVersionedContent UIVersion="4" runat="server">
<ContentTemplate>
<div class="srch-sb-main">
<div class="srch-sb-results4">
<div>
<SPSWC:ListBoundTabStrip ID="Tab1" runat="server" CSSFileName="Themable/search.css" PersistQueryString="true" CSSClassNamePrefix="ms-sctab" ListName="<%$Resources:Microsoft.Office.Server.Search,SearchCenterOnet_SearchCenterListName%>" ResourceIdforListName="$Resources:Microsoft.Office.Server.Search,SearchCenterOnet_SearchCenterListName" UnselectedTabTrimLength="-1"></SPSWC:ListBoundTabStrip>
</div>
<div class="srch-sb-results6">
</ContentTemplate>
</SharePoint:UIVersionedContent>
<WebPartPages:WebPartZone runat="server" AllowPersonalization="false" FrameType="TitleBarOnly" Title="<%$Resources:Microsoft.Office.Server.Search,LayoutPageZone_TopZone%>" ID="TopZone" Orientation="Vertical" QuickAdd-GroupNames="Search" QuickAdd-ShowListsAndLibraries="false"><ZoneTemplate>
<WpNs0:SearchBoxEx runat="server" __MarkupType="xmlmarkup" WebPart="true" __WebPartId="{C00D0719-CF8A-47A2-9E31-FA3F6A38948F}" >
<WebPart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/WebPart/v2">
  <Title>Search Box</Title>
  <FrameType>None</FrameType>
  <Description>Displays a search box that allows users to search for information.</Description>
  <IsIncluded>true</IsIncluded>
  <ZoneID>TopZone</ZoneID>
  <PartOrder>1</PartOrder>
  <FrameState>Normal</FrameState>
  <Height />
  <Width>800px</Width>
  <AllowRemove>true</AllowRemove>
  <AllowZoneChange>true</AllowZoneChange>
  <AllowMinimize>true</AllowMinimize>
  <AllowConnect>true</AllowConnect>
  <AllowEdit>true</AllowEdit>
  <AllowHide>true</AllowHide>
  <IsVisible>true</IsVisible>
  <DetailLink />
  <HelpLink />
  <HelpMode>Modeless</HelpMode>
  <Dir>Default</Dir>
  <PartImageSmall />
  <MissingAssembly>Cannot import this Web Part.</MissingAssembly>
  <PartImageLarge />
  <IsIncludedFilter />
  <ExportControlledProperties>true</ExportControlledProperties>
  <ConnectionID>00000000-0000-0000-0000-000000000000</ConnectionID>
  <ID>g_c00d0719_cf8a_47a2_9e31_fa3f6a38948f</ID>
  <GoImageUrl xmlns="urn:schemas-microsoft-com:SearchBoxEx">/_layouts/images/gosearch30.png</GoImageUrl>
  <GoImageUrlRTL xmlns="urn:schemas-microsoft-com:SearchBoxEx">/_layouts/images/gosearchrtl30.png</GoImageUrlRTL>
  <GoImageActiveUrl xmlns="urn:schemas-microsoft-com:SearchBoxEx">/_layouts/images/gosearchhover30.png</GoImageActiveUrl>
  <GoImageActiveUrlRTL xmlns="urn:schemas-microsoft-com:SearchBoxEx">/_layouts/images/gosearchrtlhover30.png</GoImageActiveUrlRTL>
  <ShowAdvancedSearch xmlns="urn:schemas-microsoft-com:SearchBoxEx">true</ShowAdvancedSearch>
  <DropDownModeEx xmlns="urn:schemas-microsoft-com:SearchBoxEx">HideScopeDD</DropDownModeEx>
  <IsMysiteSearchBox xmlns="urn:schemas-microsoft-com:SearchBoxEx">false</IsMysiteSearchBox>
  <TextBoxWidth xmlns="urn:schemas-microsoft-com:SearchBoxEx">368</TextBoxWidth>
  <ShowPerferenceLink xmlns="urn:schemas-microsoft-com:SearchBoxEx">true</ShowPerferenceLink>
  <ShowQuerySuggestions xmlns="urn:schemas-microsoft-com:SearchBoxEx">true</ShowQuerySuggestions>
  <SearchBoxVisual xmlns="urn:schemas-microsoft-com:SearchBoxEx">SearchCenterDefault</SearchBoxVisual>
  <AdvancedSearchPageURL xmlns="urn:schemas-microsoft-com:SearchBoxEx">/searchcentre/Pages/advanced.aspx</AdvancedSearchPageURL>
  <SearchResultPageURL xmlns="urn:schemas-microsoft-com:SearchBoxEx">results.aspx</SearchResultPageURL>
  <RegisterStyles xmlns="urn:schemas-microsoft-com:SearchBoxEx">true</RegisterStyles>
  <ShouldTakeFocusIfEmpty xmlns="urn:schemas-microsoft-com:SearchBoxEx">true</ShouldTakeFocusIfEmpty>
</WebPart>
</WpNs0:SearchBoxEx>
</ZoneTemplate></WebPartPages:WebPartZone>
</div>
</div>
<SharePoint:UIVersionedContent UIVersion="3" runat="server">
<ContentTemplate>
</center>
</ContentTemplate>
</SharePoint:UIVersionedContent>
</div>

That code needs to be pasted into the PlaceHolderMain content area, just after the markup to open the content area:

<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">

Save the file and take a look, and you should see this:

edited search centre 1

It’s not quite right – everything’s shifted to the left. We’ll come back to that because it’s not fixable by editing the layout pages.

You’ll also notice that there are no breadcrumbs at all so no portal connection.

Step 1b: Fix the breadcrumbs

We’ll need to get the correct code for the breadcrumbs from another layout page. I grabbed it from the article page layout. It needs to go inside the PlacholderTitleBreadcrumb content area markup.

<SharePointWebControls:VersionedPlaceHolder UIVersion="3" runat="server">
<ContentTemplate>
<asp:SiteMapPath ID="siteMapPath" runat="server" SiteMapProvider="CurrentNavigation" RenderCurrentNodeAsLink="false" SkipLinkText="" CurrentNodeStyle-CssClass="current" NodeStyle-CssClass="ms-sitemapdirectional"/>
</ContentTemplate>
</SharePointWebControls:VersionedPlaceHolder>
<SharePointWebControls:UIVersionedContent UIVersion="4" runat="server">
<ContentTemplate>
<SharePointWebControls:ListSiteMapPath runat="server" SiteMapProviders="CurrentNavigation" RenderCurrentNodeAsLink="false" PathSeparator="" CssClass="s4-breadcrumb" NodeStyle-CssClass="s4-breadcrumbNode" CurrentNodeStyle-CssClass="s4-breadcrumbCurrentNode" RootNodeStyle-CssClass="s4-breadcrumbRootNode" NodeImageOffsetX=0 NodeImageOffsetY=353 NodeImageWidth=16 NodeImageHeight=16 NodeImageUrl="/_layouts/images/fgimg.png" HideInteriorRootNodes="true" SkipLinkText="" />
</ContentTemplate>
</SharePointWebControls:UIVersionedContent>

However, if you save the page and view it now you’ll get an error, because that markup references controls that the page doesn’t know about. In order to register them, we need to add a line into the section at the top of the page code that registers tag prefixes:

<%@ Register Tagprefix="SharePointWebControls" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

The SearchMain.aspx layout page will  now work with the v4.master selected.

You’ll notice, however, that the ribbon isn’t quite right. That’s because it’s actually in twice – one in the v4.master and once in SearchMain.

Step 1c: Fix the ribbon

Find the following markup:

<asp:Content ContentPlaceHolderID="SPNavigation" runat="server">

After that line you’ll see another that reads:

<SharePoint:UIVersionedContent UIVersion="4" runat="server">

Right-click the tag and choose ‘select Tag’ from the context menu. Remove the highlighted code and you should be left with an empty SPNavigation content area. If you look at the page now, the ribbon works as it should.

Run through the same steps with the other search pages. I’m a bit paranoid, so whilst I’m pretty sure the content of the PlaceHolderTitleBreadcrumb is the same for all the layout pages, I always copy and paste the code within the page itself, then add the breadcrumb code afterwards.

You should now have a Search Centre that looks like this:

edited search centre 2edited searchresultsedited peopleresults

Step 2: Fix the master page

I said that the annoying shift to the right couldn’t be fixed in the layout pages. We need to edit the master page for that (and/or the styles if you like, but the master page is quicker for just one site).

Remember: Editing the v4.master page will prevent it being updated if Microsoft release SharePoint patches that include a new version, as we’ve modified the local copy in the site. If you want to be a good SharePoint admin, create a new master page for the search site!

This bit’s easy. Search for the line:

<div class="s4-ca s4-ca-dlgNoRibbon" id="MSO_ContentTable">

Edit it to read:

<div class="s4-ca s4-ca-dlgNoRibbon" id="MSO_ContentTable"  style="margin-left:0;">

All we’ve done is added a local styling rule to override the ones in the main stylesheets and set the left margin on that element to zero.

Save the master page and you should now get pages that look like this:

edited search centre 3edited searchresults 2edited peopleresults 2

Still to do…

Before you all shout at me, I know that the breadcrumbs don’t display like they ought to. I need to look into that – I remember reading somewhere that they work differently on pages in a page library than elsewhere. I need to do some research and see if I can fix that. Hey – isn’t ditching the minimal.master enough for you?

Next on the hit list – Access Services sites using minimal.master!

4. April 2011 13:57
by Rik Hepworth
0 Comments

Content Types programmatically added to SharePoint libraries not appearing on New menu

4. April 2011 13:57 by Rik Hepworth | 0 Comments

This one caused some consternation, I can tell you. As usual, the solution could be found on the great wide web, but it took some digging, so as usual I am repeating it here.

As part of a SharePoint migration we did recently, we replaced a SharePoint 2007 feature that the client was using (which added content types to libraries from a central list) with a mix of content type replication and PowerShell to add the content types to the libraries.

The code below scans through any site collections whose url begins with our $hostheader variable, then adds the list of content types to the Shared Document library in every web in the site collection. It’s a simple modification of some code on Phil Childs’ Get-SPScripts.com site and I take no credit for it – it’s all Phil’s work.

# Specify name of the library to look for in each site
#
$hostheader = "http://mywebapp*"
$lookForList = "Shared Documents"
#find our site collections and run through each in turn
# get all the site collections, then step into each site in each site collection
# find the list with the name in the var lookforlist
# then change content types on the list specified
#
# note - this will only find site collections where the url starts with the host header var
#
get-spsite where {$_.url -like $hostheader}| Get-SPWeb -Limit all | ForEach-Object {
    write-host "Checking site:"$_.Title
    #Make sure content types are allowed on the list specified
    $docLibrary = $_.Lists[$lookForList]
    if ($docLibrary -ne $null)
    {
        $docLibrary.ContentTypesEnabled = $true
        $docLibrary.Update()
        # Add site content types to the list
                # change the name in the quotes to the name of your content type
                #
        $ctToAdd = $site.RootWeb.ContentTypes["Word Document"]
        $ct = $docLibrary.ContentTypes.Add($ctToAdd)
        write-host "Content type" $ct.Name "added to list" $docLibrary.Title
                # 
        # Add second site content types to the list
                # change the name in the quotes to the name of your content type
                #
        $ctToAdd = $site.RootWeb.ContentTypes["Excel Spreadsheet"]
        $ct = $docLibrary.ContentTypes.Add($ctToAdd)
        write-host "Content type" $ct.Name "added to list" $docLibrary.Title
                # 
        # Add third site content types to the list
                # change the name in the quotes to the name of your content type
                #
        $ctToAdd = $site.RootWeb.ContentTypes["PowerPoint Presentation"]
        $ct = $docLibrary.ContentTypes.Add($ctToAdd)
        write-host "Content type" $ct.Name "added to list" $docLibrary.Title
                # 
        # Update the library object to commit changes
                #
        $docLibrary.Update()
    }
    else
    {
        write-host "The list" $lookForList "does not exist in site" $_.Title
    }
}

When we ran this through, however, whilst the content types were added correctly to the libraries, the New menu failed to list them.

Much (and I mean much!) digging revealed the cause to be down to a property in the library (spList.RootFolder.UniqueContentTypeOrder) that isn’t automatically set when we add the content types using code (which makes sense when you think about it…). However, all our fiddling with PowerShell failed to work. Adding a content type to the property (which is an array of content types) steadfastly refused to work.

We then found a post on the TechNet forums which appeared to give the answer in the form of C# code. We spent a long time on this, so to cut it short: You can’t simply add an item to the UniqueContentTypeOrder property – you have to set it to Null and rebuild it. The trouble is that in order to do that you have to stuff in an object that has an iList interface. Try as we might, we couldn’t create a PowerShell object that would allow us to store an array of ContentTypes and present the iList interface to the UniqueContentTypeOrder property to set the New menu values. Many people said that ArrayList or SortedList should do it, but they didn’t.

In the end, then I got our devs to knock up a rough and ready command line tool based on the code in the TechNet post. It’s really rough and ready, so I won’t post it here. Follow the posting and get your own tame devs to do the same. I only hope that this article becomes easier to find on the web to save you guys some time.

4. April 2011 13:31
by Rik Hepworth
0 Comments

Content type replication not working on imported or migrated site collections

4. April 2011 13:31 by Rik Hepworth | 0 Comments

A while ago I posted about a hidden feature that was needed if you want to use Managed Metadata columns in your SharePoint 2010 sites. We were doing some 2007-2010 migration work for a client recently that also involved exporting and importing sites and site collections to rework the content structure. Once we’d got the new structure sorted we discovered that content type replication was not occurring on the site collections we had imported. Some comparison of working and non-working SPSite properties with PowerShell later, we discovered that the culprit was the same hidden TaxonomyFieldAdded (ID 73ef14b1-13a9-416b-a9b5-ececa2b0604c) feature as I noted earlier. See my earlier post for instructions on enabling the feature.

As an addendum to my earlier post, which has code to enable the feature on a single site, Andy gave me the following snippet that will do it on all sites:

Get-SPSite -limit ALL |foreach{ Enable-SPFeature "73ef14b1-13a9-416b-a9b5-ececa2b0604c" -url $_.URL }

I don’t mind hidden features, per se, but when they’re not even logically named so I can associate them with their purpose, it’s annoying and time wasting. Why can’t we simply have a Content Type Subscriber feature that’s not hidden?

26. January 2011 12:08
by Rik Hepworth
1 Comments

Errors with TMG + Exchange Edge Connector + FPE resulting in rejected emails

26. January 2011 12:08 by Rik Hepworth | 1 Comments

Frustrating errors with little or no explanation…

Once again I find myself wiring a blog post in order to save people the time we spent figuring out what was going on and getting help with our fault.

We have Microsoft Threat Management Gateway installed at our perimeter. The Exchange 2010 Edge Connector is also installed as our mail gateway, and finally Forefront Protection for Exchange (FPE) deals with mail scanning. There are some gotchas that can trip you up when installing that lot, which I suppose I should put in another post, but the overall result is that you can manage the email filters (spam, malware etc) from within TMG’s console. It’s a nice, unified management interface and a good solution. When it works…

Our problem, when it occurred, was simple in its symptom – emails were being rejected by our email server. Emails were rejected that we didn’t think should be, and we fiddled with IP allow list settings in TMG for a while to no avail.

Looking in the event logs we noticed that there were lots of messages with the event ID 31506 and description:
Forefront TMG detected changes in Microsoft Exchange Server or Microsoft Forefront Protection configuration, and reapplied the e-mail policy configuration on server <server>.

There are quite a few people on the net with this error. One of the things they experienced, and we also saw, was that the Microsoft Forefront TMG Managed Control service was not running. Lots of messages suggested that restarting that service should do the trick. Lots of other messages also said that the service wouldn’t restart. We saw that too.

Clearing the IP block list is supposed to fix that fault. At first it did for us. To do this open the Exchange Management Shell on your TMG server and use the following powershell:

get-ipblocklistentry will return a list, if there are any entries.

remove-ipblocklistentry is the command to delete an item from the list, so get-ipblocklistentry | removeipblocklistentry –confirm:$false will get the block list, pipe the items through the remove command and delete them. The –confirm:$false tells the command just to get on with it and not prompt for confirmation.

The trouble was, whilst this worked, the solution was only temporary. We then tried something else (and promptly forgot about it, which will become important in a while).

We now found ourselves in a situation where the Microsoft Forefront TMG Managed Control service would not start. This time, whenever we tried to start the service we saw errors in the log with event id 31308 and description:
The Forefront TMG Managed Control service failed to initialize. Error information: Value does not fall within the expected range.

Nothing we could do would get this going. Again, people on the web suggested clearing the IP block list but doing so made no difference. We also saw the block list growing rapidly and incoming emails bounced off the spam filter, which we couldn’t disable because the TMG managed control service wouldn’t run.

We knocked up a quick powershell script to keep the wolves from the door and dug further. For those in the same boat, the following script simply clears the contents of the block list every 30 minutes and then sleeps.

for (;;)
{
write-host Clearing block list
get-ipblocklistentry | remove-ipblocklistentry -Confirm:$False
write-host Cleared block list. Now waiting 30 minutes...
start-sleep -seconds 1800
}

At this point I found a very obscure post talking about the original error we saw and that there is an ‘unofficial’ hotfix available via support. I’ve encountered these before and you have to log a support call to get them, because Microsoft want to make very sure that you are having the problem addressed by the fix. Usually these things get rolled into updates at a later date, once they’ve been through the full raft of testing needed to do so.

The hotfix is TMG-ISASE38387-UNOFFICIAL-AMD64-GLB and it was given to us by Microsoft Support in .exe and .msp flavours. Before you all get in touch, no I won’t give you the files. There’s a reason that the product support guys want you to log a call to get hold of this patch and not just install it randomly.

I dutifully installed the hotfix. It made no difference (or so it appeared) – the Microsoft Forefront TMG Managed Control service still refused to start.

It was at this point that we had an epiphany. In our attempts to stop email bouncing we had added items to the IP allow list, but done so through the Forefont Protection for Exchange management console. Interestingly (and importantly), the entries we had added here were not appearing in the Exchange IP Allow list (found by using get-ipallowlistentry in the Management Shell). We removed these entries and tried again.

The service started!

We then configured the IP allow list in TMG and applied the configuration changes. This time, checking the IP allow list via the management shell returned the entries we were expecting. Our email system has been functioning correctly ever since. The hotfix resolved our original error and our realisation of our mistake corrected the second problem.

Important Points

  • The error, event id 31506, description “Forefront TMG detected changes in Microsoft Exchange Server or Microsoft Forefront Protection configuration, and reapplied the e-mail policy configuration on server <server>.” is a known fault.
  • An unofficial hotfix exists, TMG-ISASE38387-UNOFFICIAL-AMD64-GLB, which addresses the issue, but you MUST engage with Product Support to get it.
  • I am told that the fully tested fix will be included in an update rollup for TMG which is due in February.
  • Don’t make configuration changes via the Forefont Protection for Exchange Server Console if your are running in this integrated setup. As we found, entries to things like the IP Allow List (and I’m guessing IP Block List) will cause the Microsoft Forefront TMG Managed Control service to fail to start with an error, event id 31308 and description ”The Forefront TMG Managed Control service failed to initialize. Error information: Value does not fall within the expected range.”
    Note:
    We also found that entries added to the IP allow list in FPE didn’t get listed when using the get-ipallowlistentry PowerShell command in the Exchange Management Shell.
  • If your Microsoft Forefront TMG Managed Control service does fail to start, check that you haven’t made configuration changes through FPE. The Exchange Management Console on TMG is clever enough to not let you make changes like this, but FPE isn’t.

6. December 2010 10:57
by Rik Hepworth
0 Comments

Server Core, Hyper-V and VLANs: An Odyssey

6. December 2010 10:57 by Rik Hepworth | 0 Comments

A sensible plan

This is a torrid tale of frustration and annoyance, tempered by the fun of digging through system commands and registry entries to try and get things working.

We’ve been restructuring our network at Black Marble. The old single subnet was creaking and we were short of addresses so we decided to subnet with network subnets for physical, virtual internal and virtual development servers, desktops, wifi etc. We don’t have a huge amount of network equipment, and we needed to put virtual servers hosted on hyper-v on separate networks so we decided to use VLANs.

Our new infrastructure has one clever switch that can generate all the VLANs we need, link those VLANs to IP subnets and provide all the routing between them. By doing it this way we can present any subnet to any port on any switch with careful configuration and use of the 802.1Q VLAN standard. Hyper-V servers can have a single physical interface with traffic from multiple VLANs flowing across it to the virtual switch, with individual VMs assigned to specific VLANs.

We did the heavy lifting of the network move without touching our Hyper-V cluster, placing all the NICs of all the servers on the VLAN corresponding to our old IP subnet. We then tested VLANs over the virtual switch in Hyper-V using a separate server and made sure we knew how to configure the switch and Hyper-V to make it all work.

Then we came to the cluster. Running Windows 2008 R2 Server Core.

Since we built the cluster Andy and I have come to decide that if we ever rebuild it, server core will not be used. It’s just too darn hard to configure when you really need to, and this is one of those times.

A tricky situation

Before we began to muck around with the VLAN settings, we needed to change the default gateway that the servers used. The old default gateway was the address of our ISA (now a shiny TMG) server. That box is still there, but now we have the router at the heart of the network, whose address is the new default gateway.

To change the default gateway on server core we need a command line tool. Enter Netsh, stage left.

We first need to list the interfaces so we know what we’re doing. IPConfig will list the interfaces and their IP settings. Old lags will no doubt abbreviate the netsh commands that we need next but I’ll write them out in full so they make sense.

Give me a list of the physical network adapters and their connection status: netsh interface show interface

Show me the IPV4 interfaces: netsh interface ipv4 show interface

To change the default gateway we must issue a set command with all the IP settings – just entering the gateway will not work as all the current settings get wiped first:
netsh interface ipv4 set address name="<name>" source=static address=x.x.x.x mask=255.255.255.0 gateway=x.x.x.x
Where <name> is the name shown in the IPV4 interface list, which will match the one shown in the ipconfig output that you want to change the gateway for. We’re using a class C subnet structure – your network mask may vary.

It’s worth pointing out that we stopped the cluster service on the server whilst we did this (changing servers one by one so we kept our services runnning).

We had two interfaces to change. Once corresponded to the NIC used to manage the server and the other corresponded to the one used by the virtual switch for Hyper-V. That accounted for two of the four NICs on our Sun X2200-M2’s, with the SAN iSCSI network taking a third. The SAN used a Broadcom, the spare was the other Broadcom and the others used each of the two nVidia NICs on the Sun (that will become important shortly).

A sudden problem

Having sorted the IP networking our next step was to sort out the VLAN configuration. To do that we changed the switch port that the NIC hosting the hyper-V virtual switch was connected to from being an untagged member of only our server subnet VLAN to being a tagged member of that VLAN and a tagged member of the new VLAN corresponding to our subnet for virtual internal servers.

The next step was to set the VLAN id for a test VM (we could ignore the host as it doesn’t share the virtual switch – it has it’s own dedicated NIC).

The snag was, the checkbox to enable VLAN ids was disabled when we looking in Hyper-V manager, both for the virtual switch and for the NIC in the VM.

Some investigation and checking of our test server showed that the physical network driver had a setting, Priority and VLAN, that needed to be set to enable priority and VLAN tagging of traffic, and that the default state was priority only. On full server that’s a checkbox in the driver setting. On server core…?

So, first of all we tried to find the device itself. Sadly, the server decided that remove management of devices from another server wasn’t going to be allowed, despite reporting that it should be. So we searched for command line tools.

To query the machine so it lists visible hardware devices: sc query type= driver (note the space before 'driver')

That will give you a list, allowing you to find the network device name.

For our server, that came back with nvenetfd – the nVidia NIC.

To use that name and find the file responsible: sc qc <device name> (in our case nvenetfd )

That returned the nvm62x64.sys driver file. Nothing about settings, but it allowed us to check the driver versions. Hold that thought, I’ll come back to it shortly.

Meanwhile

We’d also been poking at the test server, looking at the NIC settings. Logic suggested that the settings should be in the registry – all we have to do was find them.

I’ll save you the hunt:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}

That key holds all the Network Adapters. There are keys beneath that are numbered (0000, 0001, etc). The contents of those keys enabled us to figure out which key matched which adapter. Looking at the test server and comparing it to the server- core hyper-v box we found a string value call *PriorityVlanTag which had a value of 3 on the test server (priority and vlan enabled) and 1 on the hyper-v box. We set the hyper-v box to 3. Nothing. No change. We rebooted. Still nothing.

Then we noticed that in the key for the NIC there was a subkey: \Ndi\params. In there was a key called *PriorityVlanTag. In that key were settings listing the options that were displayed in the GUI settings dialog, along with the value that got set. For the nVidia the value was 2, not 3. We duly changed the value and tried again. Nothing.

So we decided to update the drivers. This brings us back to where I left us earlier with the sc command.

To update a driver on server core, you need to unpack the driver files into a folder and then run the following:
pnputil –i –a <explicit path to driver inf file>

After failing to get any other drivers to install it looked like we had the latest version and the system was not letting go. So we did some more research on the internet (what did we ever do before the internet?).

It transpires, for those of you with Sun servers, that the nVidia cards appear not to support VLAN ids on traffic, despite having all the settings to suggest that they do.

Darn.

A way forward

Fortunately we have a spare broadcom on each of our hyper-v host servers. We are now switching the virtual switch binding from the nVidia to the broadcom on each of our servers. We didn’t even have to hack around with registry settings once we did that the VLAN id settings in Hyper-V simply sprang into life.

The moral of this story is that if you want to use VLAN id’s with Hyper-V and your server has nVidia network adapters (and certainly if it’s a Sun X2200-M2) then stop now before you lose your hair. You need to use another NIC, if you have one, or install one if you don’t. Hopefully, however, the command line tools and registry keys above will help other travellers who find themselves in a similar situation to ourselves.

19. November 2010 17:06
by Rik Hepworth
0 Comments

Powershell to find missing features in SharePoint 2010

19. November 2010 17:06 by Rik Hepworth | 0 Comments

When migrating from SharePoint 2007 to 2010, no matter how hard you try there’s always the chance the the content database upgrade process will throw out errors about features being referenced that are not present in the farm. We have used Stefan Goßner’s WssAnalyzeFeatures and WSSRemoveFeatureFromSite (see his original article) to track down the references and exterminate them. It’s not the fastest thing on two legs though, and I have a fondness for having my SharePoint 2010 tooling in PowerShell because of the flexibility it gives me.

Here then, with a big hat-tip to Stefan, is the PowerShell to replicate his functionality. We differ slightly, in that I wanted one command to purge both site- and web-referenced features in one shot rather than calling a command with a scope switch. I have two functions – get-spmissingfeatures takes a Site Collection url as a parameter and scans through site and web feature collections, listing any features with a null definition property. The second function, remove-spmissingfeatures takes the same url and this time finds and removes the errant features in one pass.

Get-SpMissingFeatures:

function get-spmissingfeatures([string]$siteurl)
{
  $site = get-spsite $siteurl


  foreach ($feature in $site.features) {
    if ($feature.definition -eq $null) {
       write-host "Missing site feature:"
       write-host $feature.DefinitionId
       write-host $feature.parent
#      $site.features.remove($featureid)
    }
  }

  $webs = $site | get-spweb -limit all
  foreach ($web in $webs) {
  foreach ($feature in $web.features) {
    if ($feature.definition -eq $null) {
       write-host "Missing web feature:"
       write-host $web.url
       write-host $feature.DefinitionId
       write-host $feature.parent
#      $site.features.remove($featureid)
    }
  }

  }

}

Remove-SPMissingFeatures:

function remove-spmissingfeatures([string]$siteurl)
{
  $site = get-spsite $siteurl


  foreach ($feature in $site.features) {
    if ($feature.definition -eq $null) {
       write-host "Missing site feature:"
       write-host $feature.DefinitionId
       write-host $feature.parent
      $site.features.remove($feature.DefinitionId)
    }
  }

  $webs = $site | get-spweb -limit all
  foreach ($web in $webs) {
  foreach ($feature in $web.features) {
    if ($feature.definition -eq $null) {
       write-host "Missing web feature:"
       write-host $web.url
       write-host $feature.DefinitionId
       write-host $feature.parent
      $web.features.remove($feature.DefinitionId)
    }
  }

  }
}

11. November 2010 16:53
by Rik Hepworth
0 Comments

Enabling the TaxonomyFieldAdded feature to fix ManagedMetadata Column errors

11. November 2010 16:53 by Rik Hepworth | 0 Comments

We’re working on a solution at the moment that uses a custom site definition. For various reasons we stated with the Blank Site definition and worked from there. Our customisations include content types using custom columns that link to managed metadata term sets. We create all those through features – great! The tricky bit came when after deployment our managed metadata columns were greyed out. Examining the column we say an error telling us that the feature supporting the functionality was not activated.

What feature?

After quite a bit of hunting it turns out that there is a site collection feature called TaxonomyFieldAdded (ID 73ef14b1-13a9-416b-a9b5-ececa2b0604c) that is needed to allow the column to connect to the term set. The problem is that it’s a hidden feature so you can’t switch it on through the web site. Obviously we can enable it programmatically, but for anybody who has this problem (can’t connect a custom column to a term set) here is some simple PowerShell to enable it:

get-spfeature | where {$_Id –eq “73ef14b1-13a9-416b-a9b5-ececa2b0604c”} | enable-spfeature –url <site collection url>

29. July 2010 09:55
by Rik Hepworth
0 Comments

Powershell script to rename files for use as SharePoint 2010 User Profile thumbnails

29. July 2010 09:55 by Rik Hepworth | 0 Comments

User profile photos have changed in SharePoint 2010 in that they are now stored in a single image library in the MySite Host root site collection. They have also changed in that when you change the profile photo, SharePoint takes the file and creates three new images at specific sizes, then discards the file you gave it. These files have specific names to link them to the user account and come in small, medium and large flavours.

We’ve just delivered a solution to a customer that involved heavy customisation of the Profile page for users. This also involved replacing the large thumbnail version of the profile picture with one which met our size requirements.

The customer had a large group of image files all named in the pattern <firstname surname>.<extension> which had been loaded in to SharePoint as profile pictures. We wanted a quick way to replace the large thumbnail with our own version.

Enter Powershell, stage left. The script below is a little rough and ready but works great. It gets a directory listing, splits the filename and then looks up in AD to see if there’s a user that matches the filename (sans extension). If it finds a match it renames the file to match the pattern <domain>_<SamAccountName>_LThumb.<extension> to match the profile picture naming convention.

As I said, it’s a little rough and ready but I place here for the greater good. You need the ActiveDirectory powershell module to use this. It’s available on Server 2008 and above, and Windows 7 if you install the remote management tools.

The Active Directory Powershell Blog is a great resource for this stuff!

#import-module ActiveDirectory
if (-not (get-module -name activedirectory)) {
    write-host "This script requires the ActiveDirectory powershell modules to run"
    exit
}
$domain="mydomain"
$filesuffix = "LThumb"
$files = get-childitem
foreach ($file in $files) {
    $filesplit = $file.Name.split(".")
    $fullname = $filesplit[0]
    $fileext = $filesplit[1]
    write-host "Searching for:" $fullname
    $user = get-aduser -Filter { Name -eq $fullname }
    if ($user.SamAccountName -eq $Null) {
        write-host "Not Found!"
    } else {
        $newfilename = $domain+"_"+$user.SamAccountName+"_"+$filesuffix+"."+$fileext
        write-host "Renaming:" $file.name "New name:" $newfilename
        rename-item $file.Name $newfilename
    }
}