Uncategorized

Offboarding mailboxes back to on-premises Exchange with Office 365

mailboxoffboarding
mailboxoffboarding

Most companies use the built-in migration feature in the Office 365 Portal for onboarding mailboxes to the cloud. This has been recently upgraded with a lot of new features such as batches and migration end-points etc.

However a logical question is, what about migrating mailboxes back to our on-premises Exchange organisation? Creating those end-points can sometimes be difficult. To make life easier I use this simple PowerShell script. Before you can run the script you first have to connect to Remote PowerShell. For that please follow the instructions described here.

$opcred = get-credential domaindomainadminGet-Mailbox -Identity username@contoso.com | New-MoveRequest -OutBound -RemoteTargetDatabase ‘Database01′ -RemoteHostName ‘hybrid.contoso.com’ -RemoteCredential $opcred -TargetDeliveryDomain ‘contoso.com’

As you can see we define several parameters. Most of them should make sense to you, however I want to highlight that in a hybrid scenario you must use the database on your hybrid server. The RemoteHostName parameter is your hybrid endpoint.

Inconvenient (Sandboxed) Custom ListDefinitions

Building custom SharePoint Online solution a List Definition is likely to be a SPI you would like to use. Sandboxed Solution look like a good way of deploying these definitions to your SharePoint Online environment, but are they?

Language When we deployed custom List Definitions we came across strange behavior accessing these lists. Suddenly the language changed from Dutch (nl-NL) to the default language (en-EN). Together with the help of MS we found some interesting information in the Logs. SharePoint was trying to access a resource file we didn’t deploy.

Localized Strings A SharePoint Feature comes with the property DefaultResourceFile. This property can be set with the Feature Properties. When empty SharePoint will try to get the resource from “%ProgramFiles%Common FilesMicrosoft Sharedweb server extensions14TEMPLATESFEATURESFeatureNameResourcesResources. Culture.resx” when a resource is requested by a Localized string. When you create a ListDefinition in Visual Studio the Schema.xml is being generated for you. The <List /> element contains an Attribute called Direction which is a localized string. Direction=”$Resources:Direction;”

The Localized string doesn’t refer to a default Resource file but instead it tries to get the Resource from the DefaultResourceFile. This results in an error when you are not deploying a Resource File to this location containing “Direction”.

Solutions This blogpost states that with SP1 the problem is resolved.http://www.mysticslayer.com/?p=211 However together with MS we found out that the error in the Log files still occurs in SharePoint Online. The easiest way to fix this is to replace the localized string in your schema.xml for a hardcoded value. MSDN explains what values can be used (http://msdn.microsoft.com/en-us/library/ms415091.aspx).

If you don’t want to choose this option for some reason, according to MS you can also choose to reference the Core Resource file Direction=”$Resources:core,Direction;”. This didn’t give me the error on premise, but obviously I couldn’t test it in Office 365 because I’m not able to check the Log files. I didn’t experience the language change as before so I assume this is a good option. Still the value in the core resource file for Direction is 0 which is not given as an option according to MSDN. My guess is that SharePoint sees this as “none”.

Deploying Sandboxed Solutions

Lately I’ve been working on some Sandboxed solution for Office 365. We all know that they differ on lots of points from Farm Solutions. On the coding end by now we know all the limitations and best practices but how about deployment of these solutions. Some experiences from my end in this post.

Dependencies

Maybe a no-brainer but dependencies between sandboxed solutions can be killing and may result in errors on Solution Activation level. For instance Content Type references in a List Definition with an instance attached to it. The Content Type should be in the same solution as the definition. If there are more Feature in one Solution, make sure to use Activation Dependencies. Again make sure that two different features in two different solutions don’t have any direct dependencies with each other.

Upgrading Shared Resources

When Branding is needed in a Sandboxed solution like MasterPage, PageLayouts, CSS, Images etc. we can use the SharePoint Module SPI for provisioning. However when 1 of these resources is checked out by someone else then the user who deploys and activates the Feature which holds that module, SharePoint will give a Runtime error on Activating the feature. In this case it doesn’t matter if the person deploying the Solution is a sitecollection admin. The settings on the the library for Mandatory Check Out don’t help much either. Even when this is turned off and the file is still checked out, the error occurs.

So it’s important to make SURE that all the files that need to be upgraded are Checked In! And off course this doesn’t apply only to branding files but ALL files that are being provisioned by a Module SPI.

Create a sub site based on a custom (Sandboxed) Web Template using Powershell

