jueves, 4 de septiembre de 2014

Inventario de WorkFlows en Sharepoint 2010

Mediante este Script PowerShell podemos realizar un inventario de Workflows en Sharepoint 2010 o 2013

He incluido la opción de sacarlo por OutGrid o por CSV
También se ha extraído el AssemblyName y el ClassName del XML de configuración, de forma que permite localizar los proyectos/componentes que los contienen.
Para filtrar los workflows de aprobación (Nativos) del listado se ha usado un -NotLike, podemos usar esta linea para filtrar otros o localizar uno concreto

#List all workflows in farm
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

function ListWF()
{
    #Grab all webs
    Get-SPSite -Limit All | % {$webs += $_.Allwebs}
    if($webs.count -ge 1)
    {
        foreach($web in $webs)
        {
                #Grab all lists in the current web
                $lists = $web.Lists
                foreach($list in $lists)
                {
                   #Get all workflows that are associated with the current list
                        foreach($listassociation in $list.WorkflowAssociations)
                        {
                            if( $listassociation.name -NotLike "Aprobaci*")
                            {
                                [xml]$xmlconf=$listassociation.BaseTemplate.xml;
                                $data = @{
                                "Lista" = $List.Title; 
                                "Web" = $web.Url;
                                "NombreAsociacion" = $listassociation.name;
                                "Name" =$listassociation.BaseTemplate.Name;
                                "ID" =$listassociation.BaseTemplate.ID;
                                "CodeBesideClass" =$xmlconf.WorkflowTemplate.WorkFlowTemplateIdSet.CodeBesideClass;
                                "CodeBesideAssembly" =$xmlconf.WorkflowTemplate.WorkFlowTemplateIdSet.CodeBesideAssm;
                                }
                            New-Object PSObject -Property $data
                            }
                        }
               }         

        }
    $web.Dispose()
    }


}
ListWF | Out-GridView
#$csvFilePath = "C:\Workflows_Listado.csv"
#ListWF | Export-Csv -NoTypeInformation -Path $csvFilePath


jueves, 12 de diciembre de 2013

Suplantar Usuarios en Sharepoint 2013 y verificar la pertenencia a Grupos

Os quiero explicar una de esas cosas tan simples que uno quiere saber, como por ejemplo a que grupos pertenece un usuario.

Resulta que no es nada fácil ni mas ni menos hay que recuperar al usuario, suplantarlo, desactivar la captura de excepciones de seguridad y entonces podemos mirar y actuar sin restricciones en nombre de otro usuario.... que miedo.

Os quiero resaltar 4 cosas complejas metidas en una sola función.

1º En Rosa: Como recuperar un usuario concreto (SPUser) de la web actual
2º En rojo : Como abrir un SPSite Suplantando a un usuario, con el truco del userToken y el ID de Site/Web, sin sus contraseña... no nos hace falta.
3º En verde : Como desactivar la captura de Excepciones de Acceso denegado
4º En Azul : Como verificar la pertenencia a un grupo del usuario suplantado.

Nota: Recordad que dentro de un RunWithElevated no podemos usar directamente el SPContext.Current.Site ni el SPContext.Current.Web, tan solo podemos recuperar el ID para crear el objeto dentro del codigo de privilegios elevados.

Espero que os resulte útil este "agujero de seguridad" de sharepoint.
Nadie os impide suplantar a gente.... ni ser malos.
Funciona en todas las versiones de Sharepoint 2007,2010,2013.

 public List<string> GetAllGroupsFromUser(string sLogin)
        {
            List<string> listapertenencia = new List<string>();

            userName = sLogin;
            SPUser usuario;
            try
            {
                usuario = SPContext.Current.Web.AllUsers[userName];
            }catch(Exception ex)
            {
                usuario = null;
            }

            if (usuario != null)
            {
                SPUserToken userToken = SPContext.Current.Web.AllUsers[userName].UserToken;
                SPSecurity.RunWithElevatedPrivileges(delegate()
                            {
                                bool AccessDeniedflag = SPSecurity.CatchAccessDeniedException;
                                SPSecurity.CatchAccessDeniedException = false;
                                try
                                {

                                    using (SPSite contextSiteColl = new SPSite(SPContext.Current.Site.ID, userToken))
                                    {

                                        using (SPWeb contextSite = contextSiteColl.OpenWeb(SPContext.Current.Web.ID))
                                        {
                                            foreach (SPGroup grp in contextSite.SiteGroups)
                                            {
                                                if (contextSite.SiteGroups[grp.Name].ContainsCurrentUser)
                                                {
                                                    listapertenencia.Add(grp.Name);
                                                }
                                            }
                                        }

                                    }
                                }
                                catch (UnauthorizedAccessException ex)
                                {
                                    listapertenencia.Add("---"); //Error
                                }
                                finally 
                                {
                                    SPSecurity.CatchAccessDeniedException = AccessDeniedflag;
                                }
                                  
                            });
            }
            return listapertenencia;
        }

jueves, 23 de mayo de 2013

Comandos Powershell para Instalar Soluciones y Caracteristicas

Dejo aquí la lista de comandos powershell para instalar/actualizar soluciones y características, a modo de chuleta para no tener que buscarlo.


Add SolutionAdd-SPSolution c:\solutions\myproject.wsp

Deploy Solution
Install-SPSolution –Identity myproject.wsp –WebApplication http://myprojectsite -GACDeployment
Nota: Se pueden usar los parametros
  • –CASPolicies: Si no quieres desplegar a la GAC
  • –AllWebApplications: Si quieres desplegar la solucion a todas las aplicaciones web
  • –Force: para forzar el despliegue de la solucion
Upgrade Solution
Update-SPSolution –Identity myproject.wsp –LiteralPath c:\solutions\myproject.wsp –GACDeployment
Retract Solution
Uninstall-SPSolution –Identity myproject.wsp –WebApplication http://myprojectsite
Remove Solution
Remove-SPSolution –Identity myproject.wsp
Activate Feature
Enable-SPFeature –Identity MyFeature –url http://myprojectsite
Deactivate Feature
Disable-SPFeature –Identity MyFeature –url http://myprojectsite

martes, 14 de mayo de 2013

Depuración remota avanzada con Visual Studio y Sharepoint

Objetivo:
Realizar una depuración paso a paso usando Visual Studio 2010 de un componente (WebPart,Httpmodule,TimerJob,Feature,WebService,etc..) desplegado en un servidor remoto.

Introducción:
En ocasiones es "imposible" reproducir un entorno completamente real en una maquina local destinada para desarrollo, seguramente a muchos de nosotros nos pasa que al desplegar una solución probada hasta la saciedad, comienza a dar errores en el entorno destino, los cuales no somos capaces de reproducir.
Una solución es guardar trazas, en Ficheros de Log, EventViewer, etc..  Resulta muy buena práctica el uso de trazas, pero no es tan rápido como adjuntarnos a un proceso y depurar cualquier error que se produzca, sea cual sea ,activando  la captura de todo tipo de excepciones lanzadas (ver imágenes).
Esto último resulta extremadamente útil cuando no sabes por donde fallan las cosas.
Es harina de otro costal el poner un punto de interrupción y depurar desde nuestro visual Studio en un servidor remoto, y es precisamente lo que quiero explicar en este post, paso a paso.

Ingredientes necesarios en la máquina de desarrollo (Cliente):
1)      Visual Studio 2010 con nuestro proyecto en cuestión abierto y con los puntos de interrupción colocados.
2)      Compilar en Modo Debug y desplegar en el servidor.
3)      En la carpeta de compilación localizamos el fichero .PDB que genera Visual Studio en la carpeta /debug del proyecto, los usaremos más adelante.
4)      Abrir el firewall de Windows para todas las conexiones entrantes al PROGRAMA Remote Debugger (msvmom.exe) tanto para TCP como para UDP
http://msdn.microsoft.com/es-es/library/vstudio/bb385831(v=vs.100).aspx

Ingredientes necesarios  en el Servidor:
1)      Microsoft Visual Studio 2010 Remote Debugger (Instalado en el servidor)
http://www.microsoft.com/en-us/download/details.aspx?id=475
2)      Abrir el firewall de Windows para todas las conexiones entrantes al PROGRAMA Remote Debugger (msvmom.exe) tanto para TCP como para UDP a veces sale este mensaje.
http://msdn.microsoft.com/es-es/library/vstudio/bb385831(v=vs.100).aspx
3)      Desplegar el proyecto compilado en modo Debug en visual Studio.
4)      Si nuestro proyecto despliega a la carpeta /BIN de IIS todo es mas fácil  solo hay que copiar el fichero .PDB del punto 3 en la misma carpeta que la DLL que hemos generado en el cliente.
a.       Si el proyecto despliega a la GAC hay que abrirla en modo "Carpeta" para asi poder copiar el .PDB, esta opción se activa añadiendo la propiedad DWORD, disablecacheviewer con valor 1 en esta ruta del Registro del windows en el servidor : HKLM\Software\Microsoft\Fusion

La GAC vista como carpetas:
5)      Arrancar el Remote Debugger en el servidor
Nota:  tiene que coincidir la version y la arquitectura de procesador del cliente y servidor Cliente_x86==Servidor_x86  Cliente_x64==Servidor_x64
estan ubicados en la ruta C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Remote Debugger\  en la carpeta x64   o x86
6)      Dar permisos al usuario del cliente que quiere depurar, en la opción de permisos (esto no se guarda hay que hacerlo siempre que se reinicie el remote debugger) hay que darle a Aceptar cuando nos pregunta si queremos realmente depurar.


7)      En el Remote debugger Abrimos las Opciones y copiamos el nombre del servidor (lo necesitaremos),  es del tipo "mi_dominio\mi_usuario@nombre_servidor" también podemos Activar la opción de "Sin autenticación (solo nativo)" marcando "permitir que cualquier usuario depure", esto a veces es mas sencillo (e inseguro).

8)      Abrir IIS , y el apartado de WorkerProcesses para obtener el numero de PID del proceso a depurar, lo necesitaremos en el ultimo paso.


Si ya hemos realizado los pasos preparatorios, ahora podemos hacer …

DEPURACIÓN REMOTA
1º Desde el cliente, en el Visual Studio seleccionamos: Debug>AttachToProcess

2º En la ventana de Attach to process en el recuadro de Qualifier, escribimos el Servidor en cuestión que copiamos de las opciones del remote debugger en el servidor.
3º Se cargan todos los procesos, seleccionamos el w3wp.exe que tiene el PID que apuntamos en el Punto 8 de workerprocess.
4º Pulsamos  ATTACH y …. Voila, ya estamos depurando, ahora solo lanzar la parte que queréis depurar vía navegación y saltara el punto de interrupción.

Notas: No olvidéis copiar el .PDB en cada nueva compilación  el PID del workerprocess cambia con cada Reciclado de application Pool y con cada IIS Reset.

Truco:
Si creáis una Aplicación web Extendida de Sharepoint, en otro puerto con otro AplicationPool, no paráis todo el entorno, esto es muy útil para un equipo de desarrollo que anda depurando continuamente.

Espero que os resulte de utilidad,  y muchas gracias a Luis Lázaro por instruirme en estas difíciles artes.


lunes, 13 de mayo de 2013

Errores 403 Forbidden en SharePoint

Problema:
De manera intermitente y especialmente a reciclar en ApplicationPool o hacer IIS Reset, al acceder a Sharepoint aparecen Errores 403 Forbidden.

Pistas de resolución:
Aunque el usuario tenga los permisos adecuados en la colección de sitios, en ocasiones vuelve a aparecer.
En cambio al identificarse como un administrador con permisos de administración en los frontales, la pagina carga correctamente, incluso para todos los siguientes usuarios, por lo que suponemos que hay un problema de permisos tras la impersonación.

Utilizando la utilidad  "Filemon" o "Process Monitor" de SysInternals, localizamos un acceso denegado en el proceso w3wp.exe al acceder al directorio virtual "/bin" que solo es visible únicamente desde la consola de administración de IIS.

9


Diagnóstico:
El problema es de ASP.NET no de Sharepoint, el proceso usa las credenciales del usuario remoto para acceder, es especialmente en la primera carga (de DLL), cuando intenta acceder a este directorio virtual y es ahí donde se produce el acceso denegado. Posteriormente no intenta acceder es por ello que cuando un administrador se identifica, posteriormente ya no se produce el error.
Un usuario normal no tiene permisos de lectura y ejecución en este directorio virtual.
Nota:El error aparece especialmente si hay paginas con webparts de terceros o custom que usen ensamblados  ya que en primer lugar se buscan en /bin (donde se produce el error) y posteriormente en la GAC.

Solución:
1º Desde la consola de administración de IIS seleccionamos la carpeta /bin del sitio en cuestión que nos esté dando problemas.
2º Con el botón derecho desplegamos el menú contextual y seleccionamos "Edit permissions"
3º En la pestaña de Security y añadimos el grupo de usuarios nombre_servidor\users
4º Verificamos que puede (Listar Carpetas,Leer y Ejecutar)

Después de esto el problema desaparece.
Estos permisos pueden tener implicaciones de seguridad, especialmente si se expone el servidor a internet.

Espero que os resulte de utilidad.



miércoles, 8 de mayo de 2013

Sharepoint List Generator Web Part (ListGenWP)

He creado un web part que permite la creación masiva de listas sharepoint.

Solo hay que insertar el webpart en una pagina de sharepoint, por ejemplo en un directorio destinado a la administración del sitio
Es sencillo editar el XML ya sea introduciéndolo por el editor visual, generarlo o copiándolo de otro sitio

Lo he publicado en codeplex http://listgenwp.codeplex.com/

para que quien lo desee colabore en las funcionalidades que he planificado y bueno que así os ahorre trabajo en la pesada tarea de crear las listas.

De momento solo crea , me gustaría convertirlo en un editor de listas para hacerlo mas cómodo.

Sharepoint List Generator Web Part (ListGenWP)Generador de Listas Sharepoint, con un interfaz mas comodo y un fichero XML de Soporte que puede ser editado cargado Masivamente.
Facilita la creación de Listas con Lookups de forma Rápida.
Utiliza los nombres de Listas en lugar de los GUID por lo que funciona Siempre.
Utiliza un fichero XML que se puede generar y editar manualmente.
Permite Lookups enlazados entre listas.
NO utiliza GUID, utiliza el NOMBRE DE LISTA, para evitar problemas de portabilidad

Instrucciones
*1º Insertar las listas a crear
*2º Activar el Check "Crear" y Guardar
*3º Pulsar el Boton de Crear Listas
(bug:cuando se creen las listas hay que entrar en los campos lookup uno a uno y pulsar guardar para que funcione correctamente.)
Nota:Puede editar el XML de definición de listas ListasDef.xml de forma manual, reemplazarlo, salvarlo incluso automatizarlo.
Tipos de campo Permitidos
text : Campo de tipo texto, hay que especificar el tamaño
number : Campo de tipo Numero
currency: Campo de tipo moneda
lookup: Campo de tipo Lookup, hay que especificar la lista de origen y el campo de texto a mostrar (Hay un bug solventable)
date: Campo de tipo Fecha
datetime: Campo de tipo Fecha y Hora
calculated: Campo calculado Por ejemplo: CODIGO & ") " & DESCRIPCION , para por ejemplo rellenar Combobox
boolean: Campo tipo Si/No
percent: Numero en Porcentaje (%)


Autor: Roberto Marcos Asensio http://www.robertomarcos.com
Blog de Soporte: http://sharepointworks.blogspot.com

wpListSincMapper - Sincronizador de listas sharepoint por ODBC

Hola a todos,

Finalmente he conseguido una versión estable y completamente funcional del sincronizador de listas sharepoint que había prometido.
Lo he hecho con vs.net 2008 , también he configurado un instalador grafico para realizar el deploy mas cómodo.

Este es el sitio del proyecto: http://wplistsincmapper.codeplex.com/

También he creado un manual de instrucciones paso a paso muy cortito pero con capturas de pantalla para hacerlo mas fácil. Esta en ingles

Quería agradecer la ayuda aportada por Guillermo Martin (Goyo) sin el que una buena parte del proyecto se habría demorado mucho y gracias tambien por sus correcciones de mi ingles.

A modo de experimento he creado una cuenta paypal para donaciones por si alguien quiere aportar algo, y así poder irme de tapas con Goyo y mi hermano o tal vez de cena. Bueno no deja de ser un experimento :)


Dejo unas capturas de pantalla para abrir el apetito.




Mi intención es crear un migrador de sitios mucho mas grande en el que este proyecto solo es una pieza, para sincronizar y copiar listas sharepoint de entorno SQL
Muchas gracias por las ideas aportadas, estoy trabajando en algunas de ellas.
Espero que os sea de MUCHA UTILIDAD
Saludos, RobertoMarcos.com

wpListSincMapper Web Part (v 1.0) - ODBC Sharepoint List Synchronizer

Finally I have stabilized a fully functional version of Sharepoint List Synchronizer (which I promised)I have built it using Vs.net, and I have configured a graphical installer to deploy more easy.

I have also created a short step by step instruction manual but with screenshots to make it easier.

I wanted to thank the support provided by Guillermo Martin (Goyo), without which a good part of the project would have been delayed and thanks too for correcting my English.

Codeplex Project: http://wplistsincmapper.codeplex.com/


This project is hosted in CodePlex with the source code included if you want to take a look.

My intention is to create a site migrator much larger than this project(which this one is only one piece).
Thank you very much for the ideas, I'm working on some of them.
I hope this will be of much use. Best Regards, RobertoMarcos.com




Análisis y estadísticas de uso de Sharepoint con Piwik

Vamos a analizar las estadísticas de SharePoint con Piwik ,que es un Clon Open Source de Google Analitics/ Urchin.
La aplicación la podemos bajar en http://es.piwik.org/

Pero si lo que queremos es no complicarnos demasiado aquí os dejo una maquina Virtual Appliance con todo instalado.

Podemos entrar con Putty, pero usar el Webmin que viene de serie instalado en la MV es lo mas rápido.

Ahora solo necesitamos los ficheros de LOG de IIS ( No son los de Sharepoint ) que están en C:\Windows\System32\LogFiles\W3SVC1 
Para localizarlos también podemos seguir estos pasos : http://portal.smartertools.com/KB/a154/where-are-my-iis-log-files-stored.aspx

Los copiamos por FTP, usando Webmin o compartimos la carpeta de logs de IIS mediante NetBios y la montamos usando samba de linux.
Para un análisis puntual con copiarlo usando el gestor de ficheros de Webmin es suficiente.

Dentro de la maquina virtual lanzamos el analizador de Logs indicando la url a analizar.
    $ python /path/to/piwik/misc/log-analytics/import_logs.py  --url=http://analytics.example.com fichero_de_log.log

Y ya tenemos listas las estadísticas para ver el uso que nuestros usuarios dan a la instalación de Sharepoint, por si necesitamos añadir mas frontales y esas cosas.
Esto ayuda bastante a decidir el tamaño de nuestra granja de servidores.

Espero que os sea de utilidad.


miércoles, 12 de septiembre de 2012

Error Access Denied al modificar el web.config programaticamente o al intentar hacer acciones Administrativas

Problema:
En Sharepoint 2010 al tratar de modificar programaticamente el web.config desde un evento de feature o script de acciones Administrativas, usando el SPWebConfigModification sale un error muy descriptivo "Access Denied". Que majo! Que descriptivo!
Probamos con privilegios elevados.... y "Access Denied"


Solución:
Estas accediendo usando LOCALHOST o por la IP? Lo lógico es entrar usando el nombre del servidor o la ruta de acceso alternativa que este registrada.
No obstante si quieres que funcione ..... en Sharepoint 2010 se ha incorporado un interruptor de seguridad a nivel de Servicio para bloquear modificaciones remotas, tendremos que desactivarla....

# Con este script de PowerSell desactivamos la caracteristica de seguridad RemoteAdministratorAccessDenied
# Autor:Roberto Marcos

#Añadimos el snapin de SharePoint PowerShell 
 if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}
$servicio = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$servicio.RemoteAdministratorAccessDenied = $false
$servicio.Update()


lunes, 10 de septiembre de 2012

Obtener el Strong Name del ensamblado desde Visual Studio

Este truco de Powershell facilita la extracción de Nombre del ensamblado (StrongName) desde Visual Studio.
Funciona en Sharepoint 2010 y Sharepoint 2007

  1. En Visual Studio, ir hasta Tools –>  External Tools.
  2. Hacemos Click en "Add" para agregar una herramienta nueva, y rellenar los siguiente valores:
    1. Title: S&trong Name
    2. Command: Powershell.exe
    3. Arguments: -command "[System.Reflection.AssemblyName]::GetAssemblyName(\"$(TargetPath)\").FullName"
    4. Marcar "Use Output Window"
    5. Desmarcar cualquier otra opción

3. Ya esta, ahora en el proyecto , vamos hasta Tools –> Strong Name, y en la ventana de Salida obtendremos el Nombre de ensamblado

Ejemplo:ProyectoEjemplo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=64a818baff89cafc

lunes, 25 de junio de 2012

Background Folder Copy for Sharepoint 2010

He decidido subir a codeplex este proyecto que hice hace muchísimo tiempo, creo que aun puede ser de utilidad a mucha gente, lastima no haberlo hecho antes.

http://foldercopysp2010.codeplex.com

Se trata de un pequeño proyecto de un servicio windows que revisa constantemente una carpeta en busca de ficheros nuevos o modificados, para subirlos a una librería documental en Sharepoint 2010.

Es algo parecido a una sincronización ... pero unidireccional (del Pc a Sharepoint 2010)

He usado el Client Runtime de Sharepoint 2010 para una correcta implementación.


Copia de Forma automática los ficheros depositados en una carpeta windows a una Librería de documentos en Sharepoint 2010.

Se han combinado un servicio windows FileSystemWatcher (se incluye instalador) con las rutinas necesarias para copiar ficheros (binarios) a una Libreria de documentos en sharepoint 2010.

Lo que conseguimos es subir y actualizar ficheros de una manera mas comoda.

Los usos que yo le he dado:

  • Subida de ficheros escaneados de forma automática.
  • Interface con un Ftp al usar la misma carpeta.

En la carpeta donde se instala la dll (con el proyecto de instalación) hay un fichero app.config

<?xml version="1.0"?><configuration><startup><supportedRuntime version="v2.0.50727"/></startup><appSettings><add key="RutaCopiado" value="C:\FolderToSharepointCopier\RutaCopiado"/><add key="RutaSharepoint" value="http://servidor/LibreriaDocumentos/"/> </appSettings></configuration
 
En este fichero se definen las carpetas de origen y destino (por defecto sobreescribe)
Al instalar te pide un usuario de dominio (que tiene que tener permiso en Moss2010) con el que se copian los ficheros.



Espero que os resulte educativo y útil.
Roberto Marcos.

martes, 19 de junio de 2012

Actualizar el InfoPath de edición de ListItems en Sharepoint 2010

Cuando customizamos los formularios de alta y modificacion de un listItem una de las opciones mas cómodas es hacerlo usando Infopath 2010.

Todo es muy bonito al desarrollarlo y ponerlo en un entorno de pruebas, cuando lo ponemos en producción es fácil, hacemos un paquete STP de la lista customizada, desplegamos y listo, tenemos una lista Vacia preparada para comenzar a recoger elementos a traves del Infopath.

Los problemas aparecen cuando tras ponerlo en producción ... pasa el tiempo y claro ahora la lista esta repleta de datos, entonces es cuando las modificaciones se convierten en un "dolor" ya que no podemos borrarla y desplegar de nuevo el STP actualizado.

A simple vista y desde Infopath no se puede modificar la URL de la lista a la que esta modificando los formularios de  View y Edit
Un usuario avispado puede rebuscar un poco en el apartado conexiones de datos, pero sin éxito ya que todo apunta a que por aquí tendría que estar la cosa, pero va a ser que no.

Problema:
Sustituir/Actualizar el formulario de edición de List Items de una lista customizada con Infopath 2010.

Solución:
1º Si hemos creado campos nuevos en Desarrollo los creamos también en producción.
2º Abrimos 2 Sharepoint designer uno contra Desarrollo y otra contra Producción. 
3º Mediante Sharepoint Designer 2010 podemos acceder a la lista en cuestión en ambos entornos.
4º Abrimos la carpeta "Item" en la que podemos ver un fichero llamado template.xsn
5º Con hacer un COPY-PASTE de este fichero desde Desarrollo a Produccion y ya esta todo listo.


Solución Pro:
Creamos un modulo de aprovisionamiento que despliegue (y reemplace) el fichero en cuestión con nuestro paquete WSP
Recuerda marcarlo con GhostableInLibrary para evitar problemas.
image
Si hay que crear campos nuevos... en el feature activate es donde tendríamos que hacerlo.


Nota:
Los infopath tienen una importante limitación cuando los usamos para customizar listas...no pueden usar grupos (o parent child con otras listas) a grandes rasgos solo pueden crear/editar elementos en una sola lista a la vez.

Mis Agradecimientos a Lynton Titus que me ilustró en este tema.
Esperamos que os sea de ayuda.


jueves, 1 de marzo de 2012

Publicar de forma externa Infopath 2010 Forms Services con un Proxy Inverso (TMG)

Problema:
Publicar en internet correctamente los Form Services de Infopath 2010 a través de https y el TMG usando la funcionalidad de proxy inverso.

Análisis:
Tras analizar las peticiones que hace un ordenador externo a la red, hemos podido observar que el Explorador hace llamadas a la URL interna a pesar que hemos dado de alta la URL externa como Ruta alternativa de Sharepoint.

Solución:
Tirando del hilo hemos encontrado documentación precisa de cómo hay que hacerlo correctamente ya que el producto tiene algunas salvedades como que Infopath hace envió (postback) SIEMPRE a la dirección interna principal (http://direccioninterna.miservidor.com) de forma que no existe manera de que infopath atienda por 2 urls, por lo que la única vía es usar la funcionalidad  de "link translation" del TMG.

Reeplazos de URL que hay que añadir en la parte de link translation (sin las comillas):

"direccioninterna.miservidor.com" >> "direccionexterna.midominioexterno.com"
"http:" >> "https:"

Nota: No incluir el http en las urls, y el reemplado http tiene los dos puntos ":" de forma intencionada para que no ocurra reemplazos tipo https>>httpss que serian erróneos .

No olvidarse de incluir la ruta de acceso alternativa configurada como "Internet" en la administración central.

La documentación paso a paso de cómo hacer esta configuración en el TMG la tenemos en este link http://technet.microsoft.com/en-us/library/cc984424.aspx


lunes, 20 de febrero de 2012

Ocultar el mensaje en PeopleSearchResultWebpart : No hay resultados disponibles...

Problema:
Si no se especifica ninguna consulta el People Search Core Result Webpart muestra el mensaje...

En Inglés 
"No results are available. Either no query is specified, or the query came from advanced search (Federated Webparts do not support Advanced Search queries)."

En Español
"No hay resultados disponibles. O bien no se especificó ninguna consulta o la consulta provino de una búsqueda avanzada (los elementos web federados no son compatibles con las consultas de búsqueda avanzada)."

Pensé que podría ocultarlo cambiando el literal de $NoPeopleResults por XSLT pero por desgracia no se trata de este literal, es el literal de error por no especificar consulta y no podemos cambiarlo facilmente.

"Solución":
Crear un editor de contenido en la pagina, entrar en el editor html y pegar este Script.
No olvides configurar el webpart para que no muestre el titulo.
No es que sea una maravilla de solución pero... funciona.
He usado el selector con el modificador de inicio del literal (^) ya que el ID del elemento DIV tiene un GUID cambia en cada webpart.

<script type="text/javascript">
$(document).ready(function() { $('div[id^="SRW_Error"]').hide(); })
</script>


Nota: Requiere tener una referencia al fichero javascript de Jquery 

martes, 31 de enero de 2012

Extraer información de Perfiles de usuario de Sharepoint 2010

Podemos extraer toda la información que deseemos de la base de datos de perfiles de sharepoint.

Como nuestros amigos de Microsoft lo llaman "sincronización de perfiles" cuando realmente es un volcado de datos, a veces se queda mucha basura y perfiles con sitios creados, que son difíciles de localizar para eliminarlos.


Aunque también podemos crear las que necesitemos y obtenerlas como muestro en el script de ejemplo.

Con este script powershell podemos hacer la tarea de buscar basura y poner orden un poco mas facil.

TRUCO1: Podemos hacer un backup alternativo en excel de las propiedades de los perfiles, con este sistema (descomentar la parte final)
TRUCO2: Con otro Powershell podriamos cargar la información desde un Excel, en lugar de usar el pesado proceso de sicronización.

# List All User Profiles - SharePoint 2010- PowerShell Script (info@robertomarcos.com) 31-1-2012
#Add SharePoint PowerShell SnapIn if not already added
 if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}

function GetAllUserProfiles(){

#Get ServiceContext from associated site
$site = new-object Microsoft.SharePoint.SPSite("http://servidor_de_ejemplo");
$ServiceContext = [Microsoft.SharePoint.SPServiceContext]::GetContext($site);  

#Get UserProfileManager from the My Site Host Site context
$ProfileManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServiceContext)
$AllProfiles = $ProfileManager.GetEnumerator()  

#foreach($profile in $AllProfiles|Where-Object { $_.[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value  -match "el filtro que quieras"})
foreach($profile in $AllProfiles)
{
    $DisplayName = $profile.DisplayName
    $AccountName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value  
    $Firstname = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::FirstName].Value  
    $Lastname = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::LastName].Value  
    $JobTitle=$profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::JobTitle].Value  
    $Title=$profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::Title].Value  
    $PictureUrl=$profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::PictureUrl].Value 
    $Office=$profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::Office].Value 
    $WorkPhone=$profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::WorkPhone].Value 
    $WorkEmail=$profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::WorkEmail].Value 
    $Departamento=$profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::Department].Value;
    $MiCampoPersonalizado=$profile["MiCampoPersonalizado"].Value 
     
    
    #$User = $ProfileManager.GetUserProfile();
$data = @{
        "DisplayName"=$DisplayName;
"AccountName"=$AccountName;     
        "FirstName"=$Firstname;
        "Lastname"=$Lastname;
        "JobTitle"=$JobTitle;
        "Puesto"=$Title;
        "PictureUrl"=$PictureUrl;
        "Office"=$Office;
        "WorkPhone"=$WorkPhone;
        "WorkEmail"=$WorkEmail;
"Departamento"=$Departamento;
"MiCampoPersonalizado"=$MiCampoPersonalizado;
        
}
New-Object PSObject -Property $data   
write-Host  "Listando usuario..  $AccountName"
}
write-host "Finalizado."
$site.Dispose()
 
 }

#$csvFilePath = "C:\PerfilesDeUsuario.csv"
#GetAllUserProfiles| Export-Csv -NoTypeInformation -Path $csvFilePath

GetAllUserProfiles | Out-GridView

viernes, 18 de noviembre de 2011

