Created
July 9, 2024 10:10
-
-
Save davidlu1001/05e9ab9360803774cf8d619e00d4cbb7 to your computer and use it in GitHub Desktop.
Manage VM Snapshots
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.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