sábado, 30 de enero de 2016

Script para listar cantidad de elementos en todas las listas y bibliotecas de todas las colecciones de sitios

En esta ocasión vamos a contar el total de elemntos de cada lista y biblioteca de SharePoint.  Para identificar si es una biblioteca u otra lista utilizamos la propiead BaseTemplate.
Para comprender mejor el Script es bueno repasar la arquitectura del Modelo de Objectos de Servidor de SharePoint. A través de la siguiente imagen:

En resumen el objeto SPWebApplication contiene uno o mas objectos SPSite que representa cada colección de sitios y dentro de cada colección de sitios accedemos uno o mas sub-sitios o sitios web con el objeto SPWeb. Dentro de cada SPWeb podemos acceder las listas y/o bibliotecas con el objeto SPList.  y por ultimo aunque no lo utilicemos en este script el objeto SPListItem que representa cada elemento del objeto SPList.
Ahora vamos a describir el contenido del script que nos generará el listado del total de elementos de cada lista.
--- Inicio del Archivo ListAllListElements.ps1 ----
#Obtenemos la aplicación Web
$spWebApp = get-SPWebApplication http://misitio
#Declaramos el nombre del archivo CSV donde guararemos la información
$OutputFile ="d:\infoware\totaldocumentos.csv"
#Escribimos el encabezado del contenido del archivo csv
Add-Content $OutputFile "Titulo,Sitio,Url,Lista-Id,Lista,Tipo,Cantidad Elementos"
#Obtenemos todas las colecciones de sitios de la aplicación Web
$allSites = $spWebApp.Sites
foreach($site in $allSites)
{
    #Obtenemos todos los subisitos de la la colección de sitios actuales.
$webs = $site.AllWebs
    foreach($Web in $webs)
    {
        foreach($list in $Web.Lists)
        {
        #Establecemos el valor de la variable $row con la url, titulo del sitio y la información de la lista        $row = $web.URL+","+$web.Title + ","
        +$list.Id+","+$list.Title+","+$list.BaseTemplate+","+$list.Items.Count                       
        Add-Content $OutputFile $row
        }
    }
}
--- Fin del Archivo ListAllListElements.ps1 ----
Para ejecutar el script utilizamos Management Shell for SharePoint 2013:
c:\> .\ListAllListElements.ps1
El resultado será similar a la siguiente imagen:




SharePoint4fun Amigos!.
Hasta la próxima,
Juan Manuel Herrera Ocheita

Script para obtener el espacio ocupado y la ultima modificación realizada a los documentospor sitio para SharePoint OnPremises

Estimar el espacio ocupado de un sitio no es algo fácil de obtener ya que cada estructura de sitio y de las listas y bibliotecas de SharePoint ocupan un espacio no determinado del todo.  Lo que mejor podemos hacer es sumar el espacio de los archivos almacenados en las bibliotecas de SharePoint.
Resultado de imagen para sharepoint powershell
Este script corre en SharePoint 2010 y estimo también en 2013.
A continuación veremos un script que recorre todos los sitios de una colección de sitios:
-----Inicio del script ListadoSitios.ps1 -----
$File = "D:\scripts\MiSitio-EspacioOcupado.CSV"
#Escribimos el encabezado en el archivoAdd-Content -Path $File  -Value "Titulo,Url,Size,LastDate"
#definimos la fecha más antigua para que tengamos un punto de comparación inicial la definimos global para que podamos obtener su valor fuera del método donde se asigna.
$global:LastDate = Get-Date
$global:LastDate = $global:LastDate.AddDays(-10000)

#Método que Obtiene el sitio primario y llama el método que obtenien los sub.sitios.
function GetWebSizes ($StartWeb)
{
    $web = Get-SPWeb $StartWeb
    GetSubWebSizes -Web $web
    $web.Dispose()    # Importante destruir el objeto SPWeb para liberar la memoria RAM
}

Cuando utilizar el Dispose en el siguiente enlace: https://blogs.technet.microsoft.com/stefan_gossner/2008/12/05/disposing-spweb-and-spsite-objects/

function GetSubWebSizes ($Web)
{

    #Inicializamos nuevamente la fecha de partida para comparación
    $global:LastDate = Get-Date
    $global:LastDate = $global:LastDate.AddDays(-10000)
    #Recorremos cada subsitio de forma recursiba
    foreach ($subweb in $Web.GetSubwebsForCurrentUser())
    {
        [long]$webtotal = 0
        #Recorremos cada carpeta del subistio para obtener el espacio ocupado
    foreach ($folder in $subweb.Folders)
        {
            $webtotal += GetFolderSize -Folder $folder
        }
    $content = $subweb.Url + "," + $subweb.Title + "," +  $webtotal + "," + $global:LastDate
    Add-Content -Path $File  -Value $content
        write-host $content

       #LLamada recursiva al mismo método
        GetSubWebSizes -Web $subweb
   
    }
}

function GetFolderSize ($Folder)
{
    [long]$folderSize = 0 
    foreach ($file in $Folder.Files)
    {

    #Compara la fecha de la ultima modificación del archivo con la fecha de punto de partida y si es mas reciente la del archivo entonces la reemplaza
    if ($file.TimeLastModified -gt $global:LastDate){
        $global:LastDate = $file.TimeLastModified
    }
            #Acumula el valor de cada archivo en bytes
        $folderSize += $file.Length;
    }
    foreach ($fd in $Folder.SubFolders)
    {
        $folderSize += GetFolderSize -Folder $fd
    }
    return $folderSize
}

GetWebSizes -StartWeb HTTP://MiSharePoint
-----fin del script ListadoSitios.ps1 -----
Si necesitamos recorrer todas las colecciones de sitio solo hay que agregar las siguientes lineas de comando:
function GetWebSizes ($StartWeb)
{
$sites = Get-SPSite –StartWeb -Limit All
foreach($site in $Sites){
    $web = $site.RootWeb
    GetSubWebSizes -Web $web
    $web.Dispose()    # Importante destruir el objeto SPWeb para liberar la memoria RAM
}

}
Eso es todo amigos. SharePoint4Fun!,
Juan Manuel Herrera Ocheita

viernes, 29 de enero de 2016

Como migrar el contenido de un sitio de WordPress a las bibliotecas de SharePoint Online

La estrategia es muy sencilla y va ser la siguiente:
1) Descargar el contenido a un almacenamiento local a través de una herramienta FTP.
2) Definir una estrategia para almacenar el contenido en SharePoint Online
2) Crear un Script que lea el contenido migrado y suba los archivos a bibliotecas de SharePoint.
La herramienta
Describamos un poco la herramienta llamada FileZila.   Esta herramienta de FTP es gratuita y esta disponible para los sistemas operativos más populares.   Lo mas importante si estamos en un entrono Windows es que vamos a poder acceder el contenido de WordPress que esta en Linux.
El enlace para descargar la herramienta es el siguiente: https://filezilla-project.org/ 
Veamos ahora la conexión hacia el servicio ftp


La información que debes de solicitar para hacer la conexión es la siguiente:
Dirección IP del servidor Linux
Puerto (Opcional solo si el cliente utiliza un puerto en especifico diferente el predeterminado [21] colocarlo allí).
Luego Las credenciales un usuario con acceso y una contraseña.
Seleccionamos lo que deseamos descargar y con el clic derecho del ratón seleccionamos la opción Download.


La estrategia
Para la estrategia vamos a crear bibliotecas por cada carpeta principal ya que en SPO hay un límite de despliegue de documentos de 5,000 por razones de rendimiento.  Por lo que debemos de tomar eso en cuenta.








Para reducir el trabajo en el script vamos a crear manualmente las bibliotecas porque tampoco son muchas en mi este caso de lo contrario deberíamos tomar eso en cuenta en el script y crear con comandos de Powershell las bibliotecas.



El Script
A través de este script invocamos los comandos de CSOM Client SharePoint Object Model y no el Modelo de objetos de SharePoint.   Porque razón?, bueno porque SharePoint Online no esta local sino en la nube y la forma de acceder remotamente las librerias de SharePoint es através de CSOM que no es mas que llamadas de servicios Web por medio de un módelo de objetos definido para ese propósito.

Ahora vemos el script que hace la magia:
/* Cargamos las librerias de CSOM */
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

/* El método Ensure_Folder nos asegurará que la carpeta este creada antes de copiar el contenido */
Function Ensure-Folder()
{
Param(
  [Parameter(Mandatory=$True)]
  [Microsoft.SharePoint.Client.Web]$Web,

  [Parameter(Mandatory=$True)]
  [Microsoft.SharePoint.Client.Folder]$ParentFolder,

  [Parameter(Mandatory=$True)]
  [String]$FolderUrl

)
    $folderNames = $FolderUrl.Trim().Split("/",[System.StringSplitOptions]::RemoveEmptyEntries)
    $folderName = $folderNames[0]
    Write-Host "Creating folder [$folderName] ..."
    $curFolder = $ParentFolder.Folders.Add($folderName)
    $Web.Context.Load($curFolder)
    $web.Context.ExecuteQuery()
    Write-Host "Folder [$folderName] has been created succesfully. Url: $($curFolder.ServerRelativeUrl)"

    if ($folderNames.Length -gt 1)
    {
        $curFolderUrl = [System.String]::Join("/", $folderNames, 1, $folderNames.Length - 1)
        Ensure-Folder -Web $Web -ParentFolder $curFolder -FolderUrl $curFolderUrl
    }
}

/* El método Upload-File  recibe como parametros el url relativo de la carpeta destino y la ubicación local del archivo */
Function Upload-File()
{
Param(
  [Parameter(Mandatory=$True)]
  [Microsoft.SharePoint.Client.Web]$Web,

  [Parameter(Mandatory=$True)]
  [String]$FolderRelativeUrl,

  [Parameter(Mandatory=$True)]
  [System.IO.FileInfo]$LocalFile

)
    try {
     $folderUrl = $LocalFile.Name.ToLower().Replace($SourceFolderPath.ToLower(),"")
    
     $fileUrl = $FolderRelativeUrl + "/" + $folderUrl

       write-host "FileUrl:" $fileUrl
       Write-Host "Uploading file [$($LocalFile.FullName)] ..."
       [Microsoft.SharePoint.Client.File]::SaveBinaryDirect($Web.Context, $fileUrl, $LocalFile.OpenRead(), $true)
       Write-Host "File [$($LocalFile.FullName)] has been uploaded succesfully. Url: $fileUrl"
    }
    catch {
       write-host "An error occured while uploading file [$($LocalFile.FullName)]"
    }
}

/* El método Upload-Files es la principal ya que localiza cata archivo local y define la url destino para subir el archivo  a SPO.  Este método recibe como parameto la url destino, el usuario de O365, la contraeña, el nombre de la biblioteca de SharePoint destino, y la rutal local donde esta ubicado el contenido.  Como es recursivo solo debemos de dar el punto de partida de donde deseamos iniciar la carga de información. */

function Upload-Files()
{

Param(
  [Parameter(Mandatory=$True)]
  [String]$Url,

  [Parameter(Mandatory=$True)]
  [String]$UserName,

  [Parameter(Mandatory=$False)]
  [String]$Password,

  [Parameter(Mandatory=$True)]
  [String]$TargetListTitle,

  [Parameter(Mandatory=$True)]
  [String]$SourceFolderPath

)
    if($Password) {
       $SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
    }
    else {
      $SecurePassword = Read-Host -Prompt "Enter the password" -AsSecureString
    }

# Abajo la autenticación a O365 para acceder los objetos de SharePoint Online
    $Context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
    $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,$SecurePassword)
    $Context.Credentials = $Credentials
    #Instanciamos el Web Site que vamos acceder
    $web = $Context.Web
    $Context.Load($web)

    # Instanciamos la biblioteca destino
    $list = $web.Lists.GetByTitle($TargetListTitle);
    $Context.Load($list.RootFolder)

#Ejecutamos el conjunto de lineas anteriores
    $Context.ExecuteQuery()
#Recorremos cada directorio local del parametró de ruta origen que indicamos al ejecutar el método

    Get-ChildItem $SourceFolderPath -Recurse | % {
       if ($_.PSIsContainer -eq $True) {
          $folderUrl = $_.FullName.ToLower().Replace($SourceFolderPath.ToLower(),"")
          $folderUrl = $folderUrl.Replace("\","/").Replace(".","")  
          if($folderUrl) {
             Ensure-Folder -Web $web -ParentFolder $list.RootFolder -FolderUrl $folderUrl
          } 
       }
       else{

          # Basado en la ubicación local creamos un Url Relativo reciproco en la biblioteca de SPO
          $folderRelativeUrl = $list.RootFolder.ServerRelativeUrl + $_.DirectoryName.ToLower().Replace($SourceFolderPath.ToLower(),"").Replace("\","/").Replace(".","") 

          #Ejecutamos el métod que subira el archivo a la ruta destino
          Upload-File -Web $web -FolderRelativeUrl $folderRelativeUrl -LocalFile $_
       }
    }
}

#End of file
La ejecución
Para ejecutar el archivo uploadfiles-csom.ps1 deberemos declarar los siguientes parámetros:

$Url =
https://miempresa.sharepoint.com/sites/miSitio
$UserName = misuario@midominio.onmicrosoft.com
$Password = "******"
$TargetListTitle = "BibliotecaDestino"   #Target Library
$SourceFolderPath = "X:\www\data\uploads\CarpetaOrigen"  #Source Physical Path


#Comando
Upload-Files -Url $Url -UserName $UserName -Password $Password -TargetListTitle $TargetListTitle -SourceFolderPath $SourceFolderPath


Y eso es todo amigos.
Hasta la próxima, SharePoint4Fun!
Juan Manuel Herrera Ocheita

sábado, 26 de diciembre de 2015

Analizando como podemos consumir SharePoint OData con javascript

Pienso que es interesante las pruebas que realice para validar lo que me devuelve el servicio de Odata de SharePoint Online.

Cree una lista personalizada de SharePoint llamada Banners y adicione un par de columnas Url y Link.

Y el contenido es el siguiente: un solo elemento con una image y un enlace.


Si consumimos el servicio enviando la siguiente instrucción con jquery:
 
Lo que me devuelve al consumir json es lo siguiente:
{"odata.metadata":"https://infowareplus.sharepoint.com/sites/prueba/_api/$metadata#SP.ListData.BannersListItems"
,"value":[{"odata.type":"SP.Data.BannersListItem"
,"odata.id":"0589cb7b-2bb2-4ced-a7ea-704cd8e0dcea"
,"odata.etag":"\"4\""
,"odata.editLink":"Web/Lists(guid'2b6b9d83-4eeb-4716-86e4-5f6ee03a577e')/Items(1)"
,"FileSystemObjectType":0
,"Id":1
,"ContentTypeId":"0x01002C49C3B57506B541ABE2A829193FF712"
,"Title":"Noticias"
,"Imagen":{"Description":"Evento"
,"Url":"https://infowareplus.sharepoint.com/sites/prueba/SiteAssets/EventoMicrosoftAzureComunidadTecnica2.jpg"}
,"Link":{"Description":"Dirección de Prueba"
,"Url":"http://www.google.com"}
,"ID":1
,"Modified":"2015-12-14T19:54:56Z"
,"Created":"2015-12-10T20:47:48Z"
,"AuthorId":9
,"EditorId":9
,"OData__UIVersionString":"1.0"
,"Attachments":false
,"GUID":"f6a6e965-8f1a-436e-86c8-682e4f6368d5"}]}
Ahora observemos la siguiente prueba a tavés de javascript:





Create Object from JSON String













Lo que nos devuelve es lo siguiente:
{"odata.metadata":"https://infowareplus.sharepoint.com/sites/PRUEBA/_api/$metadata#SP.ListData.BannersListItems","value":[{"odata.type":"SP.Data.BannersListItem","odata.id":"0589cb7b-2bb2-4ced-a7ea-704cd8e0dcea","odata.etag":"'4'","odata.editLink":"Web/Lists(guid\'2b6b9d83-4eeb-4716-86e4-5f6ee03a577e\')/Items(1)","FileSystemObjectType":0,"Id":1,"ContentTypeId":"0x01002C49C3B57506B541ABE2A829193FF712","Title":"Noticias","Imagen":{"Description":"Evento","Url":"https://infowareplus.sharepoint.com/sites/prueba/SiteAssets/EventoMicrosoftAzureComunidadTecnica2.jpg"},"Link":{"Description":"Dirección de Prueba","Url":"http://www.google.com"},"ID":1,"Modified":"2015-12-14T19:54:56Z","Created":"2015-12-10T20:47:48Z","AuthorId":9,"EditorId":9,"OData__UIVersionString":"1.0","Attachments":false,"GUID":"f6a6e965-8f1a-436e-86c8-682e4f6368d5"}]}
Si accedemos  a la propiedad odata.detadata:
var obj = JSON.parse(text);
document.getElementById("demo2").innerHTML = obj["odata.metadata"];
Me retorna lo siguiente:
https://infowareplus.sharepoint.com/sites/prueba/_api/$metadata#SP.ListData.BannersListItems
Si accedemos la propiedad value obtendremos otro objeto de json que podemos acceder sus propiedades, de la siguiente forma:
var obj2 = obj["value"];
document.getElementById("demo3").innerHTML = obj2[0]["odata.type"];

Lo que nos retorna es lo siguiente:
SP.Data.BannersListItem
Asi podemos obtener otros atributos:
document.getElementById("demo4").innerHTML = obj2[0]["odata.id"];
document.getElementById("demo5").innerHTML = obj2[0]["odata.etag"];
document.getElementById("demo6").innerHTML = obj2[0]["odata.editLink"];
Lo que nos retorna es lo siguiente:
0589cb7b-2bb2-4ced-a7ea-704cd8e0dcea
'4'
Web/Lists(guid'2b6b9d83-4eeb-4716-86e4-5f6ee03a577e')/Items(1)
Y por ultimo vamos acceder la propiedad Imagen y Link de la siguiente forma:
var obj3 = obj2[0]["Imagen"];
document.getElementById("demo7").innerHTML = obj3["Url"];
var obj4 = obj2[0]["Link"];
document.getElementById("demo8").innerHTML = obj4["Url"];
Y los resultados serán las URL siguientes:
https://infowareplus.sharepoint.com/sites/PRUEBA/SiteAssets/EventoMicrosoftAzureComunidadTecnica2.jpg
http://www.google.com
Bueno como vemos podemos acceder con javascript la información que me devuelve el servicio OData de SharePoint, y como esta construído la estructura de datos de una lista Personalizada de SharePoint.  Para que observemos mejor la estructura lo mostraré de la siguiente forma:
'{
"odata.metadata":"https://infowareplus.sharepoint.com/sites/prueba/_api/$metadata#SP.ListData.BannersListItems"
,"value":[
     {"odata.type":"SP.Data.BannersListItem"
     ,"odata.id":"0589cb7b-2bb2-4ced-a7ea-704cd8e0dcea"
     ,"odata.etag":"\'4\'"
     ,"odata.editLink":"Web/Lists(guid\'2b6b9d83-4eeb-4716-86e4-5f6ee03a577e\')/Items(1)"
     ,"FileSystemObjectType":0
     ,"Id":1
     ,"ContentTypeId":"0x01002C49C3B57506B541ABE2A829193FF712"
     ,"Title":"Noticias"
     ,"Imagen":{"Description":"Evento","Url":"https://infowareplus.sharepoint.com/sites/prueba/SiteAssets/EventoMicrosoftAzureComunidadTecnica2.jpg"}
     ,"Link":{"Description":"Dirección de Prueba" ,"Url":"http://www.google.com"}
     ,"ID":1
     ,"Modified":"2015-12-14T19:54:56Z"
     ,"Created":"2015-12-10T20:47:48Z"
     ,"AuthorId":9
     ,"EditorId":9
     ,"OData__UIVersionString":"1.0"
     ,"Attachments":false
     ,"GUID":"f6a6e965-8f1a-436e-86c8-682e4f6368d5"}
     ]
}'
Espero que con eso los haya ayudado a comprender la estructura de las listas en SharePoint en formato JSON.
Hasta la próxma,
Juan Manuel Herrera Ocheita
 

