FIXED – 403 ExecuteQuery CSOM from a SharePoint Server

I came across this error when running CSOM requests to Office 365.   While troubleshooting the CSOM call worked beautifully from “powershell_ise” but not regular “powershell.”  Fiddler monitoring showed the cmdlet making HTTP traffic correctly with login handshake from ISE.    However, the regular “powershell” window did not attempt any login handshake.

Strange?   Definitely.

The root cause was “$profile” loading the Server Object Model (SOM) cmdlets before CSOM DLL were loaded.   Why would that matter?  How could it cause a CSOM issue?   There seems to be a DLL namespace overlap internally between these plugins (SOM, CSOM, SPO) so loading sequence matters.  A lot.

By proactively loading the CSOM DLL in $profile before SOM, everything worked correctly from both ISE and the regular PowerShell console.

Hope this helps!  shades_smile



  1. Run CSOM request in PowerShell
  2. From a SharePoint Server on premise (2013 here)
  3. Which also has Microsoft SharePoint Online (SPO) cmdlets installed (
  4. See this error
  5. Exception calling “ExecuteQuery” with “0” argument(s):  “The remote server returned an error:  (403) Forbidden.






  1. Open PowerShell and type “notepad $profile”
  2. Ensure below code is present.
  3. NOTE – CSOM must load before SOM (Server Object Model) for requests to execute correctly.   Workaround for an internal Microsoft naming overlap.  Both are probably using the same object somewhere.  Loading CSOM first allows CSOM to reserve the namespace first.


Code [$profile]

#CSOM first
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime") | Out-Null
Add-PSSnapIn Microsoft.SharePoint.PowerShell



Code [csom-only-test.ps1]

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime") | Out-Null
$url = ""
$user = ""
$pass = "password"
$secpw = $pass | ConvertTo-SecureString -AsPlainText -Force
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($user, $secpw)
$ctx.Credentials = $cred
$site = $ctx.Site
if (!$site.TrimAuditLog) {
    $site.TrimAuditLog = $true
    $site.AuditLogTrimmingRetention = 180
Return to Top ▲Return to Top ▲