VMware Cloud Community
JindiJee
Contributor
Contributor
Jump to solution

Determine the "lineage" of a VM | From which Template was a given VM authored?

Wonder how I could solve the question of which template our VM was created from. In some enviornments there are only a handful of templates and each one is of a particular type XP, 2K, 2003, etc. so it's no biggie. With larger deployments with more templates and many of a similar type (2003 Standard, Windows 2003 Ent) it may get more complicated. Or to put this another way, reporting on what VMs were made from which templates.

I am not sure where to start here so sorry for not posting any code or attempts.

Thanks you,

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Afaik there is no property that shows from which template a VM has been deployed.

But building on the script I wrote for you can examine the task and event log and extract the information from there.

This script does just that


$days = 10 
$tasknumber = 999 
$eventnumber = 100 
$serviceInstance = get-view ServiceInstance 
$taskMgr = Get-View TaskManager 
$eventMgr = Get-View eventManager 
$report = @() 
$filter = New-Object VMware.Vim.TaskFilterSpec 
$filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime 
$filter.Time.beginTime = (Get-Date).AddDays(-$days) 
$filter.Time.timeType = "startedTime" 
$collectionImpl = Get-View ($taskMgr.CreateCollectorForTasks($filter)) 
$dummy = $collectionImpl.RewindCollector 
$collection = $collectionImpl.ReadNextTasks($tasknumber) 
while($collection -ne $null){ 
        $collection | Where-Object {$_.DescriptionId -eq "VirtualMachine.Clone"} | Sort-Object StartTime | % { 
                $efilter = New-Object VMware.Vim.EventFilterSpec 
                $efilter.eventChainId = $_.EventChainId 
                $TemplateDeploy = $false 
                $ecollectionImpl = Get-View ($eventMgr.CreateCollectorForEvents($efilter)) 
                $ecollection = $ecollectionImpl.ReadNextEvents($eventnumber) 
                while($ecollection -ne $null){ 
                        foreach($event in $ecollection){ 
                                switch($event.GetType()){ 
                                        "VMware.Vim.TaskEvent"{ 
                                                $startTime = $event.CreatedTime 
                                        } 
                                        "VMware.Vim.VmDeployedEvent" { 
                                                $status = $event.FullFormattedMessage 
                                                $endTime = $event.CreatedTime 
                                                $templateDeploy = $true 
                                        } 
                                        "VMware.Vim.VmDeployFailedEvent"{ 
                                            $status = $event.FullFormattedMessage 
                                                $endTime = $event.CreatedTime 
                                                $templateDeploy = $true 
                                        } 
                                        "VMware.Vim.VmBeingDeployedEvent"{ 
                                            $template = (Get-View $event.SrcTemplate.Vm).Name 
                                                $target = $event.SrcTemplate.Name 
                                                $user = $event.UserName 
                                        } 
                                        Default {} 
                                } 
                        } 
                        $ecollection = $ecollectionImpl.ReadNextEvents($eventnumber) 
                } 
                if($TemplateDeploy){ 
                        $row = "" | Select StartTime, EndTime, VMname, Template, User, Status 
                        $row.StartTime = $startTime 
                        $row.EndTime = $endTime 
                        $row.VMname = $target 
                        $row.Template = $template 
                        $row.user = $user 
                        $row.Status = $status 
                        $report += $row 
                } 
                $ecollectionImpl.DestroyCollector() 
        } 
        $collection = $collectionImpl.ReadNextTasks($tasknumber) 
} 
$report | Export-Csv "C:\Clone-Template-Report.csv" -noTypeInformation 

With the $days variable at the beginning of the script you can define how many days you want to go back.

Note that it of course depends how long you keep your tasks and events in your VC database !

Update : the script will now also report on failed deployments from templates.


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

View solution in original post

Reply
0 Kudos
4 Replies
LucD
Leadership
Leadership
Jump to solution

Afaik there is no property that shows from which template a VM has been deployed.

But building on the script I wrote for you can examine the task and event log and extract the information from there.

This script does just that


