Skip to content
/ Michaël Hompus

With SharePoint it's easy to configure multiple zones for your SharePoint Web Application. For example you have a Publishing Web Site with two zones. After the content is published it'll also be available on the anonymous site and most of the URLs will be automatically translated to corresponding zone URL. There are however some places this is not the case.

With SharePoint it is easy to configure multiple zones for your SharePoint Web Application. For example, you have a Publishing Web Site with two zones.

  1. The authenticated CMS where editors can manage content: https://cms.int
  2. The anonymous website where everybody can view the content: http://www.ext

When the editors link to sites, pages, documents and images the URL will start with https://cms.int. After the content is published it’ll also be available on the anonymous site. Now most of the URLs will be automatically translated to corresponding zone URL and start with http://www.ext.

However, there are some places where this is not the case. You could try to use relative URLs but even that will not fix every scenario.

Translate the URL using code

Facing this issue, I had to translate the URLs myself. But I want to write minimal code. Luckily, Microsoft has done most of the work for me.

On the SPFarm class you will find the AlternateUrlCollections property. This “collection” is actually an instance of the SPAlternateUrlCollectionManager class and provides the RebaseUriWithAlternateUri method.

And this is where the magic happens.

This method has an overload where you supply a Uri and a SPUrlZone. You can provide one of the values of the SPUrlZone enumeration or you can provide the current zone.

To get your current zone you can use the static Lookup method of the SPAlternateUrl class. This method requires a Uri so we provide the current one using the ContextUri property from the same class.

To wrap it all up I give you the code:

var originalUri = new Uri("https://cms.int/pages/default.aspx");
var zone = SPAlternateUrl.Lookup(SPAlternateUrl.ContextUri).UrlZone;
var translateUri = SPFarm.Local.AlternateUrlCollections
.RebaseUriWithAlternateUri(originalUri, zone);
// When accessing from the authenticated zone
// translateUri == "https://cms.int/pages/default.aspx"
// When accessing from the anonymous zone
// translateUri == http://www.ext/pages/default.aspx

“Other” URLs

If you pass a URL which is not listed as an Alternate Access Mapping the method will return the original URL.

Filed under SharePoint
Last update:
/ Michaël Hompus

In a previous post I have written about Using the people picker over a one-way trust. In this post I use STSADM commands as there are no other ways to configure this. A downside of the STSADM command is your domain password being visible on the command prompt in clear text for everybody to read, or to retrieve from the command line history. SharePoint 2010 introduces several cmdlets to replace the “old” STSADM commands. Microsoft has posted an overview of the STSADM to Windows PowerShell mapping. However the commands for configuring the people picker are not available.

In a previous article, I have written about “Using the people picker over a one-way trust”. In that post I use STSADM commands as there are no other ways to configure this.

A downside of the STSADM command is your domain password being visible on the command prompt in plain text for everybody to read.

With SharePoint 2010 Microsoft introduces several cmdlets to replace the “old” STSADM commands. But looking at the STSADM to Windows PowerShell mapping you will see the commands for configuring the people picker are not present.

Creating my own script

PowerShell contains the Get-Credential cmdlet which uses a dialog to request credentials from the user and stores the password in a SecureString.

This triggered me to write a PowerShell script which will work the same as “STSADM -o setproperty -pn peoplepicker-searchadforests”, but instead of typing the credentials on the command line it will use the credential dialog for every trusted domain.

As written in my previous post the configuration is done in two steps.

SetAppPassword

First you need to create a secure store for the credentials. This is done by executing the SetAppPassword command on every server in your SharePoint Farm with the same password.

STSADM

Terminal window
stsadm -o setapppassword
-password <password>

PowerShell

Terminal window
Set-AppPassword "<password>"
Terminal window
function Set-AppPassword([String]$password) {
$type =
[Microsoft.SharePoint.Utilities.SPPropertyBag].Assembly.GetType("Microsoft.SharePoint.Utilities.SPSecureString")
$method =
$type.GetMethod("FromString", "Static, NonPublic", $null, @([String]), $null)
$secureString = $method.Invoke($null, @($password))
[Microsoft.SharePoint.SPSecurity]::SetApplicationCredentialKey($secureString)
}

PeoplePickerSearchADForests

The second step is to register the (trusted) domains to be visible in the people picker. Remember this setting is per web application and zone.

STSADM

Terminal window
stsadm -o setproperty
-url <url>
-pn "peoplepicker-searchadforests"
-pv "forest:<source forest>;domain:<trusted domain>,<trusted domain>\<account>,<password>"

PowerShell

