Saturday, February 4, 2017

My thoughts about "GitLab Outage"

Everyone heard the news of GitLab Outage.

Yes, we should use "tools" to do the administration work, and always test those tools in DEV environment first.

For SharePoint, although I have some tools to help manage site collections, the easier way is to build some "PowerShell" scripts toolsets.

Apart from that, in my opinion, the most important part is to split the huge database into many small databases, and keep those databases light-coupling.

Yes, it's just like what SharePoint does with site collections.

I have to confess: although I tried my best not to touch the production environment, and not to log on as system administrator, but, sometimes, I still deleted something accidentally, in Production environment!

Lucky that there are more than 150 site collections. So the damage only affect a small group of users, and it's not too hard to "recover" the changes.

:-)

Thursday, January 19, 2017

Resolved - Failed to configure MIIS post database

After installing SharePoint 2013 SP1 CU 201609 on DEV server, "User Profile Synchronization Service" stopped working. ULS log shows the error message below.

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

I tried all possible solutions through online research, but, none of them works.

In the end, I submitted a Microsoft support ticket.  It turns out that we have to remove "Forefront Identity Manager Service" from the dependency of windows service "FIMSynchronizationService"


Create a ".reg" file, then add the text below to it, then merge this reg file into the Windows of SharePoint server.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FIMSynchronizationService]
"DependOnService"=hex(7):57,00,69,00,6e,00,6d,00,67,00,6d,00,74,00,00,00,00,00

Then reboot the server. Below is the result.



Now we can start the SharePoint service instance "User Profile Synchronization Service".

I hope this post can save you some headache.


PS: Microsoft support team said they never got this issue before. So I assume it only happens when SharePoint and Database are installed on the same server.

Tuesday, January 17, 2017

Why Microsoft web sites are so slow?

It's always slow, especially the MSDN web sites.  Why?

Below is a screenshot from the document "Office 365 for IT Pros.201611"(Page 73). It explains the passive authentication flow, which is the default user authentication mechanism for web browsers.

In theory, after log in, the user credential/ticket is cached, and the rest operation should be faster. But unfortunately, there are a lot of dynamic data loading on MSDN, which may triggered other authentication events.

Maybe that's the reason.

PS: why Google web sites are much faster?


Tuesday, December 20, 2016

Move SharePoint 2013 search server in one go

There are many posts about how to move search components from one server to another. But I cannot find a complete version to do that in one go.

It's frustrating to keep "waiting" for the current step to complete, so we can start next step. That's why I build one as below. This one assumes that the farm only has one search server which hosts all search components. And it moves all search components from the current server to a new SharePoint server.

The whole process may take more than 20 minutes.

Most of these PowerShell scripts are copied from here, thanks for the hard work of Matt Milsark.


