How can I download all images from each item in a personal MS List?

Adrian GT 0 Reputation points
2025-03-02T16:44:31.8533333+00:00

I was checking the following post:
https://answers.microsoft.com/en-us/msoffice/forum/all/how-to-export-the-photos-from-sharepoint-list-to/4c0edd2c-d6e8-41d6-a477-4dc3ac92d519

I would like to do the same. However, my List is not in SharePoint and instead is in a personal account with the following URL https://lists.live.com/

The images I would like to download from my list are under the Image column type.

Windows for business | Windows Server | User experience | PowerShell
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Rich Matheisen 47,901 Reputation points
    2025-03-02T20:41:41.25+00:00

    I don't have access to the URL, but from what I can get from other sources, I think this should work:

    On lists.live.com, from your list(s), use the "Export to Excel" option. This should download an Excel file containing your list data, including URLs to the images.

    In the code below, you'll have to change the $excelFilePath and $outputDir variable values to whatever you've used to save the Excel file and the directory path you want the images to go. You may also have to change the string "Image_URL_Column_Name" if that's not the correct column name.

    If you have already, install the ImportExcel module. That module makes working with Excel files very easy.

    NOTE: This code has NOT been tested!

    # Import the ImportExcel module
    Import-Module ImportExcel
    
    # Path to the Excel file
    $excelFilePath = "path_to_your_excel_file.xlsx"
    
    # Read the Excel file
    $data = Import-Excel -Path $excelFilePath
    
    # Create a directory to save images
    $outputDir = "downloaded_images"
    if (-Not (Test-Path -Path $outputDir)) {
        New-Item -ItemType Directory -Path $outputDir
    }
    
    # Loop through each row and download images
    foreach ($row in $data) {
        $imageUrl = $row."Image_URL_Column_Name"
        $imageName = $imageName = [System.IO.Path]::GetFileName($imageUrl)
        $imageName = Join-Path -Path $outputDir -ChildPath $imageName
        Invoke-WebRequest -Uri $imageUrl -OutFile $imageName
    }
    

  2. Rich Matheisen 47,901 Reputation points
    2025-03-06T16:31:54.5866667+00:00

    I'm going to throw this out there not knowing if it's something that works or not. You mentioned ChatGPT, so I user CoPilot and asked it for a way to do the work using MS Graph instead of trying to get directly to a URL. Here's what it came up with:

    # Define variables
    $tenantId = "your-tenant-id"
    $clientId = "your-client-id"
    $clientSecret = "your-client-secret"
    $siteId = "your-site-id"
    $listId = "your-list-id"
    
    # Get an access token
    $body = @{
        grant_type    = "client_credentials"
        scope         = "https://graph.microsoft.com/.default"
        client_id     = $clientId
        client_secret = $clientSecret
    }
    $response = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Method Post -Body $body
    $accessToken = $response.access_token
    
    # Get the list items
    $headers = @{
        Authorization = "Bearer $accessToken"
    }
    $listItems = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/sites/$siteId/lists/$listId/items?expand=fields" -Headers $headers
    
    # Download images
    foreach ($item in $listItems.value) {
        $imageUrl = $item.fields.ImageUrl # Adjust this based on your field name
        $fileName = [System.IO.Path]::GetFileName($imageUrl)
        Invoke-WebRequest -Uri $imageUrl -OutFile "C:\path\to\save\$fileName"
    }
    
    0 comments No comments

  3. Rich Matheisen 47,901 Reputation points
    2025-03-03T20:22:56.59+00:00

    Okay . . . understand that I'm working in the dark, so to speak. I don't have access to the web site in question. So, take what I post on this subject as "educated guesses".

    With that said, I don't really have a very elegant way to get the "root" part of the URL except for copying the URL of one of the images. That value (with a bit of judicious manual editing) will replace the $baseUrl value in the code below. You'll basically just be trimming everything after the "/attachments/" to the end of the URL.

    Next, I'm not sure that getting the file name from the end of the URL is going to work very well. The HTML encoded attachment name looks like this:

    %5B5%5D_%5BImage%5D%5B28%5D_%5BScreenshot%202024-04-06%20074303%5D%5B1%5D_%5B1%5D.png

    Which decodes to this: [5]_[Image][28]_[Screenshot 2024-04-06 074303]_[1]_[1].png

    And I'm assuming the real name is Screenshot 2024-04-06 074303.png -- but I'm not sure what the [1] [1] represent.

    The invalid access is solved by your creating a credential with your name/password and using that credential when you use the Invoke-WebRequest.

    Take another shot at getting the images with this code. But you may yet need some help/guidance from a SME for the product you're working with. PowerShell can help, but it requires knowing what needs to done!

    # URL copied from web site
                #https://lists.live.com/personal/2dd00bbfdecb79f6/_api/v2.1/sites('9847079b-02c6-40fe-af8d-034b7cbf1b25,af0163b3-9812-47d9-9485-a8a853f37c4b')/lists('519f099d-d358-4665-9fb1-393b07ce7675')/items('1')/attachments('Reserved_ImageAttachment_%5B5%5D_%5BImage%5D%5B28%5D_%5BScreenshot%202024-04-06%20074303%5D%5B1%5D_%5B1%5D.png')/thumbnails/0/c3000x2000/content?prefer=noredirect%2Cclosestavailablesize
    # the part of the URL I _think_ is relevant
    $baseUrl =  "https://lists.live.com/personal/2dd00bbfdecb79f6/_api/v2.1/sites('9847079b-02c6-40fe-af8d-034b7cbf1b25,af0163b3-9812-47d9-9485-a8a853f37c4b')/lists('519f099d-d358-4665-9fb1-393b07ce7675')/items('1')/attachments/"
    
    $UserName = "your_username"
    $Password = Read-Host -AsSecureString "Enter Password"
    
    # Create a PSCredential object
    $Credential = New-Object System.Management.Automation.PSCredential($UserName, $Password)
    
    # Import the ImportExcel module
    Import-Module ImportExcel
    
    # Path to the Excel file
    $excelFilePath = "path_to_your_excel_file.xlsx"
    
    # Read the Excel file
    $data = Import-Excel -Path $excelFilePath
    
    # Create a directory to save images
    $outputDir = "downloaded_images"
    if (-Not (Test-Path -Path $outputDir)) {
        New-Item -ItemType Directory -Path $outputDir
    }
    
    # Function to extract the actual URL from the "Reserved_ImageAttachment" format
    function Get-ActualImageUrl {
        param (
            [string]$reservedImageAttachment
        )
        $imageName = $reservedImageAttachment -replace "Reserved_ImageAttachment_", ""
        "{0}{1}" -f $baseUrl, $imageName
    }
    
    # Loop through each row and download images
    foreach ($row in $data) {
        $reservedImageAttachment = $row."Image_URL_Column_Name"
        $imageUrl = Get-ActualImageUrl -reservedImageAttachment $reservedImageAttachment
        $imageName = [System.IO.Path]::GetFileName($imageUrl)
        $imageName = Join-Path -Path $outputDir -ChildPath $imageName
        Invoke-WebRequest -Uri $imageUrl -OutFile $imageName -Credential $Credential
    }
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.