Advertisement
goosegle

Untitled

Oct 2nd, 2020
361
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <#
  2. .Synopsis
  3. Use Copy-SharepointLibrary para copiar una biblioteca de documentos a disco.
  4.  
  5. .Description
  6. Este script itera recursivamente sobre todos los directorios y ficheros de una biblioteca de documentos
  7. de Sharepoint 2010 y escribe los datos a disco. La estructura se mantiene igual que en la biblioteca de
  8. documentos.
  9. Se puede indicar únicamente que se exporte una carpeta de la biblioteca de documentos.
  10. El proceso registrará su actividad en un archivo de log (o en consola, según el valor de la variable
  11. LogToConsole).
  12.  
  13. .Parameter Url
  14. Especifica el sitio web de Sharepoint que contiene la biblioteca de documentos.
  15.  
  16. .Parameter LibraryName
  17. Especifica el nombre de la biblioteca de documentos.
  18.  
  19. .Parameter Path
  20. Especifica la ruta en la que se replicará el contenido de la biblioteca de documentos.
  21.  
  22. .Parameter RemoteFolder
  23. Especifica la carpeta remota a partir de la cual extraer los ficheros de la biblioteca de documentos. El
  24. valor indicado debe comenzar con el nombre de la biblioteca, no su título.
  25.  
  26. .Parameter Security
  27. Indica si se deben replicar los permisos de los elementos copiados.
  28.  
  29. .Example
  30. PS> .\Copy-SharepointLibrary.ps1 -Url "http://spWeb" -LibraryName "Documentos" -Path "\\repositorio\documentos" -RemoteFile "Documents/carpeta1"
  31.  
  32. .Notes
  33. Autor:       Gustavo Carou <gcarou@minsait.com>
  34. Actualizado: 2020-10-01
  35. #>
  36. [CmdletBinding()]
  37. param(
  38.     [Parameter(Mandatory=$true)][string] $Url,
  39.     [Parameter(Mandatory=$true)][string] $LibraryName,
  40.     [Parameter(Mandatory=$true)][string] $Path,
  41.     [Parameter(Mandatory=$false)][string] $RemoteFolder,
  42.     [bool] $Security = $true
  43. )
  44.  
  45. # Definición de variables y constantes -------------------------------------------------------------
  46. # Constantes y variables para logs
  47. Set-Variable -Name LogLevelDebug -Option Constant -Value 4
  48. Set-Variable -Name LogLevelInfo -Option Constant -Value 3
  49. Set-Variable -Name LogLevelWarn -Option Constant -Value 2
  50. Set-Variable -Name LogLevelError -Option Constant -Value 1
  51. Set-Variable -Name LogLevelFatal -Option Constant -Value 0
  52. # Establece el nivel de mensajes a mostrar
  53. Set-Variable -Name LogLevel -Option ReadOnly -Value $LogLevelDebug
  54. # Si es true, solo escribe en consola
  55. Set-Variable -Name LogToConsole -Option ReadOnly -Value $false
  56.  
  57. Set-Variable -Name NoOpExitCode -Option Constant -Value -1
  58. Set-Variable -Name ScriptName -Option ReadOnly -Value $MyInvocation.MyCommand.Name
  59.  
  60. # Variables de progreso
  61. $global:contador = 0
  62. $global:total = 0
  63.  
  64. # Funciones ----------------------------------------------------------------------------------------
  65. function Get-ColorMessage {
  66. <#
  67. .Description
  68. Obtiene el color de texto para el nivel de mensaje
  69. #>
  70.     param(
  71.         # Clasificador del mensaje
  72.         [string] $Level
  73.         )
  74.     switch ($Level) {
  75.         "INFO" { return "White" }
  76.         "WARN" { return "Blue" }
  77.         "ERROR" { return "Yellow" }
  78.         "FATAL" { return "Red" }
  79.         "DEBUG" { return "Gray" }
  80.         Default { return "White" }
  81.     }
  82. }
  83.  
  84. function Get-LogLevel {
  85. <#
  86. .Description
  87. Devuelve la prioridad que corresponde con el nivel de log
  88. #>
  89.     param(
  90.         # Clasificador del mensaje
  91.         [string] $Level)
  92.  
  93.     switch ($Level) {
  94.         "INFO" { return $LogLevelInfo }
  95.         "WARN" { return $LogLevelWarn }
  96.         "ERROR" { return $LogLevelError }
  97.         "FATAL" { return $LogLevelFatal }
  98.         "DEBUG" { return $LogLevelDebug }
  99.         Default { return $LogLevelInfo }
  100.     }
  101. }
  102.  
  103. function Get-Log {
  104. <#
  105. .Description
  106. Devuelve el nombre del fichero de log
  107. #>
  108.     $fileName = "export-" + (Get-Date).ToString("yyyyMMdd") + ".log"
  109.     return Join-Path $PWD.Path $fileName
  110. }
  111. function Write-Log {
  112. <#
  113. .Description
  114. Escribe un mensaje en pantalla o en el fichero de log dependiendo de la salida elegida,
  115. siempre y cuando el clasificador del mensaje tenga una prioridad igual o mayor que la
  116. establecida en la variable LogLevel
  117. #>
  118.     param(
  119.         [Parameter(Mandatory = $false)]
  120.         [ValidateSet("INFO", "WARN", "ERROR", "FATAL", "DEBUG")]
  121.         [string]
  122.         # Clasificador del mensaje
  123.         $Level = "INFO",
  124.  
  125.         [Parameter(Mandatory = $true)]
  126.         [string]
  127.         # Mensaje que se añadirá a la traza
  128.         $Message
  129.     )
  130.  
  131.     $messageLevel = Get-LogLevel $Level
  132.  
  133.     $stamp = (Get-Date).ToString("HH:mm:ss.fff")
  134.     $line = "$stamp $Level $Message"
  135.  
  136.     # Sólo se escriben en fichero los mensajes con prioridad igual o mayor que la establecida por $LogLevel
  137.     if($LogLevel -lt $messageLevel) {
  138.         return
  139.     }
  140.  
  141.     if($LogToConsole) {
  142.         $color = Get-ColorMessage -Level $Level
  143.         Write-Host $line -ForegroundColor $color
  144.     }
  145.     else {
  146.         $logFile = Get-Log
  147.         if($logFile) {
  148.             try {
  149.                 Add-Content $logFile -Value $line                
  150.             }
  151.             catch {
  152.                 Write-Host $line
  153.                 Write-Host -ForegroundColor Red "Error al escribir en log: " + $_
  154.             }
  155.         }
  156.         # Los mensajes que no son de depuración, se muestran en pantalla.
  157.         if($messageLevel -lt $LogLevelDebug) {
  158.             $color = Get-ColorMessage -Level $Level
  159.             Write-Host "$stamp $Message" -ForegroundColor $color
  160.         }
  161.     }
  162. }
  163.  
  164. function Contar {
  165. <#
  166. .Description
  167. Cuenta los ficheros que se exportarán
  168. #>
  169.     param([Microsoft.SharePoint.SPFolder] $Folder)
  170.     if($Folder.Name -eq "Forms") {
  171.         return
  172.     }
  173.     $global:total += $Folder.Files.Count
  174.     if($Folder.SubFolders) {
  175.         $Folder.SubFolders | ForEach-Object { Contar $_ }
  176.     }
  177. }
  178.  
  179. function Progress {
  180. <#
  181. .Description
  182. Actualiza la barra de progreso del proceso de exportación
  183. #>
  184.     param([string] $Path)
  185.     $global:contador++
  186.     $porcentaje = $global:contador / $global:total * 100
  187.     Write-Progress -Activity "Exportando documentos de $Library" -Status $Path -PercentComplete $porcentaje
  188.     if($porcentaje -gt 0 -and $porcentaje % 10 -eq 0) {
  189.         Write-Log -Level "INFO" -Message "$global:contador de $global:total archivos exportados"
  190.     }
  191. }
  192.  
  193. function TrimFolder {
  194. <#
  195. .Description
  196. Quita el \ final de una ruta
  197. #>
  198.     param([string] $Path)
  199.  
  200.     if ($Path.EndsWith("\")) {
  201.         $Path = $Path.Substring(0, ($Path.Length - 1))
  202.     }
  203.  
  204.     return $Path
  205. }
  206.  
  207. function EnsureFolder {
  208. <#
  209. .Description
  210. La función se asegura de que la ruta exista en el sistema de ficheros
  211. #>
  212.     param([string] $Path)
  213.  
  214.     if(Test-Path $Path) {
  215.         return
  216.     }
  217.  
  218.     try {
  219.         New-Item -Path $Path -ItemType Directory
  220.         Write-Log -Level "DEBUG" -Message "Nueva carpeta: $Path"
  221.     }
  222.     catch {
  223.         Write-Log -Level "FATAL" -Message "No se ha podido crear la ruta $Path"
  224.         exit $NoOpExitCode
  225.     }
  226. }
  227.  
  228. function SaveFile {
  229. <#
  230. .Description
  231. Guarda un fichero en el sistema de ficheros
  232. #>
  233.     param (
  234.         # Objeto fichero que se guardará
  235.         $File,
  236.         # Ruta en la que se guardará el fichero
  237.         [string] $Path
  238.     )
  239.     $filePath = Join-Path $Path $File.Name
  240.     try {
  241.         $binary = $File.OpenBinary()
  242.         [System.IO.File]::WriteAllBytes($filePath, $binary)
  243.         Progress -Path $filePath
  244.     }
  245.     catch {
  246.         Write-Log -Level "INFO" -Message "Error al copiar $filePath"
  247.         Write-Log -Level "ERROR" -Message $Error[0]
  248.     }
  249. }
  250.  
  251. function ExportFiles {
  252. <#
  253. .Description
  254. Exporta los ficheros de una carpeta de una biblioteca de documentos de forma recursiva
  255. recreando la estructura de directorios en el sistema de ficheros
  256. #>
  257.     param(
  258.         # Sitio web que contiene la carpeta a exportar
  259.         [Microsoft.SharePoint.SPWeb] $Site,
  260.         # Carpeta a exportar
  261.         [Microsoft.SharePoint.SPFolder] $Folder
  262.     )
  263.  
  264.     $files = $Folder.Files
  265.     if($files) {
  266.         foreach ($file in $files) {
  267.             $destination = Join-Path $Path $Folder.Url
  268.             EnsureFolder -Path $destination
  269.             SaveFile -Path $destination -File $file
  270.         }
  271.     }
  272.  
  273.     $subFolders = $Folder.SubFolders | Where-Object { $_.Name -ne "Forms" }
  274.     if($subFolders) {
  275.         foreach ($subFolder in $subFolders) {
  276.             ExportFiles -Site $Site -Folder $subFolder
  277.         }
  278.     }
  279. }
  280.  
  281. function Get-InitialFolder {
  282. <#
  283. .Description
  284. Obtiene el objeto SPFolder que se corresponde con la url de la carpeta indicada.
  285. #>
  286.     param(
  287.         # Carpeta desde la que buscar
  288.         [Microsoft.Sharepoint.SPFolder] $Parent,
  289.         # URL de la carpeta
  290.         [string] $FolderUrl
  291.     )
  292.     [Microsoft.SharePoint.SPFolder] $result = $null
  293.    
  294.     if($Parent.Url -eq $FolderUrl) {
  295.         return $Parent
  296.     }
  297.    
  298.     $childFolder = $Parent.SubFolders | Where-Object { $FolderUrl.StartsWith($_.Url) } | Select-Object -first 1
  299.    
  300.     if($null -eq $childFolder) {
  301.         return $null
  302.     }
  303.    
  304.     return Get-InitialFolder -Parent $childFolder -FolderUrl $FolderUrl
  305. }
  306.  
  307. function Get-Permissions {
  308.     # TODO: Obtener los permisos efectivos sobre un fichero de la librería de documentos.
  309. }
  310.  
  311. function Set-Permissions {
  312.     # TODO: Establecer los permisos equivalentes en el sistema de ficheros para el fichero copiado.
  313. }
  314.  
  315. # Inicio de ejecución -----------------------------------------------------------------
  316. $snapin = (Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue)
  317. if($null -eq $snapin)
  318. {
  319.     Write-Host -ForegroundColor Gray "No se ha encontrado el snap-in de SharePoint... Cargando ahora"
  320.     Add-PSSnapin Microsoft.SharePoint.PowerShell
  321. }
  322.  
  323. if ([string]::IsNullOrEmpty($Url) -or [string]::IsNullOrEmpty($LibraryName) -or [string]::IsNullOrEmpty($Path)) {
  324.     $script = Join-Path $PWD $MyInvocation.MyCommand.Name
  325.     Get-Help $script -Detailed
  326.     exit $NoOpExitCode
  327. }
  328.  
  329. #Habilita los mensajes de depuración (en objetos de terceros)
  330. #$DebugPreference = "Continue"
  331.  
  332. Write-Log -Level "DEBUG" -Message "`r`nSitio: $Url`r`nBiblioteca: $LibraryName`r`nDestino: $Path`r`nCarpeta remota: $RemoteFolder"
  333.  
  334. $Path = TrimFolder -Path $Path
  335. EnsureFolder -Path $Path
  336.  
  337. try {
  338.     [Microsoft.SharePoint.SPSite] $Site = Get-SPSite -Identity $Url
  339.     [Microsoft.SharePoint.SPWeb] $Web = Get-SPWeb $Url
  340.     [Microsoft.SharePoint.SPList] $Library = $null
  341.         [Microsoft.SharePoint.SPFolder] $initialFolder = $null
  342.     if($Web) {
  343.         $Library = $Web.Lists | Where-Object {$_.Title -eq $LibraryName} | Select-Object -first 1
  344.     }
  345.     else {
  346.         Write-Log -Level "FATAL" -Message "No se ha podido acceder a la web"
  347.         exit $NoOpExitCode
  348.     }
  349.  
  350.     if($Library) {
  351.         Write-Log -Level "DEBUG" -Message $Library.RootFolder.Url
  352.     }
  353.     else {
  354.         Write-Log -Level "FATAL" -Message "No se ha encontrado la librería"
  355.         exit $NoOpExitCode
  356.     }
  357.  
  358.     if([string]::IsNullOrEmpty($RemoteFolder)) {
  359.         # Si no se indica una carpeta remota, se exporta desde la raíz de la biblioteca.
  360.         $initialFolder = $Library.RootFolder
  361.     }
  362.     else {
  363.         $initialFolder = Get-InitialFolder -Parent $Library.RootFolder -FolderUrl $RemoteFolder
  364.         if($null -eq $initialFolder) {
  365.             Write-Log -Level "FATAL" -Message "No se ha encontrado la carpeta $RemoteFolder. Recuerde que la ruta debe comenzar con el nombre de la biblioteca (no su título)."
  366.             exit $NoOpExitCode
  367.         }
  368.     }
  369.        
  370.     Write-Log -Level "INFO" -Message "Contando ficheros, por favor espere..."
  371.     Contar $initialFolder
  372.     Write-Log -Level "INFO" -Message "$global:total ficheros a exportar."
  373.    
  374.     if($global:total -gt 0) {
  375.         ExportFiles -Site $Web -Folder $initialFolder
  376.     }
  377. }
  378. catch {
  379.     Write-Log -Level "FATAL" -Message $Error[0]
  380. }
  381. finally {
  382.     if($Web) {
  383.         $Web.Dispose()
  384.     }
  385.    
  386.     if($Site) {
  387.         $Site.Dispose()
  388.     }
  389. }
  390.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement