Search code examples
powershellcsomcaml

CAML in Powershell with IN CLause


I'm using SP 2013 on-premises and I'm wanting to query a list for items by passing a number of IDs to the list and then returning only the Title field. This is executing in Powershell. I have the following that I am using as the ViewXml:

        <View>
         <ViewFields>
         <FieldRef Name='Title'/>
        </ViewFields>
 <Query>
  <Where>
   <In>
    <FieldRef Name='ID' />
       <Values>
        <Value Type='Counter'>1131</Value>
        <Value Type='Counter'>478</Value>
        <Value Type='Counter'>360</Value>
       <Values>
   </In>
  </Where>
 </Query>
</View>

I get the following when running $ctx.executeQuery();
Exception calling "ExecuteQuery" with "0" argument(s): "Cannot complete this action.

Please try again."

Here is the rest of the code minus the variable definitions and the bit where the client dlls are added

$pwd = Read-Host -Prompt "Enter password" -AsSecureString  
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteURL)  
$ctx.Credentials = New-Object System.Net.NetworkCredential($userId, $pwd)

$vFields = "<Value Type='Counter'>1131</Value><Value Type='Counter'>478</Value><Value Type='Counter'>360</Value>";

try{  
    $lists = $ctx.web.Lists ;
    $list = $lists.GetByTitle($ListName);  
    $query = New-Object Microsoft.SharePoint.Client.CamlQuery;
    $xmlCAML = "<View><ViewFields><FieldRef Name='Title'/></ViewFields><Query><Where><In><FieldRef Name='ID'/><Values>$vFields<Values></In></Where></Query></View>";
    write-host $xmlCAML -ForegroundColor Yellow
    $query.ViewXml = $xmlCAML

    $listItems = $list.GetItems($query);  
    $ctx.load($listItems);       
    $ctx.executeQuery();  

    foreach($listItem in $listItems)  
    {  
        Write-Host "Title - " $listItem["Title"]  
    }  
}  
catch{  
    write-host "$($_.Exception.Message)" -foregroundcolor red  
}

Solution

  • if you haven't already sorted this, it's just a single-keystroke fix, you've just failed to properly close the <Values>...</Values> element in your CAML. Needs to be:

    <View>
         <ViewFields>
             <FieldRef Name='Title'/>
         </ViewFields>
     <Query>
      <Where>
       <In>
        <FieldRef Name='ID' />
           <Values>
            <Value Type='Counter'>1131</Value>
            <Value Type='Counter'>478</Value>
            <Value Type='Counter'>360</Value>
           </Values> <!-- <== Here :) -->
       </In>
      </Where>
     </Query>
    </View>