lunes, 9 de enero de 2017

Job de Papelera de Reciclaje puede provocar caida de un sitio en SharePoint

Este caso nos tuvo casí un mes en la búsqueda de la causa del problema.



El problema:

La colección de sitios principal y primaria de SharePoint reportaba caídas aleatorias en las mañanas entre las 6 y 7 de la mañana.  Esto no sucedia a diario y la forma de corregir el problema era que el usuario reiniciaba tanto el servidor de SQL Server como el Front-End.

El Error:

01/06/2017 06:12:40.46  w3wp.exe (0x05C8)                        0x1624 SharePoint Foundation          Database                       fa45 High     System.InvalidOperationException: Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.     at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)     at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)     at System.Data.SqlClient.SqlConnection.Open()     at Microsoft.SharePoint.Utilities.SqlSession.OpenConnection() cc94ec34-1e2f-46d3-a524-1aa20ebf64e4
ConnectionString: 'Data Source=SQL_ALIAS_NAME;Initial Catalog=WSS_Content_xxxxx;Integrated Security=True;Enlist=False;Asynchronous Processing=False;Connect Timeout=15'

El Escenario:
Versión de SharePoint Server: 2010
Edición de SharePoint Server: Enterprise
Versión de actualización de Producto: 14.0.6109.5002 (SP1 + Cu Agosto 2012)
Versión Sistema Operativo: Windows 2008 R2 Enterprise SP1 (Fuera de Soporte)
Versión de SQL Server: SQL Server 2008 R2 SP1 (Fuera de Soporte)
Cantidad de Servidores 3:  1 Servidor Front-End/App Server  2 Servidores SQL Server
Configuración de Servidores:


Front End (Fisico)
16 GB RAM
2 procesdores
2 Discos (1 hd 200 Gb, 2 hd 150 Gb)
BackEnd 1 (Fisico)
16 GB RAM
2 procesdores
2 Discos (1 hd 200 Gb, 2 hd 2 Tb)
BackEnd 2 (Virtual)
2 procesdores
2 Discos (1 hd 200 Gb, 2 hd 300 Gb)
Tamaño de base de datos de contenido  principal (1.4 TB)

La causa:
SharePoint Server 2010 en adelante tiene un proceso de limpieza de la papelera de reciclaje de cada base de datos de contenido llamada Recycle Bin (Podemos encontrar en la sección de monitoreo ) Job Definitions.  Este proceso intentaba eliminar una biblioteca de 500 Gb que fue eliminada hace un mes y el tiempo definido para ejecutar este proceso 5 horas no era suficiente para eliminarla, por lo que mantenia ocupada la conexión o bien realizaba intentos fallidos hasta que agotaba las conexiones disponibles en el pool de conexiones hacia la base de datos y esto provocaba el error.



Se logró ubicar el problema, cuando en vez de iniciar los servidores y luego de reportados se empezo a validar lo siguiente:

1) Que Los recursos de los servidores de la granja estuviesen a bajo del 80% de uso y así estaban por debajo.
2) Que el servicio del IIS estuivese corriendo y no tuviese ningún sitio abajo (y estaba corriendo sin reportar problemas de hecho el central administration funcionaba)
3) Que el servicio de SQL Server de los dos servidores de SQL Server estuvise funcionando y corriendo ( efectivamente funcionaban correctamente)
4) Que el sitio estuviese accesible (aquí fallaba y daba un error 500 servicio no disponible)
5) Validó los jobs que estaban en ejecución y allí se encontró el Recyclebin ejecutandose 3 horas antes y estaba al 50%.
6) Se validó el contenido de la papelera de reciclaje y en segunda fase tenie una biblioteca de 500 GB.

La Solución Alterna:
Se deshabilitó el job de limpieza de la papelera de reciclaje para la aplicación web que contiene esta bilbioteca que no logra eliminar.



La Solución Definitiva:
La granja se planificó migrar a un ambiente virtual el cual tiene mucho mas capacidad de procesamiento y en donde este proceso de limpiza si finalizá con éxito y más rápido.  Además de distribuir el contendio de tal forma que se reduzca el tamaño de la base de datos de contenido principal depurando el contenido o moviendolo a una nueva base de datos esto trea consiguo mayor esfuerzo administrativo para el contenido pero lo hace más manejable.

Lección aprendida:
Configurar la depuración de la papelera en un porcentaje menor evitará que permita almacenar 500 GB en la segunda fase.  Distribuir el contenido y hacer un plan de gobierno es una práctica poco adoptada pero muy necesaria para evitar estos problemas a largo plazo.  Monitorear los servicios de la papelera que demoren mas de una hora para validar sus efectos en dicha demora.  También la programación del job de la papelera debe contemplarse su ejecución manual cuando el contenido es arriba de 200 GB y la capacidad de los servidores de la granja actual.

SharePointHardLesson,

Juan Manuel Herrera Ocheita




Una línea de comando de PowerShell sencilla pero poderosa en su contenido SharePoint 2010,2013,2016

Distribuir contenido es de vital importancia, pero cuando son muchas las bases de datos y colecciones de sitios creadas al restaurar una granja se complica saber donde esta la colección de sitios, por lo que es importanet que contenmos con un listado de las aplicaciones web, sus colecciones y base de datos de contenido.
 
Cuando creamos de cero una granja y deseamos montar manualmente las base de datos de contenido, es importante saber cual es la base de datos de contenido que tiene la colección de sitios primaria ya que esta debe de restaurarse de primera instancia. 

También es importante cuando el contenido esta distribuído que base de datos de contendio tiene la colección de sitios que deseamos restaurar.




El comando deberá ejecutarse desde un servidor de SharePoint desde SharePoint Management Shell.  Y la línea de comando  es la siguiente:

Get-spsite -Limit all | select url, webapplication, contentdatabase | Export-Csv e:\infoware\listados\ColeccionesSitios.csv -NoTypeInformation

Url WebApplication ContentDatabase
http://miportal SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content
http://miportal/logistica SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content_DataCross
http://miportal/portales SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content_Portales
http://miportal/sites/permisos SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content_Search_Center
http://miportal/sites/apps SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=SharePoint_OC
http://miportal/sites/capacitacion SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=SharePoint_OC
http://miportal/sites/inversiones SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content_Inversiones
http://miportal/sites/seguridad SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content
http://miportal/sites/Proyectos SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content_ProyectosIT
http://miportal/sites/prueba_EC SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content_Esthela_Prueba
http://miportal/sites/search SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content_Search_Center
http://miportal/sites/sharedspace SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content_SharedSpace
http://miportal/sites/temp SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content
http://miportal/sites/temporal SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content_ProyectosIT
http://miportal/sitios/rrhh SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=SharePoint_OC
http://miportal/sitios/prueba3 SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content_Esthela_Prueba
http://miportal/sitios/test SPWebApplication Name=SharePoint - 80 SPContentDatabase Name=WSS_Content_Portales
http://miportal:21387/sites/prueba SPWebApplication Name=Aplicacion Prueba SPContentDatabase Name=WSS_Content_PRUEBA
http://miportal:21387/sites/prueba2 SPWebApplication Name=Aplicacion Prueba SPContentDatabase Name=WSS_Content_PRUEBA
http://miportal:21387/sites/prueba3 SPWebApplication Name=Aplicacion Prueba SPContentDatabase Name=WSS_Content_PRUEBA
http://miportal:24301/sites/prueba SPWebApplication Name=Sitio Federado SPContentDatabase Name=WSS_Content_SITIOFEDERADO

En este ejemplo ficticio vemos que la base de datos de contenido primaria se llama WSS_Content.


Esta será la primera que debemos de montar a través del comando

mount-SPContentDatabase -Name Wss_Content -url http://miportal

Para más información sobre el comando puede utilizar la siguiente línea de comando:

get-help mount-SPContentDatabase -full

Eso esto por este artículo.

SharePoint4Fun!,

Juan Manuel Herrera Ocheita





lunes, 2 de enero de 2017

Cómo habilitar Distribute Cache en un Servidor Custom Role SharePoint 2016

Distribute Cache es un MinRole en SharePoint 2016.  Pero que pasa si no tenemos los servidores requeridos para separar este Rol entonces debemos de habilitarlo en un  Custom Role que es diremos la forma tradicional de hacerlo.

No hay una referencia documentada oficial aún para hacerla, pero el sentido común nos puede guiar y es que la forma de habilitarlo vía powershell en SharePoint 2013 debería ser la forma en que podemos habilitarlo en SharePoint 2016 en un Custom Role.

Si deseas saber mas sobre MinRoles puede ser este post que escribí hace algún tiempo:

https://jmhogua.blogspot.com/search?q=minrole

Retornando al tema entonces debemos  primero ir al servidor que tiene el Custom Role.  Para saber cual es podemos verlo desde el Central Administration, System Settings, Convert server role in this farm.



Luego vemos el rol de cada servidor

Entonces en el servidor con Role Custom este levantamos una instancia de Management Shell for SharePoint 2016 y ejecutamos el comando Add-SPDistributeCacheServiceInstance.


Y eso es todo ya se provisionó el Distribute Cache en ese servidor.  Ahora si vemos en el Central Administration los servicios corriendo en ese Servidor nos despliega el servicio.



Y eso es todo.

SharePointFun,

Juan Manuel Herrera Ocheita


viernes, 30 de diciembre de 2016

Introducción Azure IoT Hub

Azure IoT Hub digimos que es un servicio de Azure para conectar de forma segura dispositivos digitales a la nube, con el objetivo de obtener datos que luego podrán ser procesados y analizados por otros servicios en Azure.

Lo primero que vamos hacer para entender lo que proporciona este servicio es crear una instancia del Servicio para poder conectar un dispositivo digital como el RaspberryPI3 que es una míni computadora que nos permitirá capturar información que sera transferida al IoT Hub.

Para eso debemos de ir al portal de Azure y crear el servicio en la opción Internet de las Cosas.

 Luego deberemos escribir el nombre de la instancia del IoT Hub e indicar la subscripción, para nuestro ejemplo será F1 Gratis, como se muestra en la imagen de abajo.


Luego deberemos indicar la subscripción si tenemos más de una seleccionamos la que prefiramos.


 Luego el nombre del grupo de Recursos que será asociado a esta prueba y la ubicación donde deseamos crear esta instancia.

Para finalizar el asistente presionamos el botón Crear y esperamos a que aprovisione la instancia del servicio en Azure.


Una vez finalizado podremosl ver la información general del servicio creado  alli encontraremos el nombre del host que utilizaremos en la aplicación que desarrollemos para el dispositivo digital.

Podemos ver que en Azure tenemos un tablero que nos mostrará la cantida de transferencia de datos del dispositivo al servicio y el saldo disponible.

 En directivas de acceso copartido veremos lo que permitiremos realizar al dispositivo cuando este conectado, aqui se maneja la seguridad del mismo y las acciones que le permitiremos hacer.

Ahora para registrar el dispositivo en el servicio necesitaremos un cliente llamado Device Explorer para descargarlo podemos ir al siguiente enlace: https://github.com/Azure/azure-iot-sdks/releases .

Ejecute el archivo SetupDeviceExplorer.msi


Presione el botón sigiuente del asistente de isntalación, indique la ubicación del programa


Confirme la instalación y presione el botón siguiente.


Al finalizar la instalación presione el botón Cerrar.


Luego de instalado podrá ejecutar el exe DeviceExplorer.exe en el drive seleccionado y ruta indicada en el asistente, 



