viernes, 25 de febrero de 2011

Script PowerShell de Inventario de Granja, Pre-Migración Sharepoint 2010

Actualmente me encuentro realizando una migración de sharepoint 2007 a sharepoint 2010.
Los whitepapers y la documentación de Microsoft y terceros resultan muy utiles e ilustrativos, pero como siempre se queda un poco cortos cuando se trata de migrar contenido muy customizado con soluciones de terceros y un sin fin de cosas que siempre se quedan en el tintero o son difíciles de localizar.

En uno de los puntos del proceso oficial se hace alusión a Inventariar sitios y soluciones custom como si fuese un punto de nada.... en fin.
He preparado un script de powershell que nos resultara de utilidad para poder obtener una radiografía completa de la granja que nos facilite localizar los desarrollos customizados y en general todo lo que esta en uso o instalado

El script obtiene los datos por object model, y no usa los comandos modernos de Sharepoint2010 ya que en 2007 no están disponibles, por lo que funciona en todos los escenarios. :)

Lo que obtenemos es :
  • Granja
  • Sitios
  • Webs
  • Eventos de Web
  • Listas y Campos
  • Eventos de Lista
  • ContentTypes
  • Eventos de ContentType
  • CustomFields
  • Features
  • Modules
  • Soluciones WSP
  • Paginas por sitio con sus webparts y las AUDIENCIAS de cada uno de ellos.
  • Bases de datos de contenido
El resultado es un XML , suele ser bastante grande. Unos 50-70Mb pero depende de vuestra granja.
Para usarlo, hay que guardarlo como InventarioSP2007.PS1 e ir a un nodo del frontal y lanzarlo.
Aquí lo dejo :

===================================================================
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

#ROBERTO MARCOS 25-feb-2011 V1.1 sharepointworks.blogspot.com

$xmlFilePath = "C:\Inventario.xml"