One quick tip when using Powershell to create a SharePoint sitestructure combined with custom Web Templates (In my case Sandboxed). The correct syntax for creating Webs based on your custom (sandboxed) Web Template is: $site = Get-SPSite http://myserver/sites/mysite  $web = New-SPWeb http://myserver/sites/mysite/subsite   $web.ApplyWebTemplate(“{FeatureGUID}#MyTemplate”)

In this case you can not use the –template parameter on the New-SPWeb method. Hopefully this post will save u the wondering why your PS script is failing.

If you are trying to figure out what the correct name is for the WebTemplate, you can also use this PS command to check which Templates are available in your current Site.

$site = Get-SPSite http://myserver/sites/mysite  $site.GetWebTemplates(lcid)

lcid off course being the language ID.

Inconvenient Recurrence Data from a SharePoint Calendar using Client OM (JS)

The CAML to get SharePoint items from lists has a nice feature when it comes to Calendar data. Using the <DateRangesOverlap/> it is possible to check if a given date is within a range of dates and when passing the ExpandRecurrence property it even takes the Recurrence Data into account. Using Sandboxed Solutions to do so we can easily set this property SPQuery.ExpandRecurrence = true; However when it comes to the JavaScript Client OM we cannot use this property.

WebServices

The only way to query SharePoint for Recurrence Data using Client OM is by using theGetListItems Method from the List WebService (/_vti_bin/lists.asmx). The XML passed into the WebService can handle QueryOptions and we can use this to specify if ExpandRecurrence should be true. The Soap XML looks like this:

<soapenv:Envelopexmlns: soapenv=’http://schemas.xmlsoap.org/soap/envelope/’>    <soapenv:Body>     <GetListItemsxmlns =’http://schemas.microsoft.com/sharepoint/soap/’>        <listName>[MyListName]</listName>        <query>          <Query>            <Where>              <DateRangesOverlap>                <FieldRefName=’EventDate’ />                <FieldRefName=’EndDate’ />                <FieldRefName=’RecurrenceID’ />                <ValueType=’DateTime’>                  <Today />                </Value>              </DateRangesOverlap>            </Where>          </Query>        </query>        <queryOptions>          <QueryOptions>            <ExpandRecurrence>TRUE</ExpandRecurrence>            <CalendarDate>              <Today />            </CalendarDate>            <ViewAttributesScope=’RecursiveAll’ />          </QueryOptions>        </queryOptions>        <viewFields>          <ViewFields>            <FieldRefName=’EventDate’ />            <FieldRefName=’EndDate’ />            <FieldRefName=’fAllDayEvent’ />            <FieldRefName=’fRecurrence’ />            <FieldRefName=’Title’ />          </ViewFields>        </viewFields>        <RowLimit>10</RowLimit>      </GetListItems>    </soapenv:Body>  </soapenv:Envelope>

This example checks if there are events overlapping with <Today />. I found that it’s best to check with tags like <Today/>. <Week/>, <Month/> and <Year/> instead of using UTC Dates. Notice the <queryOptions/> wrapper passing the Options. Building regular CAML XML using the inner <QueryOptions/> tag didn’t work unfortunately. Both <ExpandRecurrence/> as <CalendarDate/> are mandatory in order for this query to work.

Tip: When using Client OM to process SharePoint data requests it’s best practice to specify as much properties as possible. Specifying <ViewFields/> will only return these fields instead of all possible fields that come with an Item. If you know the maximum amount of results specifying <RowLimit/> also helps to improve the performance on your Query.

Handling DateTime in Office 365 Sandboxed Solutions

When developing custom solutions on the SharePoint platform we don’t really think about using DateTime objects anymore. We just build solutions using server-side DateTime.Now or DateTime.Today to check Date and Time and to check that with the values we get back from SharePoint. Because we have full control over our On-Premise environment we can be sure that the Server Date and Time is correct. However moving this principal to the Cloud we loose that bit of control. We have to make sure again we get the right Date and Time from the server to do accurate checks.

Timezone of a Office 365 Server

As soon as I was testing a solution using a DateTime.Now object to get Calendar Items I came across some strange behavior when testing before 09:00 (GMT +1). I came across this article http://onlinehelp.microsoft.com/en-us/office365-enterprises/hh531509.aspx to get all Applications in the right TimeZone. It seemed that the Office 365 servers were all set to the TimeZone GMT -8 (Which is the Redmond TimeZone). So there was a 9 hour difference (I’m in Amsterdam TimeZone GMT +1).

Regional settings

