• Home
  • About

SharePointBjorn

SharePoint PowerShell Solutions
Stay updated via RSS

  • Categories

    • PowerShell scripts (7)
      • Certificates (2)
    • SharePoint PowerShell (14)
      • Database (1)
      • Service Applications (3)
        • User Profile Service (2)
      • Wep Applications (2)
      • Windows Services (1)
  • Recent Posts

    • Check my variables function
    • PowerShell tip of the day – Insert Snippets in ISE
    • Correct the WordPress character autocorrect using PowerShell
    • Copy a file to all SharePoint Servers using PowerShell
    • Start, Stop and restart one or multiple Windows services on one, all and specific SharePoint Servers using PowerShell
    • Start and Stop SharePoint Service Instances using PowerShell
    • Find SharePoint database sizes using Powershell
    • Mass Deploy and Remove SharePoint 2013 WSP solution packages using PowerShell
  • Blogroll

    • MSDN SharePoint Forum
    • Powershell.org
    • Tod Klindt's blog on SharePoint
  • Advertisements

SharePoint User Profile Synchronization Service AutoFixer

Posted: June 25, 2014 in User Profile Service
Tags: User Profile Synchronization
89

Behold! I present to you dear visitors the UPSA_SYNC_AUTOFIX PowerShell Script 🙂

This script can be very useful when struggling to start your Use Profile Synchronization Service! The script performs multiple actions with minimum user interaction. I use this myself all the time.

Instructions:

  • Copy code into a text file and save as UPSA_SYNC_AUTOFIX.ps1 or download rar file and extract it.
  • The script targets the local Server, so run it from the server hosting the synchronization service.
  • Run the script with your SharePoint install account, or any Farmaccount that has access to the databases and is in the local administrators group on the SharePoint Server.
  • The Farmadmin account needs to be in the local administrators group when starting the service.
  • Works in SharePoint 2010 and 2013.

Assumptions:

  • You have created the the User Profile Synchronization service either through Central Administration or via PowerShell (with farmadmin account).
  • If you have migrated the UPSA to a new environment, then you also have successfully imported the Encryption key and cleared the SyncDB prior to running this script.

File:

newdl

Code:


<#====================================================================  Copyright © 2014, June. Bjørn Roalkvam  www.SharePointbjorn.com, bjorn80@gmail.com   I got sick of doing the manual tidying prior to starting a synchronization service,  So i scriptet the whole thing for you:-). I have a ton of experience starting the  evil User Profile Synchronization Service, have not yet found one I could not start!  You will want to run the script on the appserver that is running the User   Profile Synchronization service.  The script only targets the server you are running the script on   and does the following: -Disables the User profile Synchronization service (Even stuck ones!). -Deletes the awfull timerjob ProfileSynchronizationSetupJob. -Clears away all ForefrontManagerIdentity Certificates from the local machine  certificate stores. -Clears the SharePoint Confiugration Cache. -Gives you a choice to start the Synchronization service, it will ask you to input the   farmadmin account password.  Always test all scripts you find in an test environment prior to production:-),   you are a responsible SharePoint Administrator afterall! ====================================================================#>

# ===================================================================================
#Checks whether the script is running as admin, if not then starts as admin.
# ===================================================================================
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))

{
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}

cls
Write-Host -f Cyan "Red ugly warning about set-executionPolicy.."
sleep 2
Write-Host -f Green "OK"
Write-Host ""

#Add sharepoint pssnapin if it doesnt exist:
if ( (Get-PSSnapin -Name microsoft.sharepoint.powershell -EA "SilentlyContinue") -eq $null )
{
    Add-PsSnapin microsoft.sharepoint.powershell
}

#Variable
$TempScript = "c:\StartSync.ps1" # This ps1-file will be created and then deleted at the end of the script.

#This script will always run on the local server:
$hostname = hostname
$server = get-spserver $hostname
$Serverdisplayname = $server.displayname

Write-Host -f Cyan "Verifying that the farmadmin account is set as local administrator on $Serverdisplayname.."
#Find the farmadmin account:
#$Farmaccount = (Get-SPFarm).DefaultServiceAccount.Name
#$admins = [adsi]'WinNT://localhost/administrators'
#$members = $admins.members() | foreach { ([adsi]$_).path.substring(8).replace('/','\') }
#$Answer = $members -contains $Farmaccount

#--Change suggested by Marcus Opel (http://devmarc.de/), thank you!
$objSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544")
$objGroup = $objSID.Translate([System.Security.Principal.NTAccount])
$objGroupname = ($objGroup.Value).Split(“\”)[1]

$winNT = ‘WinNT://localhost/’ + $objGroupname
$farmAccount = (Get-SPFarm).DefaultServiceAccount.Name
$admins = [adsi]$winNT
$members = $admins.members() | foreach { ([adsi]$_).path.substring(8).replace(‘/’,’\’) }
$Answer = $members -contains $Farmaccount
#--

if($Answer -eq $False) {Write-Host -f Yellow "$Farmaccount is not local administrator, press any key to exit"; Read-Host; exit}
Write-Host -f Green "OK"
Write-Host ""

# ===================================================================================
# Stop User Profile Synchronization Service from any status to disabled
# ===================================================================================
Write-Host -f Cyan "Making sure that the User Profile Synchronization service is not running.."
$UPS = Get-SPServiceInstance -EA "SilentlyContinue" | Where {$_.TypeName -eq "User Profile Synchronization Service" -and $_.Server -match $server}
$UPS.Unprovision()
$ups.TypeName
$UPS.status
Write-Host -f Green "OK"
Write-Host ""

# ===================================================================================
# Deleting the timerjob ProfileSynchronizationSetupJob
# ===================================================================================
Write-Host -f Cyan "Making sure that the timerjob ProfileSynchronizationSetupJob does not exist.."
if(Get-SPTimerJob -EA "SilentlyContinue" | where {$_.Name -eq "ProfileSynchronizationSetupJob"})
{
$timerjob = Get-SPTimerJob -EA "SilentlyContinue" | where {$_.Name -eq "ProfileSynchronizationSetupJob"}
$timerjob.Delete()
}
Write-Host -f Green "OK"
Write-Host ""

# ===================================================================================
# Remove all ForefrontidentityManager certificates on server
# ===================================================================================
Write-Host -f Cyan "Removing Forefront Certificates from local machine certificate stores"
$allStoreNames = Get-ChildItem -Path cert:\LocalMachine | %{$_.name}

    foreach ($storename in $allStoreNames)
    {
        $store = New-Object System.Security.Cryptography.x509Certificates.x509Store($storename,"LocalMachine")
        $store.Open("ReadWrite")

        $certs = $store.Certificates | ? {$_.subject -like "*ForefrontIdentityManager*"}
        ForEach ($cert in $certs)
        {
          if($cert){$store.Remove($cert)}
        }
    $store.Close()
    }
    Write-Host -f Green "OK"
    Write-Host ""

# ===================================================================================
# Clear SharePoint confiuration cache
# ===================================================================================

