Accéder au contenu principal

Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant

 Ce script permet donc d’exporter en CSV toutes les informations utiles de ce tenant. Il fera une boucle sur l’ensemble des collections de sites et des sous-sites en prenant en compte les volumes et la personnalisation (en mode old School SharePoint).


[boolean]$DebugGlobalMode = $True #$False
[string]$username = "Admin@yourtenant.onmicrosoft.com"

[string]$PwdTXTPath = "C:\SECUREDPWD\ExportedPWD-$($username).txt"
[string]$CSVFolderReport = "C:\SHAREPOINT\Reports\"
[string]$AdminTenantURL = "
https://YourTenant-admin.sharepoint.com"

function Load-DLLandAssemblies
{
    [string]$defaultDLLPath = ""

    # Load assemblies to PowerShell session

    $defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll"
     [System.Reflection.Assembly]::LoadFile($defaultDLLPath)

    $defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll"
    [System.Reflection.Assembly]::LoadFile($defaultDLLPath)

    $defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.Online.SharePoint.Client.Tenant.dll"
    [System.Reflection.Assembly]::LoadFile($defaultDLLPath)
}

function Get-SPOWebs(){
param(
    $Url = $(throw "Please provide a Site Collection Url"),
    $Credential = $(throw "Please provide a Credentials")
)

    $context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
    $context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Credential.UserName,$Credential.Password)
    $context.RequestTimeout = 1000000 # milliseconds
    $web = $context.Web
    $context.Load($web)
    $context.Load($web.Webs)
    $context.ExecuteQuery()
    foreach($myweb in $web.Webs)
    {
        Get-SPOWebs -Url $myweb.Url -Credential $Credential
        $myweb
    }
}

function Check-InfoPath-Usage($myspoWebSite, $myspcontext)
{
    [string]$InfotpathStatus = ""
    [boolean]$DebugMode = $false #$DebugGlobalMode
    $AllspwebLists = $myspoWebSite.lists
    $myspcontext.Load($AllspwebLists)
    $myspcontext.ExecuteQuery()
    Write-Host " ---------------------------------------------- "
    if($DebugMode) {Write-Host "         -->InfoPath:",$($myspoWebSite.Id), "-",$($myspoWebSite.Url), "-",$($myspoWebSite.Title) -ForegroundColor Yellow}
    foreach($myList in $AllspwebLists)
    {
         $myspcontext.Load($myList)
        $myspcontext.ExecuteQuery()
        $listTitle = $myList.Title
        $listType = $myList.BaseTemplate
        $listUrl = $myList.DefaultViewUrl
         try
        {
            if($DebugMode) {Write-Host "         -->Infopath: List Check", $listTitle, "(", $listType, ") at WebURL", $myspoWebSite.url -ForegroundColor Green}
            if($listType -eq 100 -or $listType -eq 101)
            {
                 if($DebugMode) {Write-Host "            -->Infopath: Line 70 - listType:", $listType}
                $isSysList = $myList.IsSystemList
                $IswebCatalog =  $myList.IsCatalog
                $IsAppList =  $myList.IsApplicationList
                 $listForms = $myList.Forms
                $myspcontext.Load($listForms)
                $myspcontext.ExecuteQuery()
                 if($DebugMode) {Write-Host "            -->Infopath: Line 77 - isSysList:", $isSysList}
                if($DebugMode) {Write-Host "            -->Infopath: Line 78 - IsCatalog:", $IswebCatalog}
                if($DebugMode) {Write-Host "            -->Infopath: Line 79 - IsApplicationList:", $IsAppList}
                if($isSysList -or $IswebCatalog -or $IsAppList)
                {
                    if($DebugMode) {Write-Host "            -->Infopath: System, Application or Catalog List Ignore", $listTitle, "at URL", $myspoWebSite.url -ForegroundColor Yellow}
                }
                else
                {
                    if($listType -eq 101)
                    {
                        if($DebugMode) {Write-Host "            -->Infopath: Line 88 - listType:",  $listType}
                         if($myList.AllowContentTypes)
                        {
                            if($DebugMode) {Write-Host "            -->Infopath: Line 89 - AllowContentTypes:", $myList.AllowContentTypes}
                            $contentTyps = $myList.ContentTypes
                            $myspcontext.Load($contentTyps)
                            $myspcontext.ExecuteQuery()
                            forEach($contType in $contentTyps)
                            {
                                if($DebugMode) {Write-Host "            -->Infopath: Line 97 - contType.Name:", $contType.Name}
                                if($contType.Name -eq "Form")
                                {
                                     Write-Host "            -->InfoPath: Found in Library", $listTitle, "at URL", $myspoWebSite.url -ForegroundColor Magenta
                                    $InfotpathStatus += "Infopath:"+ $myspoWebSite.url +";"
                                 }
                            }
                         }
                        if($DebugMode) {Write-Host "            -->Infopath: Line 105 - listType:", $listType}
                    }
                    else
                     {
                        forEach($listFm in $listForms)
                         {
                            $listPath = $listFm.ServerRelativeUrl
                            if($DebugMode) {Write-Host "            -->Infopath: Line 112 - listPath:", $listPath}
                            if ($listPath -like '*displayifs.aspx')
                            {
                                 Write-Host "            -->InfoPath: Found in List", $listTitle, "at URL", $myspoWebSite.url -ForegroundColor Magenta
                                $InfotpathStatus += "Infopath:"+ $myspoWebSite.url +";"
                            }
                         }
                    }
                }

            }
        }
        catch
        {
            Write-Host "         -->Infopath: Error Check for list:",  $listTitle -ForegroundColor Red
            Write-Host "             ErrorMessage:", $_.Exception -ForegroundColor Red
        }
    }

    return $InfotpathStatus
}

