1

I am used to working with SharePoint on-premises environments, but I am now trying to come up to speed with SharePoint Online. I can connect to my tenant using Connect-SPOService and use the standard SharePoint Online cmdlets, so my credentials are working and that route of access seems to be in good order for me.

However, I will need to use the greater utility of CSOM for work that I need to do. Initially, I have just tried to set up a simple PowerShell procedure to start walking through some of the basics using CSOM with SharePoint Online. But I continue to have a problem with ClientContext.ExecuteQuery. It always fails with the "root element is missing" error. I'm not sure if this is due to the query not retrieving any data or something else relating to my environment.

I currently have my own SharePoint tenant with some initial sites and lists. I am the only user and administrator. Everything is still very simple. I have installed and imported (using PSGallery) the following modules to set my PS environment (and sessions). I think that I have identified everything that I need, but it's certainly possible that I am missing something important.

   ModuleType Version    Name                             
   ---------- -------    ----                                
   Binary     16.0.90... Microsoft.Online.SharePoint.PowerShell
   Manifest   3.1.0.0    Microsoft.PowerShell.Management   
   Manifest   3.0.0.0    Microsoft.PowerShell.Security    
   Manifest   3.1.0.0    Microsoft.PowerShell.Utility       
   Script     1.2        PSReadline                         
   Script     1.0.0      SharePointOnline.CSOM             
   Binary     3.11.19... SharePointPnPPowerShellOnline    
   Script     2.1.6      SharePointSDK

I am working in Windows 10 with PowerShell 5.1 (running as Administrator). Everything is still very simple, but I can't get past the query execution to load the web context so I can start trying to do additional things.

I have found many online examples of PowerShell/CSOM to connect to sites and set context. I've tried them all (at least it seems like I have), but nothing has worked so far. I can't find anything else to try or additional diagnostic steps to take. So I would welcome any suggestions at this point.

Here is a PS Session Log of one of my test runs with the error message at the end ...

PS C:>$LibPath = "C:\Program Files\WindowsPowerShell\Modules\SharePointOnline.CSOM\1.0.0"
PS C:>[System.Reflection.Assembly]::LoadFile("$LibPath\Microsoft.SharePoint.Client.dll")
GAC    Version        Location
---    -------        --------
False  v4.0.30319     C:\Program Files\WindowsPowerShell\Modules\SharePointOnline.CSOM\1.0.0\Microsoft.SharePoint.Cl...

PS C:>[System.Reflection.Assembly]::LoadFile("$LibPath\Microsoft.SharePoint.Client.Runtime.dll")
GAC    Version        Location
---    -------        --------
False  v4.0.30319     C:\Program Files\WindowsPowerShell\Modules\SharePointOnline.CSOM\1.0.0\Microsoft.SharePoint.Cl...

PS C:>[System.Reflection.Assembly]::LoadFile("$LibPath\Microsoft.SharePoint.Client.UserProfiles.dll")
GAC    Version        Location
---    -------        --------
False  v4.0.30319     C:\Program Files\WindowsPowerShell\Modules\SharePointOnline.CSOM\1.0.0\Microsoft.SharePoint.Cl...

PS C:>
PS C:># try simple connection test
PS C:>Write-Host "Start connection test ..."
Start connection test ...

PS C:>
PS C:>$UserName = "xxxxxxx@xxxxxx.onmicrosoft.com"
PS C:>$SiteUrl = "https://xxxxxx.sharepoint.com/sites/Testing"
PS C:>$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
PS C:>
PS C:>$pwd = Read-Host -Prompt "Enter password" -AsSecureString
Enter password: **********
PS C:>$securePwd = ConvertTo-SecureString $pwd -AsPlainText -Force
PS C:>
PS C:>$Cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $securePwd)
PS C:>
PS C:>$ctx.credentials = $Cred
PS C:>if (!$ctx.ServerOjectIsNull.Value)
{
    Write-Host "Connected to $SiteUrl" -ForegroundColor Green
}
Connected to https://xxxxxx.sharepoint.com/sites/Testing

PS C:>
PS C:>$web = $ctx.Web
PS C:>Write-Host "Context is $ctx"
Context is Microsoft.SharePoint.Client.ClientContext

PS C:>Write-Host "Web is $web"
Web is Microsoft.SharePoint.Client.Web

PS C:>$ctx.Load($web)
PS C:>$ctx.ExecuteQuery()

**Exception calling "ExecuteQuery" with "0" argument(s): "Root element is missing."
At line:1 char:1
+ $ctx.ExecuteQuery()
+ ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : XmlException**

ADDITIONAL INFORMATION

I have added some exception handling to the test powershell script to dump more info about the "root element is missing" error message. I'm not sure if the trace is indicating a possible authentication problem. I am able to connection via Connect-SPOService to my SharePoint tenant, but is it possible that I could have some authentication issues when connecting via different utilities (such as the ClientContext object).

Here is the full exception dump - maybe there are some clues in here that someone will recognize.

An error occurred...
__________________________
Message ....
Exception calling "ExecuteQuery" with "0" argument(s): "Root element is missing."
__________________________
StackTrace ...
   at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
   at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
__________________________
InnerMessage ...
System.Xml.XmlException: Root element is missing.
   at System.Xml.XmlTextReaderImpl.Throw(Exception e)
   at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options)
   at Microsoft.SharePoint.Client.Idcrl.IdcrlAuth.DoGet(String url)
   at Microsoft.SharePoint.Client.Idcrl.IdcrlAuth.RequestFederationProviderInfo(String domainname)
   at Microsoft.SharePoint.Client.Idcrl.IdcrlAuth.GetFederationProviderInfo(String domainname)
   at Microsoft.SharePoint.Client.Idcrl.IdcrlAuth.InitFederationProviderInfoForUser(String username)
   at Microsoft.SharePoint.Client.Idcrl.IdcrlAuth.GetServiceToken(String username, String password, String serviceTarget, String servicePolicy)
   at Microsoft.SharePoint.Client.Idcrl.SharePointOnlineAuthenticationProvider.GetAuthenticationCookie(Uri url, String username, SecureString password, Boolean alwaysThrowOnFailure, EventHandler`1 executingWebRequest)
   at Microsoft.SharePoint.Client.SharePointOnlineCredentials.GetAuthenticationCookie(Uri url, Boolean refresh, Boolean alwaysThrowOnFailure)
   at Microsoft.SharePoint.Client.ClientRuntimeContext.SetupRequestCredential(ClientRuntimeContext context, HttpWebRequest request)
   at Microsoft.SharePoint.Client.SPWebRequestExecutor.GetRequestStream()
   at Microsoft.SharePoint.Client.ClientContext.GetWebRequestExecutor()
   at Microsoft.SharePoint.Client.ClientContext.GetFormDigestInfoPrivate()
   at Microsoft.SharePoint.Client.ClientContext.EnsureFormDigest()
   at Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()
   at CallSite.Target(Closure , CallSite , Object )

  • @Lee_MSFT - Thank you so much for suggesting this new code for me to try. I have adapted this using my own inputs and ran it a few times, but unfortunately the "root element is missing" exception is still raised when running the clientcontext executequery. But with your example I now feel assured that the code being used is correct. I have also added some exception handling to try to get more information about the error ("root element is missing" is not very specific). I will add the exception dump to the original post (due to space available in this comment section). – KSRayGS Jul 22 '19 at 17:46
  • Are you using SharePoint Online Management Shell to run the script? – SharePoint Badger Jul 25 '19 at 3:20
  • @user22079. Thank your for your comment. Yes, I am running in a shell where using the Microsoft.Online.SharePoint.PowerShell Module. I am using PowerShell 5.1, so I installed it from the PSGallery. As an update to my question, I think that I may have found an alternative way to do what I need to do using the SharePointPnPPowerShellOnline. I'm still trying it out, but it is allowing me to connect to my SPO tenant and access and manipulate lists. I think my CSOM issue might be related to MFA, which is new to me. Still trying to understand it. Thanks for your input and help! – KSRayGS Jul 26 '19 at 20:38
  • i recently had the same issue. to get around it, i set up an App Password then used that in my connection. App Password page: account.activedirectory.windowsazure.com/AppPasswords.aspx ... $Cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $AppPasswordHERE) – Taco_Buffet Aug 14 '19 at 2:48
  • Hello @Taco_Buffet. Thank you for sharing a method that has worked for you. I have followed this suggestion and created an App Password and have tried to use it as you describe above (by substituting it for the $Cred). It seems to work in place of my regular credentials (no error), but unfortunately I am still getting the "root element missing" error. But I am going to experiment with this some more and maybe will have some luck yet. I won't give up - and will reply back if I have success. Thanks so much for this tip! – KSRayGS Aug 15 '19 at 21:58
0

Try below.

Add-Type -Path (Resolve-Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll")
Add-Type -Path (Resolve-Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll")

Function Get-SPOContext([string]$Url,[string]$UserName,$Password)
{
    write-host Get-SPOContext    
    $Context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
    $Context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $Password) #SecurePassword
    return $Context
}

$UserName = "user@tenant.onmicrosoft.com"
$Password = Read-Host -Prompt "Enter password" -AsSecureString    
$Url = "https://tenant.sharepoint.com/sites/Developer"
$listTitle="MyList"   

$Context = Get-SPOContext -Url $Url -UserName $UserName -Password $Password
$web= $Context.Web
$List = $Context.Web.Lists.GetByTitle($ListTitle)
$Context.Load($web)
$Context.Load($List)
$Context.ExecuteQuery()       

write-host Done
| improve this answer | |

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.