Archivo de la categoría: SharePoint 2010

SharePoint 2010

Workflows en correos entrantes en Biblioteca de Documentos de SharePoint 2010

sharepoint2010 Una de las ultimas cosas con la que me he pegado, es saber por que los Workflows de una biblioteca de documentos, no se lanzaban, en el caso únicamente de añadir documentos a través de email.

Para el que no lo sepa, SharePoint 2010 incluye la funcionalidad de poder añadir información a una biblioteca de documentos, a través de email, es decir: si quieres añadir un archivo concreto a una librería y no puedes acceder al entorno de SharePoint, siempre tienes la posibilidad de enviar un email con dicho archivo, a una cuenta en concreto (esto debes haberlo configurado previamente).

declarativeworkflow

Volviendo al problema, tengo una biblioteca de documentos, donde hay un workflow personalizado, el cual se lanza cuando se añade un elemento. Esto funciona correctamente, si subes el documento a través del interface web o usando el explorador (mediante el protocolo WebDav)… pero cuando se suben a través de email, el workflow no se lanza!!!

Buceando en Internet, he visto que para habilitar esto, tiene que estar activa la propiedad “DeclarativeWorkflowAutoStartOnEmailEnabled“.

Como es habitual, esto puede hacerse usando bien STSADM o PowerShell, únicamente indicar, que los comandos a través de STSADM desde la versión de SharePoint 2007 no denegrían utilizarse (esta marcado como deprecated), Microsoft te recomienda el uso de PowerShell.

Procedimiento con STSADM:

1) Primero debemos verificar si este parámetro se encuentra activo o no, para ello lanzamos el siguiente comando:

stsadm -o getproperty -pn declarativeworkflowautostartonemailenabled

2) Verificamos el valor de la propiedad “Value” y en el caso que sea “no” deberíamos activarlo

declarativeworkflow1

3) Para activarlo ejecutamos el siguiente comando:

stsadm -o setproperty -pn declarativeworkflowautostartonemailenabled -pv true

declarativeworkflow2

Procedimiento con PowerShell:

1) Primero debemos verificar si este parámetro se encuentra activo o no, para ello lanzamos el siguiente comando:

$spWebService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$spWebService.DeclarativeWorkflowAutoStartOnEmailEnabled

2) Verificamos el valor que devuelve y en el caso que sea “False” deberíamos activarlo
3) Para activarlo ejecutamos el siguiente comando:

$spWebService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$spWebService.DeclarativeWorkflowAutoStartOnEmailEnabled = $true
$spWebService.Update()

Puedes consultar mas información sobre la propiedad DeclarativeWorkflowAutostartOnEmailEnabled aquí.

 

Shrink todas las bases de datos de un servidor de una manera rapida en SQL Server

SqlServer1En mis maquinas virtuales de desarrollo de SharePoint 2010, muchas veces me encuentro con que, el tamaño de las bases de datos SQL Server de SharePoint se ha disparado y me estoy quedando sin espacio.

Para reducir el tamaño de las bases de datos, normalmente lo que suelo hacer es un shrink (procedimiento almacenado para reducir el tamaño de los archivos de datos y de registro de la base de datos especificada).

Aunque he leído varios posts en los que no se aconseja eliminar esta información en entornos SharePoint, aquí os dejo un articulo interesante de Microsoft sobre el mantenimiento de bases de datos SharePoint 2010: Database maintenance for SharePoint 2010 Products, donde comentan el correcto uso de este comando.

Volviendo a la cuestión que nos atañe… Para poder liberar de una forma cómoda y sencilla, espacio de todas la bases de datos de una instancia de SQL server, has de ejecutar esta sentencia SQL:

declare @db varchar(255)
declare cur cursor for
select name from sys.databases where is_read_only=0 and state=0
  and name not in ('master','model','tempdb','msdb')
open cur
fetch cur into @db
while @@fetch_status=0
begin
  exec SP_dboption @db,'trunc. log on chkpt.','true' 
  DBCC shrinkdatabase (@db)
  fetch next from c into @db
end
close cur
deallocate cur

 

Este script lo que hace es lo siguiente: obtener una lista de todas las bases de datos (exceptuando las del sistema: master, model, tempdb y msdb), posteriormente establece la base de datos en ReadOnly y luego reducir el tamaño del archivo.

El resultado es el siguiente, donde te informa el tamaño inicial y el resultante:

shrink

 

Script de PowerShell para rellenar una lista de SharePoint con elementos

powershell Este ejemplo es válido tanto para plataformas SharePoint 2010 como SharePoint 2013. Viene motivado por la necesidad de probar los limites del producto en cuanto a vistas de listas se refiere.

Tanto la versión 2010 como 2013 tienen los mismos limites en cuanto a listas/bibliotecas se refiere en cuanto a:

  • Numero de elementos por lista: 30.000.000
  • Limitación de vista de lista: 5000 elementos
  • Tamaño de filas de lista: 8.000 bytes por fila

Viendo estas limitaciones, aquí tenéis un script de PowerShell con el que podréis añadir de forma automática miles de elementos en una lista:

[System.Reflection.Assembly]::LoadWithPartialName(”Microsoft.SharePoint”)
function PopulateList
{
    param ($ListURL, $count)
    $mySite = new-object Microsoft.SharePoint.SPSite($ListURL)
    $myWeb = $mySite.OpenWeb()
    $mySrcList = $myWeb.GetList($ListURL)
    $itemCount=0
    write-host "Preparando la lista para la carga de datos: " $ListURL
    write-host "-----------------------------------------------------------------"
    while ($itemCount -lt $count)
    {
        $itemCount=$itemCount+1
        write-host "Creando elemento:" $itemCount
        $listItem = $mySrcList.Items.Add()
        $title="Titulo del elemento " + $itemCount
        $listItem["Title"]=$title
        $listItem.Update()
    }
    $myweb.Dispose()
    $mySite.Dispose()
}
#---------------------------------------------------------------
#Para usar este función solo tienes que llamarla pasando como parámetro la lista y el numero de elementos a crear
$sitecollection="http://intranet/sitio/Lists/listaPrueba/"
PopulateList $sitecollection 6000
#---------------------------------------------------------------

 

Hay que destacar, que la lista (como requisito) unicamente ha de tener el campo “Titulo” (campo por defecto en listas que hereden del tipo de contenido “Elemento”), único campo que rellena el script.

 

Al menos uno de los tipos de campo no se ha instalado correctamente. Vaya a la página de configuración de la lista para eliminar estos campos.

sharepoint2010Este es el mensaje de error que me muestra cuando intento acceder a una página de un sitio de publicación tras una migración de SharePoint 2007 a SharePoint 2010: “Al menos uno de los tipos de campo no se ha instalado correctamente. Vaya a la página de configuración de la lista para eliminar estos campos” o en ingles “One or more field types are not installed properly. Go to the list settings page to delete these fields“.

ErrorTiposCampoInstalados

Este problema se produce porque cuando se activa la característica de SharePoint “Server Publishing Infrastructure“, esta crea una lista interna (esta oculta) llamada “Relationships List“, donde se almacena información de las variaciones y la información de esta lista no es correcta o no se ha actualizado correctamente.

Para solucionarlo lo que hay que hacer, únicamente es borrar la información que hay en esta lista, para ello hay que realizar los siguientes pasos, entre los que destacan la ejecución de varios comandos de PowerShell:

  1. Acceder con el navegador web a la lista “Relationships List” y eliminar los elementos que haya en esta: (http://<HostName>/<Site>/Relationships%20List/allitems.aspx)
  2. Desactivar la característica “Infraestructura de publicación de SharePoint Server“, de la colección de sitio: Disable-SPFeature –Identity f6924d36-2fa8-4f0b-b16d-06b7250180fa –url http://<HostName>/<Site>
  3. Activar la misma característica de Infraestructura: Enable-SPFeature –Identity f6924d36-2fa8-4f0b-b16d-06b7250180fa –url http://<HostName>/<Site>
  4. Desactivar la característica de “Publicación de SharePoint Server” a nivel de sitio: Disable-SPFeature –Identity 94c94ca6-b32f-4da9-a9e3-1f3d343d7ecb –url http://<HostName>/<Site>
  5. Activar característica de Publicación: Enable-SPFeature –Identity 94c94ca6-b32f-4da9-a9e3-1f3d343d7ecb –url http://<HostName>/<Site>

Tras la realización de estos pasos, podrás acceder sin problemas a todas las paginas existentes en el sitio con este problema.

IMPORTANTE: Esta solución propuesta solo es valida para plataformas SharePoint 2010.

 

“Configurar grupos para este sitio” en SharePoint 2010

sharepoint2010Una de las cosas que echo de menos de SharePoint 2007 en SharePoint 2010 es la pagina de “Configurar grupos para este sitio” o en inglés “Set up Groups for this site“, donde el usuario puede especificar quién puede tener acceso a un  sitio en concreto. Esta claro que he mejorado mucho la forma de gestionar los grupos y usuarios, pero hecho en falta esta pagina (y sobre todo su funcionalidad)…

 

ConfigurarGrupos

Por algún motivo, el equipo de SharePoint decidió que esta funcionalidad “Configurar grupos de este sitio” debía de estar oculta en el menú de Permisos del Sitio. Si que esta visible, cuando creas un Sitio nuevo (si lo creas con la opción de permisos únicos), la malo es que luego, no hay forma de ver los grupos asignados a cada perfil.

Si necesitas realizar cambios en la asignación de grupos y como esta funcionalidad sigue estando en SharePoint 2010, siempre es posible acceder a la pagina por url: /_layouts/permsetup.aspx

 

ViewFormPagesLockdown para aumentar la seguridad en SharePoint 2010

sharepoint2010 Ayudando a un amigo, vimos que en portales públicos en los que se utiliza SharePoint 2010, puedes tener una mala configuración que a nivel de seguridad, puede ser problemático.

Cuando creas un portal publico (usando las características de Publicación) basado en SharePoint, has de configurar el acceso de usuarios, como anónimo, por lo que por defecto permite que cualquier usuario acceda a los siguientes recursos:

  • /_layouts/viewlsts.aspx
  • /Lists/[ListName]/AlItems.aspx

Esto es un problema de seguridad, ya que estas dando una información muy importante a usuarios anónimos, que podrían usar en tu contra… pero no hay problema ya que SharePoint trae una característica oculta a nivel de Site, llamada ViewFormPagesLockdown, que deshabilita el acceso a estos recursos de forma anónima.

Para activar esta funcionalidad, hay que utilizar un par de comandos de PowerShell:

1) Obtenemos el GUID de la característica ViewFormPagesLockdown, la cual como he comentado esta oculta con el siguiente comando:

Get-SPFeature | where { $_.DisplayName -eq "ViewFormPagesLockdown"}

ViewFormPagesLockdown

2) Una vez tenemos el GUID o identificador, lo que hacemos es activarlo:

Enable-SPFeature -url http://sharepoint -identity 7c637b23-06c4-4724-9a9a-7c175762c5c4 -confirm:$false

Tras este cambio, los usuarios tendrán que autenticarse, para acceder a estos recursos.

IMPORTANTE: Puedes tener problemas si dentro de esta colección de sitio, tienes subsitios de tipo Blog, en los que los usuarios pueden realizar comentarios sobre post o similares… para solucionar este tipo de problema, en el blog de sharepointblues.com te explican como se puede solucionar.

Como lanzar un Workflow programaticamente en SharePoint

Tras un periodo de inactividad, vuelvo con un nuevo post… Esta vez se trata, de la necesidad de lanzar un nuevo Workflow a nivel de listas o biblioteca en todos los ítems, previamente creados. Si el Workflow se configura para que se lance a la creación o modificación del ítem, puede que haya muchos ítems, que por antigüedad, no se modifiquen y no se lance el Workflow asociado.

Para realizar esto desde el API de SharePoint, la forma mas sencilla es la siguiente:

static private void LanzarWorkflow()
{
  //definición de variables necesarias para la ejecución
  string SP_URL = "http://mi_sharepoint";
  string LIST_NAME = "Pages";
  //este es el GUID del BaseID del Workflow que queremos ejecutar
  Guid wfBaseId = new Guid("b81abdd8-faf4-4bed-86ca-a49d9cc9913e");
  //se ejecuta con privilegios elevados
  SPSecurity.RunWithElevatedPrivileges(delegate
  {
	try
	{
	  using (SPSite site = new SPSite(SP_URL))
	  {
		using (SPWeb web = site.OpenWeb())
		{
		  SPList list = web.Lists[LIST_NAME];
		  SPListItemCollection items = list.Items;
		  for (int i = 0; i < items.Count; i++)
		  {
			web.AllowUnsafeUpdates = true;  
			//selecciona el item actual
			SPListItem item = items[i];
			Console.WriteLine(string.Format("[Item] Lanzando workflow para el item Id: {0} ", item.ID));
			//obtiene el objeto plantilla de WF asociado a la lista que queremos
			SPWorkflowAssociation associationTemplate = list.WorkflowAssociations.GetAssociationByBaseID(wfBaseId);
			//lanzar el WF a nivel del item
			web.Site.WorkflowManager.StartWorkflow(item, associationTemplate, associationTemplate.AssociationData);
			web.AllowUnsafeUpdates = false; //bloquea cambios por codigo
		  }
		}
	  }
	}
	catch (Exception ex) { Console.WriteLine(string.Format("***ERROR*** {0}", ex.ToString())); }
  });
}

Los únicos parámetros que necesita esta función son:

  • SP_URL: Url del sitio de SharePoint donde se encuentra la lista que tiene asociada el Workflow que deseamos lanzar
  • LIST_NAME: Nombre de la lista o biblioteca que tiene el Workflow
  • wfBaseId: por ultimo el Base ID del Workflow (este GUID lo puedes ver, por ejemplo, desde SharePoint Designer, editando el archivo XML de configuración del propio Workflow)

 

Listado de permisos de usuarios de un sitio en SharePoint 2010

powershellUna 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
#---------------------------------------------------------------

Excel Services – The workbook cannot be opened

sharepoint2010Si 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.

excel_f1

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 …

excel_f2

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“.

excel_f3

 

4) Guarda los cambios y verás como los archivos Excel ser abren correctamente en tu navegador web.

 

Excel Services – This workbook cannot be opened because it is not stored in an Excel Services Application trusted location

sharepoint2010Si 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

excel_e1

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.

excel_e2

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.

excel_e3