VMware Cloud Community
dscottimw
Enthusiast
Enthusiast
Jump to solution

inventory report including last poweroff date

Hi,

I'm new to power cli (about a week of trying it) and am trying to run a powercli script that will give me a list of powered off vm's with specific information including the date it was powered off. My script looks like this :

@"
===============================================================================
Title:         vminventory.ps1
Description:   Exports VM Information from vCenter into a .CSV file for importing into anything
Usage:         .\vminventory.ps1
Date:          10/15/2012
===============================================================================
"@
#### Get Virtual Center To Connect to:
$VCServerName = Read-Host "What is the Virtual Center name?"
$ExportFilePath = Read-Host "Where do you want to export the data?"
$VC = Connect-VIServer $VCServerName
$Report = @()
#$VMs = Get-Folder $VMFolder | Get-VM
$VMs = get-vm |Where-object {$_.powerstate -eq "poweredoff"}
$Datastores = Get-Datastore | select Name, Id
$VMHosts = Get-VMHost | select Name, Parent
### Get powered off event time:
ForEach ($VM in $VMs) {
Get-VIEvent -Entity $VM -MaxSamples ([int]::MaxValue) | where {$_ -is [VMware.Vim.VmPoweredOffEvent]} |
Group-Object -Property {$_.Vm.Name} | %{
$lastPO = $_.Group | Sort-Object -Property CreatedTime -Descending | Select -First 1 | Select -ExpandProperty CreatedTime
New-Object PSObject -Property @{
VM = $_.Group[0].Vm.Name
  "Last Poweroff"= $lastPO
}
}
      $VMView = $VM | Get-View
      $VMInfo = {} | Select VMName,Powerstate,OS,IPAddress,ToolsStatus,Host,Cluster,Datastore,NumCPU,MemMb,DiskGb,SSGOwner,BUSowner,PowerOFF,Note
      $VMInfo.VMName = $vm.name
      $VMInfo.Powerstate = $vm.Powerstate
      $VMInfo.OS = $vm.Guest.OSFullName
      $VMInfo.IPAddress = $vm.Guest.IPAddress[0]
      $VMInfo.ToolsStatus = $VMView.Guest.ToolsStatus
      $VMInfo.Host = $vm.host.name
      $VMInfo.Cluster = $vm.host.Parent.Name
      $VMInfo.Datastore = ($Datastores | where {$_.ID -match (($vmview.Datastore | Select -First 1) | Select Value).Value} | Select Name).Name
      $VMInfo.NumCPU = $vm.NumCPU
      $VMInfo.MemMb = [Math]::Round(($vm.MemoryMB),2)
      $VMInfo.DiskGb = [Math]::Round((($vm.HardDisks | Measure-Object -Property CapacityKB -Sum).Sum * 1KB / 1GB),2)
      $VMInfo.PowerOFF = $lastPO
      $VMInfo.SSGOwner = ($vm | Get-Annotation -CustomAttribute 'SSG System Owner').Value
      $VMInfo.BUSowner = ($vm | Get-Annotation -CustomAttribute 'Business System Owner').Value
      $VMInfo.Note = $vm.Notes
      $Report += $VMInfo
}
$Report = $Report | Sort-Object VMName
IF ($Report -ne "") {
$report | Export-Csv $ExportFilePath -NoTypeInformation
}
$VC = Disconnect-VIServer $VCServerName -Confirm:$False

I can't seem to get it to loop through and read the powered off events from the Events log on the vm?  Anyone have any thoughts?

Dan Scotti
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

No, my mistake. That should have been $lastPO.VM.VM.

I corrected the code above

Update: just noticed another typo, it's corrected


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
10 Replies
LucD
Leadership
Leadership
Jump to solution

Try something like this.

I changed the logic to only do the Get-ViEvent once (that will save a lot of execution time).

The event contains a MoRef to the VM in the VM property (that can be used with the Get-ViObjectByView cmdlet).