$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local
$cul = New-Object System.Globalization.CultureInfo("ES-es")
$pscope= [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared

New-item $xmlFilePath -type file -force -value "<?xml version='1.0' encoding='utf-8'?>"

Add-Content $xmlFilePath "<MIGRACION>"
Add-Content $xmlFilePath ("<FARM name='{0}' ID='{1}' >" -f $farm.Name,$farm.ID);
foreach ($spService in $farm.Services) {
if (!($spService -is [Microsoft.SharePoint.Administration.SPWebService])) {
continue;
}
Add-Content $xmlFilePath ("<Solutions>")
foreach ($sol in $farm.Solutions)
{
Add-Content $xmlFilePath ("<Solution ID='{0}' Name='{1}' Parent='{2}'/>" -f $sol.solutionid ,$sol.displayname,$sol.Parent.Name )
}
Add-Content $xmlFilePath ("</Solutions>")
foreach ($webApp in $spService.WebApplications) {
#if ($webApp -is [Microsoft.SharePoint.Administration.SPAdministrationWebApplication]) { continue }
Add-Content $xmlFilePath ("<WebApplication name='{0}' CurrentSiteCount='{1}' >" -f $webApp.Name,$webApp.ID);#webApplication.CurrentSiteCount
Add-Content $xmlFilePath ("<ContentDatabases>")
foreach ($contentDB in $webApp.ContentDatabases)
{

$DBName = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("Name")
$DBID = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("ID")
$CurrentDBName = $DBName.GetValue($ContentDB, $null)
$CurrentDBID = $DBID.GetValue($ContentDB, $null)
Add-Content $xmlFilePath ("<ContentDatabase Name='{0}' ID='{1}'/>" -f $CurrentDBName,$CurrentDBID )
}
Add-Content $xmlFilePath ("</ContentDatabases>")
Add-Content $xmlFilePath ("<Sites>")
foreach ($site in $webApp.Sites)
{
Add-Content $xmlFilePath ("<Site PortalName='{0}' Url='{1}'>" -f $site.PortalName ,$site.Url )
##FEATURES SITE
Add-Content $xmlFilePath ("<Features>")
foreach ($feature in $site.Features)
{
if($feature.Definition -eq $null){
Add-Content $xmlFilePath ("<Feature Title='{0}' DefinitionId='{1}'/>" -f "MISSING",$feature.DefinitionId )
}
else
{
Add-Content $xmlFilePath ("<Feature Title='{0}' DefinitionId='{1}'/>" -f $feature.Definition.GetTitle($cul) ,$feature.DefinitionId )

}
}
Add-Content $xmlFilePath ("</Features>")
Add-Content $xmlFilePath ("<Webs>")
foreach ($web in $site.AllWebs)
{
Add-Content $xmlFilePath ("<Web Name='{0}' URL='{1}'>" -f $web.Name ,$web.Url )
Add-Content $xmlFilePath ("<FeaturesWeb>")
foreach ($featurew in $web.Features)
{
Add-Content $xmlFilePath ("<Feature Title='{0}' DefinitionId='{1}'/>" -f $featurew.Definition.GetTitle($cul) ,$featurew.DefinitionId )
}
Add-Content $xmlFilePath ("</FeaturesWeb>")
Add-Content $xmlFilePath ("<ContentTypes>")
foreach ($ct in $web.ContentTypes)
{
Add-Content $xmlFilePath ("<ContentType Name='{0}' ID='{1}'/>" -f $ct.Name ,$ct.ID )
}
Add-Content $xmlFilePath ("</ContentTypes>")
Add-Content $xmlFilePath ("<WebEventReceivers>")
foreach ($evt in $web.EventReceivers)
{
Add-Content $xmlFilePath ("<WebEventReceiver Name='{0}' Type='{1}' Assembly='{2}' Class='{3}' />" -f $evt.Name ,$evt.Type,$evt.Assembly, $evt.Class )
}
Add-Content $xmlFilePath ("</WebEventReceivers>")
Add-Content $xmlFilePath ("<Modules>")
foreach ($md in $web.Modules)
{
Add-Content $xmlFilePath ("<Module Name='{0}' Enabled='{1}' Url='{2}' />" -f $md.Name ,$md.Enabled,$md.Url)
}
Add-Content $xmlFilePath ("</Modules>")
Add-Content $xmlFilePath ("<Lists>")
foreach ($lst in $web.Lists)
{
Add-Content $xmlFilePath ("<List Title='{0}' Description='{1}' ItemCount='{2}' >" -f $lst.Title ,$lst.Description,$lst.ItemCount)
Add-Content $xmlFilePath ("<ContentTypes>")
foreach ($ctt in $lst.ContentTypes)
{
Add-Content $xmlFilePath ("<ContentType Name='{0}' ID='{1}'/>" -f $ctt.Name ,$ctt.ID )
}
Add-Content $xmlFilePath ("</ContentTypes>")
Add-Content $xmlFilePath ("<ListEventReceivers>")
foreach ($evtl in $lst.EventReceivers)
{
Add-Content $xmlFilePath ("<ListEventReceiver Name='{0}' Type='{1}' Assembly='{2}' Class='{3}' />" -f $evtl.Name ,$evtl.Type,$evtl.Assembly, $evtl.Class )
}
Add-Content $xmlFilePath ("</ListEventReceivers>")
Add-Content $xmlFilePath ("<Fields>")
$campos=$lst.Fields Where-Object{$_.Hidden -eq 0 }
foreach ($campo in $campos)
{
Add-Content $xmlFilePath ("<Field InternalName='{0}' Title='{1}' Description='{2}' FieldTypeDefinitionName='{3}' FieldTypeDefinitionDisplayName='{4}' FieldTypeDescription='{5}' FieldEditorUserControl='{6}' BaseRenderingTypeName='{7}' FieldTypeClass='{8}'/>" -f $campo.InternalName , $campo.Title ,$campo.Description , $campo.FieldTypeDefinition.TypeName,$campo.FieldTypeDefinition.TypeDisplayName ,$campo.FieldTypeDefinition.TypeShortDescription,$campo.FieldTypeDefinition.FieldEditorUserControl,$campo.FieldTypeDefinition.BaseRenderingTypeName,$campo.FieldTypeDefinition.FieldTypeClass )
}
Add-Content $xmlFilePath ("</Fields>")
# Views
# WorkflowAssociations
Add-Content $xmlFilePath ("<WorkflowAssociations>")
foreach ($wf in $lst.WorkflowAssociations)
{
Add-Content $xmlFilePath ("<WorkflowAssociation Name='{0}' ID='{1}' Description='{2}' />" -f $wf.Name ,$wf.ID,$wf.Description )
}
Add-Content $xmlFilePath ("</WorkflowAssociations>")
Add-Content $xmlFilePath ("</List>")
}
Add-Content $xmlFilePath ("</Lists>")
Add-Content $xmlFilePath ("<Paginas>")
$pages = $web.Files Where-Object {$_.Name -match ".aspx"}
foreach ($pag in $pages)
{
Add-Content $xmlFilePath ("<PaginaASPX Name='{0}' URL='{1}' Length='{2}' Title='{3}'>" -f $pag.Name ,$pag.ServerRelativeUrl,$pag.Length , $pag.Title )
if($pag -ne $null){
$webPartManager = $pag.GetLimitedWebPartManager([System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
if ($webPartManager.WebParts.Count -gt 0){
Add-Content $xmlFilePath ("<WebParts>")
foreach ($wp in $webPartManager.WebParts)
{
Add-Content $xmlFilePath ("<WebPart Title='{0}' Hidden='{1}' IsClosed='{2}' AuthorizationFilter='{3}' ID='{4}' UniqueID='{5}' Description='{6}'/>" -f $wp.DisplayTitle ,$wp.Hidden,$wp.IsClosed, $wp.AuthorizationFilter,$wp.ID,$wp.UniqueID,$wp.Description )
}
Add-Content $xmlFilePath ("</WebParts>")
}
Add-Content $xmlFilePath ("</PaginaASPX>")
}
}
Add-Content $xmlFilePath ("</Paginas>")
Add-Content $xmlFilePath ("</Web>")
}
Add-Content $xmlFilePath ("</Webs>")
Add-Content $xmlFilePath ("</Site>")
}
Add-Content $xmlFilePath ("</Sites>")
#Add-Content $xmlFilePath($webApp.ContentDatabases New-XML -RootTag CONTENTDATABASES -ItemTag DATABASE -Attribute=Id,Name -ChildItems Server )
Add-Content $xmlFilePath "</WebApplication>"
}
}
Add-Content $xmlFilePath "</FARM>"
Add-Content $xmlFilePath "</MIGRACION>"


========================================

2 comentarios:

  1. Con este Xpath podemos sacar todos los fields filtrando los campos estandard

    /MIGRACION/FARM/WebApplication/Sites/Site/Webs/Web/Lists/List/Fields/Field[@InternalName!="ID" and @InternalName!="ContentType" and @InternalName!="Title" and @InternalName!="Created" and @InternalName!="Author" and @InternalName!="Modified" and @InternalName!="Editor" and @InternalName!="_CopySource" and @InternalName!="CheckoutUser" and @InternalName!="LinkFilename" and @InternalName!="LinkFilenameNoMenu" and @InternalName!="DocIcon" and @InternalName!="_UIVersionString" and @InternalName!="ParentVersionString" and @InternalName!="ParentLeafName" and @InternalName!="FileLeafRef" and @InternalName!="_CheckinComment" and @InternalName!="FileSizeDisplay" and @InternalName!="Edit" and @InternalName!="Attachments" and @InternalName!="LinkTitleNoMenu" and @InternalName!="LinkTitle"]

    ResponderEliminar
  2. Gracias por tus anotaciones sobre sharepoint designer 2007 y 2010, Soy muy nuevo en estas aplicaciones y deseo hacer mi web. En un principio he escogido la 2007, y me ha sorprendido mucho que 2010 no reconocia los arhivos de 2007.

    ResponderEliminar