Accéder au contenu principal

SharePoint 20XX: Script PowerShell pour exporter en CSV toutes les listes d’une ferme pour auditer le contenu avant migration

 Dans un précédent message, nous avons pu comprendre comment nettoyer notre ferme SharePoint des listes vides:

Maintenant que celle-ci est “propre”, il convient de faire un assessment des listes contenues dans ces sites, sous-sites, … pour avoir une vue d’ensemble de la complexité du contenu à migrer et pouvoir se préparer au mieux.

Ce script va donc exporter pour vous un fichier CSV qu’il vous conviendra de manipuler selon votre besoin (via Excel, SQL Server, …).

Il reste dans le même esprit que la solution que Benoit Jester a publié pour l’exportation des sites et sous-sites d’une ferme:

Vous avez très peu de chose à paramétrer pour exécuter ce script en tant qu’administrateur sur un serveur de la ferme SharePoint.

param(
    [Parameter(Mandatory=$False)]
     [bool]$displayMessages = $true,
    [Parameter(Mandatory=$False)]
     [string]$SMTPServer="",
    [Parameter(Mandatory=$False)]
     [string]$ToEmailAddress="",
    [Parameter(Mandatory=$False)]
     [string]$FromEmailAddress="",
    [Parameter(Mandatory=$False)]
     [string]$delimiter="|"
)

[array]$ExceptionListnames = "List Template Gallery", "Master Page Gallery", "Site Template Gallery", "Web Part Gallery", "User Information List", "Settings", "Galería de plantillas de sitios", "Galería de plantillas de listas", "Galerie de modèles de sites", "Galerie de modèles de listes"

[string]$FarmType = "YOUR INTRANET TEAMSITES"
[string]$FolderToPutCSVName = "C:\TEMP\"
[string]$CSVFileName = "Lists-Usage-YourTeamsites.CSV"
[string]$ColorToShow = "green"
[string]$MyListIndexedColumns = ""
$pattern = '[^a-zA-Z]'
[string]$ColumnTitleCleaned = ""