$days = 10 
$tasknumber = 999 
$eventnumber = 100 
$serviceInstance = get-view ServiceInstance 
$taskMgr = Get-View TaskManager 
$eventMgr = Get-View eventManager 
$report = @() 
$filter = New-Object VMware.Vim.TaskFilterSpec 
$filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime 
$filter.Time.beginTime = (Get-Date).AddDays(-$days) 
$filter.Time.timeType = "startedTime" 
$collectionImpl = Get-View ($taskMgr.CreateCollectorForTasks($filter)) 
$dummy = $collectionImpl.RewindCollector 
$collection = $collectionImpl.ReadNextTasks($tasknumber) 
while($collection -ne $null){ 
        $collection | Where-Object {$_.DescriptionId -eq "VirtualMachine.Clone"} | Sort-Object StartTime | % { 
                $efilter = New-Object VMware.Vim.EventFilterSpec 
                $efilter.eventChainId = $_.EventChainId 
                $TemplateDeploy = $false 
                $ecollectionImpl = Get-View ($eventMgr.CreateCollectorForEvents($efilter)) 
                $ecollection = $ecollectionImpl.ReadNextEvents($eventnumber) 
                while($ecollection -ne $null){ 
                        foreach($event in $ecollection){ 
                                switch($event.GetType()){ 
                                        "VMware.Vim.TaskEvent"{ 
                                                $startTime = $event.CreatedTime 
                                        } 
                                        "VMware.Vim.VmDeployedEvent" { 
                                                $status = $event.FullFormattedMessage 
                                                $endTime = $event.CreatedTime 
                                                $templateDeploy = $true 
                                        } 
                                        "VMware.Vim.VmDeployFailedEvent"{ 
                                            $status = $event.FullFormattedMessage 
                                                $endTime = $event.CreatedTime 
                                                $templateDeploy = $true 
                                        } 
                                        "VMware.Vim.VmBeingDeployedEvent"{ 
                                            $template = (Get-View $event.SrcTemplate.Vm).Name 
                                                $target = $event.SrcTemplate.Name 
                                                $user = $event.UserName 
                                        } 
                                        Default {} 
                                } 
                        } 
                        $ecollection = $ecollectionImpl.ReadNextEvents($eventnumber) 
                } 
                if($TemplateDeploy){ 
                        $row = "" | Select StartTime, EndTime, VMname, Template, User, Status 
                        $row.StartTime = $startTime 
                        $row.EndTime = $endTime 
                        $row.VMname = $target 
                        $row.Template = $template 
                        $row.user = $user 
                        $row.Status = $status 
                        $report += $row 
                } 
                $ecollectionImpl.DestroyCollector() 
        } 
        $collection = $collectionImpl.ReadNextTasks($tasknumber) 
} 
$report | Export-Csv "C:\Clone-Template-Report.csv" -noTypeInformation 

With the $days variable at the beginning of the script you can define how many days you want to go back.

Note that it of course depends how long you keep your tasks and events in your VC database !

Update : the script will now also report on failed deployments from templates.


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

Reply
0 Kudos
admin
Immortal
Immortal
Jump to solution

Luc, could you tell me why you didn't use Get-Task for this one? Does it not go back far enough? I didn't have time to dig into the details unfortunately.

Reply
0 Kudos
halr9000
Commander
Commander
Jump to solution

I believe the Get-Task cmdlet can only access the recent tasks, just as you see in the bottom pane of the VIC. Therefore, it's kinda useless.






[vExpert|http://www.vmware.com/communities/vexpert/], PowerShell MVP, VI Toolkit forum moderator

Author of the upcoming book: Managing VMware Infrastructure with PowerShell

Co-Host, PowerScripting Podcast (http://powerscripting.net)

Need general, non-VMware-related PowerShell Help? Try the forums at PowerShellCommunity.org

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Carter, I have to agree with Hal, the Get-Task cmdlet is rather restricted in it's use.

1. It only allows one to specify an ESX server not the VC (afaik)

2. It only returns the tasks that are still buffered on the ESX server (I suspect)

3. The returned object doesn't contain the event chain-id which makes it rather cumbersome to find the events related to the task

The Get-VIEvent cmdlet on the other hand is vastly improved in VITK 1.5.

There are for example no more limits on the number of events you can retrieve.

One could use the TaskEvent entries to detect the "VirtualMachine.Clone" tasks and via the Key and ChainId properties detect the related events.

But there are still some, what I consider major, shortcomings of the cmdlet:

1. It needs to have the -MaxSamples parameter otherwise it only returns 100 events even when the -Start and/or -Finish parameter are given.

And it's difficult/impossible to estimate this number in advance.

2. All the events are read into an array (memory) and this could become quit big if one needs to go back a long period on a busy VI.

With the SDK collectors (Tasks & Events) this can be much better controlled.


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

Reply
0 Kudos