Accéder au contenu principal

SharePoint 2007: Script PowerShell pour nettoyer les listes vides avant migration vers Office 365 - Updated

 Le contexte est toujours le même:

  • la préparation d’une migration

En effet, lorsqu’on arrive à ce stade, il y a toujours deux situations qui sont distinctes:

  • Upgrade des environnements On Premise vers les nouvelles versions (et donc DB Upgrade)
  • Passage d’environnement On Premise vers le Cloud (Office 365)

La première option implique donc la conservation de la structure et donc une certaine largesse dans la préparation, car on reste toujours dans une zone connue et une liste de plus ou de moins ne change pas grand chose.

La seconde option est plus discutable, car quelque soit l’outil choisi, le transfert reviendra à faire un import des données vers le tenant et donc tout ce que cela implique:

  • Temps de transfert
  • Utilisation du réseau
  • Temps de configuration et création des listes par l’outil
  • Temps pour appliquer les paramètres et les permissions

De ce fait, plus on réduit le nombre de liste plus on accélère la migration potentiel.

Un exemple rapide d’une ferme hypothétique avec la configuration suivante:

  • 100 collections de sites
  • 4 sous-sites par collection
  • 5 listes vides en moyenne (calendrier, contacts, annonces, …)
  • une moyenne de 20KB par liste

On obtient très rapidement la valeur suivante:

  • Nombre de listes vides à migrer: 100 * 4 * 5 = 2000
  • Taille totale inutile pour ces listes: 2000 * 20KB = 40 MB

Le temps pour créer une liste vide avec ShareGate par exemple est d’environ 30 secondes, ce qui vous donne un temps perdu:

  • 2000 * 30 = 60 000 secondes = env. 16 heures utilisées pour rien

Pour palier à cette situation, voici un script PowerShell à adapter selon votre besoin et exécuter sur chaque Web Application:

[int]$LimitMaxNumber = 5000
[int]$NumberMonthsOlder = -18 #(around 18 months before)

[boolean]$RemoveBasicEmptyLists = $true

[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", "Galeria de Modelos de Site", "Galeria de Modelos de Lista"

[array]$BasicListToDelete = "Shared Documents", "Announcements", "Calendar", "Links", "Tasks", "Team Discussion", "Events", "General Discussion", "Contacts", "Discusión de grupo", "Tareas", "Documentos compartidos", "Calendario", "Eventos", "Contactos", "Discusión general", "Vínculos", "Anuncios", "Avisos", "Tarefas", "Documentos Compartilhados", "Contatos", "Discussão Geral", "Calendário", "Discussão em Equipe", "Eventos", "Discussion générale", "Tâches", "Événements", "Documents partagés", "Annonces", "Contacts", "Liens", "Calendrier", "Discussion d'équipe", "Извещения", "Контакты", "События", "Общие обсуждения", "Ссылки", "Ankündigungen", "Teamdiskussion", "Hyperlinks", "Freigegebene Dokumente", "Aufgaben", "Ankündigungen", "Kalender", "Documenti condivisi","Annunci", "Attività", "Calendario", "Collegamenti", "Discussione team", "Dokumenty udostępnione", "Anonsy", "Kalendarz", "Łącza", "Zadania", "Dyskusja zespołu", "共享文件", "宣告", "工作", "行事曆", "連結", "小組討論", "共有ドキュメント", "お知らせ", "タスク", "リンク", "予定表", "チーム ディスカッション", "공유 문서", "공지 사항", "링크", "일정", "작업", "팀 토론"

[array]$AnnouncementListNames = "Announcements", "Anuncios", "Annonces", "Ankündigungen", "Annunci", "Anonsy", "Извещения", "Avisos", "宣告", "お知らせ", "공지 사항"

[array]$AnnouncementDefaultItemValue = "Get Started with Windows SharePoint Services!", "¡Introducción a Windows SharePoint Services!", "Introducción a Windows SharePoint Services", "Guide de mise en route de Windows SharePoint Services", "Erste Schritte mit Windows SharePoint Services", "Introduzione a Windows SharePoint Services", "Rozpocznij pracę z programem Windows SharePoint Services!", "Начало работы с Windows SharePoint Services", "Bem-vindo ao Windows SharePoint Services!", "開始使用 Windows SharePoint Services!", "Windows SharePoint Services について", "Windows SharePoint Services를 시작합니다!"

function Check-Lists([string]$webURL)
{
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null
    $mysite = new-object Microsoft.SharePoint.SPSite($webURL)
    $myweb = $mysite.openweb()
    Write-Host "URL", $webURL
    #Write-Host "web", $myweb.Name
    Write-Host "Number of lists", $myweb.lists.count
    $ListsToDeleteFoSPWeb = New-Object System.Collections.ArrayList
   
    $LimitDate = (get-date).Addmonths($NumberMonthsOlder)
    Write-Host " >> Limit date for the lists -[", $LimitDate, "]"

    foreach($MyList in $myweb.lists)
    {
        if($ExceptionListnames -notcontains $MyList.Title)
        {
            if(($MyList.ItemCount -lt 1) -and ($MyList.LastItemModifiedDate -lt $LimitDate))
            {
                Write-Host "     ------------------------------------ "
                Write-Host "      List Name:", $MyList.Title, "- GUID:", $MyList.ID -foregroundcolor green
                Write-Host "      >>Items Count:", $MyList.ItemCount -foregroundcolor green
                Write-Host "      >>Last modified Date:", $MyList.LastItemModifiedDate -foregroundcolor green
                if($BasicListToDelete -contains $MyList.Title)
                {
                    Write-Host "       >>>>> List to delete: ", $MyList.Title, " <<<<<" -foregroundcolor green
                    $ListsToDeleteFoSPWeb += $MyList.ID
                }
            }
            else
            {
                if(($AnnouncementListNames -contains $MyList.Title) -and ($MyList.ItemCount -eq 1) -and ($MyList.LastItemModifiedDate -lt $LimitDate))
                {
                    if($AnnouncementDefaultItemValue -contains $MyList.Items[0].Title)
                    {
                        Write-Host "     ----------------------------------------------------- "
                        Write-Host "      Announcements Item[0] to delete:", $MyList.Items[0].Title -foregroundcolor green
                        Write-Host "       >>>>> List to delete: ", $MyList.Title, " <<<<<" -foregroundcolor green
                        Write-Host "     ----------------------------------------------------- "
                        $ListsToDeleteFoSPWeb += $MyList.ID
                    }
                    else
                    {
                        Write-Host "     ----------------------------------------------------- "
                        Write-Host "      Announcements Item[0] to check:", $MyList.Items[0].Title -foregroundcolor red
                        Write-Host "     ----------------------------------------------------- "
                    }
                }
                else
                {
                    if($MyList.ItemCount -gt 5000)
                    {
                        Write-Host "     ------------------------------------ "
                        Write-Host "      List Name:", $MyList.Title, "- GUID:", $MyList.ID -foregroundcolor magenta
                        Write-Host "      >>Items Count:", $MyList.ItemCount -foregroundcolor magenta
                    }
                    else
                    {
                        #Write-Host "      List Name:", $MyList.Title, "(", $MyList.ItemCount , Items") - GUID:", $MyList.ID  -foregroundcolor green $MyList.BaseTemplate
                    }
                }
            }
        }
    }

   
    if(($RemoveBasicEmptyLists) -and ($ListsToDeleteFoSPWeb.count -gt 0))
    {
        foreach($ToDeleteListGUID in $ListsToDeleteFoSPWeb)
        {
            Write-Host "      ======================================= "
            $myweb.Lists.Delete($ToDeleteListGUID)
            Write-Host "        >>> List GUID deleted:", $ToDeleteListGUID
            Write-Host "      ======================================= "
        }
    }
    foreach ($subweb in $myweb.GetSubwebsForCurrentUser())
    {
        Check-Lists $subweb.Url
    }
    $myweb.Dispose()
    $mysite.Dispose()
}

function Check-Large-Empty-Lists([string]$WebAppURL)
{
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null

    $Thesite = new-object Microsoft.SharePoint.SPSite($WebAppURL)
    $oApp = $Thesite.WebApplication

    foreach ($Sites in $oApp.Sites)
    {
        $mySubweb = $Sites.RootWeb
        Write-Host " -------------------------------------------------------- "
        #Write-Host "URL", $mySubweb.Url
        Check-Lists $mySubweb.Url
       
    }
    $Thesite.Dispose()

}

cls

Check-Large-Empty-Lists “http://YourSharePointSite2007”

En bonus, ce script vous affiche aussi en Magenta les listes qui contiennent plus qu’une valeur limite donnée dans le paramètre “$LimitMaxNumber”.

Le résultat d’exécution est le suivant:

image

Update:

J’ai ajouté la gestion de la liste “Announcement” qui contient de base 1 élément qui n’était pas donc vue comme vide. Cette fois je teste le cas de l’élément unique restant dans sa forme de base avec la valeur par défaut dans l’ensemble des langues (que j’avais à gérer).

Il ne vous reste ensuite plus qu’à faire un contrôle des sites avant migration pour voir si vous n’avez pas de site totalement vide (et donc à supprimer).

Fabrice Romelard [MBA Risk Management]

Commentaires

Posts les plus consultés de ce blog

Série de vidéos sur le montage d'une serre horticole ACD

 Episode 1: Préparation du terrain Episode 2: Montage de la serre en elle même Episode 3: Finalisation avec le montage électrique alimentant la serre Bon visionnage Fab

Présentation des outils utiles pour l'entretien de ses haies vives

Afin de gérer les haies vives, il est nécessaire d'avoir recourt à un matériel adapté. Les solutions à batteries sont bien adaptées pour un usage personnel avec des dimensions raisonnables. Ainsi dans mon cas précis, j'utilise les outils suivants de la Gamme Ryobi 18V ONE+ électroportatif: Petit taille-haies simple mais efficace -  RYOBI OHT1855R Un modèle plus puissant qui fonctionne très bien -  RYOBI RY18HTX60A Pour les parties hautes de vos haies, voici un outil très utile -  RYOBI OPT1845 Enfin lorsque vous devez élaguer certains arbres ou certaines partie hautes de vos haies, ce dernier outil est très utile -  RYOBI OPP1820 Ces outils font parti maintenant de mon arsenal de base pour maintenir notre maison chaque saison de taille. Fab

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