PeoplePicker – Double Users and Diacritic issue

Well, it is an another well know issue by Microsoft.
Here you can find some definitions:

* Experiencing inconsistencies with some user profiles where the user Account name attribute is observed to vary between e.g. Domain\aloş and Domain\alos . This is observed in SharePoint Central Administration > User Profile Service Application > Manage User Profiles and Edit User Profile sections and therefore impacting approval workflows where they are using InfoPath Forms .

*Connecting local domain to Sharepoint server, in domain are login with diacritics, in sharepoint there are login of users with diacritics – wrongly displayed .Also when search for the user in people picker we get two users account one with account name with diacritics and second without it.
In UPA profile contains correct account name (without diacritics)

Issue Reproduce:
Add a user in Active Directory. In example we are adding TESTMOSS2010T\Berkc user.

Diacritic1

For first time login the SharePoint as a Site collection administrator (which should be different that our test account)
And try to grant permission the user but use diacritic as berkç (use ‘ç’ instead of ‘c’)

Diacritics2

When you check and verify the user, move and keep Mouse over the validated user text , that will Show us the account
As you can see it is “TESTMOSS2010T\berkç” . Well so far so good . SharePoint accept it without any problem when you click the OK.

Diacritics3

If you search from user it will Show you just one with “berkç”

Diacritics4

If we try without diacritics like “berkc” it is also accepted .

Diacritics5

But wait a minute , If you keep Mouse over the validated user text , that still show us the account as
“TESTMOSS2010T\berkç” .
Diacritics3
Hmm , thats looks strange . (Well actually SharePoint has already saved the data in UserInfo table & UserInformation List as ‘berkç’) and SharePoint is clever enough to understand this is same user.
(because they have same SID) PS: If the SIDs are different well it is tottally different problem and out of scope for this article 🙂

Diacritics6

You can see in UserInfo table

Diacritics7

And User Information List

Diacritics8

Well , I dont want to use it like this. This user should be “TESTMOSS2010T\berkc” so how can i change it .
Move-SPUser will helps here.

Diacritics9

$user = get-spuser -Identity “TESTMOSS2010T\berkç” – web <web Url>
Move-SPUser -identity $user -NewAlias “TESTMOSS2010T\berkc” -IgnoreSID
(In some scenarios it doesn’t work , so in that condition you may need to delete user from SharePoint and add again )
After i changed that user account , hmm i can see now 2 account if i search from people-picker .

Diacritics10

Why ? The reason is LSA cache . Because very first time we make a query to AD as “berkç” and AD accepted it (Well the configuration of AD user resolution for diacritics is a different issue so i don’t mention here) and Server LSA cache has stored as “berkç” . So PeoplePicker has uses both SharePoint DBs and AD Resources to Show results . In that condition SharePoint DB (User Information List) returns “berkc” and AD query bypassed by LSA – Show us “berkç

The LSA maintains a SID cache on domain member computers. This cache stores mappings between SIDs and user names. If the SID information exists in the local cache, the LSA returns the cached user name information instead of checking whether the user name has changed.
The local SID cache helps reduce domain controller workload and network traffic. However, inconsistency may occur between the local cache and the domain controllers.

If you want to get rid-off this behavour ; disable LSA cache: http://support.microsoft.com/kb/946358.

To work around this issue, disable the local SID cache on the domain member computer. To do this, follow these steps:

  1. Open Registry Editor.To do this in Windows XP or in Windows Server 2003, click Start, click Run, type regedit, and then click OK.

    To do this in Windows Vista and newer, Click Start, type regedit in the Start Search box, and then press ENTER.

  2. Locate and then right-click the following registry subkey:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
  3. Point to New, and then click DWORD Value.
  4. Type LsaLookupCacheMaxSize, and then press ENTER.
  5. Right-click LsaLookupCacheMaxSize, and then click Modify.
  6. In the Value data box, type 0, and then click OK.
  7. Exit Registry Editor.

Note The LsaLookupCacheMaxSize registry entry sets the maximum number of cached mappings that can be saved in the local SID cache. The default maximum number is 128. When the LsaLookupCacheMaxSize registry entry is set to 0, the local SID cache is disabled.

Unfortunately there is no other resolution for this design.

 

Unable to sync user titles for Welcome name in SharePoint

Hello ,

If you facing this problem you may read my previous post.
http://blog.bugrapostaci.com/2011/06/22/sharepoint-2010-change-your-display-of-wellcome-name