Luego en Azure en Directivas de acceso compartido copiamos la Cadena de conexión (clave principal)


Y colocamos la cadena de conexión en la pestaña de configuración del programa Device Explorer.

Presionamos el botón Update  y esta lista la configuración del programa.



Ahora seleccionamos la pestaña Management y presionamos el botón Create.


Colocamos el nombre del dispositivo.  Para este ejemplo utilizaremos MyRaspberryPI3.


Una vez terminado nos muestra una ventana de confirmación de creado el dispositivo presionamos el botón Cerrar.


 En la pestaña Management mostrará el dispositivo creado


Listo ya hemos creado la instancia del Servicio IoT Hub que nos permitirá conectar el RaspberryPI3 y también lo registramos a través de DeviceExplorer una aplicación para Windows.  Si utiliza otro computador no windows puede utilizar la herramienta iothub-explorer  para ejecutar líneas de comando.

Eso es todo por este artículo luego escribiré como preparar el RaspBerryPI3 y conectarlo a este servicio.

Azure4Fun!,

Juan Manuel Herrera Ocheita

jueves, 29 de diciembre de 2016

Introducción de Azure IoT o Internet de las Cosas en Azure

Primero quiero definir que es Internet de las Cosas y luego como Azure apoya esta implementación de una forma ágil, escalable y confiable.

Internet de las Cosas o IoT (Internet of Things)
se refiere a la interconexión digital de objetos cotidianos con internet (Wikipedia)

Analicemos un momento este concepto.  Hoy en día la mayoría de dispositivos electrónicos son digitales esto tiene el potencial de interconectarse con otros dispositivos y la Internet es la red de interconexión entre computadoras.

Entonces interconectando la internet con estos dispositivos digitales de uso cotidiano nace el concepto del Internet de las cosas que nos permite captuar datos como temperatura, volumen, luz, calor, viento, etc. Procesarlos y luego analizarlos para predecir en base a modelos mátematicos.  Todos estos servicios están disponibles en la red de Microsoft,  Azure.



Azure
Es una plataforma de servicios en la nube que se estructura en tres grandes grupos de servicios:

SaaS o Software como Servicio
PaaS o Plataforma como Servicio 
y IaaS Infraestructura como Servicio.

Software como Servicio SaaS
Es un Software que esta centralmente hospedado  y administrado por el usuario final. Un ejemplo de SaaS es Office 365, One Drive, drop box, word press, Sales Force.  En este grupo de servicios el cliente tiene menos que administrar y se enfoca más en el uso y administración de la aplicación.

Plataforma como Servicio PasaS
Tipicamente el desarrollador instala su aplicación en un ambiente que hospeda aplicaciones.  Dentro de los servicios ofrecidos en Azure que aplica este grupo de servicios estan Azure App Service que antes se conocía como Azure Websites and Azure Cloud Services (web y worker roles).  En este grupo de servicios el desarrollador tiene control sobre su aplicación y las capacidades de la infraestructura disponible donde corre su aplicación pero sin preocuparse por la administración de ella.

Infraestructura como Servicio IaaS
Azure ofrece ejecutar y administrar el software de virtualización de los servidores de la granja, permitiendo al cliente usuario de tecnología crear máquinas virtuales que Azure ejecuta en su infraestructura.  Los servicios típicos a este nivel son redes virtuales, balanceadores de carga, almacenamiento, Máquinas Virtuales y otros.  Aquí los clientes tiene el control sobre el software que se instala, si nivel de actualización, las capacidades disponibles pero no directamente sobre la infraestructura física ni sobre el software de virtualización.  Tiene mucho mas control y mas responsabilidades sobre la disponibilidad de las máquinas virtualizadas.

Azure IoT
Luego de esta breve introducción sobre Azure vamos a hablar de Azure IoT.

