Fermer

mars 25, 2024

Exportation d’éléments multimédias avec les extensions Sitecore PowerShell / Blogs / Perficient

Exportation d’éléments multimédias avec les extensions Sitecore PowerShell / Blogs / Perficient


Introduction 📖

À ce stade, je pense que tous les développeurs Sitecore utilisent ou ont au moins entendu parler de Extensions PowerShell de Sitecore (SPE). Ce module puissant pour Sitecore est automatiquement inclus pour la plupart des équipes et des projets. Le module est inclus avec les instances XM Cloud par défaut; si vous utilisez XM Cloud, vous disposez déjà de SPE. Si, d’une manière ou d’une autre, vous n’avez pas entendu parler de SPE, arrêtez tout ce que vous faites et allez le vérifier. 🚪🏃‍♂️

SPE comprend plusieurs modules prêts à l’emploi (OOTB) rapports que les utilisateurs peuvent exécuter. Sur un projet récent, l’un de ces rapports est arrivé : le Éléments multimédias inutilisés rapport qui se trouve dans l’arborescence de contenu de Sitecore au chemin suivant :

/sitecore/system/Modules/PowerShell/Script Library/SPE/Reporting/Content Reports/Reports/Media Audit/Unused media items

Ce rapport génère une liste d’éléments multimédias qui se trouvent dans la médiathèque mais qui ne sont pas utilisés dans Sitecore, où « utilisé » est défini comme étant référencé au moins une fois dans la base de données de liens Sitecore. En d’autres termes, le rapport répertorie les éléments multimédias qui sont (probablement) prenant juste de la place.

Extension du rapport 🚀

Dans mon cas, plutôt que de générer un rapport sur les éléments multimédias inutilisés, je devais faire le contraire : générer un rapport sur les éléments multimédias inutilisés. utilisé éléments multimédias et exportez ces éléments à l’aide de packages de contenu (qui seront installés dans des environnements supérieurs dans le cadre d’une migration de contenu). Utiliser l’OOTB Éléments multimédias inutilisés rapport comme point de départ, j’ai écrit un script plus générique et à usage général pour regrouper les éléments multimédias en fonction de plusieurs critères. Lorsque le script est exécuté, cela ressemble à ceci (j’ai utilisé PowerShell ISE inclus avec SPE pour exécuter le script) :

Exporter des éléments multimédias

…suite ci-dessous 👇 (…J’ai besoin d’un moniteur plus grand 🖥)

Exporter des éléments multimédias

Paramètres ⚙