@"
===============================================================================
Title:         vminventory.ps1
Description:   Exports VM Information from vCenter into a .CSV file for importing into anything
Usage:         .\vminventory.ps1
Date:          10/15/2012
===============================================================================
"@ 
#### Get Virtual Center To Connect to: $VCServerName = Read-Host "What is the Virtual Center name?"
$ExportFilePath = Read-Host "Where do you want to export the data?"
$VC = Connect-VIServer $VCServerName

$Report = @()
$VMs
= get-vm |Where-object {$_.powerstate -eq "poweredoff"} $Datastores = Get-Datastore | select Name, Id
$VMHosts = Get-VMHost | select Name, Parent
### Get powered off event time:
Get-VIEvent -Entity $VMs -MaxSamples ([int]::MaxValue) | where {$_ -is [VMware.Vim.VmPoweredOffEvent]} |
Group-Object -Property {$_.Vm.Name} | %{   $lastPO = $_.Group | Sort-Object -Property CreatedTime -Descending | Select -First 1
  $vm = Get-VIObjectByVIView -MORef $lastPO.VM.VM
  $report += New-Object PSObject -Property @{     VMName = $vm.Name
    Powerstate = $vm.Powerstate
    OS = $vm.Guest.OSFullName
    IPAddress = $vm.Guest.IPAddress[0]     ToolsStatus = $VMView.Guest.ToolsStatus
    Host = $vm.host.name
   
Cluster = $vm.host.Parent.Name
    Datastore = ($Datastores | where {$_.ID -match (($vmview.Datastore | Select -First 1) | Select Value).Value} | Select Name).Name
    NumCPU = $vm.NumCPU
   
MemMb = [Math]::Round(($vm.MemoryMB),2)     DiskGb = [Math]::Round((($vm.HardDisks | Measure-Object -Property CapacityKB -Sum).Sum * 1KB / 1GB),2)     PowerOFF = $lastPO.CreatedTime
   
SSGOwner = ($vm | Get-Annotation -CustomAttribute 'SSG System Owner').Value
    BUSowner = ($vm | Get-Annotation -CustomAttribute 'Business System Owner').Value
    Note = $vm.Notes  } } $Report = $Report | Sort-Object VMName

if ($Report) {   $report | Export-Csv $ExportFilePath -NoTypeInformation} else{   "No PoweredOff events found"
} $VC = Disconnect-VIServer $VCServerName -Confirm:$False


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

dscottimw
Enthusiast
Enthusiast
Jump to solution

Thanks LucD.  That makes it a simpler script too!. 

I'll give it a shot and let you know how it goes.

I've been spending a lot of time with your book. Its been very helpful to me.

Dan Scotti
0 Kudos
dscottimw
Enthusiast
Enthusiast
Jump to solution

LucD,

Did I copy and paste something incorrectly? I'm getting errors that read as follows:

Get-VIObjectByVIView : Cannot bind parameter 'MORef'. Cannot convert the "VMware.Vim.VmEventArgument" value of type "VMware.Vim.VmEventArgument" to type "VMwar
e.Vim.ManagedObjectReference".
At C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\scripts\poweredoffvms3.ps1:25 char:36
+   $vm = Get-VIObjectByVIView -MORef <<<<  $lastPO.VM
    + CategoryInfo          : InvalidArgument: (:) [Get-VIObjectByVIView], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIObjectByVIViewCommand
Cannot index into a null array.
At C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\scripts\poweredoffvms3.ps1:30 char:37
+     IPAddress = $vm.Guest.IPAddress[ <<<< 0]
    + CategoryInfo          : InvalidOperation: (0:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray
Get-VIObjectByVIView : Cannot bind parameter 'MORef'. Cannot convert the "VMware.Vim.VmEventArgument" value of type "VMware.Vim.VmEventArgument" to type "VMwar
e.Vim.ManagedObjectReference".
At C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\scripts\poweredoffvms3.ps1:25 char:36
+   $vm = Get-VIObjectByVIView -MORef <<<<  $lastPO.VM
    + CategoryInfo          : InvalidArgument: (:) [Get-VIObjectByVIView], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIObjectByVIViewCommand
Cannot index into a null array.
At C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\scripts\poweredoffvms3.ps1:30 char:37
+     IPAddress = $vm.Guest.IPAddress[ <<<< 0]
    + CategoryInfo          : InvalidOperation: (0:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray
Get-VIObjectByVIView : Cannot bind parameter 'MORef'. Cannot convert the "VMware.Vim.VmEventArgument" value of type "VMware.Vim.VmEventArgument" to type "VMwar
e.Vim.ManagedObjectReference".
At C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\scripts\poweredoffvms3.ps1:25 char:36
+   $vm = Get-VIObjectByVIView -MORef <<<<  $lastPO.VM
    + CategoryInfo          : InvalidArgument: (:) [Get-VIObjectByVIView], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIObjectByVIViewCommand
Cannot index into a null array.
At C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\scripts\poweredoffvms3.ps1:30 char:37
+     IPAddress = $vm.Guest.IPAddress[ <<<< 0]
    + CategoryInfo          : InvalidOperation: (0:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray
Dan Scotti
0 Kudos
LucD
Leadership
Leadership
Jump to solution

No, my mistake. That should have been $lastPO.VM.VM.

I corrected the code above

Update: just noticed another typo, it's corrected


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
dscottimw
Enthusiast
Enthusiast
Jump to solution

Thanks LucD.  This worked almost perfectly.  It gave me everything I want (which is totally awesome).

The ordering of the output is a little out of the order I expected but I think I can manage to fix that.  Basically I am going to put the vmname in the first column. 

I did see these 2 messages in the powercli screen and am wondering about their impact on the script.

WARNING: The 'Host' property of VirtualMachine type is deprecated. Use the 'VMHost' property instead.
WARNING: The 'HardDisks' property of VirtualMachine type is deprecated. Use 'Get-HardDisk' cmdlet instead.

I got the info I wanted but if I change the properties in the messages will I need to modify the rest of the code in the affected lines which I believe are only these lines.

Host = $vm.host.name

    Cluster = $vm.host.Parent.Name

and

DiskGb = [Math]::Round((($vm.HardDisks | Measure-Object -Property CapacityKB -Sum).Sum * 1KB / 1GB),2)

Again thanks so much this is awesome.

Dan Scotti
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The order of the properties on the New-Object in PowerShell v2 is not maintained. In PowerShell v3 this has been changed.

If you want to have the properties appear in a specific order in the CSV file, you will have to add a Select-Object cmdlet.

The order of the properties on the Select will be the order that they are written to the CSV file

$Report | Select VMName,PowerState,... | Export-Csv ...

You can safely ignore the warnings for now.

It's just to warn you that these properties might disappear in a future PowerCLI build.

If you already want to update the script now, you will have to make indeed those changes


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

dscottimw
Enthusiast
Enthusiast
Jump to solution

I suspected as much on the deprecated warnings but wanted an expert opinion. 

Thanks.

Dan Scotti
0 Kudos
dscottimw
Enthusiast
Enthusiast
Jump to solution

Ok. One more question. In the output I am getting every powered off event for a particular vm.  Is there a way I can filter them to only the most recent power off event?

Thanks

Dan Scotti
0 Kudos
Grzesiekk
Expert
Expert
Jump to solution

if you have something which is already sorted by date and you want only first 10 add additional select

| select -first 10

Regards,

Greg

--- @blog https://grzegorzkulikowski.info
0 Kudos
dscottimw
Enthusiast
Enthusiast
Jump to solution

Thanks Greg

I have this line in the script which I think should sort it in descending order (newest to oldest) and select only the first one. It seems to be skipping this line.

$lastPO = $_.Group | Sort-Object -Property CreatedTime -Descending | Select -First 1

Dan Scotti
0 Kudos