Azure IoT provee servicios tanto para desarrolladores como IT Pros. Para el desarrollador más control sobre los servicios disponibles para IoT para los IT Pros menos control y más facilidad para emplear un conjunto de servicios disponibles en Azure para poner en marcha la captura de datos a través de los dispositivos conectados para su analisis y procesamiento.

Para los desarrolladores se dispone de IoT hub un servicio para interconectar dispositivos digitales a la nube de Microsoft, Azure.  El será responsable de crear los otros servicios e interconectarlos a IoT hub para procesar los datos de los dispositivos conectados con este servicio. Hay mas control y más trabajo que realizar.



IoT Suite
Por otro lado tenemos IoT Suite que es un conjunto de servicios para poner en marcha la captura, procesamiento, análisis, predicción y visualización de la información.


Ahora vamos a describir los servicios involucrados.

IoT Hub
Ya dijimos que permite de forma segura y fácil conectar los dispoistivos digitales a Azure.

Storage blobs
Almacena objetos de datos no estructurados. Puede ser cualquier tipo de texto, archivo binario, como un documento, archivo de multimedia o un instalador de aplicación.

Web/Mobile App
Crea e instala aplicaciones Web de misión crítica que pueden escalar.  Mobile App permite construir y hospedar el backend (sistema de base de datos) de cualquier aplicación Móvil.

Logic Apps
Permite crear procesos de negocios y flujos de trabajo visualmente para interconectar sistemas

DocumentoDB
Es un servicio de base de datos NoSQL totalmente administrado construido para un rendimiento rápido y predecible, alto

Disponibilidad, escala elástica, distribución global y facilidad de desarrollo. Como una base de datos NoSQL libre de esquema,

DocumentDB proporciona capacidades de consulta SQL ricas y familiares con latencias bajas consistentes en datos JSON

WebJobs
Es una solución completa de procesamiento en una plataforma administrada.  Permite correr un programa o script calendarizado que corren en los web sites de Azure.
Azure Active Directory
Es una solución moderna de administración de identidades que abarca desde locales y cloud, proporcionándole todas las capacidades necesarias para asegurar sus soluciones: control de acceso a aplicaciones, federación, administración de identidad, provisión de usuarios, protección de información, soporte de protocolos estándar, bibliotecas de desarrollo completo.
Azure Functions
Introduce una experiencia impulsada por el evento, basada en la demanda. Amplía la infraestructura WebJobs existente para permitirle implementar fácilmente código en una variedad de lenguajes de programación que reacciona a eventos generados a través de la amplia gama de servicios Azure, productos SaaS y sistemas locales.
Stream Analytics
Es un motor de procesamiento de eventos en tiempo real completamente administrado y rentable que ayuda a desbloquear profundos conocimientos de los datos. Stream Analytics facilita la configuración de cálculos analíticos en tiempo real en los datos, Streaming de dispositivos, sensores, sitios web, medios sociales, aplicaciones, sistemas de infraestructura.
Machine Learning
Para crear, implementar y compartir fácilmente soluciones de análisis predictivo
PowerBi
Es un n conjunto de aplicaciones de análisis de negocios que permite analizar datos y presentar información de forma gráfica.

Bueno esto solo fue una introducción a los servicios en la nube de Microsoft, Azure para implementar de forma fácil y escalable dispositivos digitales de uso cotidiano con la plataforma de nube Azure.

Azure4Fun!,

Juan Manuel Herrera





domingo, 25 de diciembre de 2016

Plan de Mantenimiento de las bases de datos para Granja de SharePoint

Aunque solo hay referencia de un Plan de mantenimiento para SharePoint 2010, SharePoint 2016 aún se corre sobre SQL Server y por tanto validar las bases de datos, reindexarlas y hacer un shrink de vez e cuando es algo que puede ayudar a mejorar el rendimiento y la salud de las bases de datos de SharePoint.

Básicamente el mantenimiento de SQL Server para SharePoint cubre los siguientes aspectos:


  1. Comprobación de la integridad de la base de datos
  2. Shrink de base de datos (ocasional cuando sea muy necesario)
  3. Desfragmentación de los índices mediante su reorganización o regeneración


