Scripts PowerCLI : Différence entre versions

De DiouxX's Wiki
Aller à : navigation, rechercher
(Rapport violation)
 
(8 révisions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
 
{{ Introduction | Cette page regroupe un ensemble de scripts PowerCLI/Powershell }}
 
{{ Introduction | Cette page regroupe un ensemble de scripts PowerCLI/Powershell }}
 +
 +
==VM==
 +
 +
=== Listing VM et taille ===
 +
 +
* Script pour lister les VMs et leur taille de disque dur
 +
<syntaxhighlight lang=powershell>
 +
Param (
 +
    [Alias("Host")]
 +
    [string]$VIServer = "",
 +
    [string]$User = "",
 +
    [string]$Password="",
 +
    [string]$PathToReport,
 +
    [string]$CredentialFile="credential-vsphere.xml",
 +
   
 +
    [string]$To = "mail@domain.be",
 +
    [string]$From = "report-vmware@domain.be",
 +
    [string]$SMTPServer = "mail.domain.be"
 +
)
 +
 +
#Récupération du fichier avec les identifiants
 +
$PathCredentialFile = Split-Path $Script:MyInvocation.MyCommand.Path -Parent
 +
$PathCredentialFile += "\" + $CredentialFile
 +
$PathCredentialFile
 +
 +
$credential = Get-VICredentialStoreItem -File $PathCredentialFile
 +
 +
#Conexion au serveur
 +
$connexion = Connect-VIServer -Server $credential.Host -User $credential.User -Password $credential.Password -WarningAction SilentlyContinue
 +
 +
$date = Get-Date -Format yyyy.MM.dd
 +
$file = "C:\Rapport-VMware\"+$date+"-report-vm-size.csv"
 +
 +
#Recupération de toutes les VM
 +
$listVm = Get-VM "*test*"
 +
$report=@()
 +
 +
foreach ($vm in $listVm)
 +
{
 +
    $report += $vm | Select-Object Name,@{n="Provisionedspace(GB)"; E={[math]::round($_.ProvisionedSpaceGB)}}
 +
}
 +
 +
$report
 +
$report | Export-Csv -Path $file
 +
 +
Disconnect-VIServer $connexion -Force -Confirm:$false
 +
</syntaxhighlight>
  
 
==Snapshot==
 
==Snapshot==
 +
 +
=== Liste VM et leurs snapshots ===
  
 
* Script pour lister les VMs ayant un snapshot
 
* Script pour lister les VMs ayant un snapshot
<br>
+
 
 
<syntaxhighlight lang=powershell>
 
<syntaxhighlight lang=powershell>
 
#Server VSphere
 
#Server VSphere
$server = "win2k12-Vcenter.admin.pass.be"
+
$server = "adresse-VCenter"
  
 
#Connexion au vsphere
 
#Connexion au vsphere
Connect-VIServer -Server $server -WarningAction SilentlyContinue
+
$connexion = Connect-VIServer -Server $server -WarningAction SilentlyContinue
  
 
#Liste des VM avec le nom du snapshot et la description
 
#Liste des VM avec le nom du snapshot et la description
Ligne 17 : Ligne 66 :
 
pause
 
pause
  
Disconnect-VIServer -Server $server -Force
+
Disconnect-VIServer -Server $connexion -Force -Confirm:$false
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
  
 
* Script pour réaliser un rapport des snapshot et l'envoyer par mai
 
* Script pour réaliser un rapport des snapshot et l'envoyer par mai
<br>
 
 
<syntaxhighlight lang=powershell>
 
<syntaxhighlight lang=powershell>
 
Param (
 
Param (
 
     [Alias("Host")]
 
     [Alias("Host")]
     [string]$VIServer = "win2k12-vcenter.admin.pass.be",
+
     [string]$VIServer = "",
     [string]$User = "Vsphere.local\Administrator",
+
     [string]$User = "",
     [string]$Password="TOrtu€N1nj@",
+
     [string]$Password="",
 
     [string]$PathToReport,
 
     [string]$PathToReport,
 +
    [string]$CredentialFile="credential-vsphere.xml",
 
      
 
      
     [string]$To = "devleeschauwer@pass.be",
+
     [string]$To = "nagios@pass.be",
     [string]$From = "vmreports@pass.be",
+
     [string]$From = "report-vmware@pass.be",
 
     [string]$SMTPServer = "mail.pass.be"
 
     [string]$SMTPServer = "mail.pass.be"
 
)
 
)
Ligne 79 : Ligne 129 :
  
 
#Desactiver la securité  
 
#Desactiver la securité  
Set-ExecutionPolicy RemoteSigned
+
#Set-ExecutionPolicy RemoteSigned
  
 
#Chargement du module Vmware
 
#Chargement du module Vmware
Ligne 86 : Ligne 136 :
 
     Catch { Throw "Problem loading VMware.VimAutomation.Core snapin because ""$($Error[1])""" }
 
     Catch { Throw "Problem loading VMware.VimAutomation.Core snapin because ""$($Error[1])""" }
 
}
 
}
 +
 +
