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" 
6
  • Maybe request is getting timed out. Feb 22, 2019 at 15:34
  • The response from SharePoint is immediate.
    – Edward
    Feb 22, 2019 at 15:53
  • Remove odata=verbose from Content-Type (on both places). Feb 22, 2019 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, 2019 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, 2019 at 13:05

1 Answer 1

1

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
1
  • did u try this? does it work at all?
    – Alberto S.
    Feb 9, 2021 at 17:24

Your Answer

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

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