function Check-SPWorkflow($myspoWebSite, $myspcontext)
{
    [string]$WorkflowStatus = ""
    [boolean]$DebugMode = $false #$DebugGlobalMode
    $AllspwebLists = $myspoWebSite.lists
    $myspcontext.Load($AllspwebLists)
    $myspcontext.ExecuteQuery()
    if($DebugMode) {Write-Host "         --> WorkFlow: ",$($myspoWebSite.Id), "-",$($myspoWebSite.Url), "-",$($myspoWebSite.Title) -ForegroundColor Yellow}
    foreach($list in $AllspwebLists)
    {
        if($DebugMode) {Write-Host "         -->SPWorkflow: List Check", $list.Title, " at WebURL", $myspoWebSite.url -ForegroundColor Green}
        try
        {
             $myspcontext.Load($list.WorkflowAssociations)
             $myspcontext.ExecuteQuery()
            foreach($wfAssociation in $list.WorkflowAssociations)
            {
                if($DebugMode) {Write-Host "                 -->SPWorkflow: List ", $list.Title, "- Wokflow:", $wfAssociation.Name -ForegroundColor Magenta}
                $WorkflowStatus += "`"$($list.Title)`",`"$($wfAssociation.Name)`",`"$($wfAssociation.TaskListTitle)`","
                #$WorkflowStatus += "`"$($wfAssociation.HistoryListTitle)`",$($wfAssociation.Created),$($wfAssociation.Modified)"
            } 
        }
        catch
        {
             Write-Host "         -->WorkFlowCHeck: Error Check for list:",  $list.Title -ForegroundColor Red
            Write-Host "             ErrorMessage:", $_.Exception -ForegroundColor Red
         }
    }
    return $WorkflowStatus
}

cls
Write-Host " ---------------------------------------------- "
Load-DLLandAssemblies
Write-Host " ---------------------------------------------- "

$secureStringPwd = ConvertTo-SecureString -string (Get-Content $PwdTXTPath)
$adminCreds = New-Object System.Management.Automation.PSCredential $username, $secureStringPwd
#$adminCreds = get-credential

Connect-SPOService -Url $AdminTenantURL -credential $adminCreds -ErrorAction SilentlyContinue -ErrorVariable Err

$data = @()

#Retrieve all site collection infos
#$sitesInfo = Get-SPOSite -Limit 10 | Sort-Object -Property url | Select *
#$sitesInfo = Get-SPOSite -Template "STS#0" -Limit 10 | Sort-Object -Property url | Select *
$sitesInfo = Get-SPOSite -Limit ALL | Sort-Object -Property url | Select *

[int]$i = 1;
[string]$CheckInfoPathStatus = ""
[string]$CheckWorkFlowStatus = ""
$data = @()