#Récupération du fichier avec les identifiants
 +
$PathCredentialFile = Split-Path $Script:MyInvocation.MyCommand.Path -Parent
 +
$PathCredentialFile += "\" + $CredentialFile
 +
$PathCredentialFile
 +
 +
$credential = Get-VICredentialStoreItem -File $PathCredentialFile
 +
 +
#Affectation de la variable VIServer
 +
$VIServer = $credential.Host
  
 
#Connexion au vsphere
 
#Connexion au vsphere
$connection = Connect-VIServer -Server $VIServer -User $User -Password $Password -WarningAction SilentlyContinue
+
$connection = Connect-VIServer -Server $credential.Host -User $credential.User -Password $credential.Password -WarningAction SilentlyContinue
  
 
$Report = Get-VM | Get-Snapshot | Select VM,Name,Description,@{Label="Size";Expression={"{0:N2} GB" -f ($_.SizeGB)}},Created
 
$Report = Get-VM | Get-Snapshot | Select VM,Name,Description,@{Label="Size";Expression={"{0:N2} GB" -f ($_.SizeGB)}},Created
Ligne 124 : Ligne 184 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
== Datastore==
 +
 +
=== Liste des VM par datastore ===
 +
 +
<syntaxhighlight lang=powershell>
 +
Param (
 +
    [Alias("Host")]
 +
    [string]$VIServer = "",
 +
    [string]$User = "",
 +
    [string]$Password="",
 +
    [string]$PathToReport,
 +
    [string]$CredentialFile="credential-vsphere.xml",
 +
   
 +
    [string]$To = "",
 +
    [string]$From = "",
 +
    [string]$SMTPServer = "",
 +
 +
    [boolean]$ExportCsv = $false,
 +
    [string]$DirecteoryCsv = ""
 +
 +
)
 +
 +
#Variables static
 +
$date = Get-Date -Format yyyy.MM.dd
 +
$fileNameCSV = ""+$date+"-report-datastore-vm.csv"
 +
#Tableau récupérant le contenu a exporter
 +
$content=@()
 +
 +
#Récupération du fichier avec les identifiants
 +
$PathCredentialFile = Split-Path $Script:MyInvocation.MyCommand.Path -Parent
 +
$PathCredentialFile += "\" + $CredentialFile
 +
#Affichage de debug pour le fichier credential
 +
#$PathCredentialFile
 +
 +
#Création de l'objet avec les informations de connexion
 +
$credential = Get-VICredentialStoreItem -File $PathCredentialFile
 +
 +
#Conexion au serveur
 +
$connexion = Connect-VIServer -Server $credential.Host -User $credential.User -Password $credential.Password -WarningAction SilentlyContinue
 +
 +
#Récupération des datastore et des VMs associées.
 +
Get-Datacenter | Get-Datastore | Foreach-Object {
 +
    $datastore= $_.Name
 +
    $content += $_ | Get-VM | Select-Object @{n='DataStore';e={$datastore}},Name
 +
}
 +
 +
if($ExportCsv)
 +
{
 +
    write-Host "Export en CSV"
 +
 +
    #Ficher CSV de sortie
 +
    if ( $DirecteoryCsv -eq "" )
 +
    {
 +
        $FileCsv = ".\"+$fileNameCSV
 +
    }
 +
    else
 +
    {
 +
        $FileCsv = $DirecteoryCsv+"\"+$fileNameCSV
 +
    }
 +
 +
    #Export du contenu en CSV
 +
    $content | Export-Csv -Path $FileCsv -NoTypeInformation
 +
}
 +
 +
$content
 +
 +
Disconnect-VIServer -Server $connexion -Force -Confirm:$false
 +
</syntaxhighlight>
 +
 +
== Replication ==
 +
=== Rapport réplication complet ===
 +
<syntaxhighlight lang=powershell>
 +
Param (
 +
    [Alias("Host")]
 +
    [string]$VIServer = "",
 +
    [string]$User = "",
 +
    [string]$Password="",
 +
    [string]$PathToReport,
 +
    [string]$CredentialFile="credential-vsphere.xml",
 +
   
 +
    [string]$To = "",
 +
    [string]$From = "",
 +
    [string]$SMTPServer = ""
 +
)
 +
 +
#Récupération du fichier avec les identifiants
 +
#$credential = Get-VICredentialStoreItem -File $CredentialFile
 +
#Récupération du fichier avec les identifiants
 +
$PathCredentialFile = Split-Path $Script:MyInvocation.MyCommand.Path -Parent
 +
$PathCredentialFile += "\" + $CredentialFile
 +
$PathCredentialFile
 +
 +
$credential = Get-VICredentialStoreItem -File $PathCredentialFile
 +
 +
#Affectation de la variable VIServer
 +
$VIServer = $credential.Host
 +
 +
#Connexion au vsphere
 +
$connection = Connect-VIServer -Server $credential.Host -User $credential.User -Password $credential.Password -WarningAction SilentlyContinue
 +
 +
#Récupérer tous les events lié à la réplication
 +
Get-VIEvent -MaxSamples ([int]::MaxValue) | Where { $_.EventTypeId -match "hbr|rpo" } | Select CreatedTime, FullFormattedMessage, @{Name="VMName";Expression={$_.Vm.Name}} | export-csv -NoTypeInformation -Path ([Environment]::GetFolderPath("Desktop") + "\HBR-RPOEvents.csv")
 +
 +
#Deconnexion du VIServer sans prompt
 +
Disconnect-VIServer -Server $connection -Force -Confirm:$false
 +
</syntaxhighlight>
 +
 +
=== Rapport violation ===
 +
<syntaxhighlight lang=powershell>
 +
Param (
 +
    [Alias("Host")]
 +
    [string]$VIServer = "",
 +
    [string]$User = "",
 +
    [string]$Password="",
 +
    [string]$PathToReport,
 +
    [string]$CredentialFile="credential-vsphere.xml",
 +
   
 +
    [string]$To = "",
 +
    [string]$From = "",
 +
    [string]$SMTPServer = ""
 +
)
 +
 +
#Récupération du fichier avec les identifiants
 +
#$credential = Get-VICredentialStoreItem -File $CredentialFile
 +
#Récupération du fichier avec les identifiants
 +
$PathCredentialFile = Split-Path $Script:MyInvocation.MyCommand.Path -Parent
 +
$PathCredentialFile += "\" + $CredentialFile
 +
$PathCredentialFile
 +
 +
$credential = Get-VICredentialStoreItem -File $PathCredentialFile
 +
 +
#Affectation de la variable VIServer
 +
$VIServer = $credential.Host
 +
 +
#Connexion au vsphere
 +
$connection = Connect-VIServer -Server $credential.Host -User $credential.User -Password $credential.Password -WarningAction SilentlyContinue
 +
 +
Write-Host "[$(Get-Date)] Retrieving VMs"
 +
$VMs = Get-VM
 +
 +
$Results = @()
 +
Foreach ($VM in $VMs) {
 +
  Write-Host "[$(Get-Date)] Retrieving events for $($VM.name)"
 +
  $Events = Get-VIEvent -MaxSamples ([int]::MaxValue) -Entity $VM
 +
  Write-Host "[$(Get-Date)] Filtering RPO events for $($VM.name)"
 +
  $RPOEvents = $Events | where { $_.EventTypeID -match "rpo" } | Where { $_.Vm.Name -eq $VM.Name } | Select EventTypeId, CreatedTime, FullFormattedMessage, @{Name="VMName";Expression={$_.Vm.Name}} | Sort CreatedTime
 +
  if ($RPOEvents) {
 +
      $Count = 0
 +
      Write-Host "[$(Get-Date)] Finding replication results for $($VM.Name)"
 +
      do {
 +
        $details = "" | Select VMName, ViolationStart, ViolationEnd, Mins
 +
        if ($RPOEvents[$count].EventTypeID -match "Violated") {
 +
            If (-not $details.Start) {
 +
              $Details.VMName = $RPOEvents[$Count].VMName
 +
              $Details.ViolationStart = $RPOEvents[$Count].CreatedTime
 +
              Do {
 +
              $Count++
 +
              } until (($RPOEvents[$Count].EventTypeID -match "Restored") -or ($Count -gt $RPOEvents.Count))
 +
              if ($RPOEvents[$count].EventTypeID -match "Restored") {
 +
                  $details.ViolationEnd = $RPOEvents[$Count].CreatedTime
 +
                  $Time = $details.ViolationEnd - $details.ViolationStart
 +
                  $details.Mins = "{0:N2}" -f $Time.TotalMinutes
 +
              } Else {
 +
                  $details.ViolationEnd = "No End Date"
 +
                  $details.Mins = "N/A"
 +
              }
 +
            }
 +
        }
 +
        $Results += $details
 +
        $Count++
 +
      } until ($count -gt $RPOEvents.Count)
 +
  }
 +
}
 +
$Results | export-csv -NoTypeInformation -Path ([Environment]::GetFolderPath("Desktop") + "\ViolationReport.csv")
 +
 +
#Deconnexion du VIServer sans prompt
 +
Disconnect-VIServer -Server $connection -Force -Confirm:$false
 +
</syntaxhighlight>
  
 
[[Catégorie:PowerCLI]]
 
[[Catégorie:PowerCLI]]

Version actuelle datée du 24 mai 2016 à 11:23

Cette page regroupe un ensemble de scripts PowerCLI/Powershell

VM

Listing VM et taille

  • Script pour lister les VMs et leur taille de disque dur
Param (
    [Alias("Host")]
    [string]$VIServer = "",
    [string]$User = "",
    [string]$Password="",
    [string]$PathToReport,
    [string]$CredentialFile="credential-vsphere.xml",
    
    [string]$To = "mail@domain.be",
    [string]$From = "report-vmware@domain.be",
    [string]$SMTPServer = "mail.domain.be"
)

#Récupération du fichier avec les identifiants
$PathCredentialFile = Split-Path $Script:MyInvocation.MyCommand.Path -Parent
$PathCredentialFile += "\" + $CredentialFile
$PathCredentialFile

$credential = Get-VICredentialStoreItem -File $PathCredentialFile

#Conexion au serveur
$connexion = Connect-VIServer -Server $credential.Host -User $credential.User -Password $credential.Password -WarningAction SilentlyContinue

$date = Get-Date -Format yyyy.MM.dd
$file = "C:\Rapport-VMware\"+$date+"-report-vm-size.csv"

#Recupération de toutes les VM
$listVm = Get-VM "*test*"
$report=@()

foreach ($vm in $listVm)
{
    $report += $vm | Select-Object Name,@{n="Provisionedspace(GB)"; E={[math]::round($_.ProvisionedSpaceGB)}}
}

$report
$report | Export-Csv -Path $file

Disconnect-VIServer $connexion -Force -Confirm:$false

Snapshot

Liste VM et leurs snapshots

  • Script pour lister les VMs ayant un snapshot
#Server VSphere
$server = "adresse-VCenter"

#Connexion au vsphere
$connexion = Connect-VIServer -Server $server -WarningAction SilentlyContinue

#Liste des VM avec le nom du snapshot et la description
Get-VM | Get-Snapshot | Select VM,Name,Description

pause

Disconnect-VIServer -Server $connexion -Force -Confirm:$false


  • Script pour réaliser un rapport des snapshot et l'envoyer par mai
Param (
    [Alias("Host")]
    [string]$VIServer = "",
    [string]$User = "",
    [string]$Password="",
    [string]$PathToReport,
    [string]$CredentialFile="credential-vsphere.xml",
    
    [string]$To = "nagios@pass.be",
    [string]$From = "report-vmware@pass.be",
    [string]$SMTPServer = "mail.pass.be"
)

$Header = @"
<style>
TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TR:Hover TD {Background-Color: #C1D5F8;}
TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #6495ED;}
TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;}
.odd  { background-color:#ffffff; }
.even { background-color:#dddddd; }
</style>
<title>
Snapshot Report - $VIServer
</title>
"@

Function Set-AlternatingRows {
    [CmdletBinding()]
         Param(
             [Parameter(Mandatory=$True,ValueFromPipeline=$True)]
             [object[]]$HTMLDocument,
      
             [Parameter(Mandatory=$True)]
             [string]$CSSEvenClass,
      
             [Parameter(Mandatory=$True)]
             [string]$CSSOddClass
         )
     Begin {
         $ClassName = $CSSEvenClass
     }
     Process {
         [string]$Line = $HTMLDocument
         $Line = $Line.Replace("<tr>","<tr class=""$ClassName"">")
         If ($ClassName -eq $CSSEvenClass)
         {    $ClassName = $CSSOddClass
         }
         Else
         {    $ClassName = $CSSEvenClass
         }
         $Line = $Line.Replace("<table>","<table width=""50%"">")
         Return $Line
     }
}

#Desactiver la securité 
#Set-ExecutionPolicy RemoteSigned

#Chargement du module Vmware
If (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue))
{   Try { Add-PSSnapin VMware.VimAutomation.Core -ErrorAction Stop }
    Catch { Throw "Problem loading VMware.VimAutomation.Core snapin because ""$($Error[1])""" }
}

#Récupération du fichier avec les identifiants
$PathCredentialFile = Split-Path $Script:MyInvocation.MyCommand.Path -Parent
$PathCredentialFile += "\" + $CredentialFile
$PathCredentialFile 

$credential = Get-VICredentialStoreItem -File $PathCredentialFile

#Affectation de la variable VIServer
$VIServer = $credential.Host

#Connexion au vsphere
$connection = Connect-VIServer -Server $credential.Host -User $credential.User -Password $credential.Password -WarningAction SilentlyContinue

$Report = Get-VM | Get-Snapshot | Select VM,Name,Description,@{Label="Size";Expression={"{0:N2} GB" -f ($_.SizeGB)}},Created
If (-not $Report)
{  $Report = New-Object PSObject -Property @{
      VM = "No snapshots found on any VM's controlled by $VIServer"
      Name = ""
      Description = ""
      Size = ""
      Created = ""
   }
}



$Report = $Report | Select VM,Name,Description,Size,Created | ConvertTo-Html -Head $Header -PreContent "<p><h2>Snapshot Report - $VIServer</h2></p><br>" | Set-AlternatingRows -CSSEvenClass even -CSSOddClass odd
	
#Si on veut enregistrer le rapport à un endroit
#$Report | Out-File $PathToReport\SnapShotReport.html

#Fonction d'envoi de mail
$MailSplat = @{
    To         = $To
    From       = $From
    Subject    = "$VIServer Snapshot Report"
    Body       = ($Report | Out-String)
    BodyAsHTML = $true
    SMTPServer = $SMTPServer
}

Send-MailMessage @MailSplat

#Deconnexion du VIServer sans prompt
Disconnect-VIServer -Server $connection -Force -Confirm:$false

Datastore

Liste des VM par datastore

Param (
    [Alias("Host")]
    [string]$VIServer = "",
    [string]$User = "",
    [string]$Password="",
    [string]$PathToReport,
    [string]$CredentialFile="credential-vsphere.xml",
    
    [string]$To = "",
    [string]$From = "",
    [string]$SMTPServer = "",

    [boolean]$ExportCsv = $false,
    [string]$DirecteoryCsv = ""

)

#Variables static
$date = Get-Date -Format yyyy.MM.dd
$fileNameCSV = ""+$date+"-report-datastore-vm.csv"
#Tableau récupérant le contenu a exporter
$content=@()

#Récupération du fichier avec les identifiants
$PathCredentialFile = Split-Path $Script:MyInvocation.MyCommand.Path -Parent
$PathCredentialFile += "\" + $CredentialFile
#Affichage de debug pour le fichier credential
#$PathCredentialFile

#Création de l'objet avec les informations de connexion
$credential = Get-VICredentialStoreItem -File $PathCredentialFile

#Conexion au serveur
$connexion = Connect-VIServer -Server $credential.Host -User $credential.User -Password $credential.Password -WarningAction SilentlyContinue

#Récupération des datastore et des VMs associées.
Get-Datacenter | Get-Datastore | Foreach-Object {
    $datastore= $_.Name
    $content += $_ | Get-VM | Select-Object @{n='DataStore';e={$datastore}},Name
}

if($ExportCsv)
{
    write-Host "Export en CSV"

    #Ficher CSV de sortie
    if ( $DirecteoryCsv -eq "" )
    {
        $FileCsv = ".\"+$fileNameCSV
    }
    else
    {
        $FileCsv = $DirecteoryCsv+"\"+$fileNameCSV
    }

    #Export du contenu en CSV
    $content | Export-Csv -Path $FileCsv -NoTypeInformation
}

$content

Disconnect-VIServer -Server $connexion -Force -Confirm:$false

Replication

Rapport réplication complet

Param (
    [Alias("Host")]
    [string]$VIServer = "",
    [string]$User = "",
    [string]$Password="",
    [string]$PathToReport,
    [string]$CredentialFile="credential-vsphere.xml",
    
    [string]$To = "",
    [string]$From = "",
    [string]$SMTPServer = ""
)

#Récupération du fichier avec les identifiants
#$credential = Get-VICredentialStoreItem -File $CredentialFile
#Récupération du fichier avec les identifiants
$PathCredentialFile = Split-Path $Script:MyInvocation.MyCommand.Path -Parent
$PathCredentialFile += "\" + $CredentialFile
$PathCredentialFile 

$credential = Get-VICredentialStoreItem -File $PathCredentialFile

#Affectation de la variable VIServer
$VIServer = $credential.Host

#Connexion au vsphere
$connection = Connect-VIServer -Server $credential.Host -User $credential.User -Password $credential.Password -WarningAction SilentlyContinue

#Récupérer tous les events lié à la réplication
Get-VIEvent -MaxSamples ([int]::MaxValue) | Where { $_.EventTypeId -match "hbr|rpo" } | Select CreatedTime, FullFormattedMessage, @{Name="VMName";Expression={$_.Vm.Name}} | export-csv -NoTypeInformation -Path ([Environment]::GetFolderPath("Desktop") + "\HBR-RPOEvents.csv")

#Deconnexion du VIServer sans prompt
Disconnect-VIServer -Server $connection -Force -Confirm:$false

Rapport violation

Param (
    [Alias("Host")]
    [string]$VIServer = "",
    [string]$User = "",
    [string]$Password="",
    [string]$PathToReport,
    [string]$CredentialFile="credential-vsphere.xml",
    
    [string]$To = "",
    [string]$From = "",
    [string]$SMTPServer = ""
)

#Récupération du fichier avec les identifiants
#$credential = Get-VICredentialStoreItem -File $CredentialFile
#Récupération du fichier avec les identifiants
$PathCredentialFile = Split-Path $Script:MyInvocation.MyCommand.Path -Parent
$PathCredentialFile += "\" + $CredentialFile
$PathCredentialFile 

$credential = Get-VICredentialStoreItem -File $PathCredentialFile

#Affectation de la variable VIServer
$VIServer = $credential.Host

#Connexion au vsphere
$connection = Connect-VIServer -Server $credential.Host -User $credential.User -Password $credential.Password -WarningAction SilentlyContinue

Write-Host "[$(Get-Date)] Retrieving VMs"
$VMs = Get-VM
 
$Results = @()
Foreach ($VM in $VMs) {
   Write-Host "[$(Get-Date)] Retrieving events for $($VM.name)"
   $Events = Get-VIEvent -MaxSamples ([int]::MaxValue) -Entity $VM
   Write-Host "[$(Get-Date)] Filtering RPO events for $($VM.name)"
   $RPOEvents = $Events | where { $_.EventTypeID -match "rpo" } | Where { $_.Vm.Name -eq $VM.Name } | Select EventTypeId, CreatedTime, FullFormattedMessage, @{Name="VMName";Expression={$_.Vm.Name}} | Sort CreatedTime
   if ($RPOEvents) {
      $Count = 0
      Write-Host "[$(Get-Date)] Finding replication results for $($VM.Name)"
      do {
         $details = "" | Select VMName, ViolationStart, ViolationEnd, Mins
         if ($RPOEvents[$count].EventTypeID -match "Violated") {
            If (-not $details.Start) {
               $Details.VMName = $RPOEvents[$Count].VMName
               $Details.ViolationStart = $RPOEvents[$Count].CreatedTime
               Do {
               $Count++
               } until (($RPOEvents[$Count].EventTypeID -match "Restored") -or ($Count -gt $RPOEvents.Count))
               if ($RPOEvents[$count].EventTypeID -match "Restored") {
                  $details.ViolationEnd = $RPOEvents[$Count].CreatedTime
                  $Time = $details.ViolationEnd - $details.ViolationStart
                  $details.Mins = "{0:N2}" -f $Time.TotalMinutes
               } Else {
                  $details.ViolationEnd = "No End Date"
                  $details.Mins = "N/A"
               }
            }
         }
         $Results += $details
         $Count++
      } until ($count -gt $RPOEvents.Count)
   }
}
$Results | export-csv -NoTypeInformation -Path ([Environment]::GetFolderPath("Desktop") + "\ViolationReport.csv")

#Deconnexion du VIServer sans prompt
Disconnect-VIServer -Server $connection -Force -Confirm:$false