# Applies Read Access to the specified accounts for a web application
Function Add-UserPolicy([String]$url)
{
    Try
    {
        $webapp = [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup("$url")
        $user = ([Security.Principal.WindowsIdentity]::GetCurrent()).Name
        $displayName = "Sites Usage Read Account"
        $perm = "Full Read"
       
        # If the web app is not Central Administration
        If ($webapp.IsAdministrationWebApplication -eq $false)
        {
            # If the web app is using Claims auth, change the user accounts to the proper syntax
            If ($webapp.UseClaimsAuthentication -eq $true)
            {$user = 'i:0#.w|'+$user}
            [Microsoft.SharePoint.Administration.SPPolicyCollection]$policies = $webapp.Policies
            [Microsoft.SharePoint.Administration.SPPolicy]$policy = $policies.Add($user, $displayName)
            [Microsoft.SharePoint.Administration.SPPolicyRole]$policyRole = $webapp.PolicyRoles | where {$_.Name -eq $perm}
            If ($policyRole -ne $null)
            {$policy.PolicyRoleBindings.Add($policyRole)}
            $webapp.Update()
            If($displayMessages)
            {Write-Host -ForegroundColor White " Read access applied for `"$user`" account to `"$url`""}
        }
    }
    Catch
    {
        $_
        Write-Warning "An error occurred applying Read access for `"$user`" account to `"$url`""
    }
}

# Load assemblies
Function Load-Assemblies
{
    Try
    {
        If ((Get-PsSnapin |?{$_.Name -eq "Microsoft.SharePoint.PowerShell"})-eq $null)
        {
            If($displayMessages)
            {
                Write-Host -ForegroundColor Green "-----------------------------------------"
                Write-Host -ForegroundColor Green " - Loading SharePoint Powershell Snapin -"
                Write-Host -ForegroundColor Green "-----------------------------------------"
            }
            Add-PsSnapin Microsoft.SharePoint.PowerShell -ErrorAction Stop | Out-Null
        }
    }
    Catch
    {
        If($displayMessages)
        {
            Write-Host -ForegroundColor Green "------------------------------------------"
            Write-Host -ForegroundColor Green " - Loading Microsoft.SharePoint Assembly -"
            Write-Host -ForegroundColor Green "------------------------------------------"
        }
        [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") | Out-Null
    }
}

# Send Email with log file as attachment
Function SendEmail($attachment)
{
    Try
    {
        If($displayMessages)
        {
            Write-Host -ForegroundColor White "--------------------------------------------------------------"
            Write-Host -ForegroundColor White " Sending Email to $ToEmailAddress with $attachment in attachment."
        }
        Send-MailMessage -To $ToEmailAddress -From $FromEmailAddress -Subject "Sites Usage - $env:COMPUTERNAME" -SmtpServer $SMTPServer -Attachments $attachment
       
        If($displayMessages)
        {Write-Host -ForegroundColor Green " Email sent successfully to $ToEmailAddress"}
    }
    Catch
    {Write-Warning $_}
}

$DateStarted = $(Get-date)

If($displayMessages)
{
    Write-Host -ForegroundColor Green "----------------------------------"
    Write-Host -ForegroundColor Green "- Script started on $DateStarted -"
    Write-Host -ForegroundColor Green "----------------------------------"
}
# Check Permission Level
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{Write-Warning "You don't have Administrator rights to run this script."}
else
{
    If($SMTPServer)
    {
        If (!$ToEmailAddress -or !$FromEmailAddress)
        {
            Write-Warning "Please specify a 'ToEmailAddress' and a 'FromEmailAddress' parameter."
            Exit
        }
    }
    # Load assemblies
    Load-Assemblies

    # Local variables
    $sitesList = $null
    $sitesList = @()

    # Build structure
    $itemStructure = New-Object psobject
    $itemStructure | Add-Member -MemberType NoteProperty -Name "FarmType" -value ""
    $itemStructure | Add-Member -MemberType NoteProperty -Name "SPWebAppURL" -value ""
    $itemStructure | Add-Member -MemberType NoteProperty -Name "SPSiteCollURL" -value ""
    $itemStructure | Add-Member -MemberType NoteProperty -Name "SPWebURL" -value ""
    $itemStructure | Add-Member -MemberType NoteProperty -Name "ListTitle" -value ""
    $itemStructure | Add-Member -MemberType NoteProperty -Name "ListGUID" -value ""
    $itemStructure | Add-Member -MemberType NoteProperty -Name "ListCreated" -value ""
    $itemStructure | Add-Member -MemberType NoteProperty -Name "ListLastModifiedDate" -value ""
    $itemStructure | Add-Member -MemberType NoteProperty -Name "ListDefaultViewURL" -value ""
    $itemStructure | Add-Member -MemberType NoteProperty -Name "ListTemplate" -value ""
    $itemStructure | Add-Member -MemberType NoteProperty -Name "ListItemsNumber" -value ""
    $itemStructure | Add-Member -MemberType NoteProperty -Name "ListIndexedColumns" -value ""
   
    If($displayMessages)
    {
        Write-Host -ForegroundColor Green "-----------------------"
        Write-Host -ForegroundColor Green " - Scanning All Sites -"
        Write-Host -ForegroundColor Green "-----------------------"
    }
   
    # Browse sites
    $WebSrv = [microsoft.sharepoint.administration.spwebservice]::ContentService
    foreach ($webApp in $WebSrv.WebApplications)
    {
        foreach ($AltUrl in $webapp.AlternateUrls)
        {Add-UserPolicy $AltUrl.uri}
       
        foreach ($site in $WebApp.sites)
        {
            $rootweb = $site.RootWeb;
            foreach($web in $site.AllWebs)
            {
                foreach($MyList in $web.lists)
                {
                    if($ExceptionListnames -notcontains $MyList.Title)
                    {
                        $MyListIndexedColumns = ""
                        foreach($MySPField in $MyList.Fields)
                        {
                            if($MySPField.Indexed)
                            {
                                $ColumnTitleCleaned =  $MySPField.Title -replace $pattern, ''
                                $MyListIndexedColumns += $ColumnTitleCleaned +"["+ $MySPField.InternalName +"]; "
                            }
                        }

                        if($MyList.ItemCount -gt 5000)
                        {
                            $ColorToShow = "red"
                        }
                        else
                        {
                            $ColorToShow = "green"
                        }
                        If($displayMessages)
                        {
                            Write-Host " -------------------------------------------------- "
                            Write-Host "      List Name:", $MyList.Title, "- GUID:", $MyList.ID -foregroundcolor $ColorToShow
                            Write-Host "      >>SPWebURL URL:", $web.Url -foregroundcolor $ColorToShow
                            Write-Host "      >>Items Count:", $MyList.ItemCount -foregroundcolor $ColorToShow
                            Write-Host "      >>Created Date:", $MyList.Created -foregroundcolor $ColorToShow
                            Write-Host "      >>Last modified Date:", $MyList.LastItemModifiedDate -foregroundcolor $ColorToShow
                            Write-Host "      >>List Indexed Columns:", $MyListIndexedColumns -foregroundcolor $ColorToShow
                        }
                        # Build structure
                        $siteInfos = $itemStructure | Select-Object *;

                        $siteInfos.FarmType = $FarmType;
                        $siteInfos.SPWebAppURL = $web.Url.Split("/")[2];
                        $siteInfos.SPSiteCollURL = $site.URL;
                        $siteInfos.SPWebURL =  $web.Url;

                        $siteInfos.ListTitle = $MyList.Title;
                        $siteInfos.ListGUID = $MyList.ID;
                        $siteInfos.ListCreated = $MyList.Created.ToString('d');
                        $siteInfos.ListLastModifiedDate = $MyList.LastItemModifiedDate.ToString('d');
                        $siteInfos.ListDefaultViewURL = $MyList.DefaultViewUrl;
                        $siteInfos.ListTemplate = $MyList.BaseTemplate;
                        $siteInfos.ListItemsNumber = $MyList.ItemCount;
                        $siteInfos.ListIndexedColumns = $MyListIndexedColumns;
                       
                        $sitesList += $siteInfos;
                    }
                }
            }
        }
        $rootweb.Dispose()

    }
   
    # CSV Export
    If($displayMessages)
    {
        Write-Host -ForegroundColor Green "---------------"
        Write-Host -ForegroundColor Green " - CSV Export -"
        Write-Host -ForegroundColor Green "---------------"
    }
    $sitesList | Where-Object {$_} | Export-Csv -Delimiter "$delimiter" -Path $CSVFileName -notype
     If($displayMessages)
    {Write-Host "Export file $CSVFileName successfully generated."}
 
    # Export File To DBServer
    Copy-Item $CSVFileName $FolderToPutCSVName
   
    # Email notification
    If($SMTPServer)
    {SendEmail $CSVFileName}
   
    # End
    If($displayMessages)
    {
        Write-Host -ForegroundColor Green "---------------------------------"
        Write-Host -ForegroundColor Green "- Script started : $DateStarted -"
        Write-Host -ForegroundColor Green "- Script finished : $(Get-date) -"
        Write-Host -ForegroundColor Green "---------------------------------"
    }
    Exit
}

Ce script est planifié sur toutes mes fermes afin de remonter ces CSV dans une base SQL Server qui permet ensuite de tirer des informations vitales, comme les liste ayant plus de 5’000 mais surtout plus de 20’000 items afin de placer les indexes correctement avant import. En effet, au dessus de 20’000 items il est impossible de changer la structure d’une liste SharePoint Online.

Fabrice Romelard [MBA Risk Management]

Commentaires

Posts les plus consultés de ce blog

Redonner vie à une Microsoft Surface RT : le guide ultime vers Linux !

Vous avez une vieille Microsoft Surface RT qui traîne dans un tiroir ? Vous savez, cette tablette de 2012 devenue inutilisable depuis l'abandon officiel de Windows RT par Microsoft ? Ne la jetez surtout pas ! Dans ma dernière vidéo, je vous montre comment transformer cet appareil, autrefois considéré comme un "presse-papier", en une tablette Linux moderne et parfaitement fonctionnelle . Pourquoi ce projet ? L'objectif est simple : transformer ce matériel pour en faire un dashboard dédié à mon système Home Assistant. En installant postmarketOS , une version de Linux spécialement conçue pour les appareils ARM abandonnés, on redonne une seconde jeunesse à cette machine . Ce que vous allez apprendre dans ce tutoriel complet : La libération du matériel : Comment réinstaller la version d'origine pour passer outre les blocages de Windows 8.1 . Jailbreak & Secure Boot : La procédure indispensable pour déverrouiller la machine et permettre l'installation d...

Série de Videos sur Home Assistant intégrant la production Photovoltaïque

 Un certain nombre de vidéos sont en ligne pour intégrer sa production photovoltaïque dans Home Assistant en partant de la base. Installation de Home Assistant: On peut ensuite intégrer les composant des Micro-Onduleurs Enphase, mais aussi les batteries Enphase: Ou encore le composant de contrôle Ecojoko: Ce qui permet alors de faire des comparaisons entre les valeurs capturées: Des videos seront encore publiés dans les prochaines semaines sur différents aspects de cette solution. Fab

Formation : Quelle formation après un MBA ?

Afin de poursuivre dans les réflexions menées depuis le départ de cette aventure : Tous les messages en rapport avec le MBA Une fois le diplôme MBA obtenu, la question de la suite se pose pour une partie des élèves. En effet, l’énergie positive requise pour reprendre ses études ne disparait pas pour tout le monde. Il convient alors de réfléchir à la suite possible de cette formation et je vais donc essayer de présenter quelques choix accessibles à partir de notre MBA. PhD & DBA La voie royale pour le monde universitaire est le Doctorat (ou PhD en anglais), cette formation se fait directement à travers l’université ou une école agréée. Le principe est de préparer un dossier de thèse durant plusieurs mois qui devra être présenté en fin de cursus devant un jury académique. Il existe une version adaptée pour les Business Schools : Doctorate of Business Administration Ces formations sont particulières aux écoles de commerce ou grandes écoles, dont des listes sont présen...