function MoveSPSearchComponents([string]$SearchServerNameOld, [string]$SearchServerNameNew)
{
    Write-Host "$(get-date -UFormat '%Y%m%d %H:%M:%S') - All 6 Search components are going to be moved from server '$SearchServerNameOld' to '$SearchServerNameNew'" -f DarkYellow
    # START THE SEARCH SERVICE ON THE NEW SERVER
    $ssa = Get-SPEnterpriseSearchServiceApplication
    $active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa –Active
    $clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active

    $instances = @(Get-SPEnterpriseSearchServiceInstance -Identity $SearchServerNameNew | Where-Object {$_.Status -eq "Online"})
    if ($instances.Count -eq 0)
    {
        Start-SPEnterpriseSearchServiceInstance -Identity $SearchServerNameNew
     
        do
        {
            $instances = @(Get-SPEnterpriseSearchServiceInstance -Identity $SearchServerNameNew | Where-Object {$_.Status -eq "Online"})
            Write-Host "." -NoNewLine
            Start-Sleep -s 1
        } until ($instances.Count -gt 0)
        Write-Host "Search instance on server '$SearchServerNameNew' is Online now" -f DarkGreen
    }

    $SearchComponents = @(Get-SPEnterpriseSearchComponent -SearchTopology $clone | Where-Object {$_.ServerName -eq $SearchServerNameNew})
    $SearchComponents
    $SearchComponents | Remove-SPEnterpriseSearchComponent -SearchTopology $clone -confirm:$false
    Set-SPEnterpriseSearchTopology -Identity $clone

    do
    {
        Write-Host "." -NoNewLine
        Start-Sleep -s 1
        $SearchComponents = @(Get-SPEnterpriseSearchComponent -SearchTopology $clone | Where-Object {$_.ServerName -eq $SearchServerNameNew})
    } until ($SearchComponents.Count -eq 0)
    Write-Host "$(get-date -UFormat '%Y%m%d %H:%M:%S') - Search components on server '$SearchServerNameNew' is cleaned up" -f DarkGreen
 
    # CREATE NEW SEARCH COMPONENTS ON THE NEW SEARCH SERVER
    $active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active
    $clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active
 
    New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $clone -SearchServiceInstance $SearchServerNameNew
    New-SPEnterpriseSearchAnalyticsProcessingComponent -SearchTopology $clone -SearchServiceInstance $SearchServerNameNew
    New-SPEnterpriseSearchContentProcessingComponent -SearchTopology $clone -SearchServiceInstance $SearchServerNameNew
    New-SPEnterpriseSearchCrawlComponent -SearchTopology $clone -SearchServiceInstance $SearchServerNameNew
    New-SPEnterpriseSearchIndexComponent -SearchTopology $clone -IndexPartition 0 -SearchServiceInstance $SearchServerNameNew

    Set-SPEnterpriseSearchTopology -Identity $clone

    do
    {
        Write-Host "." -NoNewLine
        Start-Sleep -s 1
        $SearchComponents = @(Get-SPEnterpriseSearchComponent -SearchTopology $clone | Where-Object {$_.ServerName -eq $SearchServerNameNew})
    } until ($SearchComponents.Count -eq 5)
    Write-Host "$(get-date -UFormat '%Y%m%d %H:%M:%S') - 5 Search components are created on server '$SearchServerNameNew' in the clone topology" -f DarkGreen

    # REMOVE COMPONENTS FROM ORGINAL SEARCH SERVER
    $active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active
    $clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active

    $SearchComponents = @(Get-SPEnterpriseSearchComponent -SearchTopology $clone | Where-Object {$_.ServerName -eq $SearchServerNameOld -and $_.Name -NotMatch 'AdminComponent'})
    $SearchComponents | Remove-SPEnterpriseSearchComponent -SearchTopology $clone -confirm:$false
 
    Set-SPEnterpriseSearchTopology -Identity $clone
 
    do
    {
        Write-Host "." -NoNewLine
        Start-Sleep -s 1
        $SearchComponents = @(Get-SPEnterpriseSearchComponent -SearchTopology $clone | Where-Object {$_.ServerName -eq $SearchServerNameOld -and $_.Name -NotMatch 'AdminComponent'})
    } until ($SearchComponents.Count -eq 0)
    Write-Host "$(get-date -UFormat '%Y%m%d %H:%M:%S') - Search components on server '$SearchServerNameOld' are removed (except the admin component)" -f DarkGreen
 
    # START AN ADMIN COMPONENT ON THE NEW SERVER
    $active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa –Active
    $clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active

    #$NewServer = Get-SPEnterpriseSearchServiceInstance -Identity $SearchServerNameNew
    New-SPEnterpriseSearchAdminComponent -SearchTopology $clone -SearchServiceInstance $SearchServerNameNew
    Set-SPEnterpriseSearchTopology -Identity $clone
 
    do
    {
        Write-Host "." -NoNewLine
        Start-Sleep -s 1
        $SearchComponents = @(Get-SPEnterpriseSearchComponent -SearchTopology $clone | Where-Object {$_.ServerName -eq $SearchServerNameNew -and $_.Name -match 'AdminComponent'})
    } until ($SearchComponents.Count -eq 1)
    Write-Host "$(get-date -UFormat '%Y%m%d %H:%M:%S') - Search Admin components on server '$SearchServerNameNew' is created" -f DarkGreen
 
    # DELETE THE OLD ADMIN COMPONENT
    $active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active
    $clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active

    $SearchComponents = @(Get-SPEnterpriseSearchComponent -SearchTopology $clone | Where-Object {$_.ServerName -eq $SearchServerNameOld -and $_.Name -match 'AdminComponent'})
    $SearchComponents | Remove-SPEnterpriseSearchComponent -SearchTopology $clone -confirm:$false
    Set-SPEnterpriseSearchTopology -Identity $clone

    do
    {
        Write-Host "." -NoNewLine
        Start-Sleep -s 1
        $SearchComponents = @(Get-SPEnterpriseSearchComponent -SearchTopology $clone | Where-Object {$_.ServerName -eq $SearchServerNameOld -and $_.Name -match 'AdminComponent'})
    } until ($SearchComponents.Count -eq 0)
    Write-Host "$(get-date -UFormat '%Y%m%d %H:%M:%S') - Search Admin components on server '$SearchServerNameOld' is removed" -f DarkGreen

    Write-Host "$(get-date -UFormat '%Y%m%d %H:%M:%S') - All 6 Search components are moved from server '$SearchServerNameOld' to '$SearchServerNameNew'" -f DarkYellow
}

$SearchServerNameNew = $env:COMPUTERNAME
MoveSPSearchComponents "OldSearchServerName" $SearchServerNameNew

Monday, December 12, 2016

Best simple guide about SharePoint search

Found an excellent post about SharePoint Search

It covers all major parts, and can be read through in a few minutes.

Strongly recommend it!

All credit goes to icansharepoint


Tuesday, December 6, 2016

No way to host server side code in container

When "SharePoint Framework" was released, I was pretty sure that, sooner or later, Microsoft would host server side code in containers (http://fangdahai.blogspot.com.au/2016/05/the-future-of-sharepoint-development.html)

After a few days of testing the container feature on Windows Server 2016, I realised that it was never going to happen :-(

The installation media of SQL Server Express 2016 with SP1 is around 421 MB (64 bit). After put it into windows container, how much disk space it takes? 10 GB!

The post Windows Containers Compared: WinDocks vs. Microsoft is correct. There is something wrong with "Windows Container" by design. To me, "Windows Container" is more like "Windows Nano Server" virtual machine.

Friday, November 25, 2016

"This item is no longer available" when trying to approve master page changes

After some minor change of a master page in SharePoint designer, I checked it in as a major version. SharePoint designer then opened the library "Master Page Gallery" ( /_catalogs/masterpage/Forms/my-sub.aspx ).

I can see the two changed master page files ( .html and .master ) in the "My submissions" list view. However, when trying to open the context menu to approve it, I got the error message "This item is no longer available".


I logged on as SharePoint farm administrator, so it should not be caused by permission issue.

Google leads me to this one, but it doesn't help.

In the end, I changed the versioning settings of this library, which fixed the problem.



Then I changed the settings back.

This is the first time I got this issue in the past 9 years. I guess it's caused by a minor bug. As alternative solution, it's good enough.

The environment is SharePoint 2016 with CU 201611.