Voici un aperçu des différents paramètres :

  • Médias à inclure
    • Défaut: Utilisé
    • Ce paramètre détermine si les processus de script ont utilisé des éléments multimédias, des éléments multimédias inutilisés ou à la fois des éléments multimédias utilisés et inutilisés. Pour déterminer si un élément est utilisé ou non, le script interroge la base de données de liens pour obtenir le nombre de référents pour l’élément.
  • Dossiers de la bibliothèque multimédia
    • Défaut: (aucun)
    • Utilisez ce paramètre pour désigner les dossiers à partir desquels vous souhaitez que le script extraie et traite les éléments multimédias. Le script inclut une vérification pour empêcher le traitement des éléments multimédias en double si, pour une raison quelconque, plusieurs dossiers multimédias qui se chevauchent sont sélectionnés.
    • Notez que le nœud de la bibliothèque multimédia racine peut être sélectionné, mais cela n’est pas idéal pour des raisons de performances. Il est préférable de limiter le script aux dossiers multimédias dont vous savez qu’ils contiennent les éléments multimédias que vous devez exporter. Si aucun dossier n’est sélectionné, le script ne fait rien.
  • Extensions à inclure
    • Défaut: (aucun)
    • Si vous souhaitez que le script traite uniquement les éléments multimédias avec certaines extensions, vérifiez les extensions correspondantes ici. Notez que, par défaut, aucune extension n’est cochée et aucun filtrage d’extension n’est appliqué. Vous souhaitez uniquement exporter des PDF ? Vérifier la pdf extension. Vous voulez tous les éléments multimédias, quelle que soit leur extension ? Ne cochez aucune extension.
  • Date limite
    • Défaut: (aucun)
    • S’il est spécifié, ce paramètre oblige le script à traiter uniquement les éléments multimédias qui ont été créés ou mis à jour. après cette date.
    • Ce paramètre est utile si vous devez exécuter une exportation « delta » pour récupérer des éléments nouveaux ou mis à jour depuis une exécution précédente. N’oubliez pas la date de votre dernière course. Notez que les noms de fichiers des packages générés incluent un horodatage, par exemple : 20240323T0504075151Z – Exporter les éléments multimédias 1.zip.
  • Taille maximale du paquet
    • Défaut: 25 Mo
    • Le script utilise le Size champ sur les éléments multimédias pour estimer la taille globale des fichiers dans un package de contenu donné. Si la taille totale des éléments multimédias empaquetés atteint ce seuil, un package supplémentaire est créé jusqu’à ce que tous les éléments multimédias soient empaquetés.
    • Le script peut générer des packages qui sont plus grand que cette taille – la vérification du seuil a lieu après un fichier a été ajouté. Notez également que la taille sur le disque d’un élément sérialisé n’est pas exactement la même que le nombre d’octets stockés dans le fichier. Size champ. En d’autres termes, la logique du « package chunking » est approximative.
    • De manière anecdotique, j’ai remarqué que lorsque les packages de contenu deviennent volumineux (x > 200 Mo), leur téléchargement et leur installation peuvent devenir risqués, en fonction de l’environnement. Choisissez une taille adaptée à votre cas d’utilisation.
  • Exclure les dossiers système
    • Par défaut : Coché (☑)
    • Si cette case est cochée, le script ignorera tous les éléments multimédias dont le chemin contient /System/. Ceci est utile pour exclure, par exemple, les miniatures générées par Sitecore.
  • Sortie détaillée de la console
    • Par défaut : Coché (☑)
    • Si cette case est cochée, une sortie supplémentaire est écrite sur la console, ce qui peut être utile lors d’un essai à sec avec le mode débogage (ci-dessous).
  • Mode débogage
    • Par défaut : Coché (☑)
    • Si cette case est cochée, le script n’écrira aucun package de contenu sur le disque. Ceci est utile lors de l’exécution d’exécutions à sec du script pour générer le rapport détaillant quel élément se trouve dans quel package avant de s’engager à écrire un nombre potentiellement important de fichiers ou des fichiers individuels volumineux sur le disque.
    • En supposant que cette case à cocher est décochéles packages de contenu résultants sont enregistrés sur le disque sous le $SitecorePackageFolder chemin, qui est généralement C:\inetpub\wwwroot\App_Data\packages.
    • Si vous ne voyez aucun package de contenu sur le disque, assurez-vous que ce paramètre est décoché.

Sortie 📝

Le script fournit essentiellement trois formes différentes de sortie : la sortie de la console, la boîte de dialogue typique des résultats du rapport SPE (avec fonctionnalité d’exportation CSV et Excel) et les packages de contenu eux-mêmes qui sont écrits sur le disque. Par exemple, en supposant que la sortie de la console détaillée soit cochée et que la taille maximale du package soit de 100 Mo, la sortie de la console pourrait ressembler à ceci :

Exporter des éléments multimédias - Sortie de la console

La ligne cyan affiche le nombre total d’éléments multimédias à traiter en fonction des paramètres. Les lignes vertes détaillent le premier package à créer, les lignes magenta répertoriant chaque élément multimédia de ce premier package. Les lignes vertes et magenta se répètent jusqu’à ce que tous les éléments multimédias soient traités et que tous les packages de contenu soient générés. Le dernier morceau de sortie de la console ressemblera à ceci :

Exporter des éléments multimédias - Console

Les lignes grises représentent les chemins sur le disque pour chacun des packages de contenu générés. Notez que les packages générés sont nommés à l’aide d’un modèle qui inclut un horodatage ; il s’agit de l’heure (du serveur) à laquelle le script a été exécuté et sera la même date et heure pour tous les packages générés lors d’une exécution particulière.

La boîte de dialogue des résultats du rapport est similaire aux autres rapports SPE et pourrait ressembler à ceci :

Exporter des éléments multimédias - Boîte de dialogue Rapport

À partir de là, l’utilisateur peut voir quels éléments multimédias se trouvent dans quels packages. En exportant ces données vers un fichier CSV ou Excel, les utilisateurs peuvent auditer les packages de contenu installés, configurer une automatisation supplémentaire en aval, utiliser le fichier comme manifeste pour l’archivage des éléments multimédias, etc.

Idées d’améliorations 💡

Il y a toujours place à l’amélioration. Voici quelques-unes de mes idées :

  • Ajouter la prise en charge des éléments non multimédias serait sympa, même si cela signifierait devoir comprendre comment calculer la taille des packages. sans l’utilisation du Size champ (qui est unique aux éléments multimédias et est automatiquement défini par Sitecore lors du téléchargement d’un fichier). Je suppose que vous pourriez déterminer la taille d’un article sérialisé en mémoire et l’utiliser…🤔
  • Y compris plus d’extensions : autres extensions d’image, extensions vidéo, extensions Office, etc.
  • Autoriser une plage de dates pour traiter les fichiers ajoutés ou modifiés dans un laps de temps donné.
  • Exposer plus d’options pour l’installation du package plutôt que de supposer un écrasement.
  • Prise en charge d’une convention de dénomination configurable pour les packages générés.
  • Ajustements généraux des performances.

Avez-vous d’autres idées d’améliorations ? Voyez-vous un bug ou une faute de frappe que j’ai manqué ? S’il vous plaît laissez-moi un commentaire ci-dessous! 💬 👇

Le Code 💻

Le script est disponible en tant que GitHub Gist public ici et est également dupliqué ci-dessous si vous ne comprenez pas l’essentiel (blague de papa ?).

<#
    .SYNOPSIS
        Creates content packages for media items matching certain criteria.
        By default, packages are saved to disk at C:\inetpub\wwwroot\App_Data\packages.
        
    .NOTES
        Original "Unused media items" report (/sitecore/system/Modules/PowerShell/Script Library/SPE/Reporting/Content Reports/Reports/Media Audit/Unused media items) written by Michael West.
        Additional parameters, filtering, content package creation, etc. written by Nick Sturdivant.

        This script requires that Sitecore PowerShell Extensions be installed.
#>

$reportName = "Export Media Items"

$extensionOptions = [ordered]@{ "bmp" = "bmp"; "gif" = "gif"; "jpg" = "jpg"; "jpeg" = "jpeg"; "pdf" = "pdf"; "png" = "png"; "svg" = "svg"; }
$maxPackageSizeOptions = [ordered]@{ "5 MB" = 5000000; "10 MB" = 10000000; "25 MB" = 25000000; "50 MB" = 50000000; "100 MB" = 100000000; "250 MB" = 250000000 }
$usedMediaItemOptions = [ordered]@{ "Both" = "both"; "Used" = "used"; "Unused" = "unused" }

$props = @{
    Parameters  = @(
        @{
            Name    = "usedMediaMode"
            Title   = "Media to Include"
            Tooltip = "Determines if the script processes used, unused, or both used and unused media items (where ""used"" is defined as having at least one entry in the link database)."
            Value   = "used"
            Options = $usedMediaItemOptions 
        }
        @{
            Name    = "selectedMediaFolders"
            Title   = "Media Library Folders"
            Tooltip = "The media library folders from which to include items."
            Value   = @()
            Editor  = "treelist" 
        }
        @{
            Name    = "selectedExtensions"
            Title   = "Extensions to Include"
            Tooltip = "The file extension(s) for the media items to process and include in the package(s)."
            Value   = @()
            Options = $extensionOptions
            Editor  = "check" 
        }
        @{
            Name    = "cutoffDate"
            Title   = "Cutoff Date"
            Tooltip = "If set, causes the script to only process media items that were created or updated after this date."
            Value   = [datetime]::MinValue
            Editor  = "date" 
        }
        @{
            Name    = "selectedMaxPackageSize"
            Title   = "Maximum Package Size"
            Tooltip = "The maximum size package the script will generate. If the total size of the media items to be packaged exceeds this limit, then multiple packages are created until all items have been packaged."
            Value   = 25000000
            Options = $maxPackageSizeOptions 
        }
        @{
            Name    = "excludeSystemFolders"
            Title   = "Exclude System Folders"
            Tooltip = "If checked, any media items with ""/System/"" anywhere in their path are ignored."
            Value   = $true
            Editor  = "check" 
        }
        @{
            Name    = "verboseOutput"
            Title   = "Verbose Console Output"
            Tooltip = "If checked, additional output will be written to the console."
            Value   = $true
            Editor  = "check" 
        }
        @{
            Name    = "debugMode"
            Title   = "Debug Mode"
            Tooltip = "If checked, no packages will be saved to disk."
            Value   = $true
            Editor  = "check" 
        }
    )
    Title       = " $reportName"
    Icon        = "OfficeWhite/32x32/box_into.png"
    Description = "This script queries for used and/or unused (referenced) media items and generates content packages containing those items."
    Width       = 600
    ShowHints   = $true
}

$result = Read-Variable @props

$items = @()
$itemsReport = @()
$timestamp = (Get-Date -Format FileDateTimeUniversal)

if ($result -eq "cancel") {
    exit
}

function HasReference {
    param(
        $Item
    )
    
    $linkDb = [Sitecore.Globals]::LinkDatabase
    $linkDb.GetReferrerCount($Item) -gt 0
}

function Get-MediaItemWithReference {
    param(
        [string]$Path,
        [string[]]$Extensions
    )
    
    $mediaItemContainer = Get-Item ("master:" + $Path)
    $excludedTemplates = @([Sitecore.TemplateIDs]::MediaFolder, [Sitecore.TemplateIDs]::Node)
    $items = $mediaItemContainer.Axes.GetDescendants() | 
    Where-Object { $excludedTemplates -notcontains $_.TemplateID } | Initialize-Item | 
    Where-Object { -not $excludeSystemFolders -or ( -not ($_.FullPath -like "*/System/*") ) } |
    Where-Object { $cutoffDate -eq [datetime]::MinValue -or ( $_.__Created -gt $cutoffDate -or $_.__Updated -gt $cutoffDate ) } |
    Where-Object { $Extensions.Count -eq 0 -or $Extensions -contains $_.Fields["Extension"].Value }
    
    # filter based on usage (links)
    foreach ($item in $items) {
        if ($usedMediaMode -eq "both") {
            $item
        }
        if ($usedMediaMode -eq "used" -and (HasReference -Item $item)) {
            $item
        }
        if ($usedMediaMode -eq "unused" -and (-not (HasReference -Item $item))) {
            $item
        }
    }
}

function Build-Package {
    param(
        [Sitecore.Data.Items.Item[]]$Items,
        [int]$Size,
        [int]$PackageNumber,
        [ref]$ItemsReport
    )    
    
    if ($verboseOutput) {
        Write-Host ""
        Write-Host "Building package $PackageNumber..." -ForegroundColor Green
        Write-Host "Total items: $($Items.Count)" -ForegroundColor Green
        Write-Host "Total size: $Size bytes" -ForegroundColor Green
        Write-Host ""
    }
    
    $package = New-Package -Name "Export Media Items"
    $package.Sources.Clear()
    $package.Metadata.Author = "SPE"
    $package.Metadata.Version = $timestamp
    $package.Metadata.Readme = "A package containing media items; generated by a Sitecore PowerShell Extensions script."
    
    $packageZipFileName = "$( $package.Metadata.Version ) - $( $package.Name ) $PackageNumber.zip"
    
    foreach ($itemToPackage in $Items) {
        if ($verboseOutput) {
            Write-Host "`t+ $($itemToPackage.FullPath)` ($($itemToPackage.Fields["Size"].Value -as [int]) bytes)" -ForegroundColor Magenta
        }
        $source = Get-Item $itemToPackage.FullPath | New-ExplicitItemSource -Name "$($itemToPackage.ID)" -InstallMode Overwrite
        $package.Sources.Add($source)
        
        $ItemsReport.Value += @{
            ID       = $itemToPackage.ID
            FullPath = $itemToPackage.FullPath
            Package  = $packageZipFileName
        }
    }

    if (-not $debugMode) {
        Export-Package -Project $package -Path $packageZipFileName -Zip
    }
}

foreach ($selectedMediaFolder in $selectedMediaFolders) {
    # ensure selected media folder is the media library itself or a folder within the media library
    if ($selectedMediaFolder.FullPath -ne "/sitecore/media library" -and $selectedMediaFolder.TemplateID -ne [Sitecore.TemplateIDs]::MediaFolder) {
        Write-Host "Selected folder $($selectedMediaFolder.FullPath) is neither the media library root nor a media folder within the media library and will be ignored." -ForegroundColor Yellow
        continue
    }
    
    $itemsFromPath = Get-MediaItemWithReference -Path $selectedMediaFolder.FullPath -Extensions $selectedExtensions
    
    # prevent duplicate items if overlapping media folders are selected
    foreach ($itemFromPath in $itemsFromPath) {
        $existingItem = $items | Where-Object { $_.ID -eq $itemFromPath.ID }
        if ($null -eq $existingItem) {
            $items += $itemFromPath
        }
    }
}

if ($items.Count -eq 0) {
    Show-Alert "There are no media items matching the specified parameters."
}
else {
    Write-Host "Total media items to be processed and packaged: $($items.Count)" -ForegroundColor Cyan

    $packageSize = 0
    $itemsInPackage = @()
    $itemsProcessed = 0
    $packageCount = 0
    
    foreach ($itemToPackage in $items) {
        $itemsInPackage += $itemToPackage
        $packageSize += $itemToPackage.Fields["Size"].Value -as [int]
        $itemsProcessed++
        
        if ($packageSize -ge $selectedMaxPackageSize -or $itemsProcessed -eq $items.Count) {
            
            $packageCount++

            Build-Package -Items $itemsInPackage -Size $packageSize -PackageNumber $packageCount -ItemsReport ([ref]$itemsReport)
            
            $packageSize = 0
            $itemsInPackage = @()
        }
    }
    
    # report output
    $mediaToInclude = ""
    if ($usedMediaMode -eq "both") {
        $mediaToInclude = "Both (used and unused)"
    } else {
        $mediaToInclude = ($usedMediaMode.Substring(0, 1).ToUpper() + $usedMediaMode.Substring(1))
    }
    $mediaFolders = ""
    $selectedMediaFolders | ForEach-Object { $mediaFolders += "<br/>&nbsp;&nbsp;- $($_.FullPath)" }
    $extensions = $selectedExtensions -join ", "
    if ($extensions -eq "") {
        $extensions = "(all)"
    }
    
    $infoDescription = "List of the media items matching the specified criteria that are contained within the generated content packages.<br/><br/>" +
    "Media to Include: $mediaToInclude<br/>" + 
    "Media Library Folders: $mediaFolders<br/>" +
    "Extensions to Include: $extensions<br/>" + 
    "Cutoff Date: "
    if ($cutoffDate -eq [datetime]::MinValue) {
        $infoDescription += "(none)<br/>"
    }
    else {
        $infoDescription += "$($cutoffDate.ToShortDateString())<br/>"
    }
    $infoDescription += "Maximum Package Size: $($selectedMaxPackageSize / 1000000) MB<br/>" +
    "Exclude System Folders: $excludeSystemFolders<br/>" +
    "Verbose: $verboseOutput<br/>" + 
    "Debug: $debugMode"

    $reportProps = @{
        InfoTitle       = $reportName
        InfoDescription = $infoDescription
        PageSize        = 25
        Title           = $reportName
    }
    
    Write-Host ""
    Write-Host "Finished! 🎉" -ForegroundColor Cyan

    if ($verboseOutput) {
        Write-Host ""
        $itemsReport | 
        ForEach-Object { $_.Package } | 
        Select-Object -Unique | 
        ForEach-Object { Write-Host ($SitecorePackageFolder + "\" + $_) -ForegroundColor Gray }
    }

    # display report output
    $itemsReport |
    Show-ListView @reportProps -Property @{ Label = "ID"; Expression = { $_.ID } },
    @{Label = "Full Path"; Expression = { $_.FullPath } },
    @{Label = "Package"; Expression = { $_.Package } }
}

(📝 Remarque : l’extrait de code ci-dessus Peut-être pas être tenu à jour avec l’essentiel au fil du temps)






Source link