P.D. utilice para las pruebas el siguiente enlace: http://www.w3schools.com/json/tryit.asp?filename=tryjson_parse .

miércoles, 9 de diciembre de 2015

Como descargar una solución de granja instalada en SharePoint 2010 y 2013

Cómo descargar una solución de granja instalada es un requerimiento muy usual cuando se esta migrando versiones de SharePoint, por ejemplo de 2010 a 2013.  O bien migrando de un conjunto de servidores a otros por temas de problemas con el existente.

image

Bueno antes de resolver el tema hablemos un poco de las soluciones de granja.  Estas son empacadas en paquetes con extensión WSP, aunque no son las únicas ya que las soluciones Sandbox, las plantillas de sitio y las famosas apps utilizan este formato de paquete para que puedan ser ejecutados desde SharePoint.  Estos paquetes no son mas que empacados que contiene un conjunto de documentos y archivos binarios que componen la solución de granja o Farm Solution.

Es esto posible si por medio de PowerShell podemos realizar esta tarea que en versiones 2007 era impensable.

$FolderPath = "c:\Solutions"

foreach ($solution in Get-SPSolution) 

    $id = $Solution.SolutionID 

    $title = $Solution.Name 

    $filename = $Solution.SolutionFile.Name 

    $solution.SolutionFile.SaveAs("$FolderPath\$filename") 

}

 

