155 lines
5.8 KiB
PowerShell
155 lines
5.8 KiB
PowerShell
# Function to update a list of paths
|
|
Function Update-ListOfPaths {
|
|
param([System.Collections.ArrayList]$List,[string]$Path)
|
|
If ( $List -inotcontains $Path ) { $List.Add($Path) | Out-Null }
|
|
}
|
|
|
|
# Function to expand the UserProfile environment variable as used by MSP360, and update $List
|
|
Function Add-UserProfilePaths {
|
|
param([System.Collections.ArrayList]$List,[string]$Path)
|
|
|
|
$ChildPath = ($Path -split '%')[2]
|
|
|
|
# Get a list of all user profile directories
|
|
ForEach ( $profile in (Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList') ) {
|
|
$profileImagePath = Get-ItemPropertyValue -Path $([System.Environment]::ExpandEnvironmentVariables($profile.PSPath)) -Name ProfileImagePath
|
|
|
|
# Skip profiles located outside C:\Users as MSP360 doesn't currently include these when using the %UserProfile% variable
|
|
If ( !($profileImagePath -ilike "*${Env:SystemDrive}\Users\*") ) { Continue }
|
|
|
|
# Build the path we're trying to add
|
|
$path = Join-Path -Path $profileImagePath -ChildPath $ChildPath
|
|
|
|
# Skip adding the path if it doesn't exist
|
|
If ( !(Test-Path $path) ) { Continue }
|
|
|
|
# Add the path
|
|
Update-ListOfPaths -List $List -Path $path
|
|
}
|
|
}
|
|
|
|
Function Use-Path {
|
|
param([System.Collections.ArrayList]$List,[string]$Path)
|
|
Switch ( $Path ) {
|
|
{ $_ -ilike '*%UserProfile%*' } { Add-UserProfilePaths -List $List -Path $Path }
|
|
{ $_ -ilike '*%*%*' } { Update-ListOfPaths -List $List -Path $([System.Environment]::ExpandEnvironmentVariables($Path)) }
|
|
default { Update-ListOfPaths -List $List -Path $Path }
|
|
}
|
|
}
|
|
|
|
# Import MSP360 module
|
|
Import-MSP360Module
|
|
|
|
# Get all backup plans
|
|
$BackupPlans = Get-MBSBackupPlan -OutputType Raw
|
|
|
|
# Track the number of processed backup plans so we can put line breaks between them in the output
|
|
$planIter = 0
|
|
|
|
# Iterate over all backup plans
|
|
ForEach ( $plan in $BackupPlans ) {
|
|
|
|
# Add a line break in the output if we've already processed a backup plan
|
|
If ( $planIter -gt 0 ) { Write-Output "`n" }
|
|
|
|
# Function to process each file
|
|
Function ProcessFile {
|
|
param([System.IO.FileInfo]$File)
|
|
|
|
Switch ( $File ) {
|
|
|
|
# Filter out if name matches an excluded path
|
|
{ $null -ne ($ExcludedPaths | Where-Object { $File.FullName.Replace('\','\\') -match $_.Replace('\','\\') }) } { Update-FilteredFiles $File }
|
|
|
|
# Filter out if file size is greater than plan maximum
|
|
{ $File.Length -gt $MaxFileSize } { Update-FilteredFiles $File }
|
|
|
|
# Add item to $IncludeFiles
|
|
default { $IncludedFiles.Add($item.FullName, $item.Length) | Out-Null }
|
|
}
|
|
}
|
|
|
|
# Function to add a file to $FilteredFiles
|
|
Function Update-FilteredFiles {
|
|
param([System.IO.FileInfo]$File)
|
|
$FilteredFiles.Add($File.FullName, $File.Length) | Out-Null
|
|
}
|
|
|
|
# Print the plan name that we're currently working on
|
|
Write-Output ('Plan Name: {0}' -f ($plan.Name))
|
|
|
|
# Create array lists to store paths included in the plans
|
|
[System.Collections.ArrayList]$IncludedPaths = @()
|
|
[System.Collections.ArrayList]$ExcludedPaths = @()
|
|
|
|
# Create array lists to keep files matching certain patterns
|
|
[System.Collections.Hashtable]$FilteredFiles = @{}
|
|
[System.Collections.Hashtable]$IncludedFiles = @{}
|
|
|
|
# Get all included items from plan
|
|
If ( $null -ne $plan.Items ) {
|
|
ForEach ( $obj in $plan.Items ) {
|
|
ForEach ( $path in $obj.PlanItem.Path ) {
|
|
Use-Path -List $IncludedPaths -Path $path
|
|
}
|
|
}
|
|
}
|
|
|
|
# Get all excluded items from plan
|
|
If ( $null -ne $plan.ExcludedItems ) {
|
|
ForEach ( $obj in $plan.ExcludedItems ) {
|
|
ForEach ( $path in $obj.PlanItem.Path ) {
|
|
Use-Path -List $ExcludedPaths -Path $path
|
|
}
|
|
}
|
|
}
|
|
|
|
# Print all paths in $IncludedPaths
|
|
If ( $IncludedPaths.Length -gt 0 ) {
|
|
Write-Output "Paths to backup:"
|
|
ForEach ( $path in ($IncludedPaths | Sort-Object) ) { Write-Output $path }
|
|
}
|
|
|
|
# Define $MaxFileSize if it exists, or set it to the default value if it can't be obtained
|
|
If ( $null -ne $plan.MaxFileSize ) { $MaxFileSize = $plan.MaxFileSize } Else { $MaxFileSize = [long]::MaxValue }
|
|
|
|
# Process each path in $IncludedPaths
|
|
ForEach ($path in $IncludedPaths ) {
|
|
|
|
# Skip paths that don't exist
|
|
If ( !(Test-Path $path) ) { Continue }
|
|
|
|
# If $path is an individual file, process it separately
|
|
$item = Get-Item -Path $path -ErrorAction SilentlyContinue
|
|
If ( $item -is [System.IO.FileInfo] ) { ProcessFile $item ; Continue }
|
|
|
|
# Get all children of $path
|
|
ForEach ( $item in (Get-ChildItem -Path $path -Recurse -Force -ErrorAction SilentlyContinue) ) {
|
|
|
|
# Process each file
|
|
If ( $item -is [System.IO.FileInfo] ) { ProcessFile $item }
|
|
}
|
|
}
|
|
|
|
# Print total files and total size
|
|
Write-Output ('Total Files: {0}' -f ($IncludedFiles.Count))
|
|
If ( $IncludedFiles.Count -gt 0 ) {
|
|
$IncludedFilesSize = 0
|
|
ForEach ($len in $IncludedFiles.Values) { $IncludedFilesSize += $len}
|
|
Write-Output $('Total size: {0}GB' -f [math]::Round(($IncludedFilesSize/1GB),2) )
|
|
}
|
|
|
|
# Print total excluded files and, optionally, the total size of excluded files as well as their full path
|
|
Write-Output ('Total Excluded Files: {0}' -f ($FilteredFiles.Count))
|
|
If ( $FilteredFiles.Count -gt 0 ) {
|
|
$FilteredFilesSize = 0
|
|
ForEach ($len in $FilteredFiles.Values) { $FilteredFilesSize += $len}
|
|
Write-Output $('Total size: {0}GB' -f [math]::Round(($FilteredFilesSize/1GB),2) )
|
|
Write-Output "All files excluded from plan:"
|
|
ForEach ($file in $FilteredFiles.GetEnumerator()) {
|
|
Write-Output $file.Name
|
|
}
|
|
}
|
|
$planIter++
|
|
}
|