El listado de todas las actualizaciones de SharePoint 2010...
Una opción muy útil ya que actualmente los dispositivos móviles de 3ª generación son capaces de interpretar y mostrar paginas sobre SharePoint
Útil script de PowerShell para el aprovisionamiento de Mi Sitio
Una de las ultimas cosas que me han solicitado es recuperar todos los usuarios y sus permisos de una colección de sitio o subsitio en SharePoint 2010…
La forma mas rápida que se me ocurrió es la de crear un script de PowerShell para ello. Como creo que os podría ser de utilidad, lo comparto con todos vosotros:
function Get-UsersPermissions([string]$portalurl, [String[]]$excludewebs, [string]$onesite)
{
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local
#añade la barra si no existe
if (-not $portalurl.EndsWith("/")) { $portalurl = $portalurl + "/" }
#recorre todos los servicios de la granaja
foreach ($spService in $farm.Services)
{
if (!($spService -is [Microsoft.SharePoint.Administration.SPWebService])) { continue; }
foreach ($webApp in $spService.WebApplications)
{
if ($webApp -is [Microsoft.SharePoint.Administration.SPAdministrationWebApplication]) { continue; }
$webAppUrl = $webApp.GetResponseUri('Default').AbsoluteUri
if ($webAppUrl.ToUpper() -eq $portalurl.ToUpper())
{
#recorre las colecciones que existen en la aplicacion web
foreach ($site in $webApp.Sites)
{
#si existe algun parametro
if (($onesite -ne $null) -and ($onesite -ne ""))
{
#verifica si se ha incluido el parametro Web
if ($site.Url.ToUpper() -ne $onesite.ToUpper()) { continue; }
}
#recorre los sitios que existen en la coleccion
foreach ($web in $site.AllWebs)
{
if ($excludewebs -contains $web.Url)
{
Write-Host "Se ha excluido el sigioente sitio: " $web.Url
continue
}
foreach ($user in $web.SiteUsers)
{
#excluye al usuario: sharepoint\system
if ($user.Loginname.StartsWith("SHAREPOINT\")) { continue; }
#recupera la informacion a mostrar
$data = @{
"Coleccion" = $site.Url
"Url sitio" = $web.Url
"Nombre sitio" = $web.Title
"Usuario" = $user.Loginname
"Nombre" = $user.Name
"Roles" = $user.Roles
"Grupos" = $user.Groups
}
New-Object PSObject -Property $data
}
$web.Dispose();
}
$site.Dispose()
}
}
}
}
}
#---------------------------------------------------------------
#Opcion 1: Listas de los usuarios y sitio del la Aplicacion Web: http://intranet, pero solo muestra los usuarios y permisos del subsitio: http://intranet/sites/test
# Get-UsersPermissions -portalurl:http://intranet/ -onesite:http://intranet/sites/test | Out-GridView
#---------------------------------------------------------------
#Opcion 2: Listas de los usuarios y sitio del la Aplicacion Web http://intranet, pero excluye los 3 sitios: /gastos, /docs y /rrhh
# Get-UsersPermissions -portalurl:http://intranet/ -excludewebs:@('http://intranet/gastos','http://intranet/docs','http://intranet/rrhh') | Out-GridView
#---------------------------------------------------------------
#Opcion 3: Lista todas los sitios y usuarios de la Aplicacion Web: http://intranet
# Get-UsersPermissions -portalurl:http://intranet/ | Out-GridView
#---------------------------------------------------------------
Si estas intentado abrir un archivo Excel en SharePoint 2010, a través de Excel Services (partimos que el servicio ya esta instalado en la granja) y recibes este mensaje de error: “The workbook cannot be opened“, sin duda, se trata de un problema de permisos de base de datos.
Para solucionar este problema, has de dar permiso de “db_owner” a la cuenta de servicio que estas usando para ejecutar Excel Services, siguiendo los siguientes pasos:
1) Abre el administrador de bases de datos “SQL Server Management Studio” y localiza la base de datos o bases de datos de contenido (puedes verlo en el Visor de Eventos de Windows “<Content Database Name>” y selecciona “Security“.
2) Dentro de esta sección, posicionate en “Users” y con el botón derecho, selecciona “New User …”
3) Introducimos la cuenta de servicio que ejecuta el servicio de Excel Service (que puedes localizar en Security -> Configure Service Accounts, seleccionado el pool del servicio) y le asignamos el rol de “db_owner“.
4) Guarda los cambios y verás como los archivos Excel ser abren correctamente en tu navegador web.
Si estas intentado abrir un archivo Excel en SharePoint 2010, a través de Excel Services (partimos que el servicio ya esta instalado en la granja) y recibes este mensaje de error: “This workbook cannot be opened because it is not stored in an Excel Services Application trusted location”
Para solucionar este problema, has de realizar los siguientes pasos:
1) Abres la Administración Central y vas a: Manage service applications -> Excel Services Application (o el nombre que le hayas dado al servicio) -> Trusted File Locations.
2) En esta pantalla, has de añadir la url del Web Application (como por ejemplo: http://intranet.com) y marcar la opción ”Children trusted” para asegurarte que todas las bibliotecas de documentos que contengan archivos Excel, se abre correctamente en el navegador web.
Si estas intentado abrir un archivo Excel en SharePoint 2010, a través de Excel Services (partimos que el servicio ya esta instalado en la granja) y recibes este mensaje de error: “Unable to process the request. Wait a few minutes and try performing this operation again” puedes realizar varias acciones:
1) Puedes verificar que la conexión de servicio con Excel Service está habilitada, para ello, en la Administración Central te vas a: Application Management -> Manage Web Application -> <Nombre_Web_Application> -> Service connections.
En este formulario, has de asegurarte de el servicio Excel (según lo hayas llamado cuando lo creaste), esta habilitado:
Con estas verificaciones, debería funcionar correctamente el servicio y abrir tus archivos Excel en el navegador web.
2) Una segunda opción, es configurar la Coleccion de Sitio, para que, en vez de abrir el archivo Excel en el navegador web, te lo abra en el cliente de paquete Office. Para ello, te remito a este post de Mario Cortés donde se detallan todos los pasos a seguir.
Es posible que te hayas visto en la necesidad de tener que editar plantillas de listas de SharePoint, para pasarlas a una granja diferente o similar… Una cosa que suele ser común es que en tu servidor de pruebas no tengas todos los Language Packs instalados, y cuando quieras usar dichas plantillas de lista, no puedas hacerlo.
Para poder realizar esto, es necesitar editar el manifiesto de la planilla y ponerle el idioma, que tengas instalado en tu entorno. Para editar un archivo stp existen varios métodos que comento a continuación:
1) Existe una forma manual de poder editarlos, cuyos pasos serian:
2) Existe otra forma mucho mas sencilla, cuyos pasos serian:
Este segundo paso es mucho mas cómodo si tu plantilla, contiene mas de un archivo (es decir a aparte del manifest.xml) ya que no tienes que generar ningún script para que te haga el empaquetado usando makecab.
Para más información sobre IExpress Wizard, puedes consultar esta pagina de Microsoft.
Uno de los problemas con el que nos podemos encontrar los desarrolladores de SharePoint 2010, es que cada vez que intentamos acceder a sitios de nuestros entornos de desarrollo o preproducción de SharePoint, que se habíamos creado previamente, nos pide en repetidas ocasiones (las tres de rigor) su usuario y contraseña antes de devolver un error 401.1 Access Denied y una entrada en el Visor de Eventos de Windows.
En principio esto no debe de ser un problema ya que ningún usuario usa directamente los servidores de la granja de SharePoint para navegar por los sitios ahí hosteados. Pero ¿y si es un servidor de desarrollo o pruebas? En estos casos es obligatorio que podamos acceder a los sitios sin que este comportamiento ocurra.
Este comportamiento del sistema, es una característica de seguridad introducida desde el Service Pack 1 de Windows Server 2003 y está presente hasta las versiones actuales de Windows Server 2008 R2. Básicamente lo que hace es bloquear el acceso a una Web Application usando el FQDN, si esto sucede la característica entra en acción y bloquea este acceso enviando un error 401.1 Access Denied. ¿Por qué se introdujo esta característica? Pues porque existían varios ataques que se basaban en reflección para engañar a IE y hacerle creer que se estaba trabajando de manera local y así burlar muchas restricciones de seguridad.
¿Como podemos solucionar este problema (siempre y cuando se traten de entornos no productivos)? Existen dos métodos .. uno a través de la ejecución de un comando de PowerShell y la segunda añadiendo una clave en el Registro de Windows.
1) Ejecución de este comando PowerShell:
New-ItemProperty HKLM:\System\CurrentControlSet\Control\Lsa -Name "DisableLoopbackCheck" -value "1" -PropertyType dword
En la siguiente imagen puede apreciarse la ejecución de este comando:
2) Modificando directamente el Registro de Windows:
- Pincha en el botón de Inicio o presiona la tecla Windows + X (dependiendo la versión de Windows), pincha en Ejecutar, escribe: “regedit” y presiona Intro.
- En el editor del Registro de Windows, localiza la siguiente clave: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
- Pincha con el botón derecho del ratón en Lsa, selecciona nueva Valor de DWORD (32 bits)

- Introducimos el nombre “DisableLoopbackCheck” y presionamos Intro.
- Pinchamos con el botón derecho del raton sobre esta nueva clave “DisableLoopbackCheck“, y seleccionamos Modificar.
- Introducimos un “1″ en el campo Información del valor y presionamos Intro.

- Cerramos el editor del Registro de Windows y reiniciamos el servidor para que los cambios tengan efecto.
Para información mas detallada sobre este problema, podéis consultar el KB896861.
Una de las cosas que me ha surgido, ha sido la necesidad de obtener mediante programación, el estado de los items de una lista o biblioteca en SharePoint 2010.
Es un proceso muy sencillo, ya que hay que obtener la el valor del campo que se genera en la lista, cuando se le asocia un workflow, únicamente lo que debemos hacer posteriormente, es convertir el numero por un texto legible. En caso de ser necesario puedes hacer directamente la traducción en castellano de los estados, si eliminas la linea System.Enum.GetName(typeof(SPWorkflowStatus), WorkflowStatusValue) y la sustituyes por un switch por ejemplo…
Aquí os dejo una función que podrá serviros de ayuda, los unicos parametros que hay que pasar son:
siteUrl = Url del sitio
listName = Nombre de la lista o libreria a la cual esta asociado el workflow
itemId = Identificador, del item que queremos consultar
wfFieldName = Nombre del campo de la lista donde se muestra el estado del workflow
static string GetWorkflowStatud(string siteUrl, string listName, int itemId, string wfFieldName)
{
string result = string.Empty;
SPSecurity.RunWithElevatedPrivileges(delegate
{
try
{
using (SPSite spSite = new SPSite(siteUrl))
{
using (SPWeb spWeb = spSite.OpenWeb())
{
//instancia la lista/biblioteca
SPList spList = spWeb.Lists[listName];
//recupera el item de la lista
SPListItem spListItem = spList.Items.GetItemById(itemId);
//recupera el valor del campo del Workflow
Int32 WorkflowStatusValue = Convert.ToInt32(spListItem[wfFieldName]);
//traduce el numero a texto
string WorkflowStatusString = System.Enum.GetName(typeof(SPWorkflowStatus), WorkflowStatusValue);
//almacena el estado del Workflow
result = WorkflowStatusString;
}
}
}
catch (Exception ex) { result = ex.Message; }
});
return result;
}
Para más información, puedes consultar el enumerador SPWorkflowStatus con los posibles estados del workflow.