Si se migra el paquete de 2010 a 2013 y este no tiene depedencias que hayan variado en la versión 2013, puede intentar el siguiente comando luego de extraer el paquete wsp de la granja SharePoint 2010.

Install-SPSolution –Identity Solution.wsp –GACDeployment –CompatibilityLevel All e intenar ejecutar el sitio en modo 2010.

https://technet.microsoft.com/en-us/library/dn673579.aspx

viernes, 27 de noviembre de 2015

Script para saber el tamaño de una carpeta de una biblioteca en SharePoint 2010-2013

 

Esta solicitud me hicieron hace un momento y como no vi un ejemplo en especifico para esto decidi compartirlo con mis amigos lectores.

Los tres parametros que necesitamos son: url del sitio web en cuestion, el nombre de la biblioteca y el nombre de la carpeta.  Como se muestra abajo:

$urlWebSite = “http://hostname/siteurl/sub-siteurl

$nombreLibreria = "Nombre-Libreria"

$nombreCarpeta = "Nombre-Carpeta"

Luego debemos de obtener el objeto SPWeb para encontrar la bilioteca de la siguiente forma:

$web = get-SPWeb $urlWebSite

Una vez que lla obtuvimos el objeto SPWeb que representa el sitio web en SharePoint obtenemos la biblioteca con la colección Folders del objeto SPWeb, como se muestra a continuación:

$folder =  $web.Folders[$nombreLibreria]

Ahora que almacenamos en la variable $folder la bilbioteca en cuestion, necesitamos obtener la carpeta que buscamos a través de la colección SubFolerds del objeto SPFolder, de la siguiente forma:

$subfolder = $folder.SubFolders[$nombreCarpeta]

Con eso tenemos ya la ubicación deseada para iniciar el proceso de lectura de los bytes ocupados en la carpeta y sub carpetas, para ello necesitamos crear un funcion que llamemos de forma recursiva hasta que obtengamos el espacio total ocupado.

[long]$total = 0

$total = GetFolderSize($subfolder)

La función es la siguiente:

function GetFolderSize ($Folder)

{

    [long]$folderSize = 0 

    foreach ($file in $Folder.Files)

    {

        write-host "Nombre documento" $file.Name

        $folderSize += $file.Length;

        write-host "Total en bytes que va acumulando:" $folderSize

    }

    foreach ($fd in $Folder.SubFolders)

    {

        $folderSize += GetFolderSize -Folder $fd

    }

    return $folderSize

}

Lo que nos falta entonces es convertir los bytes en megas, y en gigas es es lo que hacemos a continuación:

$totalInMb = ($total/1024)/1024

$totalInMb = "{0:N2}" -f $totalInMb

$totalInGb = (($total/1024)/1024)/1024

$totalInGb = "{0:N2}" -f $totalInGb

write-host "Tamaño total de la carpeta" $StartWeb "es" $total " Bytes,"

write-host "son " $totalInMb "MB o " $totalInGb "GB"

Y ahora necesitamos indicarle a Windows que libere el recurso en memoria que ocupamos a través del objeto SPWeb la invocar el comando  $web = get-SPWeb $urlWebSite , y lo hacemos de la siguiente forma:

$web.Dispose()

Para poner todo en orden debemo de prepar un contenedor de este script en un archivo con extension .ps1, por ejemplo:

C:\>GetFolderSize.ps1

