0

I am at my wits end with this one.

I am unable to modify an list item remotely via a REST request.

Can anyone see what I am doing wrong here?

I am getting at 403 Forbidden response from SharePoint Specifically.

{"error":{"code":"-2130575251, Microsoft.SharePoint.SPException","message":{"lang":"en-US","value":"The security validation for this page is invalid and might be corrupted. Please use your web browser's Back button to try your operation again."}}}

Code I am using:

#if($pass = $Host.ui.PromptForCredential("Sharepoint List Load","Enter your credentials","",""))
#{    $cred = New-Object System.Management.Automation.PSCredential ($pass)
#}else{write-host "Cancelling.";exit}
$digest = $null
$sUserName="MYUSERNAMEHERE" 
$sPassword="MYPASSWORDHERE"
$sSecPassword=ConvertTo-SecureString $sPassword -AsPlainText -Force        
$spCredentials = New-Object System.Management.Automation.PSCredential($sUserName, $sSecPassword)

$WebRMethod=[Microsoft.PowerShell.Commands.WebRequestMethod]::POST
$TargetItemURL="http://someSPhost.domain.com/sites/MYSITENAME/_api/web/lists/GetByTitle('TEST')/items(1)"

$digest = (Invoke-RestMethod -Method post -UseDefaultCredentials -uri "http://someSPhost.domain.com /_api/contextinfo").GetContextWebInformation.FormDigestValue

$header = @{}
$header.add("Accept",'application/json;odata=verbose')
$header.add("Content-Type",'application/json;odata=verbose')
$header.add("X-HTTP-Method",'MERGE')
$header.add("X-RequestDigest",$digest)
$header.add("IF-MATCH",'*')

$metadata = @{__metadata = @{type = "SP.Data.TESTListItem"}
            Title = "some new test here"
            }

$JsonMetadata = $metadata | ConvertTo-Json -Compress

Write-host "---------TargetITEM-----------"        
$TargetItemURL
Write-host "---------Header-----------"        
$header
Write-host "---------Metadata-----------"    
$metadata
$metadata.__metadata
$JsonMetadata
Write-host "--------------------"        

Invoke-RestMethod -Uri $TargetItemURL -Body $JsonMetadata -Headers $header -Method $WebRMethod -Credential $spCredentials -ContentType "application/json;odata=verbose" 
  • Maybe request is getting timed out. – Ganesh Sanap Feb 22 at 15:34
  • The response from SharePoint is immediate. – Edward Feb 22 at 15:53
  • Remove odata=verbose from Content-Type (on both places). – Lukas Nespor Feb 22 at 18:39
  • I removed odata=verbose from both Content-Type parameters; one that was added in the $header hashtable, and the other from the Invoke-RestMethod parameter, and unfortunately the same error response. This is against a SP2013 host btw, and I have tried it against multiple different hosts. I am beginning to think it is not possible to use REST and PowerShell to perform an update. – Edward Feb 26 at 12:27
  • I have looked at an example of updating the item via JavaScript/jQuery and the headers look the same... headers: {"accept": "application/json;odata=verbose","content-type":"application/json;odata=verbose","IF-MATCH":"*","X-HTTP-Method":"MERGE",:X-RequestDigest": jQuery("#_REQUESTDIGEST".val()} … From here the question I have is, since I am calling the Invoke-RestMethod twice; once to get the request digest and a second time to attempt modifying the item, have I sent the wrong request digest. Somehow should I be making that call only once? Little confused why this is not working. – Edward Feb 26 at 13:05
0

Well, it turns out it is possible. My new friend, and moderator in the Microsoft Forum posted this lovely example. And it works like a champ.

https://social.microsoft.com/Forums/en-US/e4c47435-6568-46b8-b1bc-5d61deecac85/updating-a-list-item-via-invokerestmethod?forum=sharepointdevelopment

$user = "domain\admin"
$pass = "xx"
$listName = "TEST"
$itemId=1
$url = "http://2013/sites/team"

### TOGGLE DEBUG MODE
$debug = $false

### DO NOT MODIFY
$headers = @{accept = "application/json; odata=verbose"}
$formDigest = $null
$secPass = ConvertTo-SecureString $pass -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($user, $secPass)

function SetFormDigest() {
    $response = PostRequest ("/_api/contextinfo") $null
    $formDigest = $response.d.GetContextWebInformation.FormDigestValue
    $headers.Add("X-RequestDigest", $formDigest);
    $headers.add("IF-MATCH",'*')
    $headers.add("X-HTTP-Method",'MERGE')    
    if ($debug) {
        Write-Host "Form Digest: " $formDigest
    }
}
function Request ($endpoint, $body, $method) {
    if ($debug) {
        Write-Host "Endpoint: $endpoint, Method: $method, Cred:" $cred.UserName -BackgroundColor Green -ForegroundColor Black
        Write-Host "Header Keys:" $headers.Keys -BackgroundColor DarkGreen -ForegroundColor Gray
        Write-Host "Header Values:" $headers.Values -BackgroundColor DarkGreen -ForegroundColor Gray
        Write-Host "Body:" $body -BackgroundColor DarkGreen -ForegroundColor Gray        
    }
    return Invoke-RestMethod -Uri ($url+$endpoint) -Headers $headers -Method $method -Body $body -Credential $cred -ContentType "application/json;odata=verbose"
}
function PostRequest ($endpoint, $body) {
     Write-Host "Body1:" $body -BackgroundColor DarkGreen -ForegroundColor Gray
    return Request $endpoint $body ([Microsoft.PowerShell.Commands.WebRequestMethod]::Post)
}
function UpdateListItem($listName, $itemId) {
    SetFormDigest
    $body = "{ '__metadata': { 'type': 'SP.Data."+$listName+"ListItem' }, Title: 'some new text here'}"
    $response = PostRequest ("/_api/web/lists/getbytitle('"+$listName+"')/items("+$itemId+")") $body
}

## Script Begin ##
UpdateListItem $listName $itemId

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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