title: Getting 401 Unauthorized trying to Create or Update Wiki page using Powershell script
body: <p>I am trying to create a new page in my Wiki from a Build pipeline with the generated release notes.
  I receive this error in response : <code>Invoke-WebRequest : The remote server returned an error: (401) Unauthorized</code>.</p>
  
  <p>I have looked at every resource I found on the subject and everything looks good to me.</p>
  
  <p>Here is my powershell script :</p>
  
  <pre><code># Get content of the generated release notes file
  $content = [IO.File]::ReadAllText("$(build.artifactstagingdirectory)/release-notes-$(Build.BuildNumber).md")
  $data = @{content=$content;} | ConvertTo-Json;
  
  $params = @{uri = '$(WikiPath)';
    Method = 'PUT';
    Headers = @{Authorization = "Bearer $(System.AccessToken)" };
    ContentType = "application/json";
    Body = $data;
  }
  
  Write-Host "PUT $(WikiPath)"
  
  $response = Invoke-WebRequest @params
  
  Write-Host $response
  </code></pre>
  
  <p>The value of <code>WikiPath</code> variable is set to :<br>
  <code>https://&lt;server-ip&gt;/PersonalProjects/Personal-KM/_apis/wiki/wikis/Personal-KM.wiki/pages?path=%2FRelease%20notes%2F$(Build.BuildNumber)&amp;api-version=5.0</code>  </p>
  
  <p>The uri comes from the official <a href="https://docs.microsoft.com/en-us/rest/api/azure/devops/wiki/pages/create%20or%20update?view=azure-devops-server-rest-5.0" rel="nofollow noreferrer">API documentation</a>. I would like to create sub-pages of the page <code>Release notes</code> which does exist. I tried to create a root page without success (<code>?path=$(Build.BuildNumber)&amp;api-version=5.0</code>).</p>
  
  <p>Note that I also tried without <code>.wiki</code> at the end of the wiki identifier.</p>
  
  <p>Here is the output of the build step :</p>
  
  <pre><code>##[command]"C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command ". 'C:\DevOpsAgent\_work\_temp\ebf68890-3544-4a8d-a415-4309983b1381.ps1'"
  PUT https://&lt;server-ip&gt;/PersonalProjects/Personal-KM/_apis/wiki/wikis/Personal-KM.wiki/pages?path=%2FRelease%20notes%2F1.0.0.7&amp;api-version=5.0
  Invoke-WebRequest : The remote server returned an error: (401) Unauthorized.
  At C:\DevOpsAgent\_work\_temp\ebf68890-3544-4a8d-a415-4309983b1381.ps1:26 char:13
  + $response = Invoke-WebRequest @params
  +             ~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc 
     eption
      + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
  
  ##[error]PowerShell exited with code '1'.
  </code></pre>
  
  <p>Key point 1 : I have checked <code>Allow scripts to access the OAuth Token</code> in Agent Job :  </p>
  
  <p><img src="https://i.stack.imgur.com/mPyKN.png" height="80" alt="Scripts token" /></p>
  
  <p>Key point 2 : I have given the permissions 'Contribute' to the Build service account :</p>
  
  <p><img src="https://i.stack.imgur.com/LhCER.png" height="500" alt="Build service permissions" /></p>
  
  <p>Can you see anything wrong with my script or configuration ?</p>
  
  <p><strong>Edit 1</strong> based on the comment from @MarioDietner :<br>
  I have tried to use a PAT instead of $(System.AccessToken), I get the same error (I am member of Project Collection Administrators and my PAT has Full access scope).<br>
  I also tried executing the script from my local computer (variables replaced) :</p>
  
  <p><a href="https://i.stack.imgur.com/mgiHm.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/mgiHm.png" alt="enter image description here"></a></p>
  
  <p><strong>Edit 2</strong> I tried to run the script from Azure Pipelines on our production server and it worked on the first try. I don't know what is wrong with our local Azure DevOps but I will focus the investigation on the identities and not on the Powershell script.</p>