#Detect SharePoint version
if((test-path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15") -eq $true)
{
$TimerName = "SharePoint Timer Service"
}

if((test-path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15") -ne $true)
{
$TimerName = "SharePoint 2010 Timer"
}

#Stop timer service
$SharePointimer = Get-Service $TimerName
$SharePointimer.Stop()
while($SharePointimer.Status -eq "Running")
{
write-host "Waiting for timer service to stop.."
sleep 2
$SharePointimer = Get-Service $TimerName
}
Write-Host -f Green "OK"
Write-Host ""

#Find and delete XML files in GUID + set cache.ini to 1.
$serverName = hostname
$XMLPath = "\\" + $serverName + "\c$\ProgramData\Microsoft\SharePoint\Config\" #The File path where the deploy package are located.

#Finding the newest Guid folder:
$FindGuidFolder = Get-ChildItem $XMLPath | ? { $_.PSIsContainer } | sort CreationTime -desc | select -f 1
$ActiveGuidFolder = $FindGuidFolder.name

#Deleting all XML files:
Write-Host -f Cyan "Clearing SharePoint configuration cache by deleting XML files.."
$OldNumberofXML = (Get-ChildItem ($XMLPath + $ActiveGuidFolder) | ?{$_.name -like "*xml*"}).count
$removeXML = Get-ChildItem ($XMLPath + $ActiveGuidFolder) | ?{$_.name -like "*xml*"} | % { Remove-Item $_.fullname -Force }
Set-Content (($XMLPath + $ActiveGuidFolder)+ "\" + "cache.ini") "1"
Write-Host -f Green "OK"
Write-Host ""

#Start timer service
$SharePointimer = Get-Service $TimerName
$SharePointimer.Start()

while($SharePointimer.Status -eq "Stopped")
{
Write-Host "Waiting for timer service to Start.."
sleep 2
$SharePointimer = Get-Service $TimerName
}
Write-Host -f Green "OK"
Write-Host ""

$NewNumberofXML = (Get-ChildItem ($XMLPath + $ActiveGuidFolder) | ?{$_.name -like "*xml*"}).count

#comparing xml count to previous count to make sure the cahche has been fully built up.
while($NewNumberofXML -lt $OldNumberofXML)
{
Write-Host "Waiting for new XML files to load into GUID.."
sleep 2
$NewNumberofXML = (Get-ChildItem ($XMLPath + $ActiveGuidFolder) | ?{$_.name -like "*xml*"}).count
}
Write-Host -f Green "OK"
write-host ""
Write-Host ""
Write-Host -f Green "Done Tidying"
Write-Host ""
Write-Host ""
sleep 4
write-Host "Enable the synchronization service now?"
$choice = read-host "<1> for YES and <2> for NO"

if($choice -eq "2"){Write-Host "exiting";sleep 2; exit}

# ===================================================================================
# Get farm password from user and insert it into the temp script that will run as farmadmin and start the synchronization service.
# ===================================================================================
$farmPassword = Read-Host "Type in password for $Farmaccount"
set-Content $TempScript ""
set-Content $TempScript ('$farmPassword = ' + '"' + $farmPassword + '"')

# ===================================================================================
# Create start-sync-script
# ===================================================================================
$Mainjob =
{

#Checks wheather the script is running as admin, if not then starts as admin.
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))

{
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}

#Add snaping if it doesnt exist
if ( (Get-PSSnapin -Name microsoft.sharepoint.powershell -EA "SilentlyContinue") -eq $null )
{
    Add-PsSnapin microsoft.sharepoint.powershell
}

#Script runs on local server:
$hostname = hostname
$Farmaccount = (Get-SPFarm).DefaultServiceAccount.Name

#Store instances into variables:
$service1 = $(Get-SPServiceInstance | ? {$_.TypeName -match "User Profile Service" -and $_.Server -match $hostname})
$service2 = $(Get-SPServiceInstance | ? {$_.TypeName -match "User Profile Synchronization Service" -and $_.Server -match $hostname})

#Stop service instance
Write-Host -f Cyan "Stopping the User Profile Instance"
Stop-SPServiceInstance -Identity $service1.ID -Confirm:$false

while($service1.status -ne "Disabled")
{
Write-Host "Stopping the User Profile Service instance"
sleep 3
$service1 = $(Get-SPServiceInstance | ? {$_.TypeName -match "User Profile Service" -and $_.Server -match $hostname})
}
write-host -f Green "OK"
write-host ""

#Start service instance
Write-Host -f Cyan "Starting the User Profile Instance"
Start-SPServiceInstance -Identity $service1.ID 

while($service1.status -ne "Online")
{
Write-Host "Starting the User Profile Service instance"
sleep 3
$service1 = $(Get-SPServiceInstance | ? {$_.TypeName -match "User Profile Service" -and $_.Server -match $hostname})
}
write-host -f Green "OK"
write-host ""

#Start Synchronization service
Write-Host -f Cyan "Starting the User Profile Synchronization.."
$upsa = Get-SPServiceApplication | ?{$_.TypeName -like "*User Profile Serv*"}

$service2.Status = [Microsoft.SharePoint.Administration.SPObjectStatus]::Provisioning
$service2.IsProvisioned = $false
$service2.UserProfileApplicationGuid = $upsa.Id
$service2.Update()
$upsa.SetSynchronizationMachine($hostname, $service2.Id, $Farmaccount, $farmPassword)
Start-SPServiceInstance $service2

Write-Host ""
$t = 0
$service2 = $(Get-SPServiceInstance | ? {$_.TypeName -eq "User Profile Synchronization Service" -and $_.Server -match $hostname})

#get the Forefront Identity Manager Synchronization service to monitor its status
$syncservice = Get-Service FIMSynchronizationService

while(-not ($service2.Status -eq "Online"))
{
   	sleep 10;
    Write-Host "Be Patient...You have only waited $t seconds"
    $service2 = $(Get-SPServiceInstance | ? {$_.TypeName -match "User Profile Synchronization Service" -and $_.Server -match $hostname})
    $t = $t + 10
    if($service2.Status -eq "Disabled"){Write-Host -f Yellow "Sync start has failed, press the anykey to exit";read-host;exit}
}
  $t = $t - 10
  write-host ""
Write-Host -f Green "OK - Synchronization Service is Online!"
sleep 3
write-host ""
iisreset
}

#Adding above script to the temp script.
Add-Content $TempScript $Mainjob

# ===================================================================================
# Run start-sync-script (temp script)
# ===================================================================================
$ScriptFile = $TempScript #$TempScript
$pw = convertto-securestring $farmpassword -asplaintext –force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $farmaccount, $pw

# Create a new process with UAC elevation
Start-Process $PSHOME\powershell.exe -Credential $cred -ArgumentList "-Command Start-Process $PSHOME\powershell.exe -ArgumentList `"'$scriptfile'`" -Verb Runas" -Wait

Write-Host ""
Write-Host "Wait for Sync script to finish.., press the anykey to remove temp script after"
Read-host
write-host "Clearing temp script.."
Remove-Item $TempScript
Write-Host -f Green "OK"
Read-host
exit

If the synchronization still does not start (you have waited more than 450 Seconds)…meaning that it just waits for the synchronization service to start:

“Be Patient…You have only waited X seconds”

I recommend 2 things to try:

1) Remove the User Profile Service Application without deleting the databases. Then recreate the User Profile Service Application using the old database names. Start the Synchronization Service.

2) Unprovision – Provision the SyncDB by using the steps found on step 4, 5 and 6 on page https://sharepointbjorn.com/2014/07/02/upgrade-user-profile-service-application-from-2010-to-2013/. Start the Synchronization service.

Advertisements

Share this:

  • Twitter
  • Facebook
  • Google

Like this:

Like Loading...

Related

Comments
  1. Arshad says:
    May 18, 2016 at 2:39 pm

    Thanks a Lot, I was stuck at starting in service…it worked for ….Issue resolved….

    Reply
  2. amjed2008 says:
    June 16, 2016 at 2:34 am

    Great blog & thanking you very much. UPS started after 40seconds.

    Reply
  3. Raj says:
    June 22, 2016 at 7:59 pm

    I have created a new UPS in SP 2013, UPS created successfully however While start the User Profile Synchronization service, Its automatically getting stopped

    I am using Farm admin account which has access in Local Administrator and Allow log on locally
    Also this account has access in AD and Replicating Directory changes access as well

    I have this script and got this error message ““Sync start has failed, press the any key to exit”

    When I checked the User Profile Sync service, Its in stopped state

    This is new UPS as part of new SP 2013 Farm setup

    Seeing this error in ULS log:

    UserProfileApplication.SynchronizeMIIS: Failed to configure MIIS post database, will attempt during next rerun. Exception: System.Configuration.ConfigurationErrorsException: ERR_CONFIG_DB
    at Microsoft.Office.Server.UserProfiles.Synchronization.ILMPostSetupConfiguration.ValidateConfigurationResult(UInt32 result)
    at Microsoft.Office.Server.UserProfiles.Synchronization.ILMPostSetupConfiguration.ConfigureMiisStage2()
    at Microsoft.Office.Server.Administration.UserProfileApplication.SetupSynchronizationService(ProfileSynchronizationServiceInstance profileSyncInstance).

    Thanks
    Raj

    Reply
  4. The User Profile Service Has Stopped Windows 7 | Marioosava says:
    June 25, 2016 at 2:21 pm

    […] SharePoint User Profile Synchronization Service AutoFixer … – Behold! I present to you dear visitors the UPSA_SYNC_AUTOFIX PowerShell Script. This script can be very useful when struggling to start your Use Profile … […]

    Reply
  5. Neville says:
    July 29, 2016 at 5:32 pm

    Bjorn! Thank you so much! This is amazing!
    Just curious – does the UPS restart message ever change from “Be patient, you’ve only waited X seconds” to “Panic! You’ve been waiting too long!”

    Reply
  6. toneman says:
    August 3, 2016 at 2:45 pm

    I’m sure the script works great (I ran it multiple times but could never provision the service)…but on my Dev farm rebuild, I had to install June 2015 CU before I could provision it for the first time. I’ll be sure to use it when I need it in the future though. Cheers!

    Reply
  7. LK says:
    August 18, 2016 at 1:51 pm

    I follow this URL and solved this issue. I hope this will help someone as well.
    https://www.windowstechupdates.com/user-profile-synchronization-service-not-starting-in-sharepoint-2013/

    Reply
  8. Philo says:
    September 28, 2016 at 6:36 pm

    FYI, the existence of a 15 hive doesn’t verify the SharePoint version – I’ve got a 2010 farm that has 15 and 16 subdirectories under webserverextensions (Reporting Services components)

    It’s better to use $(get-spfarm).buildversion

    Reply
  9. senstiveheart says:
    September 29, 2016 at 11:03 am

    Reblogged this on sharepointswe.

    Reply
  10. Dane says:
    October 26, 2016 at 1:00 am

    Worked flawlessly! Thank you so much!
    I’ll be saving this script in my favourites!

    Reply
  11. Suryakanta Das says:
    October 27, 2016 at 3:25 pm

    I run this script. i got “Sync start failed, press any key to exit” after 250 seconds. I created new user profile service instance on SharePoint 2013 and created new sync DB, Profile DB and Social DB. But no luck same error. Could you please help.

    following are the error got on Event Viewer

    There was an exception loading job definition “Microsoft.Office.Server.UserProfiles.UserProfileChangeCleanupJob” (id “b42baf17-60bf-49e9-a9d7-41e045b56e56”). Operation is not valid due to the current state of the object.

    Performance counters for the FIMSynchronizationService (Forefront Identity Manager Synchronization Service) service are already in the registry, no need to reinstall. This only happens when you install the same counter twice. The second time install will generate this event.

    Thanks in advance.

    Reply
  12. eddiesel357 says:
    November 14, 2016 at 12:39 pm

    BEST SCRIPT EVER THANK YOU

    Reply
  13. Hien Vo says:
    November 16, 2016 at 8:03 am

    My server keep Waiting for new XML files to load into GUID..

    Reply
    • Sankum says:
      February 28, 2017 at 4:31 pm

      Same issue with my server as well. How did you resolve it?

      Reply
      • Phil says:
        October 18, 2017 at 7:11 am

        Same issue with my server. What have you done to resolve it?

  14. Thomas Altmann says:
    January 4, 2017 at 1:48 pm

    Thank you so much for this! You just saved me hours of troubleshooting and research into the various errors I got from the sync service. Your script worked perfectly and my user sync is up and running again!

    Reply
  15. Erro ao provisionar User Profile Sync no SP2013 + SQL2014 – Tarcisio Gambin says:
    February 14, 2017 at 8:30 pm

    […] uma “googlada” rápida, verá que existem excelentes e excelentes guias, mas também scripts powershell mágicos (cuidado com eles), e claro, uma enxurrada de blogs e threads em […]

    Reply
  16. Matthew says:
    March 9, 2017 at 9:41 am

    You, sir, are a legend.

    Reply
  17. Prabu says:
    April 13, 2017 at 5:17 am

    The Script is not available for download

    Reply
    • bjorn80 says:
      April 24, 2017 at 10:33 am

      Updated

      Reply
  18. Ken says:
    November 14, 2017 at 3:50 pm

    Thanks Bjorn , excellent script that restarted our User Profile Sychronisation Service when stuck on ‘starting’.

    Reply
  19. Stan Kappiris says:
    May 11, 2018 at 7:53 pm

    Truly a great solution: The script worked on my pilot server but is looping at the “Stopping the User Profile Service instance” section. There are two User Profile Service instances. One is “online” the other is disabled. Is there any way to fix this issue?

    Reply
  20. Josh says:
    May 24, 2018 at 7:44 pm

    I tried running the script above, and I get an error at the end:

    Start-Process : This command cannot be run due to the error: The directory name is invalid.
    At line:285 char:1
    + Start-Process $PSHOME\powershell.exe -Credential $cred -ArgumentList “-Command S …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException
    + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand

    This is preventing the temp script from running, but I have no idea what about the directory name isn’t valid. I’m guessing it has something to do with the argument list. Any ideas?

    Reply
    • Josh says:
      May 25, 2018 at 1:15 pm

      I did manage to figure out the above issue (running from an H: drive rather than C:), and managed to figure out that the script breaks if there is a double quotation used as part of the password (modified line 183 with single quotations). However I still get an error at the end of the temp script that the “Sync start has failed, press the anykey to exit”. I’m not really well versed with SharePoint, and am working on fixing this issue for my organization. Any ideas why this would fail, and what I can do to correct it?

      Reply
« Older Comments

Leave a Reply Cancel reply

Fill in your details below or click an icon to log in:

Gravatar
WordPress.com Logo

You are commenting using your WordPress.com account. ( Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. ( Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. ( Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. ( Log Out /  Change )

Cancel

Connecting to %s

Hello world PowerShell
IISRESET whole SharePoint farm

  • Archives

    • March 2016
    • October 2015
    • October 2014
    • September 2014
    • August 2014
    • July 2014
    • June 2014
  • Meta

    • Register
    • Log in
    • Entries RSS
    • Comments RSS
    • WordPress.com
Create a free website or blog at WordPress.com.
Cancel
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Cookie Policy
%d bloggers like this: