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.