0

I have Sitecore 8.2 where I got spe version 6.4

I have got a csv file, where sample of data i.e. one row looks as

"Item ID","Title","Created","Changed","Media-ID","Related Site","Search Tags"
"{565E7592-8CA7-46D9-8399-2AB5E66C4EEB}","opening hours","4/17/2018 5:52:40 AM","4/23/2018 3:37:07 AM","{8BC6415F-DCB8-491B-BA3F-CD4FCF27CFD9}","Council", "About us"

Now, I want to download the media item used by this item whose item ID is in this sample data, {8BC6415F-DCB8-491B-BA3F-CD4FCF27CFD9} is a media item id used in this item, and the media is in /sitecore/media library path so for this I have written script which is trying to read from csv file(where these above sample data are), then find 'Media-ID' column for each row and find the item in the given path based on the media item id I am trying to download the media item using Send-File, and my script looks like

# Read the CSV file
$csvData = Import-Csv -Path "C:\Usman\news_export.csv"

# Loop through each row in the CSV data
foreach ($row in $csvData) {
    $mediaId = $row.'Media-ID'
    
    # Check if Media-ID is not empty
    if (-not [string]::IsNullOrEmpty($mediaId)) {
        $mediaItemPath = "master:/sitecore/media library"
        
        Write-Host "Media ID: $mediaId"
        Write-Host "Media Item Path: $mediaItemPath"
        
        # Get the media item
        $mediaItem = Get-Item -Path $mediaItemPath -ID $mediaId
        
        # Check if media item exists
        if ($mediaItem -ne $null) {
            # Download the media item
            Send-File -Item $mediaItem -Message "Download"
        } else {
            Write-Host "Media item with ID '$mediaId' not found."
        }
    }
}

My questions

  1. How do I make this work/any other way to achieve this?
  2. How do I specify a path to download, like if I need to download in C:\myImage\imageFolder ,how do I do that?

Thanks :)

Update:

Thanks Everyone, I am actually trying to read from $csvData = Import-Csv -Path "C:\Usman\news_export.csv" and grab data from this csv from each row's "Media-ID" column. Then search on media library(based on media library path '\sitecore\media library') and search for that media item id. Which I have grabbed from csv already in above script. The main thing is it does download but shows 0 kb with my code.

how do I create a zip package adding all these media items, and then download this zip specifying the path where is this zip to be downloaded

3 Answers 3

0

For both of your questions, the best way to create a zip and download it, if you have multiple items in different folders.

Take this script as a reference.

#Upload Data Folder for CSV Upload
$dataFolder = [Sitecore.Configuration.Settings]::DataFolder
$tempFolder = $dataFolder + "\temp\upload"
$filePath = Receive-File -Path $tempFolder -overwrite
 
if($filePath -eq "cancel"){
    exit
}

#Initiate the Items Array
$items = @()

$importList =  Import-Csv $filePath

foreach ( $row in $importList ) {
    $item = Get-Item -Path master: -Id $row.ID
    if ($item){
        $items += $item    
    }
}

#Now we got the list of items to be downloaded in an array.
#Pass on the array to the below out of the box script. 


#Script copied from Script Library/SPE/Maintenance/Media Library Maintenance/Content Editor/Context Menu/Download
#Commented a line below to get items from CSV
function ZipItems( $zipArchive, $sourcedir )
{
  Set-Location $sourcedir
  [System.Reflection.Assembly]::Load("WindowsBase,Version=3.0.0.0, `
      Culture=neutral, PublicKeyToken=31bf3856ad364e35") > $null
  $ZipPackage=[System.IO.Packaging.ZipPackage]::Open($zipArchive, `
      [System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::ReadWrite)
      
  #Commented this line as Items array is provided from the above script
  #$items = @(Get-Item $sourceDir) + (Get-ChildItem -recurse $sourceDir)
  
  [byte[]]$buff = new-object byte[] 40960
  $i = 0;
  ForEach ($item In $items) {
    $i++
    if([Sitecore.Resources.Media.MediaManager]::HasMediaContent($item)){
      $mediaItem = New-Object "Sitecore.Data.Items.MediaItem" $item;
      $mediaStream = $mediaItem.GetMediaStream();
      $fileName = Resolve-Path -Path $item.ProviderPath -Relative
      $fileName = "$fileName.$($item.Extension)".Replace("\","/").Replace("./","/");
      "Added: $fileName"
      Write-Progress -Activity "Zipping Files " -CurrentOperation "Adding $fileName" -Status "$i out of $($items.Length)" -PercentComplete ($i *100 / $items.Length)
      $partUri = New-Object System.Uri($fileName, [System.UriKind]::Relative)
      $partUri = [System.IO.Packaging.PackUriHelper]::CreatePartUri($partUri);
      $part=$ZipPackage.CreatePart($partUri, "application/zip", [System.IO.Packaging.CompressionOption]::Maximum)
      $stream=$part.GetStream();
      do {
        $count = $mediaStream.Read($buff, 0, $buff.Length)
        $stream.Write($buff, 0, $count)
      } while ($count -gt 0)
      $stream.Close()
      $mediaStream.Close()
    }
  }
  $ZipPackage.Close()
}

$location = get-location
$time = Get-Date -format "yyyy-MM-d_hhmmss"
$zipName = Split-Path -leaf $location | % { $_ -replace " ", ""}
$zipPath = "$($SitecoreDataFolder)\$zipName-$time.zip"

ZipItems $zipPath $location
Download-File -FullName $zipPath > $null
Remove-Item $zipPath
Close-Window

You can modify it a little bit as per your needs but it will fulfill your requirement.

For more reference:

https://www.nehemiahj.com/2022/05/

Hope this helps.

2
  • Thanks, this helped. :) Commented Mar 22 at 0:25
  • @RaunakBasnet Kindly accept the answer if this helps you. Commented Mar 22 at 6:14
1

You can refer below script to download all media files from any content folder on CMS.

$childItems = Get-ChildItem -Path "master:" -Id "Id of the content folder"
$mediaItems = @()
foreach($childitem in $childItems){
  if($childitem.Fields["Image"]){
    [Sitecore.Data.Fields.ImageField]$imageField = $childitem.Fields["Image"]
    if($imageField.MediaItem){
        $media = Get-Item -Path "master:" -Id $imageField.MediaID
        $mediaItems +=$media
    }
 }
}
Write-Host ($mediaItems | Format-List | Out-String)
try {

  Add-Type -AssemblyName System.IO.Compression
  $time = Get-Date -format "yyyy-MM-d_hhmmss"
  $zipName = "MediaFiles"
  $zipOutputPath = "$($SitecorePackageFolder)\$($zipName)-$($time).zip"
  $compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal

  $stream = New-Object System.IO.FileStream($zipOutputPath, 
  [System.IO.FileMode]::OpenOrCreate)
  $zip = New-Object System.IO.Compression.ZipArchive($stream, 
  [System.IO.Compression.ZipArchiveMode]::Update)

  $counter = 0
  $total = $mediaItems.Length

  foreach($item in $mediaItems) {
    $counter++
    Write-Progress -Activity "Zipping Files" -CurrentOperation "Processing 
    $($item.ID) $($item.Name)" -Status "$($counter) of $($total)" - 
    PercentComplete ($counter * 100 / $total)
    
    if(![Sitecore.Resources.Media.MediaManager]::HasMediaContent($item)) { 
    continue }
    
    $filename = Resolve-Path -Path $item.ProviderPath -Relative
    $entryname = "$($item.Name).$($item.Extension)"
    Write-Host "Adding $($item.ID) $($entryname)"

    $mediaItem = [Sitecore.Data.Items.MediaItem]$item
    $mediaStream = $mediaItem.GetMediaStream()
        
    $entry = $zip.CreateEntry($entryname, $compressionLevel)
    $entryStream = $entry.Open()
        
    $mediaStream.CopyTo($entryStream)
        
    $entryStream.Dispose()
    $entryStream.Close()
        
    $mediaStream.Dispose()
    $mediaStream.Close()
  }
 } finally {
   Write-Progress -Activity "Finishing up" -Completed
   $zip, $stream | Where-Object { $_ -is [System.IDisposable] } | ForEach- 
   Object Dispose
 }
Send-File -FullName $zipOutputPath > $null
Remove-Item $zipOutputPath

In the above script I am getting all the media files from the 'Image' field of the item located under the following folder. You can replace the folder ID in the above script to the ID from where you would like to read media field.

enter image description here

Hope this helps!

0

Your script looks fine as it is.

If Send-File doesn't work, you can use the Out-Download to achieve the same. It will be as below:

[Sitecore.Data.Items.MediaItem]$mediaItem = gi $mediaItemPath
$fileName = [string]::Format("{0}.{1}", $mediaItem.Name, $mediaItem.Extension)
$item.GetMediaStream() | Out-Download -Name $fileName

You cannot specify the folder it will be downloaded to. However, Sumit's answer could be useful for you to first create a zip out of it, and then download.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.