<#
.SYNOPSIS
This command is meant to add clean up snapshots that are generated on a Daily basis by default. Parameters can be used to change the scope of the searches.
.DESCRIPTION
Date Updated By Details
1-3-2023 BW Begin adding ability to use CSV File see notes below for format.
09-13-2022 BW Fixed issue where cleanupmatch was being ignored when using -daily, -weekly, or -monthly
06-02-2022 BW Added Key Press (Q) for stopping loops.
02-02-2022 BW Added Monthly quick parameter.
12-21-2021 BW Updated to throw and STOP an error.
11-15-2021 BW Added parameters for Daily and Weekly, so that it will automatically fill in the keepdate and cleanup match.
5-20-2021 BW Now stops the script when there's an error, also createst folder for logs called snapLog
05-21-2020 BW Modified to show whether we are listing or removing snapshots.
11-07-2019 BW Updated script to track number of snapshots to delete per VM.
10-30-2019 BW Added Logging mechanism with start/stop-transcript
10-29-2019 BW Initial release. Parameters set to clean Any daily snaphots older than 8 days.
NOTES 1-3-2023
CSV FILE FORMAT
VMName,KeepType,KeepInterval
WWW_2019,WEEKLY,6
MY_TEST_VM,DAILY,7
#>
Param(
[Parameter(Mandatory = $false) ] [string] $vcServer="",
[Parameter(Mandatory = $false) ] [string[]] $vmName="",
[Parameter(Mandatory = $false,ParameterSetName="LoadFile") ] [string] $vmList="",
[Parameter(Mandatory = $false,ParameterSetName='Custom') ] [string] $cleanupMatch,
[Parameter(Mandatory = $false) ] [string] $keepDate=(get-Date).adddays(-8),
[Parameter(Mandatory = $false) ] [pscredential] $vcCred,
[Parameter(Mandatory = $false) ] [switch] $cleanAll,
[Parameter(Mandatory = $false) ] [bool] $doConfirm=$false, #has to be a [bool] because of -doConfirm in the remove-snapshot bits.
[Parameter(Mandatory = $false) ] [switch] $liveRun,
[Parameter(Mandatory = $false,ParameterSetName='Daily') ] [switch] $Daily, #Run with default daily parameters
[Parameter(Mandatory = $false,ParameterSetName='Daily') ] [int] $keepDays=8, #Run with default daily parameters
[Parameter(Mandatory = $false,parametersetname='Weekly') ] [switch] $Weekly, #Run with default weekly parameters
[Parameter(Mandatory = $false,parametersetname='Weekly') ] [int] $keepWeeks=6, #Run with default weekly parameters
[Parameter(Mandatory = $false,Parametersetname='Monthly') ] [switch] $Monthly, #Run with default monthlyparameters
[Parameter(Mandatory = $false,Parametersetname='Monthly') ] [int] $keepMonths=3, #Run with default monthlyparameters
[Parameter(Mandatory = $false) ] [string] $logFile
)
if ($Daily -eq $true) {
write-host "Daily uses 1 day at a time, keeping $keepDays day(s)."
if ([string]::isnullorempty($cleanupmatch)) { $cleanupmatch="Daily" }
$keepDate=(get-date).adddays(-1 * $keepDays)
if ([string]::IsNullOrEmpty($vmName)) { $vmName=(get-content "daily-list.txt") }
}
if ($Weekly -eq $true) {
write-host "Weekly cleanup uses 7 Days per week, keeping $keepWeeks week(s)"
if ([string]::isnullorempty($cleanupmatch)) { $cleanupmatch="Weekly" }
$keepdate=(get-date).adddays(-1 ($keepWeeks 7))
if ([string]::IsNullOrEmpty($vmName)) { $vmName=(get-content "weekly-list.txt") }
}
if ($Monthly -eq $true) {
write-host "Monthly cleanup uses 30 days per month, keeping $keepMonths month(s)."
if ([string]::isnullorempty($cleanupmatch)) { $cleanupmatch="Monthly" }
$keepdate=(get-date).adddays(-1 ($keepMonths 30 ))
if ([string]::IsNullOrEmpty($vmName)) { $vmName=(get-content "monthly-list.txt") }
}
#the default progress bar is useless for this. Disable it!
$origProgressBar = $ProgressPreference
$ProgressPreference = "SilentlyContinue"
$origErrorAction = $ErrorActionPreference
$ErrorActionPreference = "STOP"
if (!(Test-Path snapLog)) { mkdir snapLog }
if ($liveRun -eq $false) {$action="Listing"} else {$action = "Cleaning"}
#vmware initialization
$hasVI=get-command connect-viserver* -ErrorAction SilentlyContinue
if ([string]::IsNullOrEmpty($hasVI) -eq $true) {
try {
import-module VMware.PowerCLI
}
catch {
write-host -foregroundcolor "Yellow" "You MUST have the VMware PowerShell Modules installed for this to work."
write-host -foregroundcolor "yellow" "Open PowerShell as an administrator and then "
write-host " "
write-host -foregroundcolor "white" "install-module vmware.powercli"
write-host " "
write-host -foregroundcolor "Yellow" "And then try this script again."
exit -2048;
}
}
if ($global:DefaultVIServers.count -lt 1) {
if ([string]::IsNullOrEmpty($vcServer) -eq $true ) {
write-host -foreground Yellow "vCenter Server Connection"
$vcServer = read-host "vCenter Server: "
}
if ($vcCred -eq $null ) {
write-host -foreground Yellow "Please enter your VCenter Admin Credentials..."
$username = read-host "Username: "
$password = read-host "Password: " -AsSecureString
$VCCred = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $password
}
try {
connect-viserver -server $vcServer -Credential $vcCred
} catch {
write-host "There was an error connecting to $vcServer!"
error[0]
exit -3072
}
}
if ($cleanAll -eq $true) {
write-host "Loading All Powered On VMs..."
$vmName=(get-vm | where {$_.PowerState -eq 'PoweredOn'} | Select Name).Name
write-host "Found $($vmName.count) machines to clean..."
}
$logFile="snapLog\snapshotCleanup_$(get-date -format "MMddyyyy_HHmmss").log"
if ($liveRun -eq $true) {start-transcript -Path $logFIle -Append }
if ($PSCmdlet.ParameterSetName -eq "LoadFile") {
$isFile=test-path $vmList
if ($isFile -eq $false) {
write-host -foregroundcolor "Red" "Unable to open file $vmList."
exit -2048
}
$csvFile=import-csv -Path $vmList
$RunTimer=new-object System.Diagnostics.Stopwatch
$runtimer.start()
foreach ($item in $csvFile) {
$vmName=""
$firstChar=""
$keepType=""
$keepInterval=""
$cleanupmatch=""
$vmName=$item.VMName
$firstChar=$vmname.tochararray()[0]
$keepType=[string] $item.KeepType
$keepInterval=$item.KeepInterval
#write-host -foregroundcolor white "Checking $vmName,$keepType,$keepInterval"
#write-host "Keep Date: $keepDate"
if ($keepType -ne "DAILY" -and $keepType -ne "WEEKLY" -and $KeepType -ne "MONTHLY") {
write-host -foregroundcolor "Invalid Content in $vmList!"
exit -2048
}
if ($keepType -eq "DAILY") {
if ([string]::isnullorempty($cleanupmatch)) { $cleanupmatch="Daily" }
$keepdate=(get-date).adddays(-1 * $keepInterval)
}
if ($keepType -eq "WEEKLY") {
#write-host "Setting Weekly... $keepInterval * 7"
if ([string]::isnullorempty($cleanupmatch)) { $cleanupmatch="Weekly" }
$keepdate=(get-date).adddays(-1 $keepInterval 7)
}
if ($keepType -eq "MONTHLY") {
if ([string]::isnullorempty($cleanupmatch)) { $cleanupmatch="Monthly" }
$keepdate=(get-date).adddays(-1 $keepInterval 30)
}
if ($firstChar -eq "#") {write-host -foregroundcolor Magenta "Skipping $vmName" }
write-host -foregroundcolor white "$vmName, Keep Type: $keepType, Keep Date: $keepDate"
if ($liveRun -eq $false) {$action="Listing"} else {$action = "Cleaning"}
if ([console]::KeyAvailable) {
$x=[System.Console]::ReadKey()
if ($x.key -eq "q" -or $x.key -eq "Q") {
write-host "Pressed Q, Stopping Script."
exit -1024
}
}
if ($firstChar -eq "#") {
$action="SKIP"
}
$vm=$vmName
#write-host "First Char is $firstChar"
write-host "$action snapshots for $vm"
if ($liveRun -eq $true -and $action -ne "SKIP") {
try {
$objVM=get-vm $vm
} catch {
write-host -ForegroundColor Red "There was a problem with $vm"
write-host $_.Exception.Message
exit -2048
}
write-host "Active Cleanup Match says: $cleanupmatch"
$objSnapshots=$objVM | get-snapshot|where {$_.Name -like "*$cleanupMatch*" -and $_.created -lt $keepDate}
$pass=0
#| remove-snapshot -confirm:$doConfirm
$snapCount=$objSnapshots.count
if ($snapCount -eq 0) {write-host "No snapshots to clean for $vm." }
if ($snapCount -gt 0) {
$hasError=$false
$timer=new-object System.Diagnostics.Stopwatch
$timer.start()
foreach ($snap in $objSnapshots) {
if ([console]::KeyAvailable) {
$x=[System.Console]::ReadKey()
if ($x.key -eq "q" -or $x.key -eq "Q") {
write-host "Pressed Q, Stopping Script."
exit -1024
}
}
if ($hasError -eq $true) {
exit -4096
}
$pass++
write-host "`rCleaning snapshot $pass of $snapCount"
try {
$snap|remove-snapshot -confirm:$doConfirm
} catch {
write-host -ForegroundColor Red "There was a problem removing the snapshot!"
$ErrorActionPreference = "STOP"
$hasError=$true
throw "There was a problem removing the snapshot!"
exit -4096
}
} #end foreach
$timer.stop()
$took="{0:hh}:{0:mm}:{0:ss}" -f $timer.elapsed
write-host "Took $vmname took $took to clean."
}
} elseif ($action -ne "SKIP") {
write-host "Listing Cleanup Match says: $cleanupmatch"
if ($firstChar -ne "#") { get-vm $vm | get-snapshot | where { $_.Name -like "*$cleanupMatch*" -and $_.created -lt $keepDate } | Select Created,Name|ft }
}
write-host " "
}
}
if ($PSCmdlet.ParameterSetName -ne "LoadFile") {
write-host "Loading from List..."
foreach ($vm in $vmName) {
if ($liveRun -eq $false) {$action="Listing"} else {$action = "Cleaning"}
if ([console]::KeyAvailable) {
$x=[System.Console]::ReadKey()
if ($x.key -eq "q" -or $x.key -eq "Q") {
write-host "Pressed Q, Stopping Script."
exit -1024
}
}
if ($vm[0] -eq "#") {
$action="SKIP"
}
write-host "$action snapshots for $vm"
if ($liveRun -eq $true -and $action -ne "SKIP") {
try {
$objVM=get-vm $vm
} catch {
write-host -ForegroundColor Red "There was a problem with $vm"
write-host $_.Exception.Message
exit -2048
}
$objSnapshots=$objVM | get-snapshot|where {$_.Name -like "*$cleanupMatch*" -and $_.created -lt $keepDate}
$pass=0
#| remove-snapshot -confirm:$doConfirm
$snapCount=$objSnapshots.count
if ($snapCount -eq 0) {write-host "No snapshots to clean for $vm." }
if ($snapCount -gt 0) {
$hasError=$false
foreach ($snap in $objSnapshots) {
if ([console]::KeyAvailable) {
$x=[System.Console]::ReadKey()
if ($x.key -eq "q" -or $x.key -eq "Q") {
write-host "Pressed Q, Stopping Script."
exit -1024
}
}
if ($hasError -eq $true) {
exit -4096
}
$pass++
write-host "`rCleaning snapshot $pass of $snapCount"
try {
$snap|remove-snapshot -confirm:$doConfirm
} catch {
write-host -ForegroundColor Red "There was a problem removing the snapshot!"
$ErrorActionPreference = "STOP"
$hasError=$true
throw "There was a problem removing the snapshot!"
exit -4096
}
} #end foreach
}
} else {
if ($vm[0] -ne "#") { get-vm $vm | get-snapshot | where { $_.Name -like "*$cleanupMatch*" -and $_.created -lt $keepDate } | Select Created,Name|ft }
}
write-host " "
}
}
if ($liveRun -eq $true) {
$runtimer.stop()
$fulltook="{0:hh}:{0:mm}:{0:ss}" -f $runtimer.elapsed
write-host "Full SCript took $fulltook"
Stop-Transcript
}
$ProgressPreference=$origProgressBar
$ErrorActionPreference=$origErrorAction
Kommentare