---
# source: blog-content: posts/de/powercli-reporting-the-duration-of-snapshots.md
# route:  /de/insights/powercli-reporting-the-duration-of-snapshots/
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
---

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
```