Error Soap al Editar Paginas con Sharepoint Designer 2010

Escenario del Error:
Abrimos Sharepoint designer 2010, y al intentar Editar una pagina nos aparece el error

En Español : "soap:Server El servidor no puede procesar la solicitud. ---> El valor no está dentro del intervalo esperado."
En Inglés: "soap:Server Server was unable to process request. ---> Value does not fall within the expected range."

Causa:
Nos estamos conectando usando la IP de la maquina, la palabra Localhost y cualquier DNS no registrado como ruta de acceso alternativa dentro de sharepoint.

Solución:
Conectarse usando el nombre de la maquina.




viernes, 11 de noviembre de 2011

Modificar el limite de registros (Throttle) en BCS

Problema:
Un BCS recupera demasiados datos y nos arroja un error de correlación, tras rastrearlo, vemos que hay problemas de timeout y nos recomienda el uso de Get-SPBusinessDataCatalogThrottleConfig

Hay que modificar el parametro Scope según donde se conecte el BCS, pueden ser Wcf, WebService, Database,Global o Custom.

Solución para WCF, los ponemos al maximo:

#Define el Proxy BCS
$bdcAppProxy = Get-SPServiceApplicationProxy | where {$_ -match "Business Data *"}

#Modifica el numero maximo de bytes
$throttleWCF = Get-SPBusinessDataCatalogThrottleConfig -Scope WCF -ThrottleType Size -ServiceApplicationProxy $bdcAppProxy
Set-SPBusinessDataCatalogThrottleConfig -Identity $throttleWCF -maximum 2147483647 -default 2147483647
$throttleWCF

#Modifica el tiempo maximo de la petición
$throttleWCF = Get-SPBusinessDataCatalogThrottleConfig -Scope WCF -ThrottleType Timeout -ServiceApplicationProxy $bdcAppProxy
Set-SPBusinessDataCatalogThrottleConfig -Identity $throttleWCF -maximum 2147483647 -default 2147483647
$throttleWCF

Encontrar el Error mensaje de error con el Correlation Id sin meterse en el barro de los logs de Sharepoint 2010

Cuando Sharepoint 2010 nos da un mensaje error y nos proporciona un Correlation ID para localizar el mensaje podemos sacarlo de forma sencilla con powershell.

image

Este es el comando que hay que lanzar en el Shell de Administracion de sharepoint.
get-splogevent | ?{$_.Correlation -eq "<GUID>"} | select Area, Category, Level, EventID, Message | Format-List

image

jueves, 9 de junio de 2011

El webpart ListingSummary no migra correctamente a Sharepoint 2010 (SOLUCION)

Problema:
Al realizar una migración a sharepoint 2010, si en algun sitio se ha usado el webpart de ListingSummary, este aparece como ErrorWebPart.

Causas:
Parece que a los chicos de microsoft se les ha pasado efectuar una operacion de transformación
para migrar correctamente este webpart


WorkAround:
Podemos ver la documentación de microsoft acerca del ListingSummary en esta página
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.portal.webcontrols.listingsummary_members(v=office.12).aspx

Este webpart nos permite usar ficheros externos XSLT para mostrar los datos con formato. Es posible que haya que reconfigurarlo pero es muy sencillo.


Si investigamos un poco, nos damos cuenta que no es posible que hayan BORRADO sin más este webpart, ya que en 2010 no aparece.... al menos donde estaba.
Lo que ha ocurrido es que lo han movido de namespace , le han cambiado el nombre y le han hecho unas mejoras (tiene mas parametros)
Podemos ver la documentación del ContentByQueryWebPart en esta página
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.publishing.webcontrols.contentbyquerywebpart_members.aspx



Solucion 1:
-Elimiar el ErrorWebpart

- Añadir el ContentByQueryWebPart y configurarlo a mano (hay que copiar la configuración antes de migrar)

Nota: Al configurarlo algunas propiedades nuevas son obligatorias.


Solucion2:

-Exportar el webpart como fichero ".webpart" (se hace desde la edicion de la pagina)

-Migrar a 2010

-Modificar a mano el fichero ".webpart"

Sustituir:

type name="Microsoft.SharePoint.Portal.WebControls.ListingSummary, Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

Por esto:

type name="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart, Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

-Verificar que las nuevas propiedades obligatorias tienen valor.

-Importar a 2010 el fichero ".Webpart"

Cuidado:
Al realizar una migración InPlace, aparece el ErrorWebpart y pierdes la configuración que tenia, apuntadla para tenerla a mano.


Saludos Espero que os sirva de ayuda.

Roberto Marcos.