If you’re anything like me, you know how important it is to keep an eye on the activity in your VMware vCenter environment. One missed event can mean extended downtime, performance hiccups, or even a serious security risk. Over the years, I’ve developed a few PowerShell scripts that help me quickly dig into the most important events on a daily or weekly basis. In this post, I’ll show you how I connect to vCenter using simple credentials, review the top five events I track, and demonstrate how to export the results for easy reporting or further analysis.
Below, you’ll find each event type explained along with a simple PowerShell snippet. I’ve also included a “connect and disconnect” routine at the beginning and end of every script so you can see how to plug everything together in one neat workflow.
Why These 5 Events Matter
- VM Being Cloned: Monitoring clone operations can catch unauthorized or unexpected copies of critical virtual machines.
- Datastore Connectivity Issues: Spotting when a datastore goes down can help you react quickly to storage or network problems.
- HA Host Restarted: Ensuring that vCenter logs any High Availability (HA) restarts helps you validate and troubleshoot cluster resiliency.
- VM Reconfiguration: Keeping track of changes to CPU, memory, or other VM settings can help prevent surprise resource usage spikes.
- VM Deletion from a Cluster: Auditing deletions helps you maintain proper documentation and security of VM workflows.
Connecting to vCenter
Before grabbing any events, you need to connect to your vCenter server. Here’s a corrected PowerShell snippet to connect and handle common errors:
# Variables
$Username = "Administrator@vsphere.local" # Replace with your username
$Password = "YourSecurePassword" # Replace with your password
$VCenter = "vcenter.mydomain.local" # Replace with your vCenter FQDN or IP
try {
Connect-VIServer -Server $VCenter -User $Username -Password $Password -ErrorAction Stop | Out-Null
Write-Host "Successfully connected to $VCenter." -ForegroundColor Green
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidLogin] {
Write-Host "Cannot connect to $VCenter with provided credentials." -ForegroundColor Red
return
}
catch [VMware.VimAutomation.Sdk.Types.V1.ErrorHandling.VimException.ViServerConnectionException] {
Write-Host "Cannot connect to $VCenter - check IP/FQDN." -ForegroundColor Red
return
}
catch {
Write-Host "Cannot connect to $VCenter - Unknown error." -ForegroundColor Red
return
}
Whenever you finish collecting or exporting events, it’s good practice to disconnect:
Disconnect-VIServer -Server $VCenter -Confirm:$false
That’s it for the basic framework. Now let’s look at how we can get details on each of these five must-watch events.
1. VM Being Cloned
Let’s say you want to check if someone cloned a VM. You can adjust the date range with -Start
and -Finish
parameters and export the results to a CSV for easy review:
# Script: Get-VMCloneEvents.ps1
# Description: Retrieves VM clone-related events within a specified timeframe.
# Variables
$VCenter = "vcenter.mydomain.local" # Replace with your vCenter FQDN or IP
$Username = "Administrator@vsphere.local" # Replace with your username
$Password = "YourSecurePassword" # Replace with your password
# Customize the timeframe
$daysAgo = 1
$thresholdDate = (Get-Date).AddDays(-$daysAgo)
# Connect to vCenter
try {
Connect-VIServer -Server $VCenter -User $Username -Password $Password -ErrorAction Stop | Out-Null
Write-Host "Successfully connected to $VCenter." -ForegroundColor Green
}
catch {
Write-Host "Error connecting to $VCenter: $($_.Exception.Message)" -ForegroundColor Red
return
}
# Get clone events from thresholdDate to now
$cloningEvents = Get-VIEvent -MaxSamples 100000 -Start $thresholdDate -Finish (Get-Date) |
Where-Object {
$_.Gettype().Name -eq "VmCreatedEvent" -or
$_.Gettype().Name -eq "VmBeingClonedEvent" -or
$_.Gettype().Name -eq "VmBeingDeployedEvent"
} |
Sort-Object CreatedTime -Descending
# Create a custom PowerShell object for easier manipulation
$cloningObjects = $cloningEvents | Select-Object CreatedTime, UserName, FullFormattedMessage
# Export to CSV (optional)
# $cloningObjects | Export-Csv "C:\tmp\events_clone.csv" -NoTypeInformation -UseCulture
Write-Host "=== Clone Events within the last $daysAgo day(s) ==="
$cloningObjects | Format-Table -AutoSize
# Disconnect from vCenter
Disconnect-VIServer -Server $VCenter -Confirm:$false
2. Datastore Connectivity Issues
Running out of disk space or losing access to a datastore can bring down multiple VMs. Catching early warnings is crucial:
# Script: Get-DatastoreDownEvents.ps1
# Description: Retrieves datastore connectivity issue events within a specified timeframe.
# Variables
$VCenter = "vcenter.mydomain.local"
$Username = "Administrator@vsphere.local"
$Password = "YourSecurePassword"
# Customize the timeframe
$daysAgo = 1
$thresholdDate = (Get-Date).AddDays(-$daysAgo)
# Connect to vCenter
try {
Connect-VIServer -Server $VCenter -User $Username -Password $Password -ErrorAction Stop | Out-Null
Write-Host "Successfully connected to $VCenter." -ForegroundColor Green
}
catch {
Write-Host "Error connecting to $VCenter: $($_.Exception.Message)" -ForegroundColor Red
return
}
# Gather ESXi hosts and datastores
$esxiHosts = Get-VMHost | Where-Object { $_.ConnectionState -eq "Connected" }
$datastores = Get-Datastore
# Check ESXi lost access events
foreach ($esxhost in $esxiHosts) {
$lostAccess = Get-VIEvent -Entity $esxhost -Start $thresholdDate -Finish (Get-Date) |
Where-Object { $_.FullFormattedMessage -match "Lost Access" }
if ($lostAccess) {
Write-Host "=== Lost Access Events for Host: $($esxhost.Name) ==="
$lostAccess | Select-Object CreatedTime, FullFormattedMessage | Format-Table -AutoSize
}
}
# Check datastore connectivity events
foreach ($datastore in $datastores) {
$events = Get-VIEvent -Entity $datastore -Start $thresholdDate -Finish (Get-Date) |
Where-Object { $_.GetType().Name -eq "DatastoreEvent" }
$lostConnectivityEvents = $events | Where-Object { $_.EventTypeId -eq "esx.problem.storage.connectivity.lost" }
if ($lostConnectivityEvents) {
Write-Host "=== Lost Connectivity Events for Datastore: $($datastore.Name) ==="
$lostConnectivityEvents | Select-Object CreatedTime, FullFormattedMessage | Format-Table -AutoSize
}
}
# Disconnect from vCenter
Disconnect-VIServer -Server $VCenter -Confirm:$false
3. HA Host Restarted
High Availability (HA) restarts are a big deal in production. Let’s capture any host restart events:
# Script: Get-HAHostRestarts.ps1
# Description: Retrieves HA host restart events within a specified timeframe.
# Variables
$VCenter = "vcenter.mydomain.local"
$Username = "Administrator@vsphere.local"
$Password = "YourSecurePassword"
# Customize the timeframe
$daysAgo = 1
$thresholdDate = (Get-Date).AddDays(-$daysAgo)
# Connect to vCenter
try {
Connect-VIServer -Server $VCenter -User $Username -Password $Password -ErrorAction Stop | Out-Null
Write-Host "Successfully connected to $VCenter." -ForegroundColor Green
}
catch {
Write-Host "Error connecting to $VCenter: $($_.Exception.Message)" -ForegroundColor Red
return
}
# Get HA restart events from thresholdDate
$HAevent = Get-VIEvent -MaxSamples 100000 -Start $thresholdDate -Finish (Get-Date) -type warning |
Where-Object { $_.FullFormattedMessage -match "restarted" }
if ($HAevent) {
Write-Host "=== HA Host Restart Events within the last $daysAgo day(s) ==="
$HAeventData = $HAevent |
Select-Object CreatedTime, FullFormattedMessage |
Sort-Object CreatedTime -Descending
$HAeventData | Format-Table -AutoSize
} else {
Write-Host "No HA restart events found in the last $daysAgo day(s)."
}
# Disconnect from vCenter
Disconnect-VIServer -Server $VCenter -Confirm:$false
4. VM Reconfiguration
Sometimes you need to check if someone changed the CPU, memory, or any other VM setting:
# Script: Get-VMReconfigurationEvents.ps1
# Description: Retrieves VM reconfiguration events (including CPU/RAM changes) within a specified timeframe.
# Variables
$VCenter = "vcenter.mydomain.local"
$Username = "Administrator@vsphere.local"
$Password = "YourSecurePassword"
# Customize the timeframe
$daysAgo = 1
$thresholdDate = (Get-Date).AddDays(-$daysAgo)
# Target VM name
$vmName = "TestVM"
# Connect to vCenter
try {
Connect-VIServer -Server $VCenter -User $Username -Password $Password -ErrorAction Stop | Out-Null
Write-Host "Successfully connected to $VCenter." -ForegroundColor Green
}
catch {
Write-Host "Error connecting to $VCenter: $($_.Exception.Message)" -ForegroundColor Red
return
}
# Retrieve the VM object
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
if (!$vm) {
Write-Host "VM '$vmName' not found. Exiting..." -ForegroundColor Red
Disconnect-VIServer -Server $VCenter -Confirm:$false
return
}
Write-Host "=== Querying reconfiguration events for VM: $($vm.Name) ==="
# Get reconfiguration events for the specified timeframe
$tasks = Get-VIEvent -Entity $vm -Start $thresholdDate -Finish (Get-Date) |
Where-Object {
$_.FullFormattedMessage -match "Reconfigure" -and
$_.CreatedTime -ge $thresholdDate
}
if ($tasks) {
foreach ($task in $tasks) {
Write-Host "Task Time: $($task.CreatedTime)"
Write-Host "Description: $($task.FullFormattedMessage)"
# Check if the message indicates CPU or memory changes
if ($task.FullFormattedMessage -match "CPU" -or $task.FullFormattedMessage -match "memory") {
Write-Host "Potential CPU/RAM change detected."
}
Write-Host "---------------------------------------------"
}
} else {
Write-Host "No reconfiguration tasks found within the last $daysAgo day(s)."
}
# Disconnect from vCenter
Disconnect-VIServer -Server $VCenter -Confirm:$false
5. VM Deletion from a Cluster
Accidentally (or intentionally) removing a VM from the cluster can lead to all sorts of confusion. Keep tabs on it:
# Script: Get-VMDeletionEvents.ps1
# Description: Retrieves events related to a VM being deleted from a cluster within a specified timeframe.
# Variables
$VCenter = "vcenter.mydomain.local"
$Username = "Administrator@vsphere.local"
$Password = "YourSecurePassword"
# Customize the timeframe
$daysAgo = 1
$thresholdDate = (Get-Date).AddDays(-$daysAgo)
# Cluster and VM name
$clusterName = "MyCluster"
$vmName = "MyVM"
# Connect to vCenter
try {
Connect-VIServer -Server $VCenter -User $Username -Password $Password -ErrorAction Stop | Out-Null
Write-Host "Successfully connected to $VCenter." -ForegroundColor Green
}
catch {
Write-Host "Error connecting to $VCenter: $($_.Exception.Message)" -ForegroundColor Red
return
}
# Retrieve the cluster object
$cluster = Get-Cluster -Name $clusterName -ErrorAction SilentlyContinue
if (!$cluster) {
Write-Host "Cluster '$clusterName' not found. Exiting..." -ForegroundColor Red
Disconnect-VIServer -Server $VCenter -Confirm:$false
return
}
# Gather VM deletion events
$events = Get-VIEvent -Entity $cluster -Start $thresholdDate -Finish (Get-Date) |
Where-Object {
$_.FullFormattedMessage -like "*$vmName*" -and
$_.EventTypeId -eq "vim.event.VmRemovedEvent"
}
if ($events) {
Write-Host "=== VM Deletion Events for '$vmName' in Cluster '$clusterName' within the last $daysAgo day(s) ==="
$events | Select-Object CreatedTime, UserName, FullFormattedMessage | Format-Table -AutoSize
} else {
Write-Host "No VM deletion events found for '$vmName' in the last $daysAgo day(s)."
}
# Disconnect from vCenter
Disconnect-VIServer -Server $VCenter -Confirm:$false
Monitoring these five event types regularly will give you a solid picture of what’s happening in your virtual environment. By customizing the date range, event types, or exporting to CSV, you can easily integrate these scripts into your existing workflows. Whether you run them daily, weekly, or as needed for auditing purposes, the insights they provide will help you manage resources more effectively, stay on top of critical changes, and maintain a stable virtual infrastructure.