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
	# Iterate all document libraries
	foreach($list in $oWebsite.Lists){
		if($list.BaseType -ne "DocumentLibrary"){
		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)		
		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)
				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)      
			Write-Host " -- " $documents.Count " document(s) checked in" -foregroundcolor green
	# Iterate all subsites
    	foreach ($childWeb in $childWebs){
        	$newpath = $siteCollectionUrl + $childWeb.ServerRelativeUrl

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