build 7bbbddf7 | content blog-content@c8490fa · 338 posts | profiles 20 · corpus 267 | 0 skipped | | format
apiVersion: soultec.ch/v1kind: Postmetadata: name: powercli-reporting-the-duration-of-snapshots locale: en labels: author: dario-doerflinger series: scripting capability/automation: 1.78 vendor/vmware: 0.88 annotations: source: blog-content/posts/en/powercli-reporting-the-duration-of-snapshots.md route: /en/insights/powercli-reporting-the-duration-of-snapshots/ schema: /nerd/schema/posts.json markdown: /en/insights/powercli-reporting-the-duration-of-snapshots.mdspec: title: Reporting the duration of snapshots date: 2017-10-10 author: dario-doerflinger locale: en summary: >- One of our customers had a problem with VMs losing network connectivity while the backup was running. Their backup solution was based on VMware snapshots. capabilities: [automation] vendors: [vmware] series: scripting legacySlug: powercli-reporting-the-duration-of-snapshots migrated: 2026-08-24 draft: false sections: - body: | One of our customers had a problem with VMs losing network connectivity while the backup was running. Their backup solution was based on VMware snapshots. After the end-users complained about a service not being responsive they investigated and found out that during the creation of the snapshot they lose the pings. In response they wanted to check how long the snapshots take on all of their VMs. Even though their environment was not very big, it would have been very tedious to gather this information manually. PowerCLI to the rescue! The script leverages Luc's awesome Get-TaskPlus function (which can be found [here](http://www.lucd.info/2013/06/01/task-data-mining-an-improved-get-task/)) with a few enhancements: - The time from the events are converted to local time (instead of UTC) - Some try/catch to filter exceptions Then it was just a matter of filtering for the correct task objects and selecting the desired properties. Because the customer wanted to see the time it took for the task to complete I've added a "New-Timespan" object to the select which calculates the total amount of seconds between "Task Started" and "Task completed". Update: this script is now published at [GitHub](https://github.com/virtualFrog/PowerCLI-Scripts). Here is the script: ```powershell # import vmware related modules, get the credentials and connect to the vCenter server Import-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null #$creds = Get-VICredentialStoreItem -file "D:\Scripts\CreateSnapshotCreationOverview\login.creds" #Connect-VIServer -Server $creds.Host -User $creds.User -Password $creds.Password connect-viserver vCenter.virtualfrog.lab function Get-TaskPlus { <# .EXAMPLE PS> Get-TaskPlus -Start (Get-Date).AddDays(-1) .EXAMPLE PS> Get-TaskPlus -Alarm $alarm -Details #> param( [CmdletBinding()] [VMware.VimAutomation.ViCore.Impl.V1.Alarm.AlarmDefinitionImpl]$Alarm, [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]$Entity, [switch]$Recurse = $false, [VMware.Vim.TaskInfoState[]]$State, [DateTime]$Start, [DateTime]$Finish, [string]$UserName, [int]$MaxSamples = 100, [switch]$Reverse = $true, [VMware.VimAutomation.ViCore.Impl.V1.VIServerImpl[]]$Server = $global:DefaultVIServer, [switch]$Realtime, [switch]$Details, [switch]$Keys, [int]$WindowSize = 100 ) begin { function Get-TaskDetails { param( [VMware.Vim.TaskInfo[]]$Tasks ) begin{ $psV3 = $PSversionTable.PSVersion.Major -ge 3 } process{ $tasks | %{ if($psV3){ $object = [ordered]@{} } else { $object = @{} } $object.Add("Name",$_.Name) $object.Add("Description",$_.Description.Message) if($Details){$object.Add("DescriptionId",$_.DescriptionId)} if($Details){$object.Add("Task Created",$_.QueueTime.tolocaltime())} $object.Add("Task Started",$_.StartTime.tolocaltime()) if($Details){$object.Add("Task Ended",$_.CompleteTime.tolocaltime())} $object.Add("State",$_.State) $object.Add("Result",$_.Result) $object.Add("Entity",$_.EntityName) $object.Add("VIServer",$VIObject.Name) $object.Add("Error",$_.Error.ocalizedMessage) if($Details){ $object.Add("Cancelled",(&{if($_.Cancelled){"Y"}else{"N"}})) $object.Add("Reason",$_.Reason.GetType().Name.Replace("TaskReason", "")) $object.Add("AlarmName",$_.Reason.AlarmName) $object.Add("AlarmEntity",$_.Reason.EntityName) $object.Add("ScheduleName",$_.Reason.Name) $object.Add("User",$_.Reason.UserName) } if($keys){ $object.Add("Key",$_.Key) $object.Add("ParentKey",$_.ParentTaskKey) $object.Add("RootKey",$_.RootTaskKey) } New-Object PSObject -Property $object } } } $filter = New-Object VMware.Vim.TaskFilterSpec if($Alarm){ $filter.Alarm = $Alarm.ExtensionData.MoRef } if($Entity){ $filter.Entity = New-Object VMware.Vim.TaskFilterSpecByEntity $filter.Entity.entity = $Entity.ExtensionData.MoRef if($Recurse){ $filter.Entity.Recursion = [VMware.Vim.TaskFilterSpecRecursionOption]::all } else{ $filter.Entity.Recursion = [VMware.Vim.TaskFilterSpecRecursionOption]::self } } if($State){ $filter.State = $State } if($Start -or $Finish){ $filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime $filter.Time.beginTime = $Start $filter.Time.endTime = $Finish $filter.Time.timeType = [vmware.vim.taskfilterspectimeoption]::startedTime } if($UserName){ $userNameFilterSpec = New-Object VMware.Vim.TaskFilterSpecByUserName $userNameFilterSpec.UserList = $UserName $filter.UserName = $userNameFilterSpec } $nrTasks = 0 } process { foreach($viObject in $Server){ $si = Get-View ServiceInstance -Server $viObject $tskMgr = Get-View $si.Content.TaskManager -Server $viObject if($Realtime -and $tskMgr.recentTask){ $tasks = Get-View $tskMgr.recentTask $selectNr = [Math]::Min($tasks.Count,$MaxSamples-$nrTasks) Get-TaskDetails -Tasks[0..($selectNr-1)] $nrTasks += $selectNr } try { $tCollector = Get-View ($tskMgr.CreateCollectorForTasks($filter)) if($Reverse){ $tCollector.ResetCollector() $taskReadOp = $tCollector.ReadPreviousTasks } else{ $taskReadOp = $tCollector.ReadNextTasks } do{ $tasks = $taskReadOp.Invoke($WindowSize) if(!$tasks){return} $selectNr = [Math]::Min($tasks.Count,$MaxSamples-$nrTasks) Get-TaskDetails -Tasks $tasks[0..($selectNr-1)] $nrTasks += $selectNr }while($nrTasks -lt $MaxSamples) } catch { Write-Host "A error occured in the collector" } } try { $tCollector.DestroyCollector() } catch { Write-Host "The error not letting us destroy the collector" } } } $start = (Get-Date).AddDays(-30) $finish = (Get-Date) $output = Get-TaskPlus -Details -MaxSamples 20000000 -Start $start -Finish $finish | ? {$_.Name -match "CreateSnapshot_Task" -or $_.Name -match "RemoveSnapshot_Task"} | select Entity, "Task Created", "Task Started", "Task Ended", User, State, Name, @{Name="Duration in Seconds"; Expression = {(New-TimeSpan -start $_."Task Started" -End $_."Task Ended").TotalSeconds}} # create a CSV file with all snapshot related results $output | Export-Csv -Path "c:\temp\snapshot_create_and_remove_times_last_month.csv" -NoTypeInformation # cleanup and removal of loaded VMware modules #Disconnect-VIServer -Server $creds.Host -Confirm:$false disconnect-viserver vCenter.virtualfrog.lab -confirm:$false Remove-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null ```status: corpus: 267 alsoLike: - {ref: posts/vmware-explore-las-vegas-hackathon-2025, score: 1.00} - {ref: posts/vmware-hackathon-2024-project, score: 1.00} - {ref: solutions/vmware/vmware-cloud-foundation/addon/application-services, score: 0.60}
{ "apiVersion": "soultec.ch/v1", "kind": "Post", "metadata": { "name": "powercli-reporting-the-duration-of-snapshots", "locale": "en", "labels": { "author": "dario-doerflinger", "series": "scripting", "capability/automation": "1.78", "vendor/vmware": "0.88" }, "annotations": { "source": "blog-content/posts/en/powercli-reporting-the-duration-of-snapshots.md", "route": "/en/insights/powercli-reporting-the-duration-of-snapshots/", "schema": "/nerd/schema/posts.json", "markdown": "/en/insights/powercli-reporting-the-duration-of-snapshots.md" } }, "spec": { "title": "Reporting the duration of snapshots", "date": "2017-10-10", "author": "dario-doerflinger", "locale": "en", "summary": "One of our customers had a problem with VMs losing network connectivity while the backup was running. Their backup solution was based on VMware snapshots.", "capabilities": [ "automation" ], "vendors": [ "vmware" ], "series": "scripting", "legacySlug": "powercli-reporting-the-duration-of-snapshots", "migrated": "2026-08-24", "draft": false }, "sections": [ { "body": "One of our customers had a problem with VMs losing network connectivity while the backup was running. Their backup solution was based on VMware snapshots. After the end-users complained about a service not being responsive they investigated and found out that during the creation of the snapshot they lose the pings.\n\nIn response they wanted to check how long the snapshots take on all of their VMs. Even though their environment was not very big, it would have been very tedious to gather this information manually. PowerCLI to the rescue!\n\nThe script leverages Luc's awesome Get-TaskPlus function (which can be found [here](http://www.lucd.info/2013/06/01/task-data-mining-an-improved-get-task/)) with a few enhancements:\n\n- The time from the events are converted to local time (instead of UTC)\n- Some try/catch to filter exceptions\n\nThen it was just a matter of filtering for the correct task objects and selecting the desired properties. Because the customer wanted to see the time it took for the task to complete I've added a \"New-Timespan\" object to the select which calculates the total amount of seconds between \"Task Started\" and \"Task completed\".\n\nUpdate: this script is now published at [GitHub](https://github.com/virtualFrog/PowerCLI-Scripts).\n\nHere is the script:\n\n```powershell\n# import vmware related modules, get the credentials and connect to the vCenter server\nImport-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null\n#$creds = Get-VICredentialStoreItem -file \"D:\\Scripts\\CreateSnapshotCreationOverview\\login.creds\"\n#Connect-VIServer -Server $creds.Host -User $creds.User -Password $creds.Password\nconnect-viserver vCenter.virtualfrog.lab\n\nfunction Get-TaskPlus {\n<#\n.EXAMPLE\n PS> Get-TaskPlus -Start (Get-Date).AddDays(-1)\n.EXAMPLE\n PS> Get-TaskPlus -Alarm $alarm -Details\n#>\n\n param(\n [CmdletBinding()]\n [VMware.VimAutomation.ViCore.Impl.V1.Alarm.AlarmDefinitionImpl]$Alarm,\n [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]$Entity,\n [switch]$Recurse = $false,\n [VMware.Vim.TaskInfoState[]]$State,\n [DateTime]$Start,\n [DateTime]$Finish,\n [string]$UserName,\n [int]$MaxSamples = 100,\n [switch]$Reverse = $true,\n [VMware.VimAutomation.ViCore.Impl.V1.VIServerImpl[]]$Server = $global:DefaultVIServer,\n [switch]$Realtime,\n [switch]$Details,\n [switch]$Keys,\n [int]$WindowSize = 100\n )\n\n begin {\n function Get-TaskDetails {\n param(\n [VMware.Vim.TaskInfo[]]$Tasks\n )\n begin{\n $psV3 = $PSversionTable.PSVersion.Major -ge 3\n }\n\n process{\n $tasks | %{\n if($psV3){\n $object = [ordered]@{}\n }\n else {\n $object = @{}\n }\n $object.Add(\"Name\",$_.Name)\n $object.Add(\"Description\",$_.Description.Message)\n if($Details){$object.Add(\"DescriptionId\",$_.DescriptionId)}\n if($Details){$object.Add(\"Task Created\",$_.QueueTime.tolocaltime())}\n $object.Add(\"Task Started\",$_.StartTime.tolocaltime())\n if($Details){$object.Add(\"Task Ended\",$_.CompleteTime.tolocaltime())}\n $object.Add(\"State\",$_.State)\n $object.Add(\"Result\",$_.Result)\n $object.Add(\"Entity\",$_.EntityName)\n $object.Add(\"VIServer\",$VIObject.Name)\n $object.Add(\"Error\",$_.Error.ocalizedMessage)\n if($Details){\n $object.Add(\"Cancelled\",(&{if($_.Cancelled){\"Y\"}else{\"N\"}}))\n $object.Add(\"Reason\",$_.Reason.GetType().Name.Replace(\"TaskReason\", \"\"))\n $object.Add(\"AlarmName\",$_.Reason.AlarmName)\n $object.Add(\"AlarmEntity\",$_.Reason.EntityName)\n $object.Add(\"ScheduleName\",$_.Reason.Name)\n $object.Add(\"User\",$_.Reason.UserName)\n }\n if($keys){\n $object.Add(\"Key\",$_.Key)\n $object.Add(\"ParentKey\",$_.ParentTaskKey)\n $object.Add(\"RootKey\",$_.RootTaskKey)\n }\n\n New-Object PSObject -Property $object\n }\n }\n }\n\n $filter = New-Object VMware.Vim.TaskFilterSpec\n if($Alarm){\n $filter.Alarm = $Alarm.ExtensionData.MoRef\n }\n if($Entity){\n $filter.Entity = New-Object VMware.Vim.TaskFilterSpecByEntity\n $filter.Entity.entity = $Entity.ExtensionData.MoRef\n if($Recurse){\n $filter.Entity.Recursion = [VMware.Vim.TaskFilterSpecRecursionOption]::all\n }\n else{\n $filter.Entity.Recursion = [VMware.Vim.TaskFilterSpecRecursionOption]::self\n }\n }\n if($State){\n $filter.State = $State\n }\n if($Start -or $Finish){\n $filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime\n $filter.Time.beginTime = $Start\n $filter.Time.endTime = $Finish\n $filter.Time.timeType = [vmware.vim.taskfilterspectimeoption]::startedTime\n }\n if($UserName){\n $userNameFilterSpec = New-Object VMware.Vim.TaskFilterSpecByUserName\n $userNameFilterSpec.UserList = $UserName\n $filter.UserName = $userNameFilterSpec\n }\n $nrTasks = 0\n }\n\n process {\n foreach($viObject in $Server){\n $si = Get-View ServiceInstance -Server $viObject\n $tskMgr = Get-View $si.Content.TaskManager -Server $viObject \n\n if($Realtime -and $tskMgr.recentTask){\n $tasks = Get-View $tskMgr.recentTask\n $selectNr = [Math]::Min($tasks.Count,$MaxSamples-$nrTasks)\n Get-TaskDetails -Tasks[0..($selectNr-1)]\n $nrTasks += $selectNr\n }\n\n try {\n $tCollector = Get-View ($tskMgr.CreateCollectorForTasks($filter))\n\n if($Reverse){\n $tCollector.ResetCollector()\n $taskReadOp = $tCollector.ReadPreviousTasks\n }\n else{\n $taskReadOp = $tCollector.ReadNextTasks\n }\n do{\n $tasks = $taskReadOp.Invoke($WindowSize)\n if(!$tasks){return}\n $selectNr = [Math]::Min($tasks.Count,$MaxSamples-$nrTasks)\n Get-TaskDetails -Tasks $tasks[0..($selectNr-1)]\n $nrTasks += $selectNr\n }while($nrTasks -lt $MaxSamples)\n }\n catch {\n Write-Host \"A error occured in the collector\"\n }\n }\n try {\n $tCollector.DestroyCollector()\n }\n catch {\n Write-Host \"The error not letting us destroy the collector\"\n }\n }\n}\n$start = (Get-Date).AddDays(-30)\n$finish = (Get-Date)\n$output = Get-TaskPlus -Details -MaxSamples 20000000 -Start $start -Finish $finish |\n? {$_.Name -match \"CreateSnapshot_Task\" -or $_.Name -match \"RemoveSnapshot_Task\"} |\nselect Entity, \"Task Created\", \"Task Started\", \"Task Ended\", User, State, Name,\n@{Name=\"Duration in Seconds\"; Expression = {(New-TimeSpan -start $_.\"Task Started\" -End $_.\"Task Ended\").TotalSeconds}}\n# create a CSV file with all snapshot related results\n$output | Export-Csv -Path \"c:\\temp\\snapshot_create_and_remove_times_last_month.csv\" -NoTypeInformation\n\n# cleanup and removal of loaded VMware modules\n#Disconnect-VIServer -Server $creds.Host -Confirm:$false\ndisconnect-viserver vCenter.virtualfrog.lab -confirm:$false\nRemove-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null\n```" } ], "status": { "corpus": 267, "alsoLike": [ { "ref": "posts/vmware-explore-las-vegas-hackathon-2025", "score": "1.00" }, { "ref": "posts/vmware-hackathon-2024-project", "score": "1.00" }, { "ref": "solutions/vmware/vmware-cloud-foundation/addon/application-services", "score": "0.60" } ] }}
apiVersion = "soultec.ch/v1"kind = "Post"[metadata]name = "powercli-reporting-the-duration-of-snapshots"locale = "en"[metadata.labels]author = "dario-doerflinger"series = "scripting""capability/automation" = "1.78""vendor/vmware" = "0.88"[metadata.annotations]source = "blog-content/posts/en/powercli-reporting-the-duration-of-snapshots.md"route = "/en/insights/powercli-reporting-the-duration-of-snapshots/"schema = "/nerd/schema/posts.json"markdown = "/en/insights/powercli-reporting-the-duration-of-snapshots.md"[spec]title = "Reporting the duration of snapshots"date = 2017-10-10author = "dario-doerflinger"locale = "en"summary = "One of our customers had a problem with VMs losing network connectivity while the backup was running. Their backup solution was based on VMware snapshots."capabilities = ["automation"]vendors = ["vmware"]series = "scripting"legacySlug = "powercli-reporting-the-duration-of-snapshots"migrated = 2026-08-24draft = false[[sections]]body = '''One of our customers had a problem with VMs losing network connectivity while the backup was running. Their backup solution was based on VMware snapshots. After the end-users complained about a service not being responsive they investigated and found out that during the creation of the snapshot they lose the pings.In response they wanted to check how long the snapshots take on all of their VMs. Even though their environment was not very big, it would have been very tedious to gather this information manually. PowerCLI to the rescue!The script leverages Luc's awesome Get-TaskPlus function (which can be found [here](http://www.lucd.info/2013/06/01/task-data-mining-an-improved-get-task/)) with a few enhancements:- The time from the events are converted to local time (instead of UTC)- Some try/catch to filter exceptionsThen it was just a matter of filtering for the correct task objects and selecting the desired properties. Because the customer wanted to see the time it took for the task to complete I've added a "New-Timespan" object to the select which calculates the total amount of seconds between "Task Started" and "Task completed".Update: this script is now published at [GitHub](https://github.com/virtualFrog/PowerCLI-Scripts).Here is the script:```powershell# import vmware related modules, get the credentials and connect to the vCenter serverImport-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null#$creds = Get-VICredentialStoreItem -file "D:\Scripts\CreateSnapshotCreationOverview\login.creds"#Connect-VIServer -Server $creds.Host -User $creds.User -Password $creds.Passwordconnect-viserver vCenter.virtualfrog.labfunction Get-TaskPlus {<#.EXAMPLE PS> Get-TaskPlus -Start (Get-Date).AddDays(-1).EXAMPLE PS> Get-TaskPlus -Alarm $alarm -Details#> param( [CmdletBinding()] [VMware.VimAutomation.ViCore.Impl.V1.Alarm.AlarmDefinitionImpl]$Alarm, [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]$Entity, [switch]$Recurse = $false, [VMware.Vim.TaskInfoState[]]$State, [DateTime]$Start, [DateTime]$Finish, [string]$UserName, [int]$MaxSamples = 100, [switch]$Reverse = $true, [VMware.VimAutomation.ViCore.Impl.V1.VIServerImpl[]]$Server = $global:DefaultVIServer, [switch]$Realtime, [switch]$Details, [switch]$Keys, [int]$WindowSize = 100 ) begin { function Get-TaskDetails { param( [VMware.Vim.TaskInfo[]]$Tasks ) begin{ $psV3 = $PSversionTable.PSVersion.Major -ge 3 } process{ $tasks | %{ if($psV3){ $object = [ordered]@{} } else { $object = @{} } $object.Add("Name",$_.Name) $object.Add("Description",$_.Description.Message) if($Details){$object.Add("DescriptionId",$_.DescriptionId)} if($Details){$object.Add("Task Created",$_.QueueTime.tolocaltime())} $object.Add("Task Started",$_.StartTime.tolocaltime()) if($Details){$object.Add("Task Ended",$_.CompleteTime.tolocaltime())} $object.Add("State",$_.State) $object.Add("Result",$_.Result) $object.Add("Entity",$_.EntityName) $object.Add("VIServer",$VIObject.Name) $object.Add("Error",$_.Error.ocalizedMessage) if($Details){ $object.Add("Cancelled",(&{if($_.Cancelled){"Y"}else{"N"}})) $object.Add("Reason",$_.Reason.GetType().Name.Replace("TaskReason", "")) $object.Add("AlarmName",$_.Reason.AlarmName) $object.Add("AlarmEntity",$_.Reason.EntityName) $object.Add("ScheduleName",$_.Reason.Name) $object.Add("User",$_.Reason.UserName) } if($keys){ $object.Add("Key",$_.Key) $object.Add("ParentKey",$_.ParentTaskKey) $object.Add("RootKey",$_.RootTaskKey) } New-Object PSObject -Property $object } } } $filter = New-Object VMware.Vim.TaskFilterSpec if($Alarm){ $filter.Alarm = $Alarm.ExtensionData.MoRef } if($Entity){ $filter.Entity = New-Object VMware.Vim.TaskFilterSpecByEntity $filter.Entity.entity = $Entity.ExtensionData.MoRef if($Recurse){ $filter.Entity.Recursion = [VMware.Vim.TaskFilterSpecRecursionOption]::all } else{ $filter.Entity.Recursion = [VMware.Vim.TaskFilterSpecRecursionOption]::self } } if($State){ $filter.State = $State } if($Start -or $Finish){ $filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime $filter.Time.beginTime = $Start $filter.Time.endTime = $Finish $filter.Time.timeType = [vmware.vim.taskfilterspectimeoption]::startedTime } if($UserName){ $userNameFilterSpec = New-Object VMware.Vim.TaskFilterSpecByUserName $userNameFilterSpec.UserList = $UserName $filter.UserName = $userNameFilterSpec } $nrTasks = 0 } process { foreach($viObject in $Server){ $si = Get-View ServiceInstance -Server $viObject $tskMgr = Get-View $si.Content.TaskManager -Server $viObject if($Realtime -and $tskMgr.recentTask){ $tasks = Get-View $tskMgr.recentTask $selectNr = [Math]::Min($tasks.Count,$MaxSamples-$nrTasks) Get-TaskDetails -Tasks[0..($selectNr-1)] $nrTasks += $selectNr } try { $tCollector = Get-View ($tskMgr.CreateCollectorForTasks($filter)) if($Reverse){ $tCollector.ResetCollector() $taskReadOp = $tCollector.ReadPreviousTasks } else{ $taskReadOp = $tCollector.ReadNextTasks } do{ $tasks = $taskReadOp.Invoke($WindowSize) if(!$tasks){return} $selectNr = [Math]::Min($tasks.Count,$MaxSamples-$nrTasks) Get-TaskDetails -Tasks $tasks[0..($selectNr-1)] $nrTasks += $selectNr }while($nrTasks -lt $MaxSamples) } catch { Write-Host "A error occured in the collector" } } try { $tCollector.DestroyCollector() } catch { Write-Host "The error not letting us destroy the collector" } }}$start = (Get-Date).AddDays(-30)$finish = (Get-Date)$output = Get-TaskPlus -Details -MaxSamples 20000000 -Start $start -Finish $finish |? {$_.Name -match "CreateSnapshot_Task" -or $_.Name -match "RemoveSnapshot_Task"} |select Entity, "Task Created", "Task Started", "Task Ended", User, State, Name,@{Name="Duration in Seconds"; Expression = {(New-TimeSpan -start $_."Task Started" -End $_."Task Ended").TotalSeconds}}# create a CSV file with all snapshot related results$output | Export-Csv -Path "c:\temp\snapshot_create_and_remove_times_last_month.csv" -NoTypeInformation# cleanup and removal of loaded VMware modules#Disconnect-VIServer -Server $creds.Host -Confirm:$falsedisconnect-viserver vCenter.virtualfrog.lab -confirm:$falseRemove-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null```'''[status]corpus = 267[[status.alsoLike]]ref = "posts/vmware-explore-las-vegas-hackathon-2025"score = "1.00"[[status.alsoLike]]ref = "posts/vmware-hackathon-2024-project"score = "1.00"[[status.alsoLike]]ref = "solutions/vmware/vmware-cloud-foundation/addon/application-services"score = "0.60"
<?xml version="1.0" encoding="UTF-8"?><manifest kind="Post"> <apiVersion>soultec.ch/v1</apiVersion> <metadata> <name>powercli-reporting-the-duration-of-snapshots</name> <locale>en</locale> <labels> <author>dario-doerflinger</author> <series>scripting</series> <entry key="capability/automation">1.78</entry> <entry key="vendor/vmware">0.88</entry> </labels> <annotations> <source>blog-content/posts/en/powercli-reporting-the-duration-of-snapshots.md</source> <route>/en/insights/powercli-reporting-the-duration-of-snapshots/</route> <schema>/nerd/schema/posts.json</schema> <markdown>/en/insights/powercli-reporting-the-duration-of-snapshots.md</markdown> </annotations> </metadata> <spec> <title>Reporting the duration of snapshots</title> <date>2017-10-10</date> <author>dario-doerflinger</author> <locale>en</locale> <summary>One of our customers had a problem with VMs losing network connectivity while the backup was running. Their backup solution was based on VMware snapshots.</summary> <capabilities> <item>automation</item> </capabilities> <vendors> <item>vmware</item> </vendors> <series>scripting</series> <legacySlug>powercli-reporting-the-duration-of-snapshots</legacySlug> <migrated>2026-08-24</migrated> <draft>false</draft> </spec> <sections> <section> <body>One of our customers had a problem with VMs losing network connectivity while the backup was running. Their backup solution was based on VMware snapshots. After the end-users complained about a service not being responsive they investigated and found out that during the creation of the snapshot they lose the pings.In response they wanted to check how long the snapshots take on all of their VMs. Even though their environment was not very big, it would have been very tedious to gather this information manually. PowerCLI to the rescue!The script leverages Luc's awesome Get-TaskPlus function (which can be found [here](http://www.lucd.info/2013/06/01/task-data-mining-an-improved-get-task/)) with a few enhancements:- The time from the events are converted to local time (instead of UTC)- Some try/catch to filter exceptionsThen it was just a matter of filtering for the correct task objects and selecting the desired properties. Because the customer wanted to see the time it took for the task to complete I've added a "New-Timespan" object to the select which calculates the total amount of seconds between "Task Started" and "Task completed".Update: this script is now published at [GitHub](https://github.com/virtualFrog/PowerCLI-Scripts).Here is the script:```powershell# import vmware related modules, get the credentials and connect to the vCenter serverImport-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null#$creds = Get-VICredentialStoreItem -file "D:\Scripts\CreateSnapshotCreationOverview\login.creds"#Connect-VIServer -Server $creds.Host -User $creds.User -Password $creds.Passwordconnect-viserver vCenter.virtualfrog.labfunction Get-TaskPlus {&lt;#.EXAMPLE PS&gt; Get-TaskPlus -Start (Get-Date).AddDays(-1).EXAMPLE PS&gt; Get-TaskPlus -Alarm $alarm -Details#&gt; param( [CmdletBinding()] [VMware.VimAutomation.ViCore.Impl.V1.Alarm.AlarmDefinitionImpl]$Alarm, [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]$Entity, [switch]$Recurse = $false, [VMware.Vim.TaskInfoState[]]$State, [DateTime]$Start, [DateTime]$Finish, [string]$UserName, [int]$MaxSamples = 100, [switch]$Reverse = $true, [VMware.VimAutomation.ViCore.Impl.V1.VIServerImpl[]]$Server = $global:DefaultVIServer, [switch]$Realtime, [switch]$Details, [switch]$Keys, [int]$WindowSize = 100 ) begin { function Get-TaskDetails { param( [VMware.Vim.TaskInfo[]]$Tasks ) begin{ $psV3 = $PSversionTable.PSVersion.Major -ge 3 } process{ $tasks | %{ if($psV3){ $object = [ordered]@{} } else { $object = @{} } $object.Add("Name",$_.Name) $object.Add("Description",$_.Description.Message) if($Details){$object.Add("DescriptionId",$_.DescriptionId)} if($Details){$object.Add("Task Created",$_.QueueTime.tolocaltime())} $object.Add("Task Started",$_.StartTime.tolocaltime()) if($Details){$object.Add("Task Ended",$_.CompleteTime.tolocaltime())} $object.Add("State",$_.State) $object.Add("Result",$_.Result) $object.Add("Entity",$_.EntityName) $object.Add("VIServer",$VIObject.Name) $object.Add("Error",$_.Error.ocalizedMessage) if($Details){ $object.Add("Cancelled",(&amp;{if($_.Cancelled){"Y"}else{"N"}})) $object.Add("Reason",$_.Reason.GetType().Name.Replace("TaskReason", "")) $object.Add("AlarmName",$_.Reason.AlarmName) $object.Add("AlarmEntity",$_.Reason.EntityName) $object.Add("ScheduleName",$_.Reason.Name) $object.Add("User",$_.Reason.UserName) } if($keys){ $object.Add("Key",$_.Key) $object.Add("ParentKey",$_.ParentTaskKey) $object.Add("RootKey",$_.RootTaskKey) } New-Object PSObject -Property $object } } } $filter = New-Object VMware.Vim.TaskFilterSpec if($Alarm){ $filter.Alarm = $Alarm.ExtensionData.MoRef } if($Entity){ $filter.Entity = New-Object VMware.Vim.TaskFilterSpecByEntity $filter.Entity.entity = $Entity.ExtensionData.MoRef if($Recurse){ $filter.Entity.Recursion = [VMware.Vim.TaskFilterSpecRecursionOption]::all } else{ $filter.Entity.Recursion = [VMware.Vim.TaskFilterSpecRecursionOption]::self } } if($State){ $filter.State = $State } if($Start -or $Finish){ $filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime $filter.Time.beginTime = $Start $filter.Time.endTime = $Finish $filter.Time.timeType = [vmware.vim.taskfilterspectimeoption]::startedTime } if($UserName){ $userNameFilterSpec = New-Object VMware.Vim.TaskFilterSpecByUserName $userNameFilterSpec.UserList = $UserName $filter.UserName = $userNameFilterSpec } $nrTasks = 0 } process { foreach($viObject in $Server){ $si = Get-View ServiceInstance -Server $viObject $tskMgr = Get-View $si.Content.TaskManager -Server $viObject if($Realtime -and $tskMgr.recentTask){ $tasks = Get-View $tskMgr.recentTask $selectNr = [Math]::Min($tasks.Count,$MaxSamples-$nrTasks) Get-TaskDetails -Tasks[0..($selectNr-1)] $nrTasks += $selectNr } try { $tCollector = Get-View ($tskMgr.CreateCollectorForTasks($filter)) if($Reverse){ $tCollector.ResetCollector() $taskReadOp = $tCollector.ReadPreviousTasks } else{ $taskReadOp = $tCollector.ReadNextTasks } do{ $tasks = $taskReadOp.Invoke($WindowSize) if(!$tasks){return} $selectNr = [Math]::Min($tasks.Count,$MaxSamples-$nrTasks) Get-TaskDetails -Tasks $tasks[0..($selectNr-1)] $nrTasks += $selectNr }while($nrTasks -lt $MaxSamples) } catch { Write-Host "A error occured in the collector" } } try { $tCollector.DestroyCollector() } catch { Write-Host "The error not letting us destroy the collector" } }}$start = (Get-Date).AddDays(-30)$finish = (Get-Date)$output = Get-TaskPlus -Details -MaxSamples 20000000 -Start $start -Finish $finish |? {$_.Name -match "CreateSnapshot_Task" -or $_.Name -match "RemoveSnapshot_Task"} |select Entity, "Task Created", "Task Started", "Task Ended", User, State, Name,@{Name="Duration in Seconds"; Expression = {(New-TimeSpan -start $_."Task Started" -End $_."Task Ended").TotalSeconds}}# create a CSV file with all snapshot related results$output | Export-Csv -Path "c:\temp\snapshot_create_and_remove_times_last_month.csv" -NoTypeInformation# cleanup and removal of loaded VMware modules#Disconnect-VIServer -Server $creds.Host -Confirm:$falsedisconnect-viserver vCenter.virtualfrog.lab -confirm:$falseRemove-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null``` </body> </section> </sections> <status> <corpus>267</corpus> <alsoLike> <item> <ref>posts/vmware-explore-las-vegas-hackathon-2025</ref> <score>1.00</score> </item> <item> <ref>posts/vmware-hackathon-2024-project</ref> <score>1.00</score> </item> <item> <ref>solutions/vmware/vmware-cloud-foundation/addon/application-services</ref> <score>0.60</score> </item> </alsoLike> </status></manifest>
Scripting · 2017-10-10

Reporting the duration of snapshots

One of our customers had a problem with VMs losing network connectivity while the backup was running. Their backup solution was based on VMware snapshots.

2017-10-10Date
Dario DörflingerAuthor
3Min read
Topics Automation 1.78
Vendors VMware 0.88

This post is from 2017. It stays online because people still look for it, but it describes the products as they were then.

One of our customers had a problem with VMs losing network connectivity while the backup was running. Their backup solution was based on VMware snapshots. After the end-users complained about a service not being responsive they investigated and found out that during the creation of the snapshot they lose the pings.

In response they wanted to check how long the snapshots take on all of their VMs. Even though their environment was not very big, it would have been very tedious to gather this information manually. PowerCLI to the rescue!

The script leverages Luc’s awesome Get-TaskPlus function (which can be found here) with a few enhancements:

  • The time from the events are converted to local time (instead of UTC)
  • Some try/catch to filter exceptions

Then it was just a matter of filtering for the correct task objects and selecting the desired properties. Because the customer wanted to see the time it took for the task to complete I’ve added a “New-Timespan” object to the select which calculates the total amount of seconds between “Task Started” and “Task completed”.

Update: this script is now published at GitHub.

Here is the script:

# import vmware related modules, get the credentials and connect to the vCenter server
Import-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null
#$creds = Get-VICredentialStoreItem -file  "D:\Scripts\CreateSnapshotCreationOverview\login.creds"
#Connect-VIServer -Server $creds.Host -User $creds.User -Password $creds.Password
connect-viserver vCenter.virtualfrog.lab

function Get-TaskPlus {
<#
.EXAMPLE
  PS> Get-TaskPlus -Start (Get-Date).AddDays(-1)
.EXAMPLE
  PS> Get-TaskPlus -Alarm $alarm -Details
#>

  param(
    [CmdletBinding()]
    [VMware.VimAutomation.ViCore.Impl.V1.Alarm.AlarmDefinitionImpl]$Alarm,
    [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]$Entity,
    [switch]$Recurse = $false,
    [VMware.Vim.TaskInfoState[]]$State,
    [DateTime]$Start,
    [DateTime]$Finish,
    [string]$UserName,
    [int]$MaxSamples = 100,
    [switch]$Reverse = $true,
    [VMware.VimAutomation.ViCore.Impl.V1.VIServerImpl[]]$Server = $global:DefaultVIServer,
    [switch]$Realtime,
    [switch]$Details,
    [switch]$Keys,
    [int]$WindowSize = 100
  )

  begin {
    function Get-TaskDetails {
      param(
        [VMware.Vim.TaskInfo[]]$Tasks
      )
      begin{
        $psV3 = $PSversionTable.PSVersion.Major -ge 3
      }

      process{
        $tasks | %{
          if($psV3){
            $object = [ordered]@{}
          }
          else {
            $object = @{}
          }
          $object.Add("Name",$_.Name)
          $object.Add("Description",$_.Description.Message)
          if($Details){$object.Add("DescriptionId",$_.DescriptionId)}
          if($Details){$object.Add("Task Created",$_.QueueTime.tolocaltime())}
          $object.Add("Task Started",$_.StartTime.tolocaltime())
          if($Details){$object.Add("Task Ended",$_.CompleteTime.tolocaltime())}
          $object.Add("State",$_.State)
          $object.Add("Result",$_.Result)
          $object.Add("Entity",$_.EntityName)
          $object.Add("VIServer",$VIObject.Name)
          $object.Add("Error",$_.Error.ocalizedMessage)
          if($Details){
            $object.Add("Cancelled",(&{if($_.Cancelled){"Y"}else{"N"}}))
            $object.Add("Reason",$_.Reason.GetType().Name.Replace("TaskReason", ""))
            $object.Add("AlarmName",$_.Reason.AlarmName)
            $object.Add("AlarmEntity",$_.Reason.EntityName)
            $object.Add("ScheduleName",$_.Reason.Name)
            $object.Add("User",$_.Reason.UserName)
          }
          if($keys){
            $object.Add("Key",$_.Key)
            $object.Add("ParentKey",$_.ParentTaskKey)
            $object.Add("RootKey",$_.RootTaskKey)
          }

          New-Object PSObject -Property $object
        }
      }
    }

    $filter = New-Object VMware.Vim.TaskFilterSpec
    if($Alarm){
      $filter.Alarm = $Alarm.ExtensionData.MoRef
    }
    if($Entity){
      $filter.Entity = New-Object VMware.Vim.TaskFilterSpecByEntity
      $filter.Entity.entity = $Entity.ExtensionData.MoRef
      if($Recurse){
        $filter.Entity.Recursion = [VMware.Vim.TaskFilterSpecRecursionOption]::all
      }
      else{
        $filter.Entity.Recursion = [VMware.Vim.TaskFilterSpecRecursionOption]::self
      }
    }
    if($State){
      $filter.State = $State
    }
    if($Start -or $Finish){
      $filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime
      $filter.Time.beginTime = $Start
      $filter.Time.endTime = $Finish
      $filter.Time.timeType = [vmware.vim.taskfilterspectimeoption]::startedTime
    }
    if($UserName){
      $userNameFilterSpec = New-Object VMware.Vim.TaskFilterSpecByUserName
      $userNameFilterSpec.UserList = $UserName
      $filter.UserName = $userNameFilterSpec
    }
    $nrTasks = 0
  }

  process {
    foreach($viObject in $Server){
      $si = Get-View ServiceInstance -Server $viObject
      $tskMgr = Get-View $si.Content.TaskManager -Server $viObject 

      if($Realtime -and $tskMgr.recentTask){
        $tasks = Get-View $tskMgr.recentTask
        $selectNr = [Math]::Min($tasks.Count,$MaxSamples-$nrTasks)
        Get-TaskDetails -Tasks[0..($selectNr-1)]
        $nrTasks += $selectNr
      }

      try {
      $tCollector = Get-View ($tskMgr.CreateCollectorForTasks($filter))

      if($Reverse){
        $tCollector.ResetCollector()
        $taskReadOp = $tCollector.ReadPreviousTasks
      }
      else{
        $taskReadOp = $tCollector.ReadNextTasks
      }
      do{
        $tasks = $taskReadOp.Invoke($WindowSize)
        if(!$tasks){return}
        $selectNr = [Math]::Min($tasks.Count,$MaxSamples-$nrTasks)
        Get-TaskDetails -Tasks $tasks[0..($selectNr-1)]
        $nrTasks += $selectNr
      }while($nrTasks -lt $MaxSamples)
      }
      catch {
        Write-Host "A error occured in the collector"
      }
    }
    try {
        $tCollector.DestroyCollector()
        }
    catch {
        Write-Host "The error not letting us destroy the collector"
    }
  }
}
$start = (Get-Date).AddDays(-30)
$finish = (Get-Date)
$output = Get-TaskPlus -Details -MaxSamples 20000000 -Start $start -Finish $finish |
? {$_.Name -match "CreateSnapshot_Task" -or $_.Name -match "RemoveSnapshot_Task"} |
select Entity, "Task Created", "Task Started", "Task Ended", User, State, Name,
@{Name="Duration in Seconds"; Expression = {(New-TimeSpan -start $_."Task Started" -End $_."Task Ended").TotalSeconds}}
# create a CSV file with all snapshot related results
$output | Export-Csv -Path "c:\temp\snapshot_create_and_remove_times_last_month.csv" -NoTypeInformation

# cleanup and removal of loaded VMware modules
#Disconnect-VIServer -Server $creds.Host -Confirm:$false
disconnect-viserver vCenter.virtualfrog.lab -confirm:$false
Remove-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null

You might also like