Skip to content

Instantly share code, notes, and snippets.

@jfrmilner
Created August 10, 2021 10:50
Show Gist options
  • Save jfrmilner/77c62167ee008940cdebd9ddb1bd3de1 to your computer and use it in GitHub Desktop.
Save jfrmilner/77c62167ee008940cdebd9ddb1bd3de1 to your computer and use it in GitHub Desktop.
PowerShell wrapper for the Veeam Backup for Microsoft Office 365 API - Export OneDrive Content Report
<#
PowerShell wrapper for the Veeam Backup for Microsoft Office 365 API - Export OneDrive Content Report
Veeam Backup for Microsoft Office 365 API - REST API Reference
https://helpcenter.veeam.com/docs/vbo365/rest/overview.html?ver=50
API Version = 5.0
.NOTES
Author: John Milner / jfrmilner
Date: 2021-08-06
Legal: This script is provided "AS IS" with no warranties or guarantees, and confers no rights. You may use, modify, reproduce, and distribute this script file in any way provided that you agree to give the original author credit.
V1 - Initial Release
#>
break
# Ignore self signed certificate or request failS
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
$veeamAPI = "https://$($env:COMPUTERNAME):4443"
$cred = Get-Credential
function Connect-VeeamAPI {
[CmdletBinding()]
param (
[string] $AppUri,
[pscredential] $Cred
)
begin {
$header = @{
"Content-Type" = "application/x-www-form-urlencoded"
"accept" = "application/json"
}
$body = @{
"grant_type" = "password"
"username" = $cred.UserName
"password" = $cred.GetNetworkCredential().password
"refresh_token" = " "
"rememberMe" = " "
}
$requestURI = $veeamAPI + $appUri
$tokenRequest = Invoke-RestMethod -Uri $requestURI -Headers $header -Body $body -Method Post -Verbose
Write-Output $tokenRequest.access_token
}
}
$token = Connect-VeeamAPI -AppUri "/v5/token" -Cred $cred
$token
function Get-VeeamAPI {
[CmdletBinding()]
param (
[string] $AppUri,
[string] $Token
)
begin {
$header = @{
"accept" = "application/json"
"Authorization" = "Bearer $Token"
}
$requestURI = $veeamAPI + $AppUri
Invoke-RestMethod -Method GET -Uri $requestUri -Headers $header
}
}
#organizationId
$organizationId = ""
#https://helpcenter.veeam.com/docs/vbo365/rest/post_organizations_id_action.html?ver=50
$header = @{
"accept" = "application/json"
"Authorization" = "Bearer $Token"
}
$explore = @{ "explore" = @{
"datetime" = $(Get-Date -UFormat '%Y.%m.%d')
"type" = "veod"
"showAllVersions" = $true
"showDeleted" = $true
}
}
$exploreJSON = $explore | ConvertTo-Json
$session = Invoke-RestMethod -Method Post -Uri "$($veeamAPI)/v5/Organizations/$($organizationId)/action" -Headers $header -Body $exploreJSON -ContentType "application/json"
$restoreSessionId = $session.id
#https://helpcenter.veeam.com/docs/vbo365/rest/get_onedrives.html?ver=50
#Get All User OneDrive(s)
#GET /v5/RestoreSessions/{restoreSessionId}/Organization/OneDrive
$appURI = "/v5/RestoreSessions/$($restoreSessionId)/Organization/OneDrives?offset=0&limit=9999"
$allODs = Get-VeeamAPI -AppUri $appURI -Token $token
#Set-ODPath - Helper Function for Logical Path Rebuild
function Set-ODPath {
param (
$find,
$set
)
begin {
}#begin
process {
try {
$folders = $allFolders | Where-Object { $_._links.parent.href -eq $find }
$folders | ForEach-Object { $_.ParentPath = $set }
$folders | ForEach-Object { $_.Path = $($set + $_.Name + "/") }
$folders
}
catch [system.exception] {
Write-Host '$_ is' $_
Write-Host '$Error[0].GetType().FullName is' $Error[0].GetType().FullName
Write-Host '$Error[0].Exception is' $Error[0].Exception
Write-Host '$Error[0].Exception.GetType().FullName is' $Error[0].Exception.GetType().FullName
Write-Host '$Error[0].Exception.Message is' $Error[0].Exception.Message
}
finally {
#"end of script"
}
}#process
end {
}#end
}
foreach ($od in $allODs) {
$oneDriveId = $od.id
Write-Host "Processing $($od.name)" -ForegroundColor DarkGreen
#All Folder List
#https://<hostname>:4443/v5/RestoreSessions/{restoreSessionId}/Organization/OneDrives/{oneDriveId}/Folders[?parentId=<value>]
$appURI = "/v5/RestoreSessions/$($restoreSessionId)/Organization/OneDrives/$($oneDriveId)/Folders?offset=0&limit=9999"
#All Folders
$allFolders = Get-VeeamAPI -AppUri $appURI -Token $token | Select-Object -ExpandProperty results
Write-Host "Folder(s): $($allFolders.count)" -ForegroundColor DarkGreen
$allFolders | Add-Member -MemberType NoteProperty -Name "Path" -Value ""
$allFolders | Add-Member -MemberType NoteProperty -Name "ParentPath" -Value ""
# #Debug - Reset
# $allFolders | % { $_.Path = $null }
# $allFolders | % { $_.ParentPath = $null }
#Set Root Folders
$foldersNext = $allFolders | Where-Object { $null -eq $_._links.parent.href } | ForEach-Object { $_.Path = "/$($_.name)/"; $_.ParentPath = "/" ; $_ }
#Starting with Root Folders, branch out and logicly rebuilt folder hierarchy
while ($foldersNext) {
$foldersNext = foreach ($folder in $foldersNext) {
Set-ODPath -find $folder._links.self.href -set $($folder.ParentPath + $folder.name + "/")
}
}
#Debug - Report
#$allFolders | ? { $_.Path } | Sort-Object -Property Path | Select-Object -Property Path, ParentPath, Name, creationTime | ft -AutoSize
#Folder Hast Table
$folderHashtable = [Ordered]@{}
$allFolders | ForEach-Object { $folderHashtable.Add($_.id, $_) }
#All Files - aka alldocuments
#Pagination 10,000 Max. Zero indexed. Process 9000 per page (9001 on first page)
$i = 0
$allFiles = do {
$page = Get-VeeamAPI -AppUri "/v5/restoresessions/$($restoreSessionId)/organization/onedrives/$($oneDriveId)/documents?offset=$($i)&limit=9000" -Token $token
$page.results
$i = $i + 9000
Write-Host "Files Page $($i/9000)" -ForegroundColor DarkGreen
} while ($page.results)
Write-Host "File(s): $($allFiles.count)"
$scriptPropertyFilePath = {
if ($null -eq $this._links.parent.href) {
#Root
"/"
}
else {
$folderHashtable[$this._links.parent.href -replace '.*/folders/'].Path
}
}
$allFiles | Add-Member -Name folder -MemberType ScriptProperty -Value $scriptPropertyFilePath
#Debug - Report
#$allFiles | Select-Object -Property Folder, Name | Sort-Object -Property Folder, Name | ConvertTo-Csv -NoTypeInformation | clip
Write-Host "Out File C:\Support\OneDrive_Content_Reports\$($od.name + "-" + $od.id).csv" -ForegroundColor Green
$allFiles | Sort-Object -Property folder, name | Select-Object -Property folder, name, sizeBytes, version, id, creationTime, modificationTime, createdBy, modifiedBy | Export-Csv -NoTypeInformation -Path "C:\Support\OneDrive_Content_Reports\$($od.name + "-" + $od.id).csv"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment