none
Upload file to Sharepoint with Powershell and REST - Error 400 Bad Request RRS feed

  • Question

  • Hi,

    I'm trying to upload a file to our SharePoint 2013 via Powershell and Rest but I get an Error (400) Bad Request.

    this is my first time I use REST, so please excuse if the following script is completely wrong:

    $response = Invoke-RestMethod -Method post -UseDefaultCredentials -uri "https://sharepoint.xyz.de/siteXXXX/_api/contextinfo"
    $Digest = $response.getcontextwebinformation.FormDigestValue
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $Headers.Add("accept","application/json;odata=verbose")
    $Headers.Add("X-RequestDigest",$Digest)
    Invoke-WebRequest -method post -UseDefaultCredentials -uri "https://sharepoint.xyz.de/siteXXXX/_api/web/GetFolderByServerRelativeUrl('/Dokumente/Folder/Subfolder')/files/add(overwrite=true,url='File1.doc')" -InFile H:\test\File1.doc -headers $Headers
    

    I read several Blogs/posting in the Internet but did not find a solution.

    Does anyone have a hint, what's wrong in my script or how to use Powershell + Rest to upload files to SharePoint?

    Kind regards,

    Georg

    Friday, March 10, 2017 10:19 AM

Answers

  • Hi all,

    I found the root cause of my problem. I had an extra / in my URL:

     GetFolderByServerRelativeUrl('/Dokumente/Folder/Subfolder')

    correct is:

    GetFolderByServerRelativeUrl('Dokumente/Folder/Subfolder')

    So, conclusion is, it's possible to upload files to SharePoint without any extra DLLs from Client side!

    For anyone who's interested here is a powershell example script for uploading files to SharePoint (quick and dirty Version):

    #Upload File
    $Response = Invoke-RestMethod -Method post -UseDefaultCredentials -uri "https://sharepoint.xyz.de/sitexxxx/_api/contextinfo"
    $Digest = $response.getcontextwebinformation.FormDigestValue
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $Headers.Add("accept","application/json;odata=verbose")
    $Headers.Add("X-RequestDigest",$Digest)
    $Headers.add("content-length",$FileContent.length)
    Invoke-RestMethod -method post -UseDefaultCredentials -uri "https://sharepoint.xyz.de/sitexxxx/_api/web/GetFolderByServerRelativeUrl('Dokumente/Folder/Subfolder')/files/add(overwrite=true,url='Testfile')" -infile h:\test\Testfile.doc -headers $Headers 
    
    #modify Metadata
    $item = Invoke-RestMethod -method get -UseDefaultCredentials -uri "https://sharepoint.xyz.de/sitexxxx/_api/web/GetFolderByServerRelativeUrl('Dokumente/Folder/Subfolder')/files('Testfile')/listitemallfields"
    $body  = "{'__metadata': { 'type': 'SP.ListItem'},'Title': 'TestTitel','OData__Version': '1.0'}";
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $Headers.Add("accept","application/json;odata=verbose")
    $Headers.Add("X-RequestDigest",$Digest)
    $Headers.add("X-HTTP-Method","PATCH")
    $Headers.add("content-length",$body.length)
    $Headers.Add("IF-MATCH",$Item.entry.etag)
    $Headers.Add("content-type","application/json;odata=verbose")
    Invoke-RestMethod -method post -UseDefaultCredentials -uri "https://sharepoint.xyz.de/sitexxxx/_api/web/GetFolderByServerRelativeUrl('Dokumente/Folder/Subfolder')/files('Testfile')/listitemallfields" -body $body -headers $Headers 
    
    #CheckIn
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $Headers.Add("X-RequestDigest",$Digest)
    Invoke-RestMethod -method post -UseDefaultCredentials -uri "https://sharepoint.xyz.de/sitexxxx/_api/web/GetFolderByServerRelativeUrl('Dokumente/Folder/Subfolder')/files('Testfile')/CheckIn(checkintype=0)" -headers $Headers 
    
    

    This will upload the file, modify the needed metadata fields and check in the file.

    If a file should be overwritten, it has to be checked out first.

    Anyway, thanks to everybody who tried to help me in this post.

    Kind regards

    Georg

    • Marked as answer by gkuehlem Monday, March 13, 2017 10:38 AM
    Monday, March 13, 2017 10:17 AM

All replies

  • Please use the following script:

    cls
    # the path here may need to change if you used e.g. C:\Lib.. 
    Add-Type -Path "C:\Install\SharePointOnlinePowerShellScripts\ISAPI\Microsoft.SharePoint.Client.dll" 
    Add-Type -Path "C:\Install\SharePointOnlinePowerShellScripts\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"  
    
    Function Invoke-RestSPO(){
        Param(
        [Parameter(Mandatory=$True)]
        [String]$Url,
    
        [Parameter(Mandatory=$False)]
        [Microsoft.PowerShell.Commands.WebRequestMethod]$Method = [Microsoft.PowerShell.Commands.WebRequestMethod]::Post,
    
        [Parameter(Mandatory=$True)]
        [String]$UserName,
    
        [Parameter(Mandatory=$False)]
        [String]$Password
        )
     
        if([string]::IsNullOrEmpty($Password)) {
           $SecurePassword = Read-Host -Prompt "Enter the password" -AsSecureString 
        }
        else {
           $SecurePassword = $Password
        }
     
    
        $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
        $request = [System.Net.WebRequest]::Create($Url)
        $request.Credentials = $credentials
        $request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f")
        $request.Accept = "application/json;odata=verbose"
        $request.Method=$Method
        $request.
        $response = $request.GetResponse()
        $requestStream = $response.GetResponseStream()
        $readStream = New-Object System.IO.StreamReader $requestStream
        $data=$readStream.ReadToEnd()
        $results = $data | ConvertFrom-Json
        $results.d.results 
    
    }
    Function Upload-SPOFile(){
    
        Param(
          [Parameter(Mandatory=$True)]
          [String]$WebUrl,
    
          [Parameter(Mandatory=$True)]
          [String]$UserName,
    
          [Parameter(Mandatory=$True)]
          [String]$Password, 
    
          [Parameter(Mandatory=$True)]
          [String]$FolderUrl,
    
          [Parameter(Mandatory=$True)]
          [System.IO.FileInfo]$FileInfo
    
        )
    
    
           $Url = $WebUrl + "/_api/web/GetFolderByServerRelativeUrl('" + $FolderUrl + "')/Files/add(url='" + $FileInfo.Name + "',overwrite=true)"
           $FileContent = [System.IO.File]::ReadAllBytes($FileInfo.FullName)
    
           $contextInfo = Get-SPOContextInfo  $WebUrl $UserName $Password
           Invoke-RestSPO -Url $Url -Method Post -UserName $UserName -Password $Password -Body $FileContent  -RequestDigest $contextInfo.GetContextWebInformation.FormDigestValue
           
    }
    
    
    #Site collection URL where we need to create the site columns  
    $WebUrl = Read-Host -Prompt 'Provide the website url'
    
    #User name and Passwords  
    $UserName = Read-Host -Prompt 'Provide the user name' 
    $Password = Read-Host -Prompt 'Provide the password' -AsSecureString
    
    #Path of the elements.xml file with field list
    #"C:\Users\user\Documents\SharePoint User Guide.docx"
    $filePath = Read-Host -Prompt 'Provide full path of the file' 
    
    #Usage: upload file into SharePoint Online folder  
    #"/Shared Documents"
    $FolderUrl = Read-Host -Prompt 'Provide the onle folder path'  
    
    Upload-SPOFile -WebUrl $WebUrl -UserName $UserName -Password $Password -FolderUrl $FolderUrl -FileInfo $UploadFileInfo

    Please refer to the following links for more details:

    https://gist.github.com/vgrem/9255180

    http://stackoverflow.com/a/25414535


    Avijit Sur




    • Edited by Avijit Sur Friday, March 10, 2017 2:04 PM edit2
    Friday, March 10, 2017 1:58 PM
  • Hi,

    thanks for the Response.

    Does it mean, that there is no way to upload files to SharePoint by using REST in Powershell without any additional components?

    Kind regards

    Georg


    • Edited by gkuehlem Monday, March 13, 2017 6:38 AM
    Monday, March 13, 2017 6:37 AM
  • Hi gkuehlem,

    If you want to to upload files in client side, then it is necessary to reference SharePoint Client dll in PowerShell script to implement it.

    A demo about uploading files in PowerShell for your reference:

    Upload files using PowerShell

    Thanks

    Best Regards


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    Monday, March 13, 2017 8:48 AM
  • Hi all,

    I found the root cause of my problem. I had an extra / in my URL:

     GetFolderByServerRelativeUrl('/Dokumente/Folder/Subfolder')

    correct is:

    GetFolderByServerRelativeUrl('Dokumente/Folder/Subfolder')

    So, conclusion is, it's possible to upload files to SharePoint without any extra DLLs from Client side!

    For anyone who's interested here is a powershell example script for uploading files to SharePoint (quick and dirty Version):

    #Upload File
    $Response = Invoke-RestMethod -Method post -UseDefaultCredentials -uri "https://sharepoint.xyz.de/sitexxxx/_api/contextinfo"
    $Digest = $response.getcontextwebinformation.FormDigestValue
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $Headers.Add("accept","application/json;odata=verbose")
    $Headers.Add("X-RequestDigest",$Digest)
    $Headers.add("content-length",$FileContent.length)
    Invoke-RestMethod -method post -UseDefaultCredentials -uri "https://sharepoint.xyz.de/sitexxxx/_api/web/GetFolderByServerRelativeUrl('Dokumente/Folder/Subfolder')/files/add(overwrite=true,url='Testfile')" -infile h:\test\Testfile.doc -headers $Headers 
    
    #modify Metadata
    $item = Invoke-RestMethod -method get -UseDefaultCredentials -uri "https://sharepoint.xyz.de/sitexxxx/_api/web/GetFolderByServerRelativeUrl('Dokumente/Folder/Subfolder')/files('Testfile')/listitemallfields"
    $body  = "{'__metadata': { 'type': 'SP.ListItem'},'Title': 'TestTitel','OData__Version': '1.0'}";
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $Headers.Add("accept","application/json;odata=verbose")
    $Headers.Add("X-RequestDigest",$Digest)
    $Headers.add("X-HTTP-Method","PATCH")
    $Headers.add("content-length",$body.length)
    $Headers.Add("IF-MATCH",$Item.entry.etag)
    $Headers.Add("content-type","application/json;odata=verbose")
    Invoke-RestMethod -method post -UseDefaultCredentials -uri "https://sharepoint.xyz.de/sitexxxx/_api/web/GetFolderByServerRelativeUrl('Dokumente/Folder/Subfolder')/files('Testfile')/listitemallfields" -body $body -headers $Headers 
    
    #CheckIn
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $Headers.Add("X-RequestDigest",$Digest)
    Invoke-RestMethod -method post -UseDefaultCredentials -uri "https://sharepoint.xyz.de/sitexxxx/_api/web/GetFolderByServerRelativeUrl('Dokumente/Folder/Subfolder')/files('Testfile')/CheckIn(checkintype=0)" -headers $Headers 
    
    

    This will upload the file, modify the needed metadata fields and check in the file.

    If a file should be overwritten, it has to be checked out first.

    Anyway, thanks to everybody who tried to help me in this post.

    Kind regards

    Georg

    • Marked as answer by gkuehlem Monday, March 13, 2017 10:38 AM
    Monday, March 13, 2017 10:17 AM