1

I've found this great script that downloads all images and their folders from a given library.

I'd like to update it so that it only gets images that have a certain value for the product code. However when I try to just log the code filed I'm getting a null value.

$destination = "D:\\images"
$webUrl = "https://site.local/"
$listUrl = "https://site.local/images"
##############################################################

$web = Get-SPWeb -Identity $webUrl
$list = $web.GetList($listUrl)
$spQuery = New-Object Microsoft.SharePoint.SPQuery
$camlQuery = '<Query>
                <Where>
                    <and>
                        <Neq>
                            <FieldRef Name='Code' />
                            <Value Type='Lookup'>''</Value>
                        </Neq>
                        <Eq>
                            <FieldRef Name='Created' />
                            <Value Type='DateTime'><Today /></Value>
                        </Eq>
                    </and>
                </Where>
            </Query>'
$spQuery.Query = $camlQuery
$spListItems = $list.GetItems($spQuery)

function ProcessFolder {
    param($folderUrl)
    $folder = $web.GetFolder($folderUrl)
    foreach ($file in $folder.Files) {
        #Customising Varun Malhotra script
        #Get value of Product Code
        $item = $list.Items[0]
        Write-Host $item["Code"].ToString()

        Write-Host $item

        #Ensure destination directory
        $destinationfolder = $destination + "/" + $folder.Url 
        if (!(Test-Path -path $destinationfolder))
        {
            $dest = New-Item $destinationfolder -type directory 
        }

        Write-Host $file

        #Download file
        $binary = $file.OpenBinary()
        $stream = New-Object System.IO.FileStream($destinationfolder + "/" + $file.Name), Create
        $writer = New-Object System.IO.BinaryWriter($stream)
        $writer.write($binary)
        $writer.Close()
        }
}

#Download root files
ProcessFolder($list.RootFolder.Url)
#Download files in folders
foreach ($folder in $list.Folders) {
    ProcessFolder($folder.Url)
}

I think I'm not getting the $item correctly as I've already got the list of files??

EDIT: I've updated the script with a Caml Query that will find only the items I want. I'm now not sure how I can get $spListItems to fit into the ProcessFolder function so it can run for ALL folders in the library but only find the Caml selected items?

  • can you be more specific, as you said "only gets images that have a certain value for the product code" What is that certain means here, any specific value, or set of values.. or any values – Gaurravs Nov 17 '15 at 6:36
0

In your foreach loop you are always selecting the first item from your list (not even filtered). You need to change the following line:

$item = $list.Items[0]

to this:

$item = $file.Item
  • Hi Paul,Thanks for the reply, though I'm still getting an error: You cannot call a method on a null-valued expression. At D:\scripts\downloadImagesTo.ps1:23 char:13 + Write-Host $item["Code"].ToString() + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull – sansSpoon Nov 18 '15 at 4:00
  • That means that "Code" column for that item is empty and the code fails when trying to convert "null" to "string" or the item itself is null. When using $item["ColumnName"], make sure that "ColumnName" is an internal column name and not the title. Try debugging your code line by line and you'll find out what's the problem. – Paul Strupeikis Nov 18 '15 at 9:01
0

I found this different way of doing a powershell query and modified it to suit what I was trying to do above. I also realised that I don't need the folder structure when exporting so that really simplified things.

Write-Host “Getting images from Diageo campaign manager….”
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue

######################## Start Variables ########################
$destination = "D:\\images\"
$webUrl = "https://site.local/"
$listUrl = "https://site.local/images"
##############################################################

#create the list
$web = Get-SPWeb -Identity $webUrl
$list = $web.GetList($listUrl)

# get items from the list based on query
$listItems = $list.Items | ?{$_["code"] -eq "1"}

#loop through each of the found items and download
try
{
    foreach($listItem in $listItems)
    {
        #Write-Host $listItem["Title"]
        Write-Host "Downloading: "$listItem.Url

        #Downloading file
        $binary = $web.GetFile($listItem.Url).OpenBinary()
        $stream = New-Object System.IO.FileStream($destination + "/" + $listItem.Name), Create
        $writer = New-Object System.IO.BinaryWriter($stream)
        $writer.write($binary)
        $writer.Close()
    }
}

catch
{
    write-host $_.exception

}

finally
{
    if($web -ne $null)
    {
        $web.Dispose()
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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