Because programming it like DateTime.Now.AddHours(9); didn’t seem the right thing to do, I found a good solution to get the right DateTime.Now based on our local TimeZone. First step is to set the Regional Settings for your Office 365 SharePoint Site Collection (https://MySharePointSite/_layouts/regionalsetng.aspx) to the correct TimeZone. With this Regional Settings we can use the SPRegionalSettings object to calculated the local time at the moment of need using the following code.

       SPRegionalSettings reg = SPContext.Current.Site.RootWeb.RegionalSettings;          SPTimeZone tz = reg.TimeZone;          DateTime utc = DateTime.Now.ToUniversalTime();          DateTime utcLocal = tz.UTCToLocalTime(utc);

The utc represents DateTime.Now at GMT. With the UTCToLocalTime() method we will get the current DateTime based on our TimeZone. Now we can use utcLocal instead of DateTime.Now to get the accurate Date and Time when doing Server Side (Sandboxed) calculation with DateTime. The picture illustrates the DateTime.Now, the TimeZone ID set for the Current Site, GMT time and our LocalTime.

BlogPost-DateTimeO365

SharePoint 2010 - Ask Me About …… “SharePoint; CPU;”

Why is my CPU load so high on my SharePoint front end server? This is what the customer asked me.  Valid question I must say as the CPU fluctuated between the 50% and the 100%. The environment was very slowwwwww.

The investigation started:

  • In the resource manager I noticed that the w3wp.exe was causing the CPU load.
  • The event viewer contained a warning (Event Id: 3001) that occurred every 30 seconds which indicated that there was something wrong with a certain mysite
  • The ULS logs gave me more info:

 

High Url Path: /my/<person>/overview.aspx
Exception Exception information: Exception information: Microsoft.SharePoint.WebPartPages.WebPartException: Thread was being aborted. ---> System.Threading.ThreadAbortException: Thread was being aborted.     at Microsoft.SharePoint.Portal.WebControls.AskMeAboutWebPart.RenderValues(HtmlTextWriter writer, Int32 startIndex, Int32 endIndex)

So from the AskMeAboutWebPart webcontrol I decided to have a look at the users profile Ask me About property and noticed an ‘&’ sign in one the tags.

 

Solution: you guessed it: I removed that tag and performed an IISRESET

It could well be that this is already solved in one of the latest CU updates. I think I have read something about this but I couldn’t find it anymore. As soon as I do, I will update this post.

Create publishing pages with PowerShell in SharePoint 2010

For a client we created an extended PowerShell script to do an One-Click deployment of their intranet. This was awesome to create because it really saved huge amounts of time creating sites & site collections, adding and activating solutions and setting permissions, navigation and master pages. But we still had to add a piece of code to create pages in the Pages Library. After a quick search, I came across this blogpost of Brendan Newell. It helped me out greatly! It just missed 1 crucial element; setting the page title. So I added this to his script. They were minor changes, so all credits go to Brendan.

PowerShell Script; # Read in list of pages from XML [xml]$pagesXML = Get-Content “pages.xml" if ($pagesXML -eq $null) { return } # Get publishing web $site = New-Object Microsoft.SharePoint.SPSite($server1) $web = $site.rootweb $pWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web) # Loop through each page node to extract filename and titlename $pagesXML.Pages.Page | ForEach-Object { $fileName = [string]$_.FileName Write-Host “Creating $fileName” $titleName = [string]$_.TitleName Write-Host “Creating $titleName” # Create blank page $newPage = $pWeb.AddPublishingPage() $newPage.Update() # Update the filename to the one specified in the XML $newPage.ListItem["BaseName"] = $fileName $newPage.ListItem["Title"] = $titleName $newPage.ListItem.SystemUpdate() # Check-in and publish page $newPage.CheckIn(“”) $newPage.ListItem.File.Publish(“”); } # Dispose of the web $web.Dispose() XML Structure; <?xml version="1.0" encoding="utf-8"?> <Pages> <Page> <FileName>P1</FileName> <TitleName>Page One</TitleName> </Page> <Page> <FileName>P2</FileName> <TitleName>Page Two</TitleName> </Page> </Pages>

List view Lookup threshold in Office365

I created a list which uses 12 Person or Group fields. So I changed the resource throttling in Manage Web Applications > General Settings in Central Admin. Customer happy, so I'm happy too. Now we have to the move this list to Office365 because their intranet is moving to the cloud. But changing the resource throttling settingis not possible in Office365 (yet?). So now we have to create a new solution.

So keep in mind when working with Office365, you can't change the list view lookup threshold.

*UPDATE*; waiting for reaction Microsoft if the settings will be made available in the future

*UPDATE 20110829*; Microsoft Customer Support has confirmed that the settings will not be available as of yet, but this may change in the future...