Una de mis tareas es revisar el Analizador de mantenimiento de SharePoint 2010, donde quedan registrados problemas que pueden hacer que una granja de SharePoint tenga problemas de seguridad, escalabilidad, rendimiento…
Uno de los problemas que he detectado y que viene siendo recurrente, es soluciones han sido eliminadas, antes de que las características correspondientes hayan sido desactivadas de colecciones de sitios y sitios.
Este problema queda registrado en el Analizador de mantenimiento, con la categoría a nivel de granja: ”Missing server side dependencies“.
Dentro de esta categoría, puedes encontrar registros como el siguiente, donde se detallo el problema:
[MissingFeature] Database [_WSS_DSI01] has reference(s) to a missing feature: Id = [e8389ec7-70fd-4179-a1c4-6fcb4342d7a0]. The feature with Id e8389ec7-70fd-4179-a1c4-6fcb4342d7a0 is referenced in the database [_WSS_DSI01], but is not installed on the current farm. The missing feature may cause upgrade to fail. Please install any solution which contains the feature and restart upgrade if necessary.
Este mensaje de error indica un nombre de base de datos de contenido (_WSS_DSI01) y el identificador de la característica (e8389ec7-70fd-4179-a1c4-6fcb4342d7a0), lo malo es que este error, no informa sobre los sitios o colecciones de sitios donde la característica existe y además, aunque supiéramos donde se ha activado esta característica, no es posible desde el interfaz de usuario desactivarla, ya que dicha solución se ha eliminado de la granja.
El siguiente script de PowerShell, nos informa de que sitios o colecciones de sitio de la base de datos de contenido, contienen la referencia a esta característica y fuerza la desactivación de de esta.
function Remove-SPFeatureFromContentDB($ContentDb, $FeatureId, [switch]$ReportOnly)
{
$db = Get-SPDatabase | where { $_.Name -eq $ContentDb }
[bool]$report = $false
if ($ReportOnly) { $report = $true }
$db.Sites | ForEach-Object
{
Remove-SPFeature -obj $_ -objName "site collection" -featId $FeatureId -report $report
$_ | Get-SPWeb -Limit all | ForEach-Object
{
Remove-SPFeature -obj $_ -objName "site" -featId $FeatureId -report $report
}
}
}
function Remove-SPFeature($obj, $objName, $featId, [bool]$report)
{
$feature = $obj.Features[$featId]
if ($feature -ne $null)
{
if ($report)
{
write-host "Feature found in" $objName ":" $obj.Url -foregroundcolor Red
}
else
{
try
{
$obj.Features.Remove($feature.DefinitionId, $true)
write-host "Feature successfully removed from" $objName ":" $obj.Url -foregroundcolor Red
}
catch
{
write-host "There has been an error trying to remove the feature:" $_
}
}
}
else
{
#write-host "Feature ID specified does not exist in" $objName ":" $obj.Url
}
}
Si únicamente queremos obtener el listado de sitios y colecciones de sitios, donde se referencia esta característica, deberás utilizando de la siguiente forma:
Remove-SPFeatureFromContentDB -ContentDB "_WSS_DSI01" -FeatureId "e8389ec7-70fd-4179-a1c4-6fcb4342d7a0" –ReportOnly
Si por el contrario, además de obtener el listado, deseas eliminar las referencias de la base de dato de contenido, deberás utilizarlo como anteriormente, el único cambio es que has de eliminar el parámetro ”–ReportOnly”:
Remove-SPFeatureFromContentDB -ContentDB "_WSS_DSI01" -FeatureId "e8389ec7-70fd-4179-a1c4-6fcb4342d7a0"
Una vez hayas eliminado todas las referencias erróneas, es necesario volver a analizar la categoría: “Missing server side dependencies” dentro del Analizador de mantenimiento, para comprobar que los errores han desaparecido.
Referencia: get-spscripts.com
Es posible que se os haya dado el caso de tener que consultar los logs de SharePoint 2010 conocidos como Unified Logging System (ULS), en entornos formados por grandes granjas de servidores… Este proceso en este caso se convierte en algo tedioso, si no tienes forma de identificar en que servidor físico estas haciendo la petición, para consultar su Correlation ID.
Antes de nada indicar que Microsoft recomienda no acceder directamente a la información de la plataforma, desde la base de datos, sino que debe hacerse a través del modelo de objetos de SharePoint. Este seria el único caso excepcional, donde podemos acceder directamente a través de consultas SQL.
SharePoint 2010, a nivel de granja crea una base de datos llamada WSS_Logging, donde almacena toda la información de la plataforma SharePoint, como por ejemplo: información que envía al visor de eventos de Windows, información de los contadores de rendimiento, inventario de los sitios existentes, los logs de ULS… eso si con un periodo de antigüedad de 14 días, toda información que pase de ese tiempo sera eliminada.
La información de esta base de datos, también es usada para consolidar los datos de Web Analytics a través de los jobs Microsoft SharePoint Foundation Usage Data Import y Microsoft SharePoint Foundation Usage Data Processing.
También es importante remarcar, que la información se vuelca desde la granja a la tabla WSS_Logging, a través de varios timer job que se ejecuta cada varios minutos (este valor es diferente para cada uno de ellos). Aquí tenéis el listado de jobs que vuelca información a esta base de datos (estos datos pueden consultarse en la Administración Central):
El job en concreto, que actualiza la información en el ULS es: Diagnostic Data Provider: Trace Log y se ejecuta por defecto cada 10 minutos y esta es su configuración:
Si, como comentábamos anteriormente, queremos acceder a la misma información que existe en los logs de SharePoint, directamente, deberemos realizar consultas sobre la vista: [dbo].[ULSTraceLog]. Es importante remarcar que debes utilizar las vistas y no las tablas para realizar las consultas.
Los campos de esta vista son: [PartitionId], [RowId], [LogTime], [MachineName], [ProcessID], [ProcessName], [ThreadID], [Area], [Category], [Level], [EventID], [Message], [CorrelationId], [RowCreatedTime]. Estos campos son similares a la informacion que se almacenan en los archivos de ULS.
Como veis existe el campo [CorrelationId] por el cual vamos a conseguir filtrar los datos, para cotar la información.
De este modo, podrás localizar registros de logs sin tener que buscar físicamente en varios archivos ULS, a través de la granja…