Terminal window
Set-PeoplePickerSearchADForests "<url>"
"forest:<source forest>;domain:<trusted domain>"
Terminal window
function Set-PeoplePickerSearchADForests([String] $webApplicationUrl, [String] $value) {
$webApplication = Get-SPWebApplication $webApplicationUrl
$searchActiveDirectoryDomains = $webApplication.PeoplePickerSettings.SearchActiveDirectoryDomains
$searchActiveDirectoryDomains.Clear()
$currentDomain = (Get-WmiObject -Class Win32_ComputerSystem).Domain
if (![String]::IsNullOrEmpty($value)) {
$value.Split(@(';'), "RemoveEmptyEntries") | ForEach {
$strArray = $_.Split(@(';'))
$item = New-Object Microsoft.SharePoint.Administration.SPPeoplePickerSearchActiveDirectoryDomain
[String]$value = $strArray[0]
$index = $value.IndexOf(':');
if ($index -ge 0) {
$item.DomainName = $value.Substring($index + 1);
} else {
$item.DomainName = $value;
}
if ([Globalization.CultureInfo]::InvariantCulture.CompareInfo.IsPrefix($value, "domain:","IgnoreCase")) {
$item.IsForest = $false;
} else {
$item.IsForest = $true;
}
if ($item.DomainName -ne $currentDomain) {
$credentials = $host.ui.PromptForCredential("Foreign domain trust"
+ " credentials", "Please enter the trust credentials to"
+ " connect to the " + $item.DomainName + " domain", "", "")
$item.LoginName = $credentials.UserName;
$item.SetPassword($credentials.Password);
}
$searchActiveDirectoryDomains.Add($item);
}
$webApplication.Update()
}
}

Using the script

I have attached the script so you can use it in any way you want. You can put the commands in your own .ps1 file, or load the script in your current session using the following syntax:

Terminal window
. .\<path to file>PeoplePickerSearchADForests.ps1

(Yes, that is a dot, then a space, then the path to the script)

PeoplePickerSearchADForests.zip

/ Michaël Hompus

With the introduction of LINQ the difference between writing code for accessing a lists of objects in memory and accessing a list of data in an external data source like SQL is vanishing. Combining a in memory with a external list in a single query was not yet possible. With the introduction of .NET Framework 4.0 this has changed.

With the introduction of LINQ, the difference between writing code for accessing a list of objects in memory and accessing a list of data in an external data source like SQL Server is vanishing.

Combining an “in memory” list with an external list in a single query was not yet possible. With the introduction of .NET Framework 4.0 this has changed.

In this article, I want to filter my SQL data using a list of integers I have stored in memory.

read more…
Filed under C#, SQL
Last update:
/ Michaël Hompus

With SharePoint 2010 the amount of databases on your SQL server has grown quite a bit. By default most of these databases have their recovery model set to 'FULL'. After some time you will discover you're running out of space.

With SharePoint 2010 the number of databases on your SQL Server has grown quite a bit. By default, most of these databases have their recovery model set to FULL. After some time, you will discover you’re running out of space.

read more…
/ Michaël Hompus

When you have a SharePoint farm and you want to use accounts from another domain you need a partial (one-way) or a full (two-way) trust between those domain. A full trust is not always desirable and there your problem begins. After setting up the one-way trust you can authenticate with an account from the trusted domain, but the SharePoint People Picker doesn't show any accounts from this domain. It has been documented by others before, but as I ran into this recently I'll give my summary how I fixed this.

When you have a SharePoint farm and you want to use accounts from another domain you need a partial (one-way) or a full (two-way) trust between those domains.

A full trust is not always desirable and there your problem begins. After setting up the one-way trust you can authenticate with an account from the trusted domain, but the SharePoint People Picker won’t show any accounts from this domain.

It has been documented by others before, but as I ran into this recently, I will give my summary how I fixed this.
This solution is the same for WSS 3.0/SharePoint 2007 as SharePoint 2010.

The problem

When using a one-way trust, you do not see any accounts from the other domain in the people picker.

SharePoint People Picker not showing any accounts.
People picker not showing accounts from the other domain.

The reason

This is an example of how you could use a partial trust.

Architecture with a company and a development domain setup with a partial trust.
Example of a one-way trust architecture.

You want to allow employees to authenticate in a development farm, but you do not want to allow any test or service account from the development domain to authenticate in the company domain.

As the application pool account is based in the development domain it doesn’t have the right to query the company domain.

The solution

Using STSADM we can configure which forests and domains are searched for accounts by setting the peoplepicker-searchadforests property. The best part is that we can supply a username and password for a trusted domain.

SharePoint does not allow you to store this username and password in plain text on the server. So, you will have to configure a secure store. If you skip this step, configuring the search account for trusted domains will always fail with the following message.

“Cannot retrieve the information for application credential key.”

To create a credential key, you will have to use the following command.

Terminal window
stsadm -o setapppassword
-password <password>

This command has to be executed on every server in the farm.

Now you can configure the forests and domains you want to search using the following command.

Terminal window
stsadm -o setproperty
-url <web application url>
-pn peoplepicker-searchadforests
-pv forest:<source forest>;domain:<trusted domain>,<trusted domain>\<account>,<password>

You can combine any number of forests and domains, but you need to specify at least one.
You also need to include all forests and domains in one statement because every time you execute this command it will reset the current settings.

Also note this setting is per web application, and even per zone.

SharePoint People Picker showing an account from the one-way trusted domain.
People picker showing accounts from the other domain.
Filed under SharePoint
Last update: