core/api/m365/SharePointOnline/csom/helpers/list/Get-MonkeyCSOMListItem.ps1
# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Function Get-MonkeyCSOMListItem{ <# .SYNOPSIS .DESCRIPTION .INPUTS .OUTPUTS .EXAMPLE .NOTES Author : Juan Garrido Twitter : @tr1ana File Name : Get-MonkeyCSOMListItem Version : 1.0 .LINK https://github.com/silverhack/monkey365 #> [cmdletbinding()] Param ( [parameter(Mandatory=$false, HelpMessage="Authentication object")] [Object]$Authentication, [Parameter(Mandatory= $True, ValueFromPipeline = $true, HelpMessage="SharePoint List Object")] [Object]$List, [Parameter(Mandatory= $false, HelpMessage="Paged Size")] [Int]$PagedSize = 500, [Parameter(Mandatory= $false, HelpMessage="EndPoint")] [string]$Endpoint ) Begin{ $raw_data = $postData = $null $objectPathID = Get-Random -Minimum 20000 -Maximum 50000 $objectPathID_1 = $objectPathID+1 $objectPathID_2 = $objectPathID_1+1 #Set generic list $all_items = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() } Process{ $objectType = $PSBoundParameters['List'] | Select-Object -ExpandProperty _ObjectType_ -ErrorAction Ignore if ($null -ne $objectType -and $objectType -eq 'SP.List'){ #Fill Post data $postData = '<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="Monkey365" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="${objectPathID1}" ObjectPathId="${objectPathID}" /><Query Id="${objectPathID2}" ObjectPathId="${objectPathID}"><Query SelectAllProperties="true"><Properties /></Query><ChildItemQuery SelectAllProperties="true"><Properties /></ChildItemQuery></Query></Actions><ObjectPaths><Method Id="${objectPathID}" ParentId="11" Name="GetItems"><Parameters><Parameter TypeId="{3d248d7b-fc86-40a3-aa97-02a75d69fb8a}"><Property Name="AllowIncrementalResults" Type="Boolean">false</Property><Property Name="DatesInUtc" Type="Boolean">true</Property><Property Name="FolderServerRelativePath" Type="Null" /><Property Name="FolderServerRelativeUrl" Type="Null" /><Property Name="ListItemCollectionPosition" Type="Null" /><Property Name="ViewXml" Type="String"><View Scope="RecursiveAll">
 <Query></Query>
 <RowLimit Paged="TRUE">${pagedSize}</RowLimit>
 </View></Property></Parameter></Parameters></Method><Identity Id="11" Name="${ListID}" /></ObjectPaths></Request>' -replace '\${ListID}', $PSBoundParameters['List']._ObjectIdentity_ -replace '\${pagedSize}', $pagedSize -replace '\${objectPathID}',$objectPathID -replace '\${objectPathID1}',$objectPathID_1 -replace '\${objectPathID2}',$objectPathID_2 #Set command parameters $p = Set-CommandParameter -Command "Invoke-MonkeyCSOMDefaultRequest" -Params $PSBoundParameters #Add authentication header if missing if(!$p.ContainsKey('Authentication')){ if($null -ne $O365Object.auth_tokens.SharePointOnline){ [void]$p.Add('Authentication',$O365Object.auth_tokens.SharePointOnline); } Else{ Write-Warning -Message ($message.NullAuthenticationDetected -f "SharePoint Online") break } } #Add Post Data [void]$p.Add('Data',$postData); #Add Object Metadata [void]$p.Add('ObjectMetadata',$null); #Execute query $tmp_object = Invoke-MonkeyCSOMDefaultRequest @p if($null -ne $tmp_object -and $tmp_object -is [System.Management.Automation.PSCustomObject]){ if($null -ne $tmp_object.psobject.properties.Item('ErrorInfo') -and $null -ne $tmp_object.ErrorInfo){ #Errors found $errorData = $tmp_object[0] $errorMessage = "[{0}][{1}]:[{2}]" -f $errorData.ErrorInfo.ErrorTypeName, $errorData.ErrorInfo.ErrorCode, $errorData.ErrorInfo.ErrorMessage $msg = @{ MessageData = ($message.SPSDetailedErrorMessage -f $errorMessage); callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'verbose'; Verbose = $O365Object.verbose; Tags = @('MonkeyCSOMRequestError'); } Write-Verbose @msg } } elseif($null -ne $tmp_object -and $tmp_object -is [System.Object[]] -and $tmp_object.GetValue(1) -eq $objectPathID_1 ` -and ($tmp_object.GetValue(4)).GetType().Name -eq "PsCustomObject"){ #Get object $raw_data = $tmp_object.GetValue(4) } else{ $msg = @{ MessageData = ("Unable to get list item"); callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'verbose'; Verbose = $O365Object.verbose; Tags = @('MonkeyCSOMRequestError'); } Write-Verbose @msg } #Check if childitems if($null -ne $raw_data -and $null -ne ($raw_data.psobject.Properties.Item('_Child_Items_'))){ $raw_data._Child_Items_.Foreach({[void]$all_items.Add($_)}); } try{ $listItemCol = $raw_data | Select-Object -ExpandProperty ListItemCollectionPosition -ErrorAction Ignore if($null -ne $listItemCol){ $nl = $listItemCol | Select-Object -ExpandProperty PagingInfo -ErrorAction Ignore if($null -ne $nl){ $nextLink = $nl -replace "&", "&" } else{ $nextLink = $null } } else{ $nextLink = $null; } } catch{ $nextLink = $null } #Sum pagedSize and objectpathid $objectPathID = $objectPathID + $pagedSize + 4 $objectPathID_1 = $objectPathID + 1 $objectPathID_2 = $objectPathID_1 + 1 #Check for paging objects while ($null -ne $nextLink){ $postData = '<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="Monkey365" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="${objectPathID1}" ObjectPathId="${objectPathID}" /><Query Id="${objectPathID2}" ObjectPathId="${objectPathID}"><Query SelectAllProperties="true"><Properties /></Query><ChildItemQuery SelectAllProperties="true"><Properties /></ChildItemQuery></Query></Actions><ObjectPaths><Method Id="${objectPathID}" ParentId="11" Name="GetItems"><Parameters><Parameter TypeId="{3d248d7b-fc86-40a3-aa97-02a75d69fb8a}"><Property Name="AllowIncrementalResults" Type="Boolean">false</Property><Property Name="DatesInUtc" Type="Boolean">true</Property><Property Name="FolderServerRelativePath" Type="Null" /><Property Name="FolderServerRelativeUrl" Type="Null" /><Property Name="ListItemCollectionPosition" TypeId="{922354eb-c56a-4d88-ad59-67496854efe1}"><Property Name="PagingInfo" Type="String">${PageID}</Property></Property><Property Name="ViewXml" Type="String"><View Scope="RecursiveAll">
 <Query></Query>
 <RowLimit Paged="TRUE">${pagedSize}</RowLimit>
 </View></Property></Parameter></Parameters></Method><Identity Id="11" Name="${ListID}" /></ObjectPaths></Request>' -replace '\${ListID}', $PSBoundParameters['List']._ObjectIdentity_ -replace '\${pagedSize}', $pagedSize -replace '\${PageID}', $nextLink -replace '\${objectPathID}',$objectPathID -replace '\${objectPathID1}',$objectPathID_1 -replace '\${objectPathID2}',$objectPathID_2 #Update params $p.Item('Data') = $postData; $tmp_object = Invoke-MonkeyCSOMDefaultRequest @p if($tmp_object -is [object] -and $tmp_object.GetValue(1) -eq $objectPathID_1 ` -and ($tmp_object.GetValue(4)).GetType().Name -eq "PsCustomObject"){ #Get object $raw_data = $tmp_object.GetValue(4) } #Check if childitems if($null -ne $raw_data -and $raw_data.psobject.Properties.name -match "_Child_Items_"){ $raw_data._Child_Items_.Foreach({[void]$all_items.Add($_)}); } try{ $nextLink = $raw_data.ListItemCollectionPosition.PagingInfo } catch{ $nextLink = $null } if($null -ne $nextLink){ $nextLink = $nextLink -replace "&", "&" $objectPathID = $objectPathID + $pagedSize + 4 $objectPathID_1 = $objectPathID + 1 $objectPathID_2 = $objectPathID_1 + 1 } } } Else{ $msg = @{ MessageData = "Invalid SharePoint List Object"; callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'Warning'; InformationAction = $O365Object.InformationAction; Tags = @('MonkeyCSOMInvalidListObject'); } Write-Warning @msg } } End{ if($all_items.Count -gt 0){ $all_clean_objs = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() foreach($obj in $all_items){ #Clean object $_object = New-Object -TypeName PSCustomObject foreach($elem in $obj.psobject.properties){ if($elem.Name.Contains("$")){ $_object | Add-Member NoteProperty -name $elem.Name.Split('$')[0] -value $elem.Value -Force } else{ $_object | Add-Member NoteProperty -name $elem.Name -value $elem.Value -Force } } if($_object){ [void]$all_clean_objs.Add($_object); } } if($all_clean_objs.Count -gt 0){ Write-Output $all_clean_objs -NoEnumerate } else{ Write-Output $all_items -NoEnumerate } } } } |