jueves, 11 de agosto de 2016

Error al utilizar SharePoint Search. Field or property “TimeZoneId” does not exist. Search API REST no funciona.

Nuestro paciente Search venía con visión borrosa, desorientado y muy confundido, incluso había olvidado lo que tenía guardado en los bolsillos, una especie de amnesia pasajera, directo a psiquiatría.

No paraba de repetir constantemente "Field or property “TimeZoneId” does not exist" cada vez que intentábamos hacer que recordase algo mediante su caja de texto en el buscador.

Además su API REST mediante la cual podríamos darle instrucciones de búsqueda estaba caída, el servicio simplemente no respondía ni mediante una simple llamada a http://<server>/_api/search/query dando un error 400 de error de procesamiento de solicitud.

Pero tranquilos, hay tratamiento, Microsoft ya señaló en su día que la actualización CU Agosto de 2015 requiere un parcheo más exhaustivo al pasar el obligado configurador de productos de SharePoint cada vez realizamos una actualización.

El parcheo es necesario si actualizamos desde antes de Agosto de 2015 a cualquier CU de fecha posterior si queremos evitar que el servicio de Search funcione mal.

Para resolver esto, una vez instalado el CU, hacemos en todos los servidores de la granja lo siguiente:

IISRESET

PSConfig.exe -cmd upgrade -inplace b2b -wait -cmd applicationcontent -install -cmd installfeatures -cmd secureresources

Información en inglés del doctor que conocía estos detalles: 

https://vigneshsharepointthoughts.com/2015/09/15/fix-for-the-search-issue-in-august-2015-cu-for-sharepoint-2013/

Especificación de PSConfig.exe:

https://technet.microsoft.com/es-es/library/cc263093(v=office.14).aspx

miércoles, 10 de agosto de 2016

Search Service: Exception while communicating with Host Controller. Node IndexComponent x for system cannot be deployed on this host due to insufficient physical memory


En esta ocasión a nuestro paciente se le comenzó a ulcerar la cara con un aspecto algo preocupante mientras intentaba aprovisionar una topología de búsqueda en dicho servicio con un Set-SPEnterpriseSearchTopology -Identity $NewSearchTopology:

[DBG]: PS C:\Windows\system32>> 
Set-SPEnterpriseSearchTopology : Topology activation failed. Service call 
AddNodeMapping failed with message 'Exception while communicating with Host 
Controller at ctshpliv01: Node deployment failed [System = E308E7, Node = 
IndexComponent5] [Cause: Node IndexComponent5 for system E308E7 cannot be 
deployed on this host due to insufficient physical memory, 2000 MB required 
but only 1106 MB available.]'

A pesar de lo que pueda parecer este mensaje puede despistar un poco, y aunque lo primero que nos viene a la cabeza es echarle unos cuantos gigas extra a nuestra memoria física, eso no resolverá el problema si observamos el indicador de memoria en Task Manager mientras ejecutamos Set-SPEnterpriseSearchTopology.

La solución vino al adecuar mejor la arquitectura de topología a los recursos de que disponemos, por tanto al reducir el número de componentes de índice que se pretendía crear a la mitad, de ocho a cuatro (finalmente 2 por máquina), el problema fue subsanado y el servicio creado sin problemas. 

Finalmente, la arquitectura creada fue la siguiente:


Y el script adaptado a nuestro caso utilizado el siguiente, el cual fue sacado originalmente de https://blogs.msdn.microsoft.com/chandru/2013/02/18/sharepoint-2013-configuring-search-service-application-and-topology-using-powershell/

El script original presentaba la topología con 8 índices, lo cual dio el actual problema de úlceras faciales que presentamos en nuestro caso.

#==============================================================
    #Search Service Application Configuration Settings
     Add-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue
#==============================================================

$SearchApplicationPoolName = "SearchApplicationPool"
$SearchApplicationPoolAccountName = "dominio\cuentaSvc"
$SearchServiceApplicationName = "Search Service Application"
$SearchServiceApplicationProxyName = "Search Service Application Proxy"
$DatabaseServer = "DATABASESERVER"
$DatabaseName = "SEARCH_DATABASE_NAME"
$IndexLocationServer = "C:\Indexes"  
$NoLocalServerName = "server2"

#==============================================================
          #Search Application Pool

                   #==============================================================
                   
Write-Host -ForegroundColor DarkGray "Checking if Search Application Pool exists"
$SPServiceApplicationPool = Get-SPServiceApplicationPool -Identity $SearchApplicationPoolName -ErrorAction SilentlyContinue
if (!$SPServiceApplicationPool)
{
    Write-Host -ForegroundColor Yellow "Creating Search Application Pool"
    #$SPServiceApplicationPool = New-SPServiceApplicationPool -Name $SearchApplicationPoolName -Account $SearchApplicationPoolAccountName -Verbose
   
}
 $SPServiceApplicationPool = Get-SPServiceApplicationPool -Identity "SearchApplicationPool"

#==============================================================
          #Search Service Application
