Here are a few solutions I've seen.
Sitecore OOTB
@jammykam has a nice article on using the WebDav, file upload (zip), and media watcher features. These are nice because there is not much to setup. You however have no way of getting the item Ids.
SPE Script
Himadri wrote an article that probably predates the SPE Remoting module. Here he used a script that was bundled with SPE called Upload-SitecoreFile
. I'm not sure if this still functions but it could be worth a try. The nice part is that you are working from within the Sitecore instance and can essentially write whatever script you want. It also assumes that the files are on the local machine, perhaps $SitecoreDataFolder
would be a good place.
SPE Script #2
Mikael shared a gist to update existing media items. In there he uses the System.IO.FileStream
to read in media files. Perhaps extending this script to upload media that do not yet exist would get you pretty close.
SPE Script #3
@adamnaj wrote a gist which provides both a New-MediaItem
and Update-MediaItem
command that can be used in the Sitecore instance with files on the local machine. After running these commands I would pass the data to Export-Csv
with the item Ids and path.
function New-MediaItem{
[CmdletBinding()]
param(
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
[ValidateNotNullOrEmpty()]
[string]$filePath,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$mediaPath
)
$mco = New-Object Sitecore.Resources.Media.MediaCreatorOptions
$mco.Database = [Sitecore.Configuration.Factory]::GetDatabase("master");
$mco.Language = [Sitecore.Globalization.Language]::Parse("en");
$mco.Versioned = [Sitecore.Configuration.Settings+Media]::UploadAsVersionableByDefault;
$mco.Destination = "$($mediaPath)/$([System.IO.Path]::GetFileNameWithoutExtension($filePath))";
$mc = New-Object Sitecore.Resources.Media.MediaCreator
$mc.CreateFromFile($filepath, $mco);
}
# Usage example
New-MediaItem "C:\Users\Adam\Desktop\Accelerators.jpg" "$([Sitecore.Constants]::MediaLibraryPath)/Images"
function Update-MediaItem{
[CmdletBinding()]
param(
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
[ValidateNotNullOrEmpty()]
[string]$filePath,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$mediaPath)
[Sitecore.Data.Items.MediaItem]$item = gi $mediaPath
[Sitecore.Resources.Media.Media] $media = [Sitecore.Resources.Media.MediaManager]::GetMedia($item);
$extension = [System.IO.Path]::GetExtension($filePath);
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList $filePath, "Open", "Read"
$media.SetStream($stream, $extension);
$stream.Close();
}
# Usage example - overwrite the image created with previous cmdlet with new image
Update-MediaItem "$SitecoreDataFolder\Tchotchkeys.jpg" "$([Sitecore.Constants]::MediaLibraryPath)/Images/Accelerators"
SPE Receive-File
If you like the ease of use with the OOTB upload wizard, then this command is a good choice. The book has examples on the command usage. If you kept it simple, then upload to a custom directory, then use Get-ChildItem
to get all the item Ids. Restructure after the fact per your requirements.
Receive-File -ParentItem (get-item "master:\media library\mymedia")
SPE Remoting Service
This is usually a popular choice because it can be performed when Sitecore is on the same machine and when it's not.
The SPE repository contains an example script that shows how to upload individual files to the media library and then receive the related item GUID. If the item already exists then it can update the existing item (think detach/attach). There is also an example to upload a zip file containing a folder, which should maintain the folder structure.
Conclusion
As you can see, everyone has had an approach. Hopefully what you come up with with be even better and you'll share it here ;-)