PowerCLI: Linked VMs Refresh
April 1, 2015 – 5:19 pmAnd here is the follow up script for the pre-prod environment. This script can be scheduled to run daily to provide a fresh pre-production or test environment when your team arrives in the office.
#============================================================================= # Script : Pre-Production environment refresh # Author : Marc Bouchard # Credits : Rob Girard # Version : 1.0 # Revision : 03/31/2015 # Purpose : Refresh non-persistent copies of production VMs # Requirements : # 1. Source VM snapshot is created # 2. New VM is created, configured to use the base virtual HD of the source VM. # This drive is configured as a non-persistent disk to prevent corruption of # the reference image. This basically makes a point in time reference image # for testing changes to the production environment. # 3. Both VMs must be powered on # # Parameters : List of source (production) VMs #============================================================================= #============================================================================= # --- Command line parameters #============================================================================= param ( [Parameter(Mandatory=$true)] [String[]]$ListOfVMs = $(throw "List of source (production) VMs required") ) #============================================================================= # Screen setup #============================================================================= # set regular console colours [console]::backgroundcolor = "black" [console]::foregroundcolor = "white" # clear screen clear-host #============================================================================= # --- Load Powershell Snap-ins #============================================================================= if (!(get-pssnapin -name VMware.VimAutomation.Core -erroraction 'SilentlyContinue')) { Write-Host "[INFO] Adding PowerCLI Snapin" add-pssnapin VMware.VimAutomation.Core -ErrorAction 'SilentlyContinue' if (!(get-pssnapin -name VMware.VimAutomation.Core -erroraction 'SilentlyContinue')) { Write-Host "[ERROR] PowerCLI snapin NOT added" -ForegroundColor Red } Else { Write-Host "[INFO] PowerCLI snapin added" } } #============================================================================= # --- CUSTOMIZE THIS SECTION ONLY FOR YOUR ENVIRONMENT #============================================================================= $DateOnly = Get-Date -f yyyy-MM-dd $ScriptLocation="C:\Scripts\PreProd\" $CredUser = "ServiceAccountUserID" $CredFile = $ScriptLocation + "Refresh-PreProd.crd" $ReptFile = $ScriptLocation + "Refresh-PreProd_" + $DateOnly + ".log" $vCenter = "vCenterServerName" $Prefix = "PRE_" #SMTP relay $smtpServer = "smtp.companyname.com" $Sender = "refresh-preprod@companyname.com" $Recipient = "sysadmin@companyname" #============================================================================= # --- FUNCTION: Send e-mail #============================================================================= function SendMail{ Write-Host "[INFO] Sending e-mail" #Creating a Mail object $msg = new-object Net.Mail.MailMessage #Creating email attachment object $att = new-object Net.Mail.Attachment($ReptFile) #Creating SMTP server object $smtp = new-object Net.Mail.SmtpClient($smtpServer) #Email structure $msg.From = $Sender $msg.To.Add($Recipient) $msg.subject = "Pre-production environment refresh " + $DateOnly $msg.body = "Please see attached file." $msg.Attachments.Add($att) #Sending email $smtp.Send($msg) $att.Dispose() } #============================================================================= # --- Log Messages to journal #============================================================================= function LogMessages($LogMessage, $LogErrorMsg) { $(Get-Date -Format s) + " [INFO] " + $LogMessage | Out-file $ReptFile -Encoding ASCII -append if ($LogErrorMsg -ne $null) { $(Get-Date -Format s) + " [ERROR] " + $LogErrorMsg | Out-file $ReptFile -Encoding ASCII -append } } #============================================================================= # --- MAIN PROGRAM #============================================================================= Write-Host "[INFO] ======================================" Write-Host "[INFO] Refresh Linked VM Script" Write-Host "[INFO] ======================================" Write-Host "[INFO]" #============================================================================= # --- Credentials management #============================================================================= if ((Test-Path $CredFile) -eq $false) { $cred = new-object system.management.automation.pscredential $CredUser, (read-host -assecurestring -prompt "Enter administrator password") try { $cred.Password | ConvertFrom-SecureString | Set-Content $CredFile -ErrorAction Stop } catch { $Message = "Error saving credentials" $ErrorMessage = $_.Exception.Message LogMessages $Message $ErrorMessage SendMail Exit } } else { $password = get-content $CredFile | convertto-securestring $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $CredUser,$password } #============================================================================= # --- Connect to vCenter server #============================================================================= Write-Host "[INFO] Connecting to vCenter: " $vCenter try { Connect-VIServer -server $vCenter -credential $cred -ErrorAction Stop -WarningAction SilentlyContinue | Out-Null $Message = "Connecting to vCenter: " + $vCenter LogMessages $Message } Catch { $Message = "Failed connecting to " + $vCenter $ErrorMessage = $_.Exception.Message LogMessages $Message $ErrorMessage SendMail Exit } #============================================================================= # --- Shutdown current clones #============================================================================= ForEach ($SourceVM in $ListOfVMs) { try { $TargetVM = $Prefix + $SourceVM Write-Host "[INFO] Shutting down" $TargetVM $task = Stop-VM -VM $TargetVM -confirm:$false -runasync -ErrorAction Stop wait-task -Task $task | Out-Null $Message = "Stopping " + $TargetVM LogMessages $Message } Catch { Write-Host "[ERROR] Shutting down " $TargetVM -foregroundcolor Red $Message = "Error powering off "+ $Prefix + $SourceVM $ErrorMessage = $_.Exception.Message LogMessages $Message $ErrorMessage SendMail Exit } } #============================================================================= # --- Remove old snapshots #============================================================================= ForEach ($SourceVM in $ListOfVMs) { Try { Write-Host "[INFO] Deleting Snapshots for" $SourceVM $task = Get-VM $SourceVM | Get-Snapshot | Remove-Snapshot -confirm:$false -runasync -ErrorAction Stop wait-task -Task $task | Out-Null $Message = "Deleting snapshot for " + $SourceVM LogMessages $Message } Catch { Write-Host "[ERROR] Failed removing snapshot for" $SourceVM -foregroundcolor Red $Message = "Error removing snapshot for " + $SourceVM $ErrorMessage = $_.Exception.Message LogMessages $Message $ErrorMessage SendMail Exit } } #============================================================================= # --- Create new snapshots #============================================================================= ForEach ($SourceVM in $ListOfVMs) { try { Write-Host "[INFO] Creating snapshot for" $SourceVM $task = New-Snapshot -VM $SourceVM -Name ($(Get-Date -format s)) -runasync -ErrorAction Stop wait-task -Task $task | Out-Null $Message = "Creating snapshot for " + $SourceVM LogMessages $Message } Catch { Write-Host "[ERROR] Failed creating snapshot for" $SourceVM -foregroundcolor Red $Message = "Error creating snapshot for " + $SourceVM $ErrorMessage = $_.Exception.Message LogMessages $Message $ErrorMessage SendMail Exit } } #============================================================================= # --- Power up refreshed environment #============================================================================= ForEach ($SourceVM in $ListOfVMs) { try { $TargetVM = $Prefix + $SourceVM Write-Host "[INFO] Powering up " $TargetVM Start-VM -VM $TargetVM -confirm:$false -runasync -ErrorAction Stop | Out-Null $Message = "Restarting " + $TargetVM LogMessages $Message } catch { Write-Host "[ERROR] Failure starting " $SourceVM -foregroundcolor Red $Message = "Error starting " + $SourceVM $ErrorMessage = $_.Exception.Message LogMessages $Message $ErrorMessage SendMail Exit } } #============================================================================= # --- Close session #============================================================================= Disconnect-VIServer -server $vCenter -confirm:$false -force Write-Host "[INFO] Disconnecting from vCenter" $Message = "Disconnecting from vCenter" LogMessages $Message SendMail Write-Host