#==============================================================
Write-Host -ForegroundColor DarkGray "Checking if SSA exists"
$SearchServiceApplication = Get-SPEnterpriseSearchServiceApplication -Identity $SearchServiceApplicationName -ErrorAction SilentlyContinue
if (!$SearchServiceApplication)
{
   Write-Host -ForegroundColor Yellow "Creating Search Service Application"    
   $SearchServiceApplication = New-SPEnterpriseSearchServiceApplication -Name $SearchServiceApplicationName -ApplicationPool $SPServiceApplicationPool -DatabaseServer  $DatabaseServer -DatabaseName $DatabaseName 
}
Write-Host -ForegroundColor DarkGray "Checking if SSA Proxy exists"
$SearchServiceApplicationProxy = Get-SPEnterpriseSearchServiceApplicationProxy -Identity $SearchServiceApplicationProxyName -ErrorAction SilentlyContinue
if (!$SearchServiceApplicationProxy)
{
    Write-Host -ForegroundColor Yellow "Creating SSA Proxy"
    New-SPEnterpriseSearchServiceApplicationProxy -Name $SearchServiceApplicationProxyName -SearchApplication $SearchServiceApplicationName
}


 #==============================================================
          #Start Search Service Instance on Server1 -local
 #==============================================================
 $SearchServiceInstanceServer1 = Get-SPEnterpriseSearchServiceInstance -local 
 Write-Host -ForegroundColor DarkGray "Checking if SSI is Online on Server1"
 if($SearchServiceInstanceServer1.Status -ne "Online")
 {
   Write-Host -ForegroundColor Yellow "Starting Search Service Instance"
   Start-SPEnterpriseSearchServiceInstance -Identity $SearchServiceInstanceServer1
   While ($SearchServiceInstanceServer1.Status -ne "Online")
   {
       Start-Sleep -s 5
   }
   Write-Host -ForegroundColor Yellow "SSI on Server1 is started"
 }

  #==============================================================
         #Start Search Service Instance on Server2 liv03
 #==============================================================
 $SearchServiceInstanceServer2 = Get-SPEnterpriseSearchServiceInstance -Identity $NoLocalServerName #liv03
 Write-Host -ForegroundColor DarkGray "Checking if SSI is Online on Server2"
 if($SearchServiceInstanceServer2.Status -ne "Online")
 {
   Write-Host -ForegroundColor Yellow "Starting Search Service Instance"
   Start-SPEnterpriseSearchServiceInstance -Identity $SearchServiceInstanceServer2
   While ($SearchServiceInstanceServer2.Status -ne "Online")
   {
       Start-Sleep -s 5
   }
   Write-Host -ForegroundColor Yellow "SSI on Server2 is started"
 }

 #==============================================================
 #Cannot make changes to topology in Active State.
 #Create new topology to add components
 #=========================================
 $InitialSearchTopology = $SearchServiceApplication | Get-SPEnterpriseSearchTopology -Active 
$NewSearchTopology = $SearchServiceApplication | New-SPEnterpriseSearchTopology


#==============================================================
        #Search Service Application Components on Server1
        #Creating all components except Index (created later)     
#==============================================================

New-SPEnterpriseSearchAnalyticsProcessingComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $SearchServiceInstanceServer1
New-SPEnterpriseSearchContentProcessingComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $SearchServiceInstanceServer1
New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $SearchServiceInstanceServer1
New-SPEnterpriseSearchAdminComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $SearchServiceInstanceServer1

#==============================================================
#Search Service Application Components on Server2.
#Crawl, Query, and CPC
#==============================================================

New-SPEnterpriseSearchContentProcessingComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $SearchServiceInstanceServer2
New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $SearchServiceInstanceServer2
New-SPEnterpriseSearchCrawlComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $SearchServiceInstanceServer2 


#==============================================================
        #Index Components with replicas
#==============================================================
$IndexLocationServer = "S:\Indexes"

New-SPEnterpriseSearchIndexComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $SearchServiceInstanceServer1  -IndexPartition 0 -RootDirectory $IndexLocationServer
New-SPEnterpriseSearchIndexComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $SearchServiceInstanceServer1  -IndexPartition 1 -RootDirectory $IndexLocationServer 
New-SPEnterpriseSearchIndexComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $SearchServiceInstanceServer2  -IndexPartition 0 -RootDirectory $IndexLocationServer 
New-SPEnterpriseSearchIndexComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $SearchServiceInstanceServer2  -IndexPartition 1 -RootDirectory $IndexLocationServer 

#==============================================================
  #Setting Search Topology using Set-SPEnterpriseSearchTopology
#==============================================================

Set-SPEnterpriseSearchTopology -Identity $NewSearchTopology

#==============================================================
                #Clean-Up Operation
#==============================================================

Write-Host -ForegroundColor DarkGray "Deleting old topology"
Remove-SPEnterpriseSearchTopology -Identity $InitialSearchTopology -Confirm:$false
Write-Host -ForegroundColor Yellow "Old topology deleted"

#==============================================================
                #Check Search Topology
#==============================================================
Get-SPEnterpriseSearchStatus -SearchApplication $SearchServiceApplication -Text
Write-Host -ForegroundColor Yellow "Search Service Application and Topology is configured!!"