In this post i have adding another powershell script that detects and fixes this problems for a workaround.

# THIS CODE-SAMPLE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR
# FITNESS FOR A PARTICULAR PURPOSE.
<#

#Add SharePoint PowerShell SnapIn if not already added
if ((Get-PSSnapin “Microsoft.SharePoint.PowerShell” -ErrorAction SilentlyContinue) -eq $null) {
Add-PSSnapin “Microsoft.SharePoint.PowerShell”
}

if( $args.Length -eq 0) {
write-host “Usage : Missing ”
exit
}

$MissMatchCount = 0
$NoProfile = 0;
$NoPrefferedName = 0
$TotalUser = 0
$Matched = 0
$Fixed = 0

write-host “Intializing…”
$site = new-object Microsoft.SharePoint.SPSite($args[0]);
$ServiceContext = [Microsoft.SharePoint.SPServiceContext]::GetContext($site);
$ProfileManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServiceContext);

foreach($siteUser in $site.RootWeb.SiteUsers)
{
write-host “Checking -> AccountName: ” $siteUser.LoginName ” ID:” $siteUser.ID
try
{
$profile = $ProfileManager.GetUserProfile($siteUser.LoginName);
}
catch
{
write-host “Unable to get profile for user” $siteUser.LoginName -foregroundcolor red
$NoProfile++
$TotalUser++
Write-host “————-”
continue;
}

$AccountName= $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value
$PreferredName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::PreferredName].Value

write-host “Profile Data -> Account: ” $AccountName ” DisplayName:” $siteUser.DisplayName ” PrefferedName:” $PreferredName

if( $accountName -ne $siteUser.LoginName)
{
write-host “Account MissMatch -> LoginName: ” $siteUser.LoginName ” Profile Account:” $AccountName -foregroundcolor red
}

if( $PreferredName -ne “NONE” )
{
if($PreferredName -ne $siteUser.DisplayName)
{
write-host “MissMatch :” $siteUser.LoginName ” DisplayName:” $siteUser.DisplayName ” PrefferedName:” $PreferredName -foregroundcolor yellow
$MissMatchCount++

#Set-SPUser -identity $siteUser.LoginName -Displayname $PreferredName -web $args[0]
#$Fixed++
}
else
{
Write-host “OK”
$Matched++
}
}
else
{
$NoPrefferedName++
}
Write-host “————-”
$TotalUser++
}

Write-host “Results”
write-host “Total User : ” $TotalUser
write-host “Total Matched User Count : ” $Matched
write-host “Total Fixed User Count : ” $Fixed
Write-host “Total Missmatch User Count : ” $MissMatchCount
Write-host “Total Missing Profile User Count : ” $NoProfile
write-host “Total Empty Preffered Name user Count : ” $NoPrefferedName

For fixing option just activate the line by deleting “#” charecter.

#Set-SPUser -identity $siteUser.LoginName -Displayname $PreferredName -web $args[0]
#$Fixed++

Usage is simple:
Save the script in your drive as ps1 file.

C:\> .\syncuser.ps1 <SiteUrl>
Exp
C:\> .\syncuser.ps1 http://blog.bugrapostaci.com

PS: To get output in a text file is a little tricky but you can do it like this.
Start a Command Prompt ( Not Powershell! )
Type following command
C:\> powershell .\syncuser.ps1 http://blog.bugrapostaci.com > .\results.txt

Getting Last Accessed user for a SharePoint Site

Assume that you would like to get last accessed users for a specific site or web in SharePoint. The correct approch is creating a custom IIS Module to get update statistics by every request. If you dont want to do that there you may alternatively use following method.

But we have some conditions:
1) Usage and Health Data Collection Service Application is running.
2) And Microsoft SharePoint Foundation Usage Data Import job running in a small interval (one hour maybe). (Because the data first stores in a Usage file in file System and when the timer job has been executed that data transfered to you Logging Database) Thats mean it is not real time. (If you would like a statistics in real time i suggest that use a custom IIS module)

Than you can search the last 5 accessed user from SQL Server Management Studio by quering Logging Database Server (It would be delayed by interval of Import Timer Job)

Declare @serUrl as nvarchar(MAX), @sitUrl as nvarchar(MAX) , @wUrl as nvarchar(MAX)
Declare webcursor CURSOR FOR select serverurl,siteurl,weburl from RequestUsage group by ServerUrl,SiteUrl,WebUrl
Open webcursor

FETCH NEXT FROM webcursor INTO @serUrl,@sitUrl,@wUrl
WHILE @@FETCH_STATUS = 0 
BEGIN
PRint 'ServerUrl: ' + @serUrl + ' Site Url:' + @sitUrl +  ' Web Url:' + @wUrl
select Top 5 LogTime, UserLogin,ServerUrl,SiteUrl,WebUrl from RequestUsage 
where ServerUrl = @serUrl and SiteUrl = @sitUrl and WebUrl =  @wUrl
--Dont Forget to Exclude SharePoint\system , Central Administration Web Site, Crawler Account, And Timer Service Account for correct results.
and ServerUrl <> 'http://contoso.com:32843'  and UserLogin <> 'SHAREPOINT\system' and UserLogin<> 'Contoso\Crawler'
order by LogTime desc 
FETCH NEXT FROM webcursor INTO @serUrl,@sitUrl,@wUrl
END
CLOSE webcursor
DEALLOCATE webcursor

Failed to create the Pages library – SharePoint 2010

When try to create a new site ( Publishing Site ) under your site collection Event log message was: ‘Failed to create the ‘Pages’ library.’.
Exception was: ‘Microsoft.SharePoint.SPException: User cannot be found.
at Microsoft.SharePoint.SPUserCollection.get_Item(String loginName)
at Microsoft.SharePoint.Workflow.SPWorkflowNoCodeSupport.LoadWorkflowBytesElevated(SPFile file, Int32 fileVer, Int32& userid, DateTime& lastModified)

the error caused by the user who created the latest revision of the workflow no longer exists in the site collection.

1) Download and install Sharepoint Designer 2010 if you already do not have it on your system.
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=16573

2)In Sharepoint Designer, please open the root web

3)Go to All files > _Catalogs> wfpub

4)Check out and then Check in all Publishing Workflow configuration files:

5)De-activate and re-activate the publishing Feature from Site Settings

Important: Please proceed with a full farm backup before proceeding with this . It would also be beneficial for your users if you could implement the action plan outside of your regular business hours.

Could we create a second User Profile Service Application ?

Yes you can but ,
If you have only one server in your farm you can use just one User Profile Service Application (UPA) in this server because the windows Service of User Profile Syncronization Service just configurable only one UPA. So if you have more than one sharepoint server in your farm for example 3 server;  you can create more than 3 UPA but you can only syncronize 3 of them.

For Another scenario, i assume that you have only one server and already provisioned one UPA and configured the syncronization connection. After adding second UPA as you know you can not able to add any Sycronization connection for Second UPA . But if you stop CA-> Services On Server -> User Profile Syncronization Service and restart it will prompt you to select UPA options mean you can change the relation for specific UPA . Still only one UPA can able to sync for one server.

Create all users’ personal site via Powershell script – Sharepoint 2010

#PowerShell Script - Create All Users Personel Sites - SharePoint 2010 #The scripts is distributet "as-is." Use it on your own risk. 
#Add SharePoint PowerShell SnapIn if not already added if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}

[Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server")

$mysiteHostUrl = "http://my"
$personalSiteGlobalAdmin = "DOMAIN\padm"
$personalSiteGlobalAdminNot ="padm@bugrapostaci.com"
$personalSiteGlobalAdminDisplayName = "Personel Site admin"
$mysite = Get-SPSite $mysiteHostUrl

$context = [Microsoft.Office.Server.ServerContext]::GetContext($mysite)
$upm =  New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)

$AllProfiles = $upm.GetEnumerator()

foreach($profile in $AllProfiles)
{

    $DisplayName = $profile.DisplayName
    $AccountName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value
       #Add your restrictions for users.        if($Accountname -like "YourDomain*")
       {
          if($profile.PersonalSite -eq $Null)
          {
               write-host "Creating personel site for ", $AccountName
               $profile.CreatePersonalSite()
               #Adding an extra admin for personel sites                $pweb = $profile.PersonalSite.OpenWeb()
               $pweb.AllUsers.Add($personalSiteGlobalAdmin,$personalSiteGlobalAdminNot,$personalSiteGlobalAdminDisplayName,$null);
               $padm= $pweb.AllUsers[$personalSiteGlobalAdmin];
               $padm.IsSiteAdmin = $true;
               $padm.Update();
               $pweb.Dispose();
               write-host "Personal Site Admin has assigned"
          }
          else
          {
               write-host $AccountName ," has already personel site"
          }
   }
}
$mysite.Dispose();