In part 4 of the series we will configure the user profile synchronization with a PowerShell script, so it is reproducable. 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.

To configure user profile synchronization it is very important, which permissions are set for the synchronization account and with which account the user profile synchronization is configured.

In Technet you will find the necessary permissions, depending on your environment. The most important permission is the Replicating Directory Changes permissions. Without this permission for the synchronization account, the user profile synchronization will fail. The Technet article will show how this permission is set.

To configure the user profile synchronization, we use a simple PowerShell script (“ProvisionSync.ps1”).


#region functions

Function ConvertTo-UnsecureString([System.Security.SecureString]$string)
{
	$unmanagedString = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($string)
	$unsecureString = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($unmanagedString)
    
    [System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($unmanagedString)
	
	return $unsecureString
}

Function IsServiceRunning([System.String] $serviceName, [System.String] $computerName)
{
    $service = Get-Service $serviceName -ComputerName $computerName

    if ($service -eq $null)
    {
        return $false
    }
    else
    {
        if ($service.Status -eq "Running")
        {
            return $true
        }
        else
        {
            return $false
        }
    }
}

#endregion


#region initialize

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#endregion


#region variables

. .\ProvisionVariables.ps1

#endregion


#region store farm credentials

Write-Host "Store farm credentials..."

$currentUser = $env:USERDOMAIN + "\" + $env:USERNAME

$farm = Get-SPFarm
$ts = $farm.TimerService

$farmAccount = $ts.ProcessIdentity.UserName 

if ($currentUser.ToUpper() -ne $farmAccount.ToUpper())
{
    Write-Host -ForegroundColor Yellow `
        "You should be logged in and run this script with the farm account."

    return
}

$farmCredentials = $host.ui.PromptForCredential("Credentials needed", "", $farmAccount, "")

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

    return
}

$farmAccountPassword = ConvertTo-UnsecureString($farmCredentials.Password)

Write-Host "We have the credentials to continue."

#endregion


#region ask the user if the permissions are correct

$answer = Read-Host "Are the permissions for the account" $farmAccount "set correct in Active Directory? (Y/N)"

if ($answer -ne "Y")
{
    return
}

$answer = Read-Host "Is the account" $farmAccount "member of the local Administrators group on" $syncHost"? (Y/N)"

if ($answer -ne "Y")
{
    return
}

$answer = Read-Host "Was" $syncHost "restarted, after" $farmAccount "was made a local admin? (Y/N)"

if ($answer -ne "Y")
{
    return
}

#endregion


#region set the sync host

Write-Host "Set the sync host..."

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

$UserProfileSyncServiceInstance = get-spserviceinstance |
    where `
    {
        $_.server -like "*" + $syncHost -and $_.Typename -eq "User Profile Synchronization Service"
    }

$syncMachine = Get-SPServer $syncHost

$upa.SetSynchronizationMachine($syncHost, $UserProfileSyncServiceInstance.id, $farmAccount, $farmAccountPassword)

Write-Host "Synchronization Machine is set to" $syncHost

Read-Host "Press any key to continue..."

#endregion


#region start sync instance

$serviceInstance = Start-SPServiceInstance $UserProfileSyncServiceInstance

Write-Host "Start of user profile synchronization service initiated."


# wait until online

$FIMSyncServiceIsRunning = $false

while ($UserProfileSyncServiceInstance.status -ne "online")
{
    sleep 2

    Write-Host -NoNewline "."

    $serviceRunning = IsServiceRunning $FIMSyncService $syncHost

    if ($serviceRunning -eq $true)
    {
        if ($FIMSyncServiceIsRunning -eq $false)
        {
            $FIMSyncServiceIsRunning = $true

            Write-Host
            Write-Host $FIMSyncService "is running."
        }
    }

    if (($FIMSyncServiceIsRunning -eq $true) -and ($serviceRunning -ne $true))
    {
        Write-Host
        Write-Host -ForegroundColor Red $FIMSyncService "has stopped!"
        Write-Host -ForegroundColor Red "Cannot start User Profile Service Synchronization."

        return
    }

    $UserProfileSyncServiceInstance = get-spserviceinstance |
        where `
        {
            $_.server -like "*" + $syncHost -and $_.Typename -eq "User Profile Synchronization Service"
        }
}

Write-Host ""
Write-Host -ForegroundColor green "Everything done."

#endregion
</p><p>

This script does use the same parameter script (“ProvisionVariables.ps1”) as the script to configure the user profile service application. This parameter script contains the variable “syncHost” that specifies the host, which should run the service instance for the user profile synchronization.

The script itself has the following sections (regions in the script)

Store farm credentials

This section will ask the user for the credentials of the farm account

Ask the user if the permissions are correct

In this section the user/administrator is asked for the current permissions of the sync account

Set the sync host

This region sets the sync host to the machine specified in the parameters

Start sync instance

This is the main part, this one provisions and starts the service instance for the user profile synchronization

 

To complete the provisioning of the user profile synchronization successful, it is necessary to configure the permissions correctly and to execute the script with the farm account.

First of all set the permissions of the sync account (the farm account) as shown in the Technet article I just talked about. When this is done, make the farm account a local administrator on the machine, where the user profile synchronization should run. Last but not least, before you execute the script, reboot the machine, where the synchronization should run to become the permission settings active.

On the host, where you want to execute the script, log off and log on with the farm account. Open a PowerShell window with “Run as Administrator” and execute the script “ProvisionSync.ps1”. The farm account should be a local administrator on the machine.

The script will ask for the credentials of the farm account. After a few minutes the provisioning should finish successful.

The final steps are to configure the synchronization connections with your identity systems, run a full synchronization and configure the schedule for the incremental synchronization.

Don’t forget to revoke the local administrator permissions for the farm account on the machines, where these permissions are granted.

That’s it. The user profile synchronization is configured and running, and also the user profile synchronization.

Advertisements