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