A customer of mine had the need to get an overview of all the checked out documents for a given Site Collection, and to check them in afterwards prior to a content migration from SharePoint 2013 to SharePoint Online.

Since no out of the box features exist to accomplish this goal, I had to write a Powershell-script to find all the checked out documents in a Site Collection.

You can find the script here. It works for SharePoint Online as for SharePoint 2013. I did not test it with SharePoint 2010.

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

# Global variables
$username = "[username]"
$password = "[password]"
$securePassword = ConvertTo-SecureString $Password -AsPlainText -Force
$siteCollectionUrl = "[url]"
$global:totaldocumentsCheckedIn = 0

function GetCheckedOutdocuments($url)
{
	Write-Host "Connecting to site: $url"
	
	$clientContext = New-Object  Microsoft.SharePoint.Client.ClientContext($url)
	# Credentials for on-premise environment
	$credentials = New-Object System.Net.NetworkCredential($username, $securePassword)
	# Credentials for SharePoint Online
	# $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $securePassword)
	$clientContext.Credentials = $credentials 
	
	$oWebsite = $clientContext.Web
	$childWebs = $oWebsite.Webs
    
	$clientContext.Load($oWebsite)
	$clientContext.Load($oWebsite.Lists)	
    	$clientContext.Load($childWebs)
    	$clientContext.ExecuteQuery()
	
	# Iterate all document libraries
	foreach($list in $oWebsite.Lists){
		if($list.BaseType -ne "DocumentLibrary"){
			continue
		}
		
		Write-Host " - Scanning document library: " $list.Title
		
		# CAML query to find all checked out documents, recursive thru folders	
		$caml = "<View Scope='RecursiveAll'><Query><Where><Geq><FieldRef Name='CheckoutUser' LookupId='TRUE'/><Value Type='int'>0</Value></Geq></Where></Query></View>"
		$spquery = New-Object Microsoft.SharePoint.Client.CamlQuery
		$spquery.ViewXml = $caml
			
		$documents = $list.GetItems($spquery)		
		$clientContext.Load($documents)
		$clientContext.ExecuteQuery()	
			
		if ($documents.Count -gt 0){
			Write-Host " -- " $documents.Count " checked out document(s) found" -foregroundcolor green
				
			foreach($document in $documents){
				$docItem = $list.GetItemById($document.Id)
				$clientContext.Load($docItem)
				$clientContext.Load($docItem.File)
				$clientContext.ExecuteQuery()				
					
				Write-Host " --- " $docItem.File.Name " ("$docItem.File.ServerRelativeUrl")"
					
				# Check in file
				$docItem.File.CheckIn("Auto check-in prior to migration", [Microsoft.SharePoint.Client.CheckinType]::MajorCheckIn)      
				$clientContext.ExecuteQuery()
				
				$global:totaldocumentsCheckedIn++
			}
				
			Write-Host " -- " $documents.Count " document(s) checked in" -foregroundcolor green
		}
	}
	
	# Iterate all subsites
    	foreach ($childWeb in $childWebs){
        	$newpath = $siteCollectionUrl + $childWeb.ServerRelativeUrl
        	GetCheckedOutdocuments($newpath)
    	}
}

GetCheckedOutdocuments($siteCollectionUrl)
Write-Host $global:totaldocumentsCheckedIn " document(s) checked in" -foregroundcolor green