Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- asnp "VeeamPSSnapIn" -ErrorAction SilentlyContinue
- #region User-Variables
- # Print job lines
- $jlines = $true
- # File Output path and filename
- $file = "C:\Scripts\Test.htm"
- ###############################
- # report mode, valid modes
- # 24, 48, "Weekly", "Monthly"
- $reportMode = 24
- # Email configuration
- $sendEmail = 0
- $emailHost = "smtp.lab.local"
- $emailUser = "Veeam(at)lab.local"
- $emailPass = "MyPass"
- $emailFrom = "Veeam(at)lab.local"
- $emailTo = "john.doe(at)lab.local"
- #####################
- #endregion
- #region VersionInfo
- $vPCARversion = 1.1
- #
- # Version 1.1
- # Added job lines as per a request on the website
- #
- # Version 1.0
- # Clean up for release
- #
- # Version 0.9
- # More cmdlet rewrite to improve perfomace, credit to @SethBartlett
- # for practically writing the Get-vPCRepoInfo
- #
- # Version 0.8
- # Added Read/Write stats for proxies at requests of @bsousapt
- # Performance improvement of proxy tear down due to rewrite of cmdlet
- # Replaced 2 other functions
- # Added Warning counter, .00 to all storage returns and fetch credentials for
- # remote WinLocal repos
- #
- # Version 0.7
- # Added Utilisation(Get-vPCDailyProxyUsage) and Modes 24, 48, Weekly, and Monthly
- # Minor performance tweaks
- #endregion
- #region NonUser-Variables
- # Get the B&R Server
- $vbrServer = Get-VBRLocalHost
- # Get all the VI proxies in your army
- $viProxyList = Get-VBRViProxy
- # Get all the HV proxies in your army
- #$hvProxyList = Get-VBRHvProxy
- # Get all the backup repositories
- $repoList = Get-VBRBackupRepository
- # Get all the backup sessions for mode
- if ($reportMode -eq "Monthly") {
- $seshList = Get-VBRBackupSession | ?{($_.CreationTime -ge (Get-Date).AddMonths(-1)) -and ($_.State -ne "Working")}
- } elseif ($reportMode -eq "Weekly") {
- $seshList = Get-VBRBackupSession | ?{($_.CreationTime -ge (Get-Date).AddDays(-7)) -and ($_.State -ne "Working")}
- } elseif ($reportMode -eq 48) {
- $seshList = Get-VBRBackupSession | ?{($_.CreationTime -ge (Get-Date).AddHours(-48)) -and ($_.State -ne "Working")}
- } else {
- $seshList = Get-VBRBackupSession | ?{($_.CreationTime -ge (Get-Date).AddHours(-24)) -and ($_.State -ne "Working")}
- }
- if (($reportMode -eq 24) -or ($reportMode -eq 48)) {
- $emailSubject = "vPowerCLI v6 Army Report ($reportMode Hrs)"
- } else {
- $emailSubject = "vPowerCLI v6 Army Report ($reportMode)"
- }
- #Get replica jobs
- $repList = Get-VBRJob | ?{$_.IsReplica}
- $global:vPCRTArray = @() #HT Used to track returned datastores
- # Get the job counts
- $totalJobCount = @($seshList)
- $succesJobCount = @($seshList | ?{$_.Result -eq "Success"})
- $warningJobCount = @($seshList | ?{$_.Result -eq "Warning"})
- $failedJobCount = @($seshList | ?{$_.Result -eq "Failed"})
- #endregion
- #region Functions
- function Get-vPCProxyInfo {
- [CmdletBinding()]
- param (
- [Parameter(Position=0)]
- [String[]]$Name,
- [Parameter(Mandatory=$true, Position=1)]
- [PSObject[]]$Sessions
- )
- Begin {
- $vPCObjAry = @()
- [Int]$script:jobcount = 0
- [Int]$totalObjInJob = 0
- $cleanSessions = $Sessions | ?{($_.Result -ne "Failed") -and
- ($_.State -eq "Stopped") -and ($_.JobType -ne "Copy")}
- $cleanSessions | %{$totalObjInJob = $totalObjInJob + $_.Progress.TotalObjects} |
- Out-Null
- function Build-vPCObj {param ([PsObject]$inputObj)
- $ping = new-object system.net.networkinformation.ping
- $pinginfo = $ping.send("$($inputObj.Host.RealName)")
- if ($pinginfo.Status -eq "Success") {
- $hostAlive = "Alive"
- } else {
- $hostAlive = "Dead"
- }
- $vPCFuncObject = New-Object PSObject -Property @{
- ProxyName = $inputObj.Name
- RealName = $inputObj.Host.RealName.ToLower()
- Disabled = $inputObj.IsDisabled
- Status = $hostAlive
- IP = $pinginfo.Address
- Responce = $pinginfo.RoundtripTime
- ReadData = [Decimal]0.00
- WriteData = [Decimal]0.00
- UsageCount = 0
- ProxiesInSessions = $($totalObjInJob*2)
- }
- return $vPCFuncObject
- }
- function Get-vPCProxyName {param ([String]$title)
- $titleAry = @($title.Split())
- $ai = 3
- $bi = $titleAry.count - 1
- while ($ai -ne $bi) {
- $proxyString = $proxyString + " " + $titleAry[$ai]
- $ai ++
- }
- return $proxyString.Trim()
- }
- function Get-vPCProxyRole {param ([String]$title)
- $titleAry = @($title.Split())
- $roleString = $titleAry[1]
- return $roleString
- }
- Get-VBRViProxy | %{$vPCObjAry = $vPCObjAry + $(Build-vPCObj $_)}
- }
- Process {
- foreach ($session in $cleanSessions) {
- [Int]$vms = $session.Progress.TotalObjects
- [Int]$i = 0
- while ($i -lt $vms) {
- $vmTask = $session.GetTaskSessions()[$i]
- $readData = $vmTask.info.progress.readsize/1GB
- $writeData = $vmTask.info.progress.storedsize/1GB
- $vmTaskLog = $vmTask.Logger.GetLog()
- $proxies = @($vmTaskLog.UpdatedRecords | ?{($_.Title -like "Using source proxy*") -or
- ($_.Title -like "Using target proxy*")})
- # Update Values
- if ($proxies.Count -eq 2) {
- foreach ($proxy in $proxies) {
- $udProxy = $vPCObjAry | ?{$_.ProxyName -eq $(Get-vPCProxyName $proxy.Title)}
- $udProxy.UsageCount ++
- $role = Get-vPCProxyRole $proxy.Title
- if ($role -eq "source") {
- $udProxy.ReadData = [Math]::Round(([Decimal]$udProxy.ReadData + $readData),2)
- }
- elseif ($role -eq "target") {
- $udProxy.WriteData = [Math]::Round(([Decimal]$udProxy.WriteData + $writeData), 2)
- }
- }
- }
- elseif ($proxies.Count -eq 1) {
- foreach ($proxy in $proxies) {
- $udProxy = $vPCObjAry | ?{$_.ProxyName -eq $(Get-vPCProxyName $proxy.Title)}
- $udProxy.UsageCount += 2
- $udProxy.ReadData = [Math]::Round(([Decimal]$udProxy.ReadData + $readData),2)
- $udProxy.WriteData = [Math]::Round(([Decimal]$udProxy.WriteData + $writeData),2)
- }
- }
- $i ++
- }
- }
- if ($Name -ne $null) {
- $output = $vPCObjAry | ?{$Name -like $_.ProxyName}
- }
- else {
- $output = $vPCObjAry
- }
- }
- End {
- foreach ($obj in $output) {
- $obj | Add-Member Noteproperty Util $([Math]::Round(($obj.UsageCount/$obj.ProxiesInSessions)*100))
- }
- $output
- }
- }
- function Get-vPCRepoInfo {
- [CmdletBinding()]
- param (
- [Parameter(Position=0, ValueFromPipeline=$true)]
- [PSObject[]]$Repository
- )
- Begin {
- $outputAry = @()
- [Reflection.Assembly]::LoadFile("C:\Program Files\Veeam\Backup and Replication\Veeam.Backup.Common.dll") | Out-Null
- function Build-Object {param($name, $path, $free, $total)
- $repoObj = New-Object -TypeName PSObject -Property @{
- Target = $name
- Storepath = $path
- StorageFree = [Math]::Round([Decimal]$free/1GB,2)
- StorageTotal = [Math]::Round([Decimal]$total/1GB,2)
- FreePercentage = [Math]::Round(($free/$total)*100)
- }
- return $repoObj | Select Target, Storepath, StorageFree, StorageTotal, FreePercentage
- }
- }
- Process {
- foreach ($r in $Repository) {
- if ($r.GetType().Name -eq [String]) {
- $r = Get-VBRBackupRepository -Name $r
- }
- if ($r.Type -eq "WinLocal") {
- $Server = $r.GetHost()
- $FileCommander = [Veeam.Backup.Core.CRemoteWinFileCommander]::Create($Server.Info)
- $storage = $FileCommander.GetDrives([ref]$null) | ?{$_.Name -eq $r.Path.Substring(0,3)}
- $outputObj = Build-Object $r.Name $r.Path $storage.FreeSpace $storage.TotalSpace
- }
- elseif ($r.Type -eq "LinuxLocal") {
- $Server = $r.GetHost()
- $FileCommander = new-object Veeam.Backup.Core.CSshFileCommander $server.info
- $storage = $FileCommander.FindDirInfo($r.Path)
- $outputObj = Build-Object $r.Name $r.Path $storage.FreeSpace $storage.TotalSize
- }
- elseif ($r.Type -eq "CifsShare") {
- $fso = New-Object -Com Scripting.FileSystemObject
- $storage = $fso.GetDrive($r.Path)
- $outputObj = Build-Object $r.Name $r.Path $storage.AvailableSpace $storage.TotalSize
- }
- $outputAry = $outputAry + $outputObj
- }
- }
- End {
- $outputAry
- }
- }
- function Get-vPCReplicaTarget {
- [CmdletBinding()]
- param(
- [Parameter(Position=0)]
- [String]$Name,
- [Parameter(Position=1, ValueFromPipeline=$true)]
- [PSObject[]]$InputObj
- )
- BEGIN {
- $outputAry = @()
- $dsAry = @()
- if (($Name -ne $null) -and ($InputObj -eq $null)) {
- $InputObj = Get-VBRJob -Name $Name
- }
- }
- PROCESS {
- foreach ($obj in $InputObj) {
- if (($dsAry -contains $obj.ViReplicaTargetOptions.DatastoreName) -eq $false) {
- $esxi = $obj.GetTargetHost()
- $dtstr = $esxi | Find-VBRDatastore -Name $obj.ViReplicaTargetOptions.DatastoreName
- $objoutput = New-Object -TypeName PSObject -Property @{
- Target = $esxi.Name
- Datastore = $obj.ViReplicaTargetOptions.DatastoreName
- StorageFree = [Math]::Round([Decimal]$dtstr.FreeSpace/1GB,2)
- StorageTotal = [Math]::Round([Decimal]$dtstr.Capacity/1GB,2)
- FreePercentage = [Math]::Round(($dtstr.FreeSpace/$dtstr.Capacity)*100)
- }
- $dsAry = $dsAry + $obj.ViReplicaTargetOptions.DatastoreName
- $outputAry = $outputAry + $objoutput
- }
- else {
- return
- }
- }
- }
- END {
- $outputAry | Select Target, Datastore, StorageFree, StorageTotal, FreePercentage
- }
- }
- #endregion
- #region Report
- # HTML Stuff
- $headerObj = @"
- <html>
- <head>
- <title>vPowerCLI v6 Army Report</title>
- <style>
- body {font-family: Tahoma; background-color:#fff;width: 800px;}
- h1.top {background-color: #fb9895;color: White;font-weight: bold;font-size: 16px;vertical-align: center;padding: 5px;}
- table {font-family: Tahoma;font-size: 12px;background-color: #e3e3e3;width:800px;border-collapse:collapse;}
- .headerTable{background-color: #fb9895;color: White;font-weight: bold;font-size: 16px;height: 70px;vertical-align: bottom;padding: 0 0 15px 15px;border-bottom: none;}
- .subheader{height: 35px;background-color: #f3f4f4;font-size: 16px;vertical-align: middle;padding: 5px 0 0 15px;color: #626365;}
- table.inner tr{height: 17px;}
- table.inner td{padding: 2px 3px 2px 3px;vertical-align: top;border: 1px solid #a7a9ac;}
- table.inner .subheader{height: 35px;background-color: #f3f4f4;font-size: 16px;vertical-align: middle;padding: 5px 0 0 15px;color: #626365;}
- th {border: 1px solid #a7a9ac;border-bottom: none;}
- tr {height: 17px;}
- td {background-color: #fff;border: 1px solid #a7a9ac;padding: 2px 3px 2px 3px;vertical-align: top;}
- </style>
- </head>
- "@
- if (($reportMode -eq 24) -or ($reportMode -eq 48)) {
- $headSubHead = "$(Get-Date -f D) $(Get-Date -f HH:mm:ss) ($reportMode Hrs)"
- } else {
- $headSubHead = "$(Get-Date -f D) $(Get-Date -f HH:mm:ss) ($reportMode)"
- }
- $bodyTop = @"
- <body>
- <table>
- <tr>
- <td style="width: 80%;border: none;" class="headerTable">vPowerCLI v6 Army Report</td>
- <td style="width: 30%;border: none;vertical-align:text-top;font-size:xx-small;text-align:right;padding: 2px 3px 2px 3px;" class="headerTable">v: $vPCARversion.Custom</td>
- </tr>
- </table>
- <table cellspacing="0" cellpadding="0" class="inner" border="0" style="margin: 0px;">
- <tr>
- <td class="subheader" style="border-top: none;border-bottom: none;">
- $headSubHead
- </td>
- </tr>
- </table>
- "@
- $subHead01 = @"
- <table cellspacing="0" cellpadding="0" class="inner" border="0" style="margin: 0px;">
- <tr>
- <td class="subheader" style="border-top: none;border-bottom: none;">
- "@
- $subHead02 = @"
- </td>
- </tr>
- </table>
- "@
- $vbrMasterHash = @{"Coordinator" = "$((gc env:computername).ToLower())";"Total" = $totalJobCount.Count;
- "Successfull" = $succesJobCount.Count; "Warning" = $warningJobCount.Count; "Failed" = $failedJobCount.Count;}
- $vbrMasterObj = New-Object -TypeName PSObject -Property $vbrMasterHash
- $bodyMasterT = $vbrMasterObj | Select Coordinator, @{Name="Total Jobs"; Expression = {$_.Total}},
- @{Name="Successfull"; Expression = {$_.Successfull}}, @{Name="Warning"; Expression = {$_.Warning}},
- @{Name="Failed"; Expression = {$_.Failed}} |
- ConvertTo-HTML -Fragment
- $bodyMasterB = Get-Service -Name "*Veeam*" | Select @{Name="Service Name"; Expression = {$_.DisplayName}}, Status |
- ConvertTo-HTML -Fragment
- $bodyMasterB = $subHead01 + "Services" + $subHead02 + $bodyMasterB
- if ($jlines -eq $true) {
- $counter = @($seshList | ?{($_.Result -eq "Warning") -or ($_.Result -eq "Failed")})
- if ($counter.count -gt 0) {
- $bodyjLines = $seshList | ?{($_.Result -eq "Warning") -or ($_.Result -eq "Failed")} | Sort Creationtime -Descending | Select @{Name="Job Name"; Expression = {$_.Name}},
- @{Name="Start Date"; Expression = {$_.Progress.StartTime.ToShortDateString()}},
- @{Name="Start Time"; Expression = {$_.Progress.StartTime.ToShortTimeString()}},
- @{Name="Stop Time"; Expression = {$_.Progress.StopTime.ToShortTimeString()}}, @{Name="Duration"; Expression = {Get-Date "$($_.Progress.Duration)" -f HH:mm:ss}},
- @{Name="Read (GB)"; Expression = {[Math]::Round([Decimal]$_.Progress.ReadSize/1GB, 2)}},
- @{Name="Write (GB)"; Expression = {[Math]::Round([Decimal]$_.Progress.StoredSize/1GB, 2)}}, Result | ConvertTo-HTML -Fragment
- $bodyjLines = $subHead01 + "Job Details" + $subHead02 + $bodyjLines
- }
- }
- if ($viProxyList -ne $null) {
- $bodyProxy = Get-vPCProxyInfo -Sessions $seshList | Select @{Name="Proxy Host"; Expression = {$_.RealName}},
- @{Name="IP Address"; Expression = {$_.IP}}, Status, @{Name="RT (ms)"; Expression = {$_.Responce}}, Disabled,
- @{Name="Read (GB)"; Expression = {$_.ReadData}}, @{Name="Write (GB)"; Expression = {$_.WriteData}},
- @{Name="Util (%)"; Expression = {$_.Util}} | ConvertTo-HTML -Fragment
- $bodyProxy = $subHead01 + "vSphere Proxy Details" + $subHead02 + $bodyProxy
- }
- #if ($hvProxyList -ne $null) {
- #}
- if ($repoList -ne $null) {
- $bodyRepo = $repoList | Get-vPCRepoInfo | Select @{Name="Repository Name"; Expression = {$_.Target}},
- @{Name="Path"; Expression = {$_.Storepath}}, @{Name="Free (GB)"; Expression = {$_.StorageFree}},
- @{Name="Total (GB)"; Expression = {$_.StorageTotal}}, @{Name="Free (%)"; Expression = {$_.FreePercentage}} |
- ConvertTo-HTML -Fragment
- $bodyRepo = $subHead01 + "Repository Details" + $subHead02 + $bodyRepo
- }
- if ($repList -ne $null) {
- $bodyReplica = $repList | Get-vPCReplicaTarget | Select @{Name="Replica Target"; Expression = {$_.Target}}, Datastore,
- @{Name="Free (GB)"; Expression = {$_.StorageFree}}, @{Name="Total (GB)"; Expression = {$_.StorageTotal}},
- @{Name="Free (%)"; Expression = {$_.FreePercentage}} | ConvertTo-HTML -Fragment
- $bodyReplica = $subHead01 + "Replica Details" + $subHead02 + $bodyReplica
- }
- $footerObj = @"
- </body>
- </html>
- "@
- $htmlOutput = $headerObj + $bodyTop + $bodyMasterT + $bodyMasterB + $bodyjLines + $bodyProxy + $bodyRepo + $bodyReplica + $footerObj
- #endregion
- #region Output
- if ($sendEmail -eq 1) {
- $body = $htmlOutput
- $smtp = New-Object System.Net.Mail.SmtpClient $emailHost
- $smtp.Credentials = New-Object System.Net.NetworkCredential($emailUser, $emailPass);
- $msg = New-Object System.Net.Mail.MailMessage $emailFrom, $emailTo, $emailSubject, $body
- $msg.isBodyhtml = $true
- $smtp.send($msg)
- } else {
- $htmlOutput | Out-File $file
- Invoke-Expression $file
- }
- #endregion
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement