In Part 3 of this series, I will show how to configure and start the user profile service application via PowerShell. The series itself is devided into four parts:

Part 1 will show the environment used.

Part 2 shows the steps, when using the web interface.

Part 3 will show the creation of the user profile service application by using a PowerShell script.

Part 4 will show how to start the user profile synchronization by using a PowerShell script.

The preparation is the same is in part 2, when we used the web interface of the Central Administration. That means, the MySite host is already created. As in the manual steps, the service instance should be started on both SharePoint hosts.

To do the implementation by PowerShell, I use three separate scripts. The first one contains the parameters and will be used again in part 4, when the user profile synchronization is started. The second script is the configuration script itself. The third script is used for the call of the New-SPProfileServiceApplication cmdlet, because this should run in the context of the farm account. Special thanks to Spencer Harbar, who has provided a blueprint for this in his blog post about the database schema of the sync database: http://www.harbar.net/archive/2010/10/30/avoiding-the-default-schema-issue-when-creating-the-user-profile.aspx.

So, let’s first have a look into the script with the parameters (“ProvisionVariables”):

#region variables

$UPAServer = `
    @("SP01", "SP02")

$UPAname = "User Profile Service"
$appPool = "SharePoint User Profile Service"

$serviceAccountLogin = "MYDOMAIN\SharePoint.UPA"

$profileDB = "Profile_DB"
$socialDB = "Social_DB"
$syncDB = "Sync_DB"

$mySiteHost = "http://my.mydomain.local"
$mySiteManagedPath = "pers"   # this managed path must exist in the MySite Host web application
$siteNameConflictResolution = "Block"   # use domain and username


$FIMSyncService = "ForeFront Identity Manager Synchronization Service"

$syncHost = "SP02"

#endregion

The script itself should be self explaining. The UPAServer variable contains an array with the hostnames, where the service application should be started. The siteNameConflictResolution variable has the setting on how to handle the name of the My Content site. The following values are possible:

None

Simply use the user name, do not resolve any conflicts

Resolve

Take the user name, resolve conflicts by using domain_username

Block

Take domain and username (domain_username), will not generate any conflicts

This parameter will be used with the New-SPProfileServiceApplication cmdlet.

The second script (“ProvisionUPA.ps1”) is the main part of the whole configuration of the user profile service application:

#region initialize

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#endregion


#region variables

. .\ProvisionVariables.ps1

$scriptFile = (Get-Location).Path + "\ProvisionUPAServiceApplication.ps1"

#endregion


#region managed account

Write-Host "Handle managed account..."

$serviceAccount = Get-SPManagedAccount $serviceAccountLogin -ErrorAction SilentlyContinue

if ($serviceAccount -eq $null)
{
    $serviceAccountCredentials = $host.ui.PromptForCredential("Credentials needed", "", $serviceAccountLogin, "")

    if ($serviceAccountCredentials -eq $null)
    {
        Write-Host -ForegroundColor Yellow "No credentials to continue!"

        return
    }

    $serviceAccount = New-SPManagedAccount $serviceAccountCredentials -ErrorAction SilentlyContinue

    # $serviceAccount = Get-SPManagedAccount $serviceAccountLogin -ErrorAction SilentlyContinue

    if ($serviceAccount -eq $null)
    {
        Write-Host -ForegroundColor Red "Cannot add managed account!"
    }
}

#endregion


#region application pool

Write-Host "Handle application pool..."

$UserProfileServiceApplicationAppPool = Get-SPServiceApplicationPool -Identity $appPool -ErrorAction SilentlyContinue

if ($UserProfileServiceApplicationAppPool -eq $null)
{
    Write-Host "Application pool does not exist."

    $UserProfileServiceApplicationAppPool = New-SPServiceApplicationPool `
        -Name $appPool `
        -Account $serviceAccount `
        -ErrorAction SilentlyContinue

    if ($UserProfileServiceApplicationAppPool -eq $null)
    {
        Write-Host -ForegroundColor Red "Cannot create application pool!"

        return
    }
}

#endregion


#region get and start user profile service instance

Write-Host "Start the service instance..."

foreach ($server in $UPAServer)
{
    $userProfileServiceInstance = Get-SPServiceInstance |
        where {$_.server -like "*" + $server -and $_.Typename -eq "User Profile Service"} |
            Start-SPServiceInstance
}

#endregion


#region create user profile service application

Write-Host "Create the user profile service application..."

$argumentList = "-Command Start-Process $PSHOME\powershell.exe -ArgumentList `"'$scriptFile'`" -Verb Runas"

Write-Host $argumentList

$farmAccount = (Get-SPFarm).DefaultServiceAccount

$cred = Get-Credential $farmAccount.Name -Message "We need the credentials for the farm account."

Start-Process $PSHOME\powershell.exe `
    -Credential $cred `
    -ArgumentList "-Command Start-Process $PSHOME\powershell.exe -ArgumentList `"'$scriptFile'`" -Verb Runas" -Wait

#endregion


#region create user profile service application proxy

Write-Host "Create the user profile service application proxy..."

$UserProfileSA = Get-SPServiceApplication |
    where-object `
    { 
        $_.DisplayName -eq $UPAname
    }

if ($UserProfileSA -ne $null)
{
    $UserProfileSAProxy = New-SPProfileServiceApplicationProxy `
        -Name ($UPAname + " Proxy") `
        -ServiceApplication $UserProfileSA `
        -DefaultProxyGroup

    if ($UserProfileSAProxy -ne $null)
    {
        Write-Host -ForegroundColor Green "User Profile Service Proxy created."
    }
    else
    {
        Write-Host -ForegroundColor Red "Cannot create User Profile Service Proxy!"

        return
    }
}
else
{
    Write-Host -ForegroundColor Red "User Profile Service Application $UPAname does not exist."
}

#endregion

This script is split into the following sections (regions in the script):

Managed account

Get the credentials of the farm account

Application pool

Create the application pool for the user profile service application

Get and start user profile service instance

Start the service instance on the hosts, mentioned in the parameter script

Create user profile service application

Create the service application, in this section another script is executed in the context of the farm account

Create user profile service application proxy

Create the service application proxy for the new service application

 

The third script (“ProvisionUPAServiceApplication.ps1) is simply the execution of the SPProfileServiceApplication cmdlet. It was necessary to put this call into a separate script, because we need another user context.

#region initialize

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#endregion


#region variables

$currentDir = Split-Path -parent $PSCommandPath

. $currentDir\ProvisionVariables.ps1

#endregion


#region create user profile service application

Write-Host "Nested creation of the user profile service application..."
Write-Host $appPool

$UserProfileSA = New-SPProfileServiceApplication `
    -Name $UPAname `
    -ApplicationPool $appPool `
    -ProfileDBName $profileDB `
    -ProfileSyncDBName $syncDB `
    -SocialDBName $socialDB `
    -MySiteHostLocation $mySiteHost `
    -MySiteManagedPath $mySiteManagedPath `
    -SiteNamingConflictResolution $siteNameConflictResolution

if ($UserProfileSA -ne $null)
{
    Write-Host -ForegroundColor Green "User Profile Service Application created."
}
else
{
    Write-Host -ForegroundColor Red "Cannot create User Profile Service Application!"
}

Read-Host

#endregion

Before we start provisioning the user profile service application, we need to make the farm account a local administrator on the machine, where we start the script. When this is done, we simply execute the script “ProvisionUPA.ps1” from a PowerShell console. During execution you will be asked for the credentials of the account to use for the application pool of the user profile service application. When the application pool is created, there will be a second dialog asking for the credentials of the farm account. When you have entered the farm account credentials, a new PowerShell session is started.

When the user profile service application was created, press any key to close the second PowerShell window.

The surrounding script will continue and finish successful.

When you have access to the database server, check the schema settings of the synchronization database.

In the users of this database you should not see the farm account. When you see the farm account in this listing, it is very likely that the provisioning of the user profile synchronization will fail.

At this point, our user profile service application is provisioned and running on two hosts. Next we will continue in part 4 with the provisioning of the user profile synchronization.