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?

1
  • 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
    Commented Nov 17, 2015 at 6:36

2 Answers 2

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
2
  • 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
    Commented Nov 18, 2015 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. Commented Nov 18, 2015 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 and acknowledge you have read our privacy policy.

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