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: de labels: author: dario-doerflinger series: scripting capability/automation: 1.78 vendor/vmware: 0.88 annotations: source: blog-content/posts/de/powercli-reporting-the-duration-of-snapshots.md route: /de/insights/powercli-reporting-the-duration-of-snapshots/ schema: /nerd/schema/posts.json markdown: /de/insights/powercli-reporting-the-duration-of-snapshots.mdspec: title: Die Dauer von Snapshots auswerten date: 2017-10-10 author: dario-doerflinger locale: de summary: >- Bei einem Kunden verloren VMs während des Backups die Netzwerkverbindung. Die Backup-Lösung arbeitet mit VMware Snapshots. capabilities: [automation] vendors: [vmware] series: scripting migrated: 2026-08-24 translationReviewed: false draft: false sections: - body: | Bei einem unserer Kunden verloren VMs während des Backups die Netzwerkverbindung. Seine Backup-Lösung arbeitet mit VMware Snapshots. Nachdem sich Anwender über einen nicht erreichbaren Dienst beschwert hatten, ging der Kunde der Sache nach und stellte fest, dass die Pings genau beim Erstellen des Snapshots ausfallen. Daraufhin wollte er wissen, wie lange die Snapshots über alle VMs hinweg dauern. Auch wenn die Umgebung nicht sehr gross ist, wäre es sehr mühsam gewesen, das von Hand zusammenzutragen. Also PowerCLI. Das Script nutzt Lucs ausgezeichnete Funktion Get-TaskPlus, die du [hier](http://www.lucd.info/2013/06/01/task-data-mining-an-improved-get-task/) findest, mit ein paar Ergänzungen: - Die Zeiten aus den Events werden in Lokalzeit umgerechnet statt UTC - Ein paar try/catch, um Exceptions abzufangen Danach ging es nur noch darum, auf die richtigen Task-Objekte zu filtern und die gewünschten Eigenschaften auszuwählen. Weil der Kunde sehen wollte, wie lange der Task gedauert hat, habe ich dem Select ein «New-Timespan» hinzugefügt, das die Sekunden zwischen «Task Started» und «Task completed» berechnet. Update: Dieses Script liegt inzwischen auf [GitHub](https://github.com/virtualFrog/PowerCLI-Scripts). Hier ist das 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": "de", "labels": { "author": "dario-doerflinger", "series": "scripting", "capability/automation": "1.78", "vendor/vmware": "0.88" }, "annotations": { "source": "blog-content/posts/de/powercli-reporting-the-duration-of-snapshots.md", "route": "/de/insights/powercli-reporting-the-duration-of-snapshots/", "schema": "/nerd/schema/posts.json", "markdown": "/de/insights/powercli-reporting-the-duration-of-snapshots.md" } }, "spec": { "title": "Die Dauer von Snapshots auswerten", "date": "2017-10-10", "author": "dario-doerflinger", "locale": "de", "summary": "Bei einem Kunden verloren VMs während des Backups die Netzwerkverbindung. Die Backup-Lösung arbeitet mit VMware Snapshots.", "capabilities": [ "automation" ], "vendors": [ "vmware" ], "series": "scripting", "migrated": "2026-08-24", "translationReviewed": false, "draft": false }, "sections": [ { "body": "Bei einem unserer Kunden verloren VMs während des Backups die Netzwerkverbindung. Seine Backup-Lösung arbeitet mit VMware Snapshots. Nachdem sich Anwender über einen nicht erreichbaren Dienst beschwert hatten, ging der Kunde der Sache nach und stellte fest, dass die Pings genau beim Erstellen des Snapshots ausfallen.\n\nDaraufhin wollte er wissen, wie lange die Snapshots über alle VMs hinweg dauern. Auch wenn die Umgebung nicht sehr gross ist, wäre es sehr mühsam gewesen, das von Hand zusammenzutragen. Also PowerCLI.\n\nDas Script nutzt Lucs ausgezeichnete Funktion Get-TaskPlus, die du [hier](http://www.lucd.info/2013/06/01/task-data-mining-an-improved-get-task/) findest, mit ein paar Ergänzungen:\n\n- Die Zeiten aus den Events werden in Lokalzeit umgerechnet statt UTC\n- Ein paar try/catch, um Exceptions abzufangen\n\nDanach ging es nur noch darum, auf die richtigen Task-Objekte zu filtern und die gewünschten Eigenschaften auszuwählen. Weil der Kunde sehen wollte, wie lange der Task gedauert hat, habe ich dem Select ein «New-Timespan» hinzugefügt, das die Sekunden zwischen «Task Started» und «Task completed» berechnet.\n\nUpdate: Dieses Script liegt inzwischen auf [GitHub](https://github.com/virtualFrog/PowerCLI-Scripts).\n\nHier ist das 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 = "de"[metadata.labels]author = "dario-doerflinger"series = "scripting""capability/automation" = "1.78""vendor/vmware" = "0.88"[metadata.annotations]source = "blog-content/posts/de/powercli-reporting-the-duration-of-snapshots.md"route = "/de/insights/powercli-reporting-the-duration-of-snapshots/"schema = "/nerd/schema/posts.json"markdown = "/de/insights/powercli-reporting-the-duration-of-snapshots.md"[spec]title = "Die Dauer von Snapshots auswerten"date = 2017-10-10author = "dario-doerflinger"locale = "de"summary = "Bei einem Kunden verloren VMs während des Backups die Netzwerkverbindung. Die Backup-Lösung arbeitet mit VMware Snapshots."capabilities = ["automation"]vendors = ["vmware"]series = "scripting"migrated = 2026-08-24translationReviewed = falsedraft = false[[sections]]body = '''Bei einem unserer Kunden verloren VMs während des Backups die Netzwerkverbindung. Seine Backup-Lösung arbeitet mit VMware Snapshots. Nachdem sich Anwender über einen nicht erreichbaren Dienst beschwert hatten, ging der Kunde der Sache nach und stellte fest, dass die Pings genau beim Erstellen des Snapshots ausfallen.Daraufhin wollte er wissen, wie lange die Snapshots über alle VMs hinweg dauern. Auch wenn die Umgebung nicht sehr gross ist, wäre es sehr mühsam gewesen, das von Hand zusammenzutragen. Also PowerCLI.Das Script nutzt Lucs ausgezeichnete Funktion Get-TaskPlus, die du [hier](http://www.lucd.info/2013/06/01/task-data-mining-an-improved-get-task/) findest, mit ein paar Ergänzungen:- Die Zeiten aus den Events werden in Lokalzeit umgerechnet statt UTC- Ein paar try/catch, um Exceptions abzufangenDanach ging es nur noch darum, auf die richtigen Task-Objekte zu filtern und die gewünschten Eigenschaften auszuwählen. Weil der Kunde sehen wollte, wie lange der Task gedauert hat, habe ich dem Select ein «New-Timespan» hinzugefügt, das die Sekunden zwischen «Task Started» und «Task completed» berechnet.Update: Dieses Script liegt inzwischen auf [GitHub](https://github.com/virtualFrog/PowerCLI-Scripts).Hier ist das 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>de</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/de/powercli-reporting-the-duration-of-snapshots.md</source> <route>/de/insights/powercli-reporting-the-duration-of-snapshots/</route> <schema>/nerd/schema/posts.json</schema> <markdown>/de/insights/powercli-reporting-the-duration-of-snapshots.md</markdown> </annotations> </metadata> <spec> <title>Die Dauer von Snapshots auswerten</title> <date>2017-10-10</date> <author>dario-doerflinger</author> <locale>de</locale> <summary>Bei einem Kunden verloren VMs während des Backups die Netzwerkverbindung. Die Backup-Lösung arbeitet mit VMware Snapshots.</summary> <capabilities> <item>automation</item> </capabilities> <vendors> <item>vmware</item> </vendors> <series>scripting</series> <migrated>2026-08-24</migrated> <translationReviewed>false</translationReviewed> <draft>false</draft> </spec> <sections> <section> <body>Bei einem unserer Kunden verloren VMs während des Backups die Netzwerkverbindung. Seine Backup-Lösung arbeitet mit VMware Snapshots. Nachdem sich Anwender über einen nicht erreichbaren Dienst beschwert hatten, ging der Kunde der Sache nach und stellte fest, dass die Pings genau beim Erstellen des Snapshots ausfallen.Daraufhin wollte er wissen, wie lange die Snapshots über alle VMs hinweg dauern. Auch wenn die Umgebung nicht sehr gross ist, wäre es sehr mühsam gewesen, das von Hand zusammenzutragen. Also PowerCLI.Das Script nutzt Lucs ausgezeichnete Funktion Get-TaskPlus, die du [hier](http://www.lucd.info/2013/06/01/task-data-mining-an-improved-get-task/) findest, mit ein paar Ergänzungen:- Die Zeiten aus den Events werden in Lokalzeit umgerechnet statt UTC- Ein paar try/catch, um Exceptions abzufangenDanach ging es nur noch darum, auf die richtigen Task-Objekte zu filtern und die gewünschten Eigenschaften auszuwählen. Weil der Kunde sehen wollte, wie lange der Task gedauert hat, habe ich dem Select ein «New-Timespan» hinzugefügt, das die Sekunden zwischen «Task Started» und «Task completed» berechnet.Update: Dieses Script liegt inzwischen auf [GitHub](https://github.com/virtualFrog/PowerCLI-Scripts).Hier ist das 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

Die Dauer von Snapshots auswerten

Bei einem Kunden verloren VMs während des Backups die Netzwerkverbindung. Die Backup-Lösung arbeitet mit VMware Snapshots.

2017-10-10Datum
Dario DörflingerAutor
3Min. Lesezeit
Themen Automation 1.78
Hersteller VMware 0.88

Dieser Beitrag ist von 2017. Er bleibt online, weil er nach wie vor nachgefragt wird, beschreibt aber einen Produktstand von damals.

Bei einem unserer Kunden verloren VMs während des Backups die Netzwerkverbindung. Seine Backup-Lösung arbeitet mit VMware Snapshots. Nachdem sich Anwender über einen nicht erreichbaren Dienst beschwert hatten, ging der Kunde der Sache nach und stellte fest, dass die Pings genau beim Erstellen des Snapshots ausfallen.

Daraufhin wollte er wissen, wie lange die Snapshots über alle VMs hinweg dauern. Auch wenn die Umgebung nicht sehr gross ist, wäre es sehr mühsam gewesen, das von Hand zusammenzutragen. Also PowerCLI.

Das Script nutzt Lucs ausgezeichnete Funktion Get-TaskPlus, die du hier findest, mit ein paar Ergänzungen:

  • Die Zeiten aus den Events werden in Lokalzeit umgerechnet statt UTC
  • Ein paar try/catch, um Exceptions abzufangen

Danach ging es nur noch darum, auf die richtigen Task-Objekte zu filtern und die gewünschten Eigenschaften auszuwählen. Weil der Kunde sehen wollte, wie lange der Task gedauert hat, habe ich dem Select ein «New-Timespan» hinzugefügt, das die Sekunden zwischen «Task Started» und «Task completed» berechnet.

Update: Dieses Script liegt inzwischen auf GitHub.

Hier ist das 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

Passt ausserdem