4

I'm attempting to upload a file to SharePoint 2010:

Function Add-Attachments()
{

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$True)]
        [int]$Id,
        [Parameter(Mandatory=$True)]
        [string[]]$Paths
    )

    BEGIN {}
    PROCESS {

        $url = "http://server/resource/_vti_bin/listdata.svc/TheList($Id)/Attachments"

        Foreach ($Path in $Paths) {

            Write-Verbose "Attaching $Path ..."
            $headers = @{
                'Slug' = "TheList|$Id|$(Split-Path $path -Leaf)"
            }

            $Payload = @{filename=(Split-Path $path -Leaf);filecontent=([IO.File]::ReadAllBytes($path))}

            Invoke-WebRequest -Uri $url -Method Post -UseDefaultCredentials -Body $Payload -Headers $headers

        } # Foreach

    } # PROCESS
    END {}

}

Add-Attachments -Id 1234 -Paths 'C:\Users\gandalf\Desktop\test.txt' -verbose

I get an error that reads:

Invoke-WebRequest : An error occurred while processing this request. At C:\Users\gandalf\Documents\WindowsPowerShell\Scripts\SP\SharePoint2010.ps1:382 char:13 + Invoke-WebRequest -Uri $url -Method Post -UseDefaultCredentials -Bod ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

** edit **

The file's original content:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.

The script does create a file on the server, but with this content:

filename=test.txt&filecontent=Lorem+ipsum+dolor+sit+amet%2c+consectetur+adipiscing+elit.+Donec+a+diam+lectus.+Sed+sit+amet+ipsum+mauris.+Maecenas+congue+ligula+ac+quam+viverra+nec+consectetur+ante+hendrerit.+Donec+et+mollis+dolor.+Praesent+et+diam+eget+libero+egestas+mattis+sit+amet+vitae+augue.+Nam+tincidunt+congue+enim%2c+ut+porta+lorem+lacinia+consectetur.+Donec+ut+libero+sed+arcu+vehicula+ultricies+a+non+tortor.+Lorem+ipsum+dolor+sit+amet%2c+consectetur+adipiscing+elit.+Aenean+ut+gravida+lorem.+Ut+turpis+felis%2c+pulvinar+a+semper+sed%2c+adipiscing+id+dolor.+Pellentesque+auctor+nisi+id+magna+consequat+sagittis.+Curabitur+dapibus+enim+sit+amet+elit+pharetra+tincidunt+feugiat+nisl+imperdiet.+Ut+convallis+libero+in+urna+ultrices+accumsan.+Donec+sed+odio+eros.+Donec+viverra+mi+quis+quam+pulvinar+at+malesuada+arcu+rhoncus.+Cum+sociis+natoque+penatibus+et+magnis+dis+parturient+montes%2c+nascetur+ridiculus+mus.+In+rutrum+accumsan+ultricies.+Mauris+vitae+nisi+at+sem+facilisis+semper+ac+in+est.

What am I missing? Do I need to include the content length? Set the MIME type?

3
  • 1
    Have you tried with Fiddler to see traffic from server ? If on premise check ULS log Commented Jun 17, 2015 at 9:09
  • A few questions: 1) Are you trying to attach a file to an existing list item or are you wanting to just upload the file to a folder? /Attachments should be specific to attaching to list items. 2) Is this being uploaded from a server in the farm or is this remote? 3) What line in the code does 382 point to? (as you only have 35 lines, I assume there's more). Commented Jun 19, 2015 at 17:55
  • 1. attach file to existing list item 2. uploaded from workstation 3. needs research Commented Jun 19, 2015 at 21:01

1 Answer 1

2
+50

In order to create an attachment resource the following properties have to be specified:

Endpoint Uri: http://server/site/_vti_bin/listdata.svc/entityset(itemid)/Attachments
Method: POST
Headers:
   Slug: "entityset|itemid|name"
   ContentType: */* 
Body: content

Having said that, my conslution that the specified body parameter ($payload) is invalid in the provided example.

The following example demonstrates how to upload attachment file via SharePoint 2010 REST Interface:

Function Add-Attachments()
{

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$True)]
        [string]$WebUrl, 
        [Parameter(Mandatory=$True)]
        [string]$ListName, 
        [Parameter(Mandatory=$True)]
        [int]$ItemId,
        [Parameter(Mandatory=$True)]
        [string]$SourcePath
    )

    BEGIN {}
    PROCESS {
        $endpointUri = New-Object System.Uri("$WebUrl/_vti_bin/listdata.svc/$ListName($ItemId)/Attachments")
        $fileName = (Split-Path $SourcePath -Leaf)
        $fileContent = ([IO.File]::ReadAllBytes($SourcePath))
        $headers = @{
                 'Slug' = "$ListName|$ItemId|$fileName";
        }

        Invoke-WebRequest -Uri $endpointUri -Method Post -UseDefaultCredentials -Body $fileContent -Headers $headers -ContentType "*/*"

    } # PROCESS
    END {}

}

Usage:

Add-Attachments -WebUrl "http://contoso.intranet.com/" -ListName "Tasks" -ItemId 1 -SourcePath "C:\Users\user\Documents\SharePointUserGuide.docx" -verbose

Update

After performing some analysis via Fiddler, it was determined that the proper endpoint url should be:

/_vti_bin/listdata.svc/Attachments HTTP/1.1

instead of:

/_vti_bin/listdata.svc/Tasks(<id>)/Attachments HTTP/1.1

Modified example

Function Add-Attachments()
{

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$True)]
        [string]$WebUrl, 
        [Parameter(Mandatory=$True)]
        [string]$ListName, 
        [Parameter(Mandatory=$True)]
        [int]$ItemId,
        [Parameter(Mandatory=$True)]
        [string]$SourcePath
    )

    BEGIN {}
    PROCESS {
        $endpointUri = New-Object System.Uri("$WebUrl/_vti_bin/listdata.svc/Attachments")  
        $fileName = (Split-Path $SourcePath -Leaf)
        $fileContent = ([IO.File]::ReadAllBytes($SourcePath))
        $headers = @{
                 'Slug' = "$ListName|$ItemId|$fileName";
        }

        Invoke-WebRequest -Uri $endpointUri -Method Post -UseDefaultCredentials -Body $fileContent -Headers $headers -ContentType "*/*"

    } # PROCESS
    END {}

}
Sign up to request clarification or add additional context in comments.

7 Comments

Would this work to replace a file (assuming same names) with a new version? Or would the method need to be PUT?
The function returns System.Net.WebException: The remote server returned an error: (500) Internal Server Error.. On a positive note, the file is attached to the task and its content appears to be valid. Thoughts?
It seems so, tried to consume the same request via c# Web Request but never encountered the same error..
Or this?
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.