Write-Host "--------------------------------------------------------------------------------------------"
#Retrieve and print all sites
foreach ($site in $sitesInfo)
{
    Write-Host "SiteColl Number:", $i, "- of:", $sitesInfo.Count;
    $i += 1;
    $RootSiteCreatedDate = get-date "1900-01-01"
    try
    {
        $Rootcontext = New-Object Microsoft.SharePoint.Client.ClientContext($site.Url)
        $Rootcontext.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($adminCreds.UserName,$adminCreds.Password)
        $Rootcontext.RequestTimeout = 1000000 # milliseconds
        $RootWeb = $Rootcontext.web
        $Rootcontext.Load($RootWeb)
        $Rootcontext.ExecuteQuery()
        $RootSiteCreatedDate = $RootWeb.Created
        $CheckInfoPathStatus = Check-InfoPath-Usage $RootWeb $Rootcontext
         $CheckWorkFlowStatus = Check-SPWorkflow $RootWeb $Rootcontext
    }
    catch
    {
        Write-host "  =====>>>> Impossible to get the RootSite " -ForegroundColor Red
        Write-host "  =====>>>> RootSite:", $site.Url -ForegroundColor Yellow
    }
       
    Write-Host "SPO Site collection:", $site.Url, "- Title:", $site.Title
    Write-Host "   => Creation Date:", $RootSiteCreatedDate, "- LastItemModifiedDate", $site.LastContentModifiedDate
    Write-Host "   => External Sharing:", $site.SharingCapability
    Write-Host "   => Site Template Used:", $site.Template
    Write-Host "   => Storage Quota:", $site.StorageQuota
    Write-Host "   => Storage used:", $site.StorageUsageCurrent
    Write-Host "   => Storage Warning Level:", $site.StorageQuotaWarningLevel
    Write-Host "   => Resource Quota:", $site.ResourceQuota, "- Resource used:", $site.ResourceUsageCurrent

    $SuborRootSite = "RootSite"
    $data += @(
        [pscustomobject]@{
        SiteCollectionURL = $site.Url
        SiteCollectionTitle = $site.Title
        SPType = $site.Template
        SubsiteURL = $site.Url
        SuborRootSite = $SuborRootSite
         WebTemplate = $site.Template
        WebCreationDate = $RootSiteCreatedDate
        LastItemModifiedDate = $site.LastContentModifiedDate
        ExternalSharingCapability = $site.SharingCapability
        StorageQuotaMB = $site.StorageQuota
        StorageUsageCurrentMB = $site.StorageUsageCurrent
        StorageQuotaWarningLevelMB = $site.StorageQuotaWarningLevel
        ResourceQuota = $site.ResourceQuota
        ResourceUsageCurrent = $site.ResourceUsageCurrent
        DevCustomCreated = ""
        DevCustomSPWorkflow = $CheckWorkFlowStatus
        DevSPFxCreated = ""
        DevMSFloworPowerAppsCreated = ""
        DevInforpathForm = $CheckInfoPathStatus
        }
    )
    try
    {
         $AllWebs = Get-SPOWebs -Url $site.Url -Credential $adminCreds
        if($DebugMode) {$AllWebs | %{ Write-Host "   >>", $_.Title, "-", $_.Url}}
        Write-Host "--------------------------------------------------------------------------------------------"

        foreach($mySPWeb in $AllWebs)
        {
             Write-Host "         >> Subsite:", $mySPWeb.Url -ForegroundColor magenta
            $CheckInfoPathStatus = Check-InfoPath-Usage $RootWeb $Rootcontext
            $CheckWorkFlowStatus = Check-SPWorkflow $RootWeb $Rootcontext
            $SuborRootSite = "SubSite"
            $data += @(
                [pscustomobject]@{
                SiteCollectionURL = $site.Url
                 SiteCollectionTitle = $site.Title
                SPType = $site.Template
                SubsiteURL = $mySPWeb.Url
                 SuborRootSite = $SuborRootSite
                WebTemplate = $mySPWeb.WebTemplate
                WebCreationDate = $mySPWeb.Created
                LastItemModifiedDate = $mySPWeb.LastItemModifiedDate
                ExternalSharingCapability = $site.SharingCapability
                StorageQuotaMB = $site.StorageQuota
                StorageUsageCurrentMB = $site.StorageUsageCurrent
                StorageQuotaWarningLevelMB = $site.StorageQuotaWarningLevel
                ResourceQuota = $site.ResourceQuota
                ResourceUsageCurrent = $site.ResourceUsageCurrent
                DevCustomCreated = ""
                 DevCustomSPWorkflow = $CheckWorkFlowStatus
                DevSPFxCreated = ""
                DevMSFloworPowerAppsCreated = ""
                DevInforpathForm = $CheckInfoPathStatus
                 }
            )
        }
    }
    catch
    {
         Write-host "  =====>>>> Impossible to get the Subsites " -ForegroundColor Red
        Write-host "  =====>>>> RootSite:", $site.Url -ForegroundColor Yellow
    }

}

#Write-Host $data

$datestring = (get-date).ToString("yyyyMMdd-hhmm")
$CSVFileToExport = Join-Path -Path $CSVFolderReport  -ChildPath $("SharePoint_"+ $datestring + ".csv")
   
Write-host " -----------------------------------------" -ForegroundColor Green
Write-Host (" >>> writing to file {0}" -f $CSVFileToExport) -ForegroundColor Green
$data | Export-csv $CSVFileToExport -NoTypeInformation -enc utf8
Write-host " -----------------------------------------" -ForegroundColor Green


Vous pouvez adapter et utiliser ce script selon vos propres besoins.

Romelard Fabrice

Version Anglaise:

Sources utilisées:

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