y debera contener el siguiente orden del código descripto arriba:

<!--- Begin of File –->

function GetFolderSize ($Folder)

{

    [long]$folderSize = 0 

    foreach ($file in $Folder.Files)

    {

        write-host "Nombre documento" $file.Name

        $folderSize += $file.Length;

        write-host "Total en bytes que va acumulando:" $folderSize

    }

    foreach ($fd in $Folder.SubFolders)

    {

        $folderSize += GetFolderSize -Folder $fd

    }

    return $folderSize

}

$urlWebSite = “http://hostname/siteurl/sub-siteurl

$nombreLibreria = "Nombre-Libreria"

$nombreCarpeta = "Nombre-Carpeta"

$web = get-SPWeb $urlWebSite

$folder =  $web.Folders[$nombreLibreria]

$subfolder = $folder.SubFolders[$nombreCarpeta]

$totalInMb = ($total/1024)/1024

$totalInMb = "{0:N2}" -f $totalInMb

$totalInGb = (($total/1024)/1024)/1024

$totalInGb = "{0:N2}" -f $totalInGb

write-host "Tamaño total de la carpeta" $StartWeb "es" $total " Bytes,"

write-host "son " $totalInMb "MB o " $totalInGb "GB"

$web.Dispose()

<!--- End of File –->

Y por ultimo utilizamo el Management Shell for SharePoint para ejecutar el script de la siguiente forma:

c:\>.\GetFolderSize.ps1

Eso es todo amigos.

SharePoint4Fun!,

Juan Manuel Herrera Ocheita

martes, 17 de noviembre de 2015

Autenticación Mixta en SharePoint 2013 no se lleva bien con las SharePonit Apps

image

El problema

Recientemente habilitamos para un cliente en Azure un SharePoint Foundatio 2013 con autenticación mixta, Windows y Azure AD.   Pero las apps no respondian adecuadamente, mostrandonos el error típico de las apps cuando no son correctamente configuradas. 

image

Al parecer cuando esta en modo mixto las apps no saben como resolver la autenticación.  Cuando retornabamos al Windows las apps comenzaron a funcionar correctamente.

image

Pensamos que el problema era la autenticación con los usuarios de AD de Azure, aunque nos parecia incorrecta esta apreciación.   Por lo que se nos ocurrió ahislar el problema y en vez de adicionar otro proveedor de autenticación a la aplicación Web existente lo que se nos occurió fue extender la aplicación Web.

Identity Providers dialog box in Azure

La Estrategía y solución

Extender la aplicación Web es una opción de SharePoint que lo que hace es hacer una copia del Web Site del IIS actual en otro Web Site y diferenciarlo por el nuevo nombre de la aplicación Web.  Si deseamos utilizar el puerto http es necesario utilizar un host header diferente.   Por lo que para este ejemplo utilizaremos el nombre extranet.midominio.com  para diferenciarlo de la zona predeterminada de la Aplicación Web, que diremos se llama portal.midominio.com.   Al momento de extenderla le indicamos que el proveedor de autenticación ya no era windows sino el Azure Provider la etiqueta que le pusimos al configurar al autenticación de Azure Active Directory.

Con eso nuestra sorpresa fue que las Apps empezaron a funcionar correctamente.  Ya que teniamos una entrada por autenticación Windows a través del url http://portal.midominio.com y para usuarios del Azure AD la dirección http://extranet.midominio.com

image

Enalces de referencia relacionados al tema:

Usar Active Directory de Microsoft Azure para autenticación de SharePoint 2013

https://technet.microsoft.com/es-es/library/dn635311.aspx

Extender las aplicaciones web basadas en notificaciones en SharePoint 2013

https://technet.microsoft.com/es-es/library/gg276325.aspx

Configuración de un entorno para aplicaciones de SharePoint (SharePoint 2013)

https://technet.microsoft.com/es-es/library/fp161236.aspx

En conclusión hasta hoy podré decir que la recomendación es no utilizar la autenticación mixta en SharePoint adicionando el proveedor de autenticación en la misma Aplicación Web, sino mejor extender la Aplicación Web con el siguiente método de autenticación.

Espero pueda salvarles el dia amigo lector.

SharePoint4Fun!,

Juan Manuel Herrera Ocheita