4
votes

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?

1
Have you tried with Fiddler to see traffic from server ? If on premise check ULS logMax
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).Graham
1. attach file to existing list item 2. uploaded from workstation 3. needs researchcraig

1 Answers

2
votes

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 {}

}