Skip to content

Instantly share code, notes, and snippets.

@davidlu1001
Created July 9, 2024 10:10
Show Gist options
  • Save davidlu1001/05e9ab9360803774cf8d619e00d4cbb7 to your computer and use it in GitHub Desktop.
Save davidlu1001/05e9ab9360803774cf8d619e00d4cbb7 to your computer and use it in GitHub Desktop.
Manage VM Snapshots
<#
.SYNOPSIS
Automates snapshot management for virtual machines.
.DESCRIPTION
This script automates the process of creating and managing snapshots for virtual machines
in a web-based management interface. It is compatible with PowerShell V5 and does not rely on external WebDriver dependencies.
.NOTES
File Name : manageVMSnapshots.ps1
Author : [Your Name]
Prerequisite : PowerShell V5
#>
# Enable strict mode for better error handling
Set-StrictMode -Version Latest
# Error action preference
$ErrorActionPreference = "Stop"
# Import required assemblies
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# Script variables
$global:logFile = ".\\VMSnapshotManagement_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
$global:baseUrl = "<https://webappvcloud.xxx.com/vcac/>"
# Logging function
function Write-Log {
param (
[Parameter(Mandatory=$true)]
[string]$Message,
[ValidateSet("INFO", "WARNING", "ERROR")]
[string]$Level = "INFO"
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "[$timestamp] [$Level] $Message"
Add-Content -Path $global:logFile -Value $logMessage
Write-Host $logMessage
}
# Function to simulate mouse click
function Invoke-MouseClick {
param (
[Parameter(Mandatory=$true)]
[System.Drawing.Point]$Position
)
$signature = @'
[DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
'@
$SendMouseClick = Add-Type -memberDefinition $signature -name "Win32MouseEventNew" -namespace Win32Functions -passThru
$SendMouseClick::mouse_event(0x00000002, $Position.X, $Position.Y, 0, 0) # Mouse down
$SendMouseClick::mouse_event(0x00000004, $Position.X, $Position.Y, 0, 0) # Mouse up
}
# Function to wait for an element
function Wait-ForElement {
param (
[Parameter(Mandatory=$true)]
[string]$Selector,
[int]$Timeout = 30
)
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
while ($stopwatch.Elapsed.TotalSeconds -lt $Timeout) {
$element = $null
try {
$element = [System.Windows.Forms.Control]::FromHandle($ie.HWND).Document.GetElementsByTagName("*") | Where-Object { $_.id -eq $Selector -or $_.name -eq $Selector }
if ($element) {
return $element
}
}
catch {
# Ignore errors and continue waiting
}
Start-Sleep -Milliseconds 500
}
throw "Element not found: $Selector"
}
# Function to navigate to a URL
function Navigate-ToUrl {
param (
[Parameter(Mandatory=$true)]
[string]$Url
)
try {
$ie.Navigate($Url)
while ($ie.Busy -or $ie.ReadyState -ne 4) {
Start-Sleep -Milliseconds 100
}
}
catch {
Write-Log "Failed to navigate to $Url. Error: $_" -Level ERROR
throw
}
}
# Function to delete existing snapshot
function Remove-ExistingSnapshot {
param (
[Parameter(Mandatory=$true)]
[string]$MachineName
)
try {
$snapshotsTab = Wait-ForElement "snapshotsTab"
$snapshotsTab.Click()
$existingSnapshot = $ie.Document.GetElementsByTagName("div") | Where-Object { $_.className -like "*snapshot-item*" }
if ($existingSnapshot) {
$deleteButton = Wait-ForElement "deleteSnapshotButton"
$deleteButton.Click()
$confirmDelete = Wait-ForElement "confirmDeleteButton"
$confirmDelete.Click()
Write-Log "Deleted existing snapshot for $MachineName"
}
else {
Write-Log "No existing snapshot found for $MachineName"
}
}
catch {
Write-Log "Failed to delete existing snapshot for $MachineName. Error: $_" -Level ERROR
throw
}
}
# Function to create new snapshot
function New-VMSnapshot {
param (
[Parameter(Mandatory=$true)]
[string]$MachineName
)
try {
$createSnapshotButton = Wait-ForElement "createSnapshotButton"
$createSnapshotButton.Click()
$snapshotName = Wait-ForElement "snapshotName"
$snapshotName.Value = "$MachineName-$(Get-Date -Format 'yyyy-MM-dd-HH-mm')"
$snapshotDescription = Wait-ForElement "snapshotDescription"
$snapshotDescription.Value = "Automated snapshot created by script"
$submitButton = Wait-ForElement "submitSnapshotButton"
$submitButton.Click()
Write-Log "Created new snapshot for $MachineName"
}
catch {
Write-Log "Failed to create new snapshot for $MachineName. Error: $_" -Level ERROR
throw
}
}
# Main script logic
try {
Write-Log "Script started"
# Create Internet Explorer COM object
$ie = New-Object -ComObject InternetExplorer.Application
$ie.Visible = $true
Navigate-ToUrl $global:baseUrl
# Get all machine list
$machines = $ie.Document.GetElementsByTagName("div") | Where-Object { $_.className -like "*machine-item*" }
foreach ($machine in $machines) {
$machineName = $machine.innerText
Write-Log "Processing machine: $machineName"
# Click to enter machine details page
$machine.Click()
# Delete existing snapshot (if exists)
Remove-ExistingSnapshot $machineName
# Create new snapshot
New-VMSnapshot $machineName
# Navigate back to machine list
Navigate-ToUrl $global:baseUrl
}
Write-Log "Script completed successfully"
}
catch {
Write-Log "An error occurred: $_" -Level ERROR
}
finally {
# Close Internet Explorer
if ($ie) {
$ie.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie) | Out-Null
}
Write-Log "Script execution ended"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment