jueves, 31 de julio de 2014

Ocultar newsfeeds,sites y OneDrive de la barra superior en Office 365 y Sharepoint On-premise

La idea es ocultar primero mediante css las opciones de Newsfeed, OneDrive y Sites en Office 365

image

IMPORTANTE: en Office 365 se puede realizar desde el Sharepoint admin center (Top Navigation Bar User Experience), pero esto lo realizará para todos nuestros sites collection.

image

La idea es mostrarlo sólo para una página particular, pero se podría crear una App en Office 365 que incluya este código css en cada página o en la master page de nuestro sitio. Les recomiendo que revisen “Office365 Development Patterns and Practices” para buscar una solución con Apps en Office 365. En Sharepoint On-Premise les recomiendo que revisen el siguiente link, donde se deploya un custom.css en cada página de los sitios.

Veamos primero para Office 365. Insertamos un Script Editor Web part

image

y agregamos lo siguiente:

<style type="text/css">
#O365_MainLink_ShellSites
{
  display: none;
}

#O365_MainLink_ShellDocuments
{
  display: none;
}

#O365_MainLink_ShellNewsfeed
{
  display: none;
}

</style>

Para el caso que Sharepoint On-Premise podemos agregar el siguiente código css.

a.ms-core-suiteLink-a[id$="ShellDocuments"]{
    display:none;
}

a.ms-core-suiteLink-a[id$="ShellSites"]{
    display:none;
}

a.ms-core-suiteLink-a[id$="ShellNewsfeed"]{
    display:none;
}

domingo, 27 de julio de 2014

Configurar un servidor específico para ser un target search crawler

Supongamos que tenemos la siguiente arquitectura de servidores:

image

Donde el servidor WFE recibe todas las consultas realizadas por el search services. Lo que quiero hacer es que el crawler le “pegue” al servidor APP2 para indexar el contenido para reducir la carga sobre los servidores que el usuario interactura (WFE) y potencialmente reducir los tiempos de crawl. Una manera es utilizando el archivo host (C:\windows\system32\drivers) y apuntando los dns al servidor deseado para indexar el contenido. Ej:

192.168.1.1 http://teamsites.sharepoint.com

Pero este método no es el método correcto para Sharepoint, ya que puede generar errores dificiles de detectar y hay que actualizar este archivo cada vez que se realice un cambio en la infraestructura (por ej: cambio de IP´s), para solucionar este problema Microsoft dispone de la propiedad SiteDataServers de un web application sobre una zona específica. Esta propiedad está disponible para Sharepoint 2010 como para Sharepoint 2013. Veamos su uso.

Primero verifico que esté iniciado el servicio “Microsoft Sharepoint Foundation Web Application” para el servidor APP2.

image

image

Después abro un consola de powershell ISE y ejecuto lo siguiente. Importante: este código se deberá ejecutar sobre el servidor APP2, ya que deshabilita el throttling localmente.

$snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}
if ($snapin -eq $null)
{
Write-Host "Loading SharePoint Powershell Snap-in"
Add-PSSnapin "Microsoft.SharePoint.Powershell"
}

$svc=[Microsoft.SharePoint.Administration.SPWebServiceInstance]::LocalContent
$svc.DisableLocalHttpThrottling
$svc.DisableLocalHttpThrottling=$true
$svc.Update()

$wa = Get-SPWebApplication http://urlwebapplication
$crawltarget = "NOMBRESERVIDOR" #especifica el nombre de la máquina que será el crawl target
$target = New-Object System.Uri("http://$crawltarget")
$uri = New-Object System.Collections.Generic.List[System.Uri](1)
$uri.Add($target)
$zone = [Microsoft.SharePoint.Administration.SPUrlZone]'Default' #especifica el nombre de la zona
$wa.SiteDataServers.Add($zone, $uri)
$wa.Update()
$wa.SiteDataServers | fl

Para verificar que se haya configurado bien esta propiedad, inicia un crawl de tu contenido, y revisa los logs del IIS, deberás encontrar lo siguiente (sitedata.asmx y MS-Search):

POST /sites/test/_vti_bin/sitedata.asmx - 80 - fe80::2817:36bb:71ae:2ecb%10 Mozilla/4.0+(compatible;+MSIE+4.01;+Windows+NT;+MS+Search+6.0+Robot

El SharePoint crawler comienza enumerando todos los items del site llamando al servicio Site Data web service (test/_vti_bin/sitedata.asmx), el Crawler deja que el Site Data web service le pregunte al WFE que contenido tiene para esa url.

La otra propiedad (MS-Search) es cuando el servicio de search llama al servicio Site Data web service, utiliza un User Agent predeterminado que podrás encontrar en la clave de registro HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Global\Gathering Manager\

image

Mozilla/4.0 (compatible; MSIE 4.01; Windows NT; MS Search 6.0 Robot)

El otro punto a remacar, es que deshabilité HTTP throttling sobre el crawl target así las solicitudes de crawl no se encolan o se retrasan en el WFE. Este mecanismo es para proteger el servidor de peaks load (picos de carga), monitorea un par de contadores para evaluar la performance del servidor y generar un contador del estado (0 a 9). Pueden tener más info en el siguiente link: http://blogs.msdn.com/b/besidethepoint/archive/2010/09/13/http-request-throttling-in-sharepoint-2010.aspx

Importante: Recuerda que esta configuración es por Web Application y por zona.

En el caso que quieras borrar esta configuración ejecuta lo siguiente:

#$zone = [Microsoft.SharePoint.Administration.SPUrlZone]'Default' #especifica el nombre de la zona
#$wa = Get-SPWebApplication http://urlwebapplication
#$wa.SiteDataServers.Remove($zone)
#$wa.Update()

TIP para buscar los logs del IIS

Supongamos que buscamos los logs del web application http://urlwebapplication, para ello buscamos ese nombre dentro del IIS, y vemos campo ID en Advanced Settings.

image

Después ingresamos al path donde están los logs del IIS, y buscamos ese ID en las carpetas.

image

sábado, 26 de julio de 2014

Crear un custom page layout responsive para Sharepoint 2013 (create a custom page layout responsive)

Primero activo la feature SharePoint Server Publishing Infrastructure (_layouts/15/ManageFeatures.aspx?Scope=Site), y a continuación activo la feature SharePoint Server Publishing (_layouts/15/ManageFeatures.aspx)

Ingreso al Design Manager

image

Después ingreso a Edit Page Layouts

image

Hago click en “Create a page layout”

image

image

Vuelvo a Design Manager , y mapeo la librería _catalogs/masterpage/

image

image

image

Dentro de la unidad mapeada ya podemos ver el archivo html recién creado

image

Ahora vuelvo de nuevo a Page Layouts dentro de Design Manager

image

Hago click en el archivo recién creado, y me aparece la página de preview

image

Hago click en Snippets

image

Hago click en web part zone

image

Configuro todas las propiedades del page layout, por ejemplo Back Color

image

image

Después copio el HTML Snippet

image

Hago click sobre el archivo de layout creado, y lo edito con la tool favorita que tengan para html

image

Dentro del código busco

<!--MS:<asp:ContentPlaceHolder ID="PlaceHolderMain" runat="server">—>

y reemplazo su contenido con lo siguiente (voy a hacer un layout responsive de 3 columnas).

image

Por ejemplo quedaría así.

image

De vuelta hago click en Web Part Zone (fijate que cambia el ID del snippet) y lo pego en la columna sideNav

image

Hago lo mismo para la columna righColumn

Quedaría así, donde los web part zone están cerrados (gracias VS)

image

Ahora quedaría agregar el css para que los divs sean responsive, subo el archivo .css a la libreria SiteAssets.

image

*, *:before, *:after {
  -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}

.columnsContainer, footer { position: relative; margin: .5em; }

.leftColumn, .rightColumn, .sideNav, footer {  border: 1px solid  #ccc; padding: 1.25em;  }
.leftColumn, .sideNav { margin-bottom: .5em; }

@media screen and (min-width: 47.5em ) {
  .leftColumn { margin-right: 19.5em; margin-left: 9.5em;  }

  .rightColumn { position: absolute; top: 0; right: 0; width: 18.75em; }

  .sideNav { float: left; }
}

.ms-core-navigation { DISPLAY: none }
#contentBox { margin-left: 10px }
#contentRow
{
padding-top:0px;
}

Ahora agrego una referencia al css en el código html, para ello lo agregamos en la sección PlaceHolderAdditionalPageHead

image

IMPORTANTE: deben usar el atributo ms-design-css-conversion="no", sino no funcionará esta parte.

En el caso que quieras agregar directamente el elemento styles dentro del código, deberás usarlo de la siguiente manera:

<!--MS:<style type="text/css">-->
          ACA VA EL CODIGO CSS
<!--ME: </style>—>

Es muy importante usar MS (markup start) y ME (markup end) para abrir y cerrar el estilo.

Ahora es hora de publicar el page layout

image

Una vez publicada vemos que se convirtió correctamente

image

Ahora creo una nueva página, y le cambio el layout

image

image

image

Al publicarla, me queda así

image

Que pasa si reduzco la página, aparece el diseño responsive.

image

Algunos tips más:

En el caso que al publicar el diseño te lance el siguiente error: SharePoint requires HTML files to be XML-compliant. Your file isn't XML-compliant, likely because of tag properties without quotes, missing closing tags, or invalid properties in tags.
Data at the root level is invalid. Line 15, position 75.
Run the file through an XML validator, fix any issues using your HTML editor, save the file, and refresh this preview.

Entra a la siguiente página y valida el xml generado (copia todo el html del archivo)

http://www.w3schools.com/xml/xml_validator.asp

Segundo tip, configura que la librería MasterPage (/_catalogs/masterpage/Forms/AllItems.aspx)  tenga configurado correctamente el versionado, así no generas muchas versiones.

image

High Availability para SQL Server–Sharepoint 2013

Les dejo una tabla comparativa para saber cual es la mejor opción de alta disponibilidad para SQL Server relacionado a Sharepoint

Opción

Potencial Data Los (RPO)

Potential Recovery Time (RTO)

Auto-Failover

Copias adicionales de lectura

Limitaciones para Sharepoint

AlwaysOn Availability Groups – Sincrónico (dual-phase commit, sin pérdida de datos, no puede operar sobre WAN)

Nada

5-7 segundos

Si

0-2

No se puede usar sobre redes con alta latencia/bajo bandwidth
AlwaysOn Availability Groups – Asincrónico (tolerante a latencias, opción para Cross-WAN, potencial perdida de datos)

Segundos

Minutos

No

0-4

No puede ser usado para las bases de datos: Central Admin Content, Farm Configuration, todas las bases de search, State Service,UPA Sync, y Usage
AlwaysOn Failover Cluster Instance (FCI) – Clustering tradicional de storage compartido

N/A. Por default FCI no provee protección de datos. Depende del sistema de storage

30 segundos a varios minutos (dependiendo del disk failover)

Si

N/A

N/A

Database Mirroring – High safety (Sincrónico)

Nada

5-10 segundos

Si

N/A

 
Database Mirroring – High Performance (Asincrónico)

Segundos

Minutos

No

N/A

No hay datos disponibles oficiales, pero para 2010 era común no usar este método para UPA Sync, Usage, Search, Word Automation,  BCS, Secure Store, Subscription Settings Database y Web Analitics (ahora dentro de las bases de search)

SQL Log Shipping

Minutos

Minutos

No

No durante un restore

N/A

Simple tip de desarrollo: SPSite.AllWebs vs SPWeb.Webs

SPSite.AllWebs retorna los subsites inmediatos del sitecollection y todos sus subsites (en otras palabras, todo los web recursivamente dentro del site collection); SPWeb.Webs tiene un alcance más limitado, sólo retorna el primer nivel de subsitios del objeto SPWeb.

En el caso que te pidan obtener todos los subsites de un site collection (hasta el último nivel) puedes hacerlo de forma recursiva con el objeto SPWeb.Webs o mediante el objeto AllWebs. Veamos un ejemplo con SPWeb.Webs

public void BuscarWebSites(SPSite site)
{
    using (var web = site.RootWeb)
    {
        ProcesarRecursivamente(web);
    }
}

//Metodo recursivo
private static void ProcesarRecursivamente(SPWeb web)
{
    //hago el uso del objeto
    foreach (SPWeb subWeb in web.Webs)
    {
        using (subWeb)
        {
            ProcesarRecursivamente(subWeb);           
        }
    }
}

Ahora veamos un ejemplo con SPSite.AllWebs

public void BuscarWebSites(url sitecollection)
{    using(SPSite site = new SPSite(sitecollection) 
    { 
        foreach(SPWebInfo webInfo in site.AllWebs.WebsInfo) 
        {
            var result = webInfo.Title +
               webInfo.ServerRelativeUrl +
               webInfo.Description +
               webInfo.Id +
               webInfo.Language +
               webInfo.LastItemModifiedDate +
               webInfo.WebTemplateId +
               webInfo.Configuration +
               webInfo.UIVersionConfigurationEnabled +
               webInfo.UIVersion +
               webInfo.MasterUrl +
               webInfo.CustomMasterUrl;
        } 
    } 
}

Cuando se usa SPSite.AllWebs se usa menos memoria, ya que carga sólo un web site a la vez.

También miren que use la propiedad WebsInfo, esto se debe a que carga la información más importante (title, description, URL, Web template identifier, configuration identifier, last-modified time, UI version, status flags, master URL, y custom master URL). Esto difiere del siguiente ejemplo

foreach (SPWeb web in site.AllWebs)
{
Console.WriteLine(web.Description + “: ” + web.Title);
web.Dispose();
}

ya que este ejemplo carga de forma lazy (lazy loading) la propiedad Description, yendo de nuevo a la base de datos a buscar el ejemplo.

TIP: siempre usa SPSite.AllWebs.WebsInfo

viernes, 25 de julio de 2014

Error al agregar un usuario en el People Picker–Sharepoint 2010

Al agregar un usuario en el People Picker, y presionar Aceptar, me lanzaba el siguiente error:

image

System.InvalidOperationException: Namespace prefix 'xsd' is not defined.  
at System.Xml.Serialization.XmlSerializationReader.ToXmlQualifiedName(String value, Boolean decodeName)   
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderDictionaryEntryArray.Read1_Object(Boolean isNullable, Boolean checkType)   
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderDictionaryEntryArray.Read2_DictionaryEntry(Boolean checkType)   
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderDictionaryEntryArray.Read3_ArrayOfDictionaryEntry()

Para solucionarlo, lo único que hice es poner el sitio en modo compatibilidad.

image

image

martes, 15 de julio de 2014

Simple tip para Distributed Cache

Para poder conectarse al cluster de cache de Distributed Cache, tenés que tener permisos para hacerlo, para ello podemos ver que grupo o usuarios tienen permisos para hacerlo mediante el comando Get-CacheAllowedClientAccounts

Por default deberían estar dos grupos: "WSS_WPG" y "WSS_ADMIN_WPG". Para verificarlo ejecuta los siguientes comandos:

Use-CacheCluster
Get-CacheAllowedClientAccounts

Tanto la cuenta de Farm y la cuenta de los application pool de los web application deben estar en estos grupos, en caso contrario las cuentas tendrán problemas para conectarse al cluster de cache.

Para agregarlo ejecuta lo siguiente:

Grant-CacheAllowedClientAccount WSS_WPG

Errores típicos de cuando no están estas cuentas en los grupos:

  • Timeouts
  • IOException
  • ErrorCode<ERRCA0017>:SubStatus<ES0006
  • An existing connection was forcibly closed by the remote host
  • Failed to initialize SPDistributedSecurityTokenCache 
  • Acceso a Sharepoint muy lento, las páginas tardan en cargar

domingo, 13 de julio de 2014

Evaluar la performance de la red accediendo a Sharepoint con Message Analyzer–Parte 3

PARTE 1 – Parseo de ETW para Sharepoint

PARTE 2 – Monitoreo de red standart

PARTE 3 – Crear un web part que simule lentitud de Sharepoint (acá estamos)

Creamos un web part con Visual Studio

image

image

En el archivo VisualWebPart.cs, en el método CreateChildControls, agrego la siguiente línea:

System.Threading.Thread.Sleep(10000); //10 segundos de delay

Es para simular un delay de 10 segundos

image

Agregamos el web part custom a la página inicial del sitio

image

Guardamos la página, y vemos que tarda en renderizar la página (10 segundos de delay). Recuerda deshabilitar Minimal Download Strategy, así no se actualiza sólo una parte de la página

Ahora abrimos Message analyzer como administrador, y hacemos un trace del acceso al site. Y vemos los resultados

image

Acá vemos que el tiempo que paso que el cliente solicitó la página, y la respuesta que tuvo fue de 12.1581361. Pero el servidor tardo en responder en 11.9876931. Lo que claramente es que el problema estaba en el servidor, porque todo el tiempo lo consumía el servidor (Sharepoint).

Una vez que sabemos que el problema está en el servicio, es este caso Sharepoint, podemos usar en primer medida, Sharepoint Developer Dashboard. Para ello la habilitamos

$svc = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$dds = $svc.DeveloperDashboardSettings
$dds.DisplayLevel = "On"
$dds.Update()

image

Espero que les haya sido de ayuda esa serie de post, se puede hacer un excelente monitoreo de networking con Message Analyzer.

Evaluar la performance de la red accediendo a Sharepoint con Message Analyzer (parte 2)

PARTE 1 – Parseo de ETW para Sharepoint

PARTE 2 – Monitoreo de red standart (acá estamos)

PARTE 3 – Crear un web part que simule lentitud de Sharepoint

Hay dos posibilidades para utilizar Message Analyser, dentro del servidor y desde el cliente. El uso desde dentro del servidor es para evaluar protocolos relacionados a Sharepoint, ej: DNS, SMTP, LDAP, Kerberos, etc-

Desde el lado del cliente permitirá tener un acercamiento de lo que reporta el usuario final. Voy a usar el modo client. Genero un nuevo Capture/Trace con el filtro

Elegimos un escenario de trace, es recomendable elegir alguno que haga trace de nuestra placa de red. En este caso yo estoy vía Wireless. Por lo tanto elegí “WLAN (Windows 8.1/Windows Server 2012 R2)”, pero si están por LAN que es el caso general deberías usar los relacionados a LAN. http://msdn.microsoft.com/en-us/library/jj659262.aspx

image

Y agregamos el filtro: TCP.Port==80

image

Y vemos que ya loguea mensajes.

image

Cambiamos el ViewPoint a HTTP

image

Ahora empezemos a evaluar los datos:

TimeElapsed: esta columna cómo es la experiencia del usuario con el sitio. Ej: supogamos la siguientes lineas

image

Vemos que nuestra solicitud (desde source 192.168.1.1) tardo en llegar a chrissp2013dev.cloudapp.net (destination) 0.0610551 (TimeElapsed).

Otro punto para ver es que podemos ver todo el stack de mensajes, por ej: message number = 540 (que es la respuesta del servidor), vemos por donde pasaron los mensajes y cuanto tardo cada  uno

image

Click sobre la línea, y seleccionamos Show details podemos ver más de la solicitud

image

Uri: que página llame

StatusCode: 200 (OK)

Payload: es el contenido del mensaje.

Otra columna importante es ResponseTime, que mide cuanto tiemppo tardo el server en responder. Pero cual es la diferencia con TimeElapsed? veamos el ejmplo

image

TimeElapsed= es el tiempo que persive el usuario en que el servidor le contesto. es decir lo que le tardo en renderizar la página. 0.2206734

ResponseTime= es el tiempo que tardo el servidor en empezar a responder. En este caso 0.1684419. Es decir la diferencia entre 0.2206734 y 0.1684419 es el tiempo de red entre el servidor y cliente.

Otro punto para ver, es la columna “Diagnostic”, donde podrás ver algún error en los paquetes. En este caso: Segment lost, missing 3-way handshake.

image

image

3-way handshake

Casi siempre los errores de tipo TCP, son problemas con la red. Puedes ver distintos tipos de mensajes, ej:

image

También puedes agregar colores sobre los mensajes, los más últiles, los de kerberos.

image

Por ejemplo, errores 401

image