I did some further tests, and it looks like the script was not capturing all types of power off events.
I also added sort on VM name and Hard Disk name.
function Get-VMInfo { param(
[string]$Name
)
$vm = Get-View -ViewType VirtualMachine -Property Name, runtime.powerState, Guest.net, Config.Hardware.numCPU, Config.Hardware.MemoryMB, Runtime.Host, Guest.GuestFullName,
Config.GuestFullName, Parent, ResourcePool, Config.Hardware.Device, Config.version, guest.toolsversionstatus,
Config.Files.VMPathName -filter @{'Name' = "^$Name$" }
if ($vm) {
$t = Get-View $vm.ResourcePool -Property Name, Parent
while ($t.getType().Name -eq "ResourcePool") {
$t = Get-View $t.Parent -Property Name, Parent
}
if ($t.GetType().Name -eq "ClusterComputeResource") {
$cluster = $t.Name
} else {
$cluster = "Stand Alone Host"
}
while ($t.getType().Name -ne "Datacenter") {
$t = Get-View $t.Parent -Property Name, Parent
}
$datacenter = $t.Name
$vm.Config.Hardware.Device | Where-Object { $_.GetType().Name -eq "VirtualDisk" } |
Select-Object @{N = "vCenter"; E = { $script:vmhost = Get-View -Id $vm.Runtime.Host; $script:vmhost.Client.ServiceUrl.Split('/')[2] } },
@{N = "VM"; E = { $vm.Name } },
@{N = 'powerState'; E = { $vm.runtime.powerState } },
@{N = 'IP'; E = { [string]::Join(',', ($vm.Guest.Net | ForEach-Object { $_.IpAddress | Where-Object { $_.Split('.').Count -eq 4 } | ForEach-Object { $_ } })) } },
@{N = 'NumCPU'; E = { $vm.config.Hardware.NumCpu } },
@{N = 'Memory GB'; E = { $vm.Config.Hardware.MemoryMB | ForEach-Object { [math]::Round($_/1kb, 2) } } },
@{N = 'VMHost'; E = { $script:esx = Get-View -Id $vm.Runtime.Host; $script:esx.name } },
@{N = 'GuestOS'; E = { $vm.Guest.GuestFullName } },
@{N = 'ConfiguredOS'; E = { $vm.Config.GuestFullName } },
#@{N="Folder";E={$path}},
@{N = "Cluster"; E = { $cluster } },
@{N = "Datacenter"; E = { $datacenter } },
@{N = "Scsi"; E = { $_.UnitNumber } },
@{N = "Hard Disk"; E = { $_.DeviceInfo.Label } },
@{N = "Disk datastore"; E = { $_.Backing.Filename.Split(']')[0].TrimStart('[') } },
@{N = "Disk capacity GB"; E = { $_.CapacityInKB | ForEach-Object { [math]::Round($_/1MB, 2) } } },
@{N = "Disk type"; E = {
if ($_.Backing.GetType().Name -match "flat") {
"Flat"
} else {
$_.Backing.CompatibilityMode
} }
},
@{N = 'DeviceName'; E = {
if ($_.Backing.GetType().Name -match 'raw') {
($_.Backing.DeviceName) -join '|'
} else {
$script:lunnaa = (Get-View -Id $_.Backing.Datastore).Info.Vmfs.Extent[0].DiskName
$script:lun = $script:esx.Config.StorageDevice.ScsiLun | Where-Object { $_.CanonicalName -eq $script:lunnaa }
$script:lun.Descriptor | Where-Object { $_.Id -match 'vml.' } | Select-Object -ExpandProperty Id
} }
},
@{N = 'LUN NAA'; E = {
if ($_.Backing.GetType().Name -match 'raw') {
$lunUuid = $_.Backing.LunUuid
$script:lun = $script:esx.Config.StorageDevice.ScsiLun | Where-Object { $_.Uuid -eq $lunUuid }
$script:lun.CanonicalName
} else {
$script:lunnaa
} }
},
@{N = 'LUN ID'; E = {
$dev = $script:esx.Config.StorageDevice.PlugStoreTopology.Device | Where-Object { $_.Lun -eq $script:lun.Key }
$script:esx.Config.StorageDevice.PlugStoreTopology.Path | Where-Object { $_.Device -eq $dev.Key } |
Select-Object -First 1 -ExpandProperty LunNumber
}
},
@{N = 'VMConfigFile'; E = { $VM.config.files.VMpathname } },
@{N = 'VMDKPath'; E = { $_.Backing.FileName } },
@{N = "HW Version"; E = { $vm.Config.version } },
@{N = "Tools Status"; E = { $vm.guest.toolsversionstatus } },
@{N = "NIC Name"; E = { ($vm.config.hardware.device | Where-Object { ($_.DeviceInfo.Label -like "Network*") }).DeviceInfo.Label -join '|' } },
@{N = "Mac"; E = { ($vm.Config.Hardware.Device | Where-Object { $_.DeviceInfo.Label -like "Network*" }).MacAddress -join '|' } },
@{N = "Portgroup"; E = {
$nic = $vm.Config.Hardware.Device | Where-Object { $_.DeviceInfo.Label -like "Network*" }
[string]::Join(',', (
$nic | ForEach-Object {
if ($_.DeviceInfo.Summary -notmatch 'DVSwitch') {
$_.DeviceInfo.Summary
} else {
Get-View -ViewType DistributedVirtualPortgroup -Property Name -Filter @{'Key' = $_.Backing.Port.PortgroupKey } |
Select-Object -ExpandProperty Name
} })) }
}
}
}
$fileName = '.\VMreport.csv'
$configFile = $fileName.Replace('.csv', '.cfg')
$eventTypes = 'VmReconfiguredEvent', 'VmRemovedEvent', 'VmDeployedEvent', 'VmCreatedEvent', 'VmPoweredOffEvent',
'VmPoweredOnEvent', 'DrsVmPoweredOnEvent'
$start = (Get-Date).AddDays(-1)
$hash = @{ }
$now = Get-Date
if (Test-Path -Path $fileName) {
Import-Csv -Path .\VMreport.csv -UseCulture |
ForEach-Object -Process {
$hash.Add("$($_.VM)$($_.'Hard Disk')", $_)
}
$start = [DateTime](Get-Content -Path $configFile)
Get-VIEvent -Start $start -MaxSamples ([int]::MaxValue) |
Where-Object { $eventTypes -contains ($_.GetType()).FullName.Split('.')[2] -or $eventTypes -contains ($_.GetType()).BaseType.Name } |
Group-Object -Property { $_.VM.Name } |
ForEach-Object -Process {
Write-Host "Looking at $($_.Name)"
$_.Group | Sort-Object -Property CreatedTime |
ForEach-Object -Process {
$event = $_
switch ($event.GetType().FullName.Split('.')[2]) {
'VmRemovedEvent' {
$rows = $hash.GetEnumerator() | Where-Object { $_.Key -match "^$($event.VM.Name)" }
$rows | ForEach-Object -Process {
$hash.Remove("$($_.Value.VM)$($_.Value.'Hard Disk')")
}
}
{ 'VmDeployedEvent', 'VmCreatedEvent' -contains $_ } {
Get-VMInfo -Name $event.VM.Name |
ForEach-Object -Process {
$hash.Add("$($_.VM)$($_.'Hard Disk')", $_)
}
}
'VmReconfiguredEvent' {
Get-VMInfo -Name $event.VM.Name |
ForEach-Object -Process {
$hash.Item("$($_.VM)$($_.'Hard Disk')") = $_
}
}
{ 'VmPoweredOnEvent', 'DrsVmPoweredOnEvent' -contains $_ } {
$rows = $hash.GetEnumerator() | Where-Object { $_.Key -match "^$($event.VM.Name)" }
$rows | ForEach-Object -Process {
$_.Value.PowerState = 'poweredOn'
$hash.Item($_.Key) = $_.Value
}
}
'VmPoweredOffEvent' {
$rows = $hash.GetEnumerator() | Where-Object { $_.Key -match "^$($event.VM.Name)" }
$rows | ForEach-Object -Process {
$_.Value.PowerState = 'poweredOff'
$hash.Item($_.Key) = $_.Value
}
}
}
}
}
} else {
Get-View -ViewType Virtualmachine -Property Name -Filter @{'Config.Template' = 'False' } |
ForEach-Object -Process {
Write-Host "Looking at $($_.Name)"
Get-VMInfo -Name $_.Name |
ForEach-Object -Process {
$hash.Add("$($_.VM)$($_.'Hard Disk')", $_)
}
}
}
$hash.Values |
Sort-Object -Property VM, 'Hard Disk' |
Export-Csv -Path $fileName -NoTypeInformation -UseCulture
$now.ToString() | Out-File -FilePath $configFile