Pero en vez de utilizar el asistente de SQL Server Management Studio les detallare los scripts 

Listado de bases de datos

select * from sys.databases WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb'); 

Con este query se puede generar un listado de todas las bases de datos que con excel nos puede servir para generar los comandos  t-sql más facilmente.


Comprobación de la integridad de la base de datos


DBCC CHECKDB ([SharePoint_Config]) WITH PHYSICAL_ONLY 

* Limita la comprobación a la integridad de la estructura física de los encabezados de página y registro y la coherencia de la asignación de la base de datos

https://msdn.microsoft.com/en-us/library/ms176064.aspx

Shrink de base de datos (ocasional cuando sea muy necesario)
Esto aunque no es muy recomendado se hace necesario cuando necesitamos disponer de espacio libre y hay mucho espacio sin ocupar especialmente cuando se ha depurado contenido en el portal de gran volumen.  El Comando es el siguiente:


DBCC SHRINKDATABASE  ([SharePoint_Config],TRUNCATEONLY)
Desfragmentación de los índices mediante su reorganización o regeneración

Este script fue tomado del sitio abajo indicado funciona muy bien y toma como necesario la reindexación si el porcentaje de desfragmentación es mayor al 30% y si tiene más de 1000 páginas la tabla analizada de la base de datos.

-- Ensure a USE statement has been executed first.
use [WSS_Content_GUID]
go
SET NOCOUNT ON

-- adapted from "Rebuild or reorganize indexes (with configuration)" from MSDN Books Online
-- (http://msdn.microsoft.com/en-us/library/ms188917.aspx)

-- =======================================================
-- || Configuration variables:
-- || - 10 is an arbitrary decision point at which to
-- || reorganize indexes.
-- || - 30 is an arbitrary decision point at which to
-- || switch from reorganizing, to rebuilding.
-- || - 0 is the default fill factor. Set this to a
-- || a value from 1 to 99, if needed.
-- =======================================================
DECLARE @reorg_frag_thresh   float        SET @reorg_frag_thresh   = 10.0
DECLARE @rebuild_frag_thresh float        SET @rebuild_frag_thresh = 30.0
DECLARE @fill_factor         tinyint      SET @fill_factor         = 80
DECLARE @report_only         bit                SET @report_only         = 1

-- added (DS) : page_count_thresh is used to check how many pages the current table uses
DECLARE @page_count_thresh    smallint   SET @page_count_thresh   = 1000

-- Variables required for processing.
DECLARE @objectid       int
DECLARE @indexid        int
DECLARE @partitioncount bigint
DECLARE @schemaname     nvarchar(130)
DECLARE @objectname     nvarchar(130)
DECLARE @indexname      nvarchar(130)
DECLARE @partitionnum   bigint
DECLARE @partitions     bigint
DECLARE @frag           float
DECLARE @page_count     int
DECLARE @command        nvarchar(4000)
DECLARE @intentions     nvarchar(4000)
DECLARE @table_var      TABLE(
                          objectid     int,
                          indexid      int,
                          partitionnum int,
                          frag         float,
                                                  page_count   int
                        )

-- Conditionally select tables and indexes from the
-- sys.dm_db_index_physical_stats function and
-- convert object and index IDs to names.
INSERT INTO
    @table_var
SELECT
    [object_id]                    AS objectid,
    [index_id]                     AS indexid,
    [partition_number]             AS partitionnum,
    [avg_fragmentation_in_percent] AS frag,
      [page_count]                           AS page_count
FROM
    sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED')
WHERE
    [avg_fragmentation_in_percent] > @reorg_frag_thresh
      AND
      page_count > @page_count_thresh
      AND
    index_id > 0
     

-- Declare the cursor for the list of partitions to be processed.
DECLARE partitions CURSOR FOR
    SELECT * FROM @table_var

-- Open the cursor.
OPEN partitions

-- Loop through the partitions.
WHILE (1=1) BEGIN
    FETCH NEXT
        FROM partitions
        INTO @objectid, @indexid, @partitionnum, @frag, @page_count

    IF @@FETCH_STATUS < 0 BREAK

    SELECT
        @objectname = QUOTENAME(o.[name]),
        @schemaname = QUOTENAME(s.[name])
    FROM
        sys.objects AS o WITH (NOLOCK)
        JOIN sys.schemas as s WITH (NOLOCK)
        ON s.[schema_id] = o.[schema_id]
    WHERE
        o.[object_id] = @objectid

    SELECT
        @indexname = QUOTENAME([name])
    FROM
        sys.indexes WITH (NOLOCK)
    WHERE
        [object_id] = @objectid AND
        [index_id] = @indexid

    SELECT
        @partitioncount = count (*)
    FROM
        sys.partitions WITH (NOLOCK)
    WHERE
        [object_id] = @objectid AND
        [index_id] = @indexid

    -- Build the required statement dynamically based on options and index stats.
    SET @intentions =
        @schemaname + N'.' +
        @objectname + N'.' +
        @indexname + N':' + CHAR(13) + CHAR(10)
    SET @intentions =
        REPLACE(SPACE(LEN(@intentions)), ' ', '=') + CHAR(13) + CHAR(10) +
        @intentions
    SET @intentions = @intentions +
        N' FRAGMENTATION: ' + CAST(@frag AS nvarchar) + N'%' + CHAR(13) + CHAR(10) +
        N' PAGE COUNT: '    + CAST(@page_count AS nvarchar) + CHAR(13) + CHAR(10)

    IF @frag < @rebuild_frag_thresh BEGIN
        SET @intentions = @intentions +
            N' OPERATION: REORGANIZE' + CHAR(13) + CHAR(10)
        SET @command =
            N'ALTER INDEX ' + @indexname +
            N' ON ' + @schemaname + N'.' + @objectname +
            N' REORGANIZE; ' +
            N' UPDATE STATISTICS ' + @schemaname + N'.' + @objectname +
            N' ' + @indexname + ';'

    END
    IF @frag >= @rebuild_frag_thresh BEGIN
        SET @intentions = @intentions +
            N' OPERATION: REBUILD' + CHAR(13) + CHAR(10)
        SET @command =
            N'ALTER INDEX ' + @indexname +
            N' ON ' + @schemaname + N'.' +     @objectname +
            N' REBUILD'
    END
    IF @partitioncount > 1 BEGIN
        SET @intentions = @intentions +
            N' PARTITION: ' + CAST(@partitionnum AS nvarchar(10)) + CHAR(13) + CHAR(10)
        SET @command = @command +
            N' PARTITION=' + CAST(@partitionnum AS nvarchar(10))
    END
    IF @frag >= @rebuild_frag_thresh AND @fill_factor > 0 AND @fill_factor < 100 BEGIN
        SET @intentions = @intentions +
            N' FILL FACTOR: ' + CAST(@fill_factor AS nvarchar) + CHAR(13) + CHAR(10)
        SET @command = @command +
            N' WITH (FILLFACTOR = ' + CAST(@fill_factor AS nvarchar) + ')'
    END

    -- Execute determined operation, or report intentions
    IF @report_only = 0 BEGIN
        SET @intentions = @intentions + N' EXECUTING: ' + @command
        PRINT @intentions        
        EXEC (@command)
    END ELSE BEGIN
        PRINT @intentions
    END
      PRINT @command

END

-- Close and deallocate the cursor.
CLOSE partitions
DEALLOCATE partitions

GO
--===========================================
--[dbo].[AllDocStreams].[AllDocStreams_CI]:
-- FRAGMENTATION: 19.7798%
-- PAGE COUNT: 557169
-- OPERATION: REORGANIZE
--ALTER INDEX [AllDocStreams_CI] ON [dbo].[AllDocStreams] REORGANIZE;  UPDATE STATISTICS [dbo].[AllDocStreams] [AllDocStreams_CI];
--=============================================
--[dbo].[AllDocVersions].[AllDocVersions_PK]:
-- FRAGMENTATION: 12.833%
-- PAGE COUNT: 21959
-- OPERATION: REORGANIZE
--ALTER INDEX [AllDocVersions_PK] ON [dbo].[AllDocVersions] REORGANIZE;  UPDATE STATISTICS [dbo].[AllDocVersions] [AllDocVersions_PK];
--===================================
--[dbo].[AllLinks].[Links_Forward]:
-- FRAGMENTATION: 26.2066%
-- PAGE COUNT: 48793
-- OPERATION: REORGANIZE
--ALTER INDEX [Links_Forward] ON [dbo].[AllLinks] REORGANIZE;  UPDATE STATISTICS [dbo].[AllLinks] [Links_Forward];
--====================================
--[dbo].[AllLinks].[Links_Backward]:
-- FRAGMENTATION: 25.3887%
-- PAGE COUNT: 44059
-- OPERATION: REORGANIZE
--ALTER INDEX [Links_Backward] ON [dbo].[AllLinks] REORGANIZE;  UPDATE STATISTICS [dbo].[AllLinks] [Links_Backward];
--=======================================
--[dbo].[EventCache].[EventCache_Time]:
-- FRAGMENTATION: 25.687%
-- PAGE COUNT: 1674
-- OPERATION: REORGANIZE
--ALTER INDEX [EventCache_Time] ON [dbo].[EventCache] REORGANIZE;  UPDATE STATISTICS [dbo].[EventCache] [EventCache_Time];
--=========================================
--[dbo].[EventCache].[EventCache_ListId]:
-- FRAGMENTATION: 22.176%
-- PAGE COUNT: 3603
-- OPERATION: REORGANIZE
--ALTER INDEX [EventCache_ListId] ON [dbo].[EventCache] REORGANIZE;  UPDATE STATISTICS [dbo].[EventCache] [EventCache_ListId];
--=================================
--[dbo].[EventLog].[EventLog_Id]:
-- FRAGMENTATION: 32.5723%
-- PAGE COUNT: 16207
-- OPERATION: REBUILD
-- FILL FACTOR: 80
--ALTER INDEX [EventLog_Id] ON [dbo].[EventLog] REBUILD WITH (FILLFACTOR = 80)
--=============================================
--[dbo].[AllUserData].[AllUserData_ParentId]:
-- FRAGMENTATION: 13.7654%
-- PAGE COUNT: 1006816
-- OPERATION: REORGANIZE
--ALTER INDEX [AllUserData_ParentId] ON [dbo].[AllUserData] REORGANIZE;  UPDATE STATISTICS [dbo].[AllUserData] [AllUserData_ParentId];
--=================================
--[dbo].[Workflow].[Workflow_CI]:
-- FRAGMENTATION: 15.8641%
-- PAGE COUNT: 3385
-- OPERATION: REORGANIZE
--ALTER INDEX [Workflow_CI] ON [dbo].[Workflow] REORGANIZE;  UPDATE STATISTICS [dbo].[Workflow] [Workflow_CI];
--=======================================
--[dbo].[AuditData].[AuditData_OnItem]:
-- FRAGMENTATION: 12.085%
-- PAGE COUNT: 243318
-- OPERATION: REORGANIZE
--ALTER INDEX [AuditData_OnItem] ON [dbo].[AuditData] REORGANIZE;  UPDATE STATISTICS [dbo].[AuditData] [AuditData_OnItem];

Bueno eso es todo por ahora, con esto terminamos la serie que tiene que ver con bases de datos y la granja de SharePoint en sus versiones 2010,2013 y 2016.

SharePoint4fun!,

Juan Manuel Herrera Ocheita