mirror of
https://github.com/tsmagnum/Hyper-V-Report.git
synced 2026-04-27 03:05:41 +02:00
Add files via upload
This commit is contained in:
155
Functions.ps1
Normal file
155
Functions.ps1
Normal file
@@ -0,0 +1,155 @@
|
||||
#DO NOT MODIFY
|
||||
function Get-MgmtOsNicIpAddr
|
||||
{
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)] $adapterName
|
||||
)
|
||||
|
||||
$ipAddr = (Get-NetIPAddress | Where-Object {$_.InterfaceAlias -like "*$($adapterName)*" -and $_.AddressFamily -eq 'IPv4'}).IPAddress
|
||||
|
||||
return $ipAddr
|
||||
}
|
||||
|
||||
function Get-VswitchMember
|
||||
{
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)] $vswitch
|
||||
)
|
||||
|
||||
$targetSwitch = Get-VMSwitch -Name $vswitch
|
||||
|
||||
$vswitchMembers = ($targetSwitch.NetAdapterInterfaceDescriptions)
|
||||
|
||||
$physNics = @()
|
||||
|
||||
foreach ($vswitchMember in $vswitchMembers)
|
||||
{
|
||||
$physNic = (Get-Netadapter -InterfaceDescription $vswitchMember).Name
|
||||
$physNics += $physNic
|
||||
}
|
||||
|
||||
$vswitchPhysNics = $physNics | Out-String
|
||||
|
||||
return $vswitchPhysNics
|
||||
|
||||
}
|
||||
|
||||
function SendEmailReport-MSGraph
|
||||
{
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)] $body
|
||||
)
|
||||
#Checking if required module is present; if not, install it
|
||||
if (!(Get-Module -Name Microsoft.Graph -ListAvailable))
|
||||
{
|
||||
Write-Host -ForegroundColor Yellow "MS Graph module missing, installing..."
|
||||
Install-Module -Name Microsoft.Graph -Scope CurrentUser -Force
|
||||
Import-Module -Name Microsoft.Graph
|
||||
}
|
||||
|
||||
#Connect interactively to Microsoft Graph with required permissions
|
||||
Connect-MgGraph -NoWelcome -Scopes 'Mail.Send', 'Mail.Send.Shared'
|
||||
|
||||
if ($ccrecipient)
|
||||
{
|
||||
$params = @{
|
||||
Message = @{
|
||||
Subject = $subject
|
||||
Body = @{
|
||||
ContentType = $type
|
||||
Content = $body
|
||||
}
|
||||
ToRecipients = @(
|
||||
@{
|
||||
EmailAddress = @{
|
||||
Address = $reportRecipient
|
||||
}
|
||||
}
|
||||
)
|
||||
CcRecipients = @(
|
||||
@{
|
||||
EmailAddress = @{
|
||||
Address = $ccrecipient
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
SaveToSentItems = $save
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$params = @{
|
||||
Message = @{
|
||||
Subject = $subject
|
||||
Body = @{
|
||||
ContentType = $type
|
||||
Content = $body
|
||||
}
|
||||
ToRecipients = @(
|
||||
@{
|
||||
EmailAddress = @{
|
||||
Address = $reportRecipient
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
SaveToSentItems = $save
|
||||
}
|
||||
}
|
||||
|
||||
# Send message
|
||||
Send-MgUserMail -UserId $reportSender -BodyParameter $params
|
||||
|
||||
}
|
||||
|
||||
function SendEmailReport-Mailkit
|
||||
{
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)] $body
|
||||
)
|
||||
|
||||
#Checking if required module is present; if not, install it
|
||||
if (!(Get-Module -ListAvailable -Name "Send-MailKitMessage"))
|
||||
{
|
||||
Write-Host -ForegroundColor Yellow "Send-MailKitMessage module missing, installing..."
|
||||
Install-Module -Name "Send-MailKitMessage" -Scope CurrentUser -Force
|
||||
Import-Module -Name "Send-MailKitMessage"
|
||||
}
|
||||
|
||||
$UseSecureConnectionIfAvailable = $true
|
||||
|
||||
$credential = `
|
||||
[System.Management.Automation.PSCredential]::new($smtpServerUser, `
|
||||
(ConvertTo-SecureString -String $smtpServerPwd -AsPlainText -Force))
|
||||
|
||||
$from = [MimeKit.MailboxAddress]$reportSender
|
||||
|
||||
$recipientList = [MimeKit.InternetAddressList]::new()
|
||||
$recipientList.Add([MimeKit.InternetAddress]$reportRecipient)
|
||||
|
||||
if ($ccrecipient)
|
||||
{
|
||||
$ccList = [MimeKit.InternetAddressList]::new();
|
||||
$ccList.Add([MimeKit.InternetAddress]$ccrecipient);
|
||||
}
|
||||
|
||||
$Parameters = @{
|
||||
"UseSecureConnectionIfAvailable" = $UseSecureConnectionIfAvailable
|
||||
"Credential" = $credential
|
||||
"SMTPServer" = $smtpServer
|
||||
"Port" = $smtpServerPort
|
||||
"From" = $from
|
||||
"RecipientList" = $recipientList
|
||||
"CCList" = $ccList
|
||||
"Subject" = $subject
|
||||
"HTMLBody" = $body
|
||||
}
|
||||
|
||||
Send-MailKitMessage @Parameters
|
||||
}
|
||||
40
GlobalVariables.ps1
Normal file
40
GlobalVariables.ps1
Normal file
@@ -0,0 +1,40 @@
|
||||
#Script Info - do not modify
|
||||
$scriptVersion = "1.0"
|
||||
|
||||
#Cluster Environment - Coming soon...
|
||||
$clusterDeployment = $false
|
||||
$vmHosts = "hv1", "hv2"
|
||||
|
||||
#Reporting section
|
||||
$reportHtmlRequired = $true #Set to $true to generate an HTML report
|
||||
$reportHtmlName = "Hyper-V_Status_Report" #Report file name without extension, e.g., "MyReport"
|
||||
$reportHtmlDir = "C:\Temp" #Directory to save the report (no trailing slash), e.g., "C:\Temp"
|
||||
|
||||
#Information to be included in the report
|
||||
$replicationInfoNeeded = $true # Set to true to include replication details
|
||||
$vhdxInfoNeeded = $true #Set to true to include detailed VHDX information
|
||||
$vmnetInfoNeeded = $true #Set to true to include VM network adapter details
|
||||
$osNetInfoNeeded = $true #Set to true to include Management OS network adapter details
|
||||
$vswitchInfoNeeded = $true #Set to true to include virtual switch details
|
||||
|
||||
#Email Configuration
|
||||
$emailReport = $true #Set to true to send the report via email
|
||||
$emailSystem = "mailkit" #Choose the email system: "msgraph" or "mailkit"
|
||||
|
||||
$reportSender = "mySender@mydomain.com" #Sender email address (use quotes)
|
||||
$reportRecipient = "myRecipient@mydomain.com" #Recipient email address (use quotes)
|
||||
$ccrecipient = $null #CC email address (use quotes); leave as $null if not used
|
||||
$subject = "Hyper-V Status Report" #Email subject line
|
||||
|
||||
#MS Graph Email specific configuration
|
||||
$type = "HTML" #Choose between "HTML" or "TXT"
|
||||
$save = $false #Set to true to save the email in the Sent Items folder
|
||||
|
||||
#MailKit Email specific configuration
|
||||
$smtpServer = "mysmtpserver.domain.com"
|
||||
$smtpServerPort = 587
|
||||
$smtpAuthRequired = $true
|
||||
#If SMTP authentication is required, set a username and password below.
|
||||
#DO NOT USE A SENSITIVE OR PRIVILEGED ACCOUNT HERE!!!
|
||||
$smtpServerUser = "smtpserver.user"
|
||||
$smtpServerPwd = "mySecretPwd"
|
||||
15
HtmlCode.ps1
Normal file
15
HtmlCode.ps1
Normal file
@@ -0,0 +1,15 @@
|
||||
$preContent = "<h2>Hyper-V Status Report</h2>"
|
||||
$postContent = "<p>Creation Date: $($today | Out-String) -
|
||||
<a href='https://github.com/tsmagnum/Hyper-V_Report' target='_blank'>Hyper-V-Report ($scriptVersion) by F. Lillacci</a><p>"
|
||||
|
||||
$title = "Hyper-V Status Report"
|
||||
$breakHtml = "</br>"
|
||||
|
||||
$titleHtmlHosts = "<h3>Hyper-V Server</h3>"
|
||||
$titleHtmlVms = "<h3>Virtual Machines</h3>"
|
||||
$titleHtmlSnapshots = "<h3>Snapshots</h3>"
|
||||
$titleHtmlReplication = "<h3>Replication</h3>"
|
||||
$titleHtmlVhdx = "<h3>VHDX Disks</h3>"
|
||||
$titleHtmlVmnetAdapter = "<h3>VM Network Adatpers</h3>"
|
||||
$titleHtmlOsNetAdapter = "<h3>Management OS Network Adatpers</h3>"
|
||||
$titleHtmlVswitch = "<h3>Virtual Switches</h3>"
|
||||
378
Hyper-V-Report.ps1
Normal file
378
Hyper-V-Report.ps1
Normal file
@@ -0,0 +1,378 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Generates a comprehensive HTML report of the Hyper-V environment, including host details,
|
||||
virtual machines, snapshots, replication status, VHDX files, network adapters,
|
||||
and virtual switches. Optionally sends the report via email.
|
||||
|
||||
.DESCRIPTION
|
||||
The Hyper-V-Report.ps1 script is designed to automate the collection and reporting of key metrics
|
||||
and configuration details from a Hyper-V infrastructure. It supports both standalone and
|
||||
(future) clustered deployments and provides detailed insights into:
|
||||
|
||||
Host system resources and configuration
|
||||
Virtual machine specifications and states
|
||||
Snapshot inventory and age
|
||||
Replication status and health
|
||||
VHDX file properties and fragmentation
|
||||
VM and management OS network adapter configurations
|
||||
Virtual switch topology and uplinks
|
||||
|
||||
The script generates an HTML report and can send it via email using either MS Graph or MailKit,
|
||||
depending on the configuration.
|
||||
It relies on external modular scripts (GlobalVariables.ps1, StyleCSS.ps1, HtmlCode.ps1, Functions.ps1)
|
||||
for customization and formatting.
|
||||
|
||||
.EXAMPLE
|
||||
.\Hyper-V-Report.ps1
|
||||
#>
|
||||
|
||||
#Region Credits
|
||||
#Author: Federico Lillacci
|
||||
#Github: https://github.com/tsmagnum
|
||||
#endregion
|
||||
|
||||
# Setup all paths required for script to run
|
||||
|
||||
#Scripted execution
|
||||
$ScriptPath = (Split-Path ((Get-Variable MyInvocation).Value).MyCommand.Path)
|
||||
|
||||
#Getting date (logging,timestamps, etc.)
|
||||
$today = Get-Date
|
||||
$launchTime = $today.ToString('ddMMyyyy-hhmm')
|
||||
|
||||
#Setting the report filename
|
||||
$reportHtmlFile = $reportHtmlDir+"\$($reportHtmlName)_"+$launchTime+".html"
|
||||
|
||||
#Importing required assets
|
||||
. ("$($ScriptPath)\GlobalVariables.ps1")
|
||||
. ("$($ScriptPath)\StyleCSS.ps1")
|
||||
. ("$($ScriptPath)\HtmlCode.ps1")
|
||||
. ("$($ScriptPath)\Functions.ps1")
|
||||
|
||||
#Region Hosts
|
||||
#Getting Host infos
|
||||
if ($clusterDeployment)
|
||||
{
|
||||
#Doing stuff for cluster env - Coming soon...
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$vmHostsList = @()
|
||||
$vmHost = Get-VMHost
|
||||
|
||||
$hostInfos = Get-CimInstance Win32_OperatingSystem
|
||||
$vhdPathDrive = (Get-VMHost).VirtualHardDiskPath.Split(":")[0]
|
||||
$hypervInfo = [PSCustomObject]@{
|
||||
Name = $vmHost.ComputerName
|
||||
LogicalCPU = $vmHost.LogicalProcessorCount
|
||||
RAM_GB = [System.Math]::round((($vmHost.MemoryCapacity)/1GB),2)
|
||||
Free_RAM_GB = [System.Math]::round((($hostInfos).FreePhysicalMemory/1MB),2)
|
||||
VHD_Volume = $vhdPathDrive+":"
|
||||
Free_VHD_Vol_GB = [System.Math]::round(((Get-Volume $vhdPathDrive).SizeRemaining/1GB),2)
|
||||
OsVersion = $hostInfos.Version
|
||||
}
|
||||
|
||||
$vmHostsList += $hypervInfo
|
||||
}
|
||||
Write-Host -ForegroundColor Cyan "###### Hyper-V Hosts infos ######"
|
||||
$vmHostsList | Format-Table
|
||||
|
||||
#endregion
|
||||
|
||||
#Region VMs
|
||||
#Getting VMs detailed infos
|
||||
$vmsList =@()
|
||||
$vms = Get-VM
|
||||
|
||||
foreach ($vm in $vms)
|
||||
{
|
||||
$vmInfo = [PSCustomObject]@{
|
||||
Name = $vm.Name
|
||||
Gen = $vm.Generation
|
||||
Version = $vm.Version
|
||||
vCPU = $vm.ProcessorCount
|
||||
RAM_Assigned = [System.Math]::round((($vm.MemoryAssigned)/1GB),2)
|
||||
RAM_Demand = [System.Math]::round((($vm.MemoryDemand)/1GB),2)
|
||||
Dyn_Memory = $vm.DynamicMemoryEnabled
|
||||
IP_Addr_NIC0 = $vm.NetworkAdapters[0].IPAddresses[0]
|
||||
Snapshots = (Get-VMSnapshot -VMName $vm.Name).Count
|
||||
State = $vm.State
|
||||
Heartbeat = $vm.Heartbeat
|
||||
Uptime = $vm.Uptime.ToString("dd\.hh\:mm")
|
||||
Replication = $vm.ReplicationState
|
||||
Creation_Time = $vm.CreationTime
|
||||
}
|
||||
|
||||
$vmsList += $vmInfo
|
||||
}
|
||||
|
||||
Write-Host -ForegroundColor Cyan "###### Virtual Machines infos ######"
|
||||
$vmsList | Format-Table
|
||||
|
||||
#endregion
|
||||
|
||||
#Region Snapshots
|
||||
#Getting Snapshots
|
||||
$vmSnapshotsList = @()
|
||||
|
||||
foreach ($vm in $vms)
|
||||
{
|
||||
$foundSnapshots = Get-VMSnapshot -VMName $vm.name
|
||||
|
||||
if (($foundSnapshots).Count -gt 0)
|
||||
{
|
||||
foreach ($foundSnapshot in $foundSnapshots)
|
||||
{
|
||||
$snapInfo = [PSCustomObject]@{
|
||||
VM = $foundSnapshot.VMName
|
||||
Name = $foundSnapshot.Name
|
||||
Creation_Time = $foundSnapshot.CreationTime
|
||||
Age_Days = $today.Subtract($foundSnapshot.CreationTime).Days
|
||||
Parent_Snap = $foundSnapshot.ParentSnapshotName
|
||||
}
|
||||
|
||||
$vmSnapshotsList += $snapInfo
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$snapInfo = [PSCustomObject]@{
|
||||
VM = $vm.VMName
|
||||
Name = "No snapshots found"
|
||||
Creation_Time = "N/A"
|
||||
Age_Days = "N/A"
|
||||
Parent_Snap = "No snapshots found"
|
||||
}
|
||||
|
||||
$vmSnapshotsList += $snapInfo
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Write-Host -ForegroundColor Cyan "###### Snapshots infos ######"
|
||||
$vmSnapshotsList | Format-Table
|
||||
|
||||
#endregion
|
||||
|
||||
#Region replication
|
||||
if($replicationInfoNeeded)
|
||||
{
|
||||
$replicationsList = @()
|
||||
#Getting the Replication status
|
||||
$replicatedVms = ($vm | Where-Object {$_.ReplicationState -ne "Disabled"})
|
||||
if (($replicatedVms).Count -gt 0)
|
||||
{
|
||||
foreach ($vm in $replicatedVms)
|
||||
{
|
||||
$replication = Get-VmReplication -Vmname $vm.VMName |`
|
||||
Select-Object Name,State,Health,LastReplicationTime,PrimaryServer,ReplicaServer,AuthType
|
||||
$replicationsList += $replication
|
||||
}
|
||||
|
||||
Write-Host -ForegroundColor Cyan "###### Replication infos ######"
|
||||
$replicationsList | Format-Table
|
||||
}
|
||||
|
||||
#Creating a dummy object to correctly format the HTML report with no replications
|
||||
else
|
||||
{
|
||||
$statusMsg = "No replicated VMs found!"
|
||||
Write-Host -ForegroundColor Cyan "###### Replication infos ######"
|
||||
Write-Host -ForegroundColor Yellow $statusMsg
|
||||
$noReplicationInfo = [PSCustomObject]@{
|
||||
Replication_Infos = $statusMsg
|
||||
}
|
||||
$replicationsList += $noReplicationInfo
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#Region VHDX
|
||||
if ($vhdxInfoNeeded)
|
||||
{
|
||||
$vhdxList = @()
|
||||
|
||||
foreach ($vm in $vms)
|
||||
{
|
||||
$vhdxs = Get-VHD -VMId $vm.VMId |`
|
||||
Select-Object ComputerName,Path,VhdFormat,VhdType,FileSize,Size,FragmentationPercentage
|
||||
|
||||
foreach ($vhdx in $vhdxs)
|
||||
{
|
||||
$vhdxInfo = [PSCustomObject]@{
|
||||
Host = $vhdx.ComputerName
|
||||
Path = $vhdx.Path
|
||||
Format = $vhdx.VhdFormat
|
||||
Type = $vhdx.VhdType
|
||||
File_Size_GB = [System.Math]::round(($vhdx.FileSize/1GB),2)
|
||||
Size_GB = $vhdx.Size/1GB
|
||||
Frag_Perc = $vhdx.FragmentationPercentage
|
||||
}
|
||||
|
||||
$vhdxList += $vhdxInfo
|
||||
}
|
||||
|
||||
}
|
||||
Write-Host -ForegroundColor Cyan "###### VHDX infos ######"
|
||||
$vhdxList | Format-Table
|
||||
}
|
||||
#endregion
|
||||
|
||||
#Region VMNetworkAdapter
|
||||
if ($vmnetInfoNeeded)
|
||||
{
|
||||
$vmnetAdapterList = @()
|
||||
|
||||
foreach ($vm in $vms)
|
||||
{
|
||||
$vmnetadapts = Get-VMNetworkAdapter -vm $vm |`
|
||||
Select-Object MacAddress,Connected,VMName,IsSynthetic,IPAddresses,SwitchName,Status,VlanSetting
|
||||
|
||||
foreach ($vmnetadapt in $vmnetadapts)
|
||||
{
|
||||
$vmnetAdaptInfo = [PSCustomObject]@{
|
||||
VM = $vmnetadapt.VMName
|
||||
MAC = $vmnetadapt.MacAddress
|
||||
IP_Addr = $vmnetadapt.IPAddresses | Out-String
|
||||
Connected = $vmnetadapt.Connected
|
||||
vSwitch = $vmnetadapt.SwitchName
|
||||
#Status = $vmnetadapt.Status.
|
||||
Vlan_Mode = $vmnetadapt.VlanSetting.OperationMode
|
||||
Vlan_Id = $vmnetadapt.VlanSetting.AccessVlanId
|
||||
|
||||
}
|
||||
|
||||
$vmnetAdapterList += $vmnetAdaptInfo
|
||||
}
|
||||
|
||||
}
|
||||
Write-Host -ForegroundColor Cyan "###### VM Net Adapters infos ######"
|
||||
$vmnetAdapterList | Format-Table
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#Region Management OS NetworkAdapter
|
||||
if ($osNetInfoNeeded)
|
||||
{
|
||||
$osNetAdapterList = @()
|
||||
|
||||
$osNetadapts = Get-VMNetworkAdapter -ManagementOS |`
|
||||
Select-Object Name,MacAddress,IPAddresses,SwitchName,Status,VlanSetting
|
||||
|
||||
foreach ($osNetadapt in $osNetadapts)
|
||||
{
|
||||
$osNetAdaptInfo = [PSCustomObject]@{
|
||||
Name = $osNetadapt.Name
|
||||
MAC = $osNetadapt.MacAddress
|
||||
IP_Addr = Get-MgmtOsNicIpAddr -adapterName $osNetadapt.Name
|
||||
vSwitch = $osNetadapt.SwitchName
|
||||
Status = $osNetadapt.Status | Out-String
|
||||
Vlan_Mode = $osNetadapt.VlanSetting.OperationMode
|
||||
Vlan_Id = $osNetadapt.VlanSetting.AccessVlanId
|
||||
|
||||
|
||||
}
|
||||
|
||||
$osNetAdapterList += $osNetAdaptInfo
|
||||
}
|
||||
|
||||
Write-Host -ForegroundColor Cyan "###### Management OS Adapters infos ######"
|
||||
$osNetAdapterList | Format-Table
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#Region VirtualSwitch
|
||||
if ($vswitchInfoNeeded)
|
||||
{
|
||||
$vswitchList = @()
|
||||
|
||||
$vswitches = Get-VMSwitch | `
|
||||
Select-Object ComputerName,Name,EmbeddedTeamingEnabled,SwitchType,AllowManagementOS
|
||||
|
||||
foreach ($vswitch in $vswitches)
|
||||
{
|
||||
$vswitchInfo = [PSCustomObject]@{
|
||||
Host = $vswitch.ComputerName
|
||||
Virtual_Switch = $vswitch.Name
|
||||
SET = $vswitch.EmbeddedTeamingEnabled
|
||||
Uplinks = Get-VswitchMember -vswitch $vswitch.Name
|
||||
Type = $vswitch.SwitchType
|
||||
Mgmt_OS_Allowed = $vswitch.AllowManagementOS
|
||||
|
||||
}
|
||||
|
||||
$vswitchList += $vswitchInfo
|
||||
}
|
||||
|
||||
Write-Host -ForegroundColor Cyan "###### Virtual Switches infos ######"
|
||||
$vswitchList | Format-Table
|
||||
}
|
||||
#endregion
|
||||
|
||||
#Creating the HTML report
|
||||
if ($reportHtmlRequired)
|
||||
{
|
||||
$dataHTML =@()
|
||||
|
||||
$vmhostsHTML = $preContent + $titleHtmlHosts + ($vmHostsList | ConvertTo-Html -Fragment)
|
||||
$dataHTML += $vmhostsHTML
|
||||
|
||||
$vmsHTML = $titleHtmlVms + ($vmsList | ConvertTo-Html -Fragment)
|
||||
$dataHTML += $vmsHTML
|
||||
|
||||
$snapshotsHTML = $titleHtmlSnapshots + ($vmSnapshotsList | ConvertTo-Html -Fragment)
|
||||
$dataHTML += $snapshotsHTML
|
||||
|
||||
if ($replicationInfoNeeded)
|
||||
{
|
||||
$replicationHTML = $titleHtmlReplication + ($replicationsList | ConvertTo-Html -Fragment)
|
||||
$dataHTML += $replicationHTML
|
||||
}
|
||||
|
||||
if ($vhdxList)
|
||||
{
|
||||
$vhdxListHTML = $titleHtmlVhdx + ($vhdxList | ConvertTo-Html -Fragment)
|
||||
$dataHTML += $vhdxListHTML
|
||||
}
|
||||
|
||||
if ($vmnetInfoNeeded)
|
||||
{
|
||||
$vmnetAdapterListHTML = $titleHtmlVmnetAdapter + ($vmnetAdapterList | ConvertTo-Html -Fragment)
|
||||
$dataHTML += $vmnetAdapterListHTML
|
||||
}
|
||||
|
||||
if ($osNetInfoNeeded)
|
||||
{
|
||||
$osNetAdapterListHTML = $titleHtmlOsNetAdapter + ($osNetAdapterList | ConvertTo-Html -Fragment)
|
||||
$dataHTML += $osNetAdapterListHTML
|
||||
}
|
||||
|
||||
if ($vswitchInfoNeeded)
|
||||
{
|
||||
$vswitchListHTML = $titleHtmlVswitch + ($vswitchList | ConvertTo-Html -Fragment)
|
||||
$dataHTML += $vswitchListHTML
|
||||
}
|
||||
|
||||
$htmlReport = ConvertTo-Html -Head $header -Title $title -PostContent $postContent -Body $dataHTML
|
||||
$htmlReport | Out-File $reportHtmlFile
|
||||
|
||||
}
|
||||
|
||||
#Sending the report via email
|
||||
if ($emailReport -and $reportHtmlRequired)
|
||||
{
|
||||
switch ($emailSystem) {
|
||||
msgraph
|
||||
{ SendEmailReport-MSGraph -body (Out-String -InputObject $htmlReport) }
|
||||
|
||||
mailkit
|
||||
{ SendEmailReport-Mailkit -body (Out-String -InputObject $htmlReport) }
|
||||
|
||||
Default {Write-Host -ForegroundColor Yellow "You must select an email system, msgraph or mailkit"}
|
||||
}
|
||||
|
||||
}
|
||||
91
README.md
Normal file
91
README.md
Normal file
@@ -0,0 +1,91 @@
|
||||
|
||||
# Hyper-V Report Script Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
This PowerShell script automates the collection of detailed information about a Hyper-V environment, including hosts, virtual machines, snapshots, replication status, virtual hard disks (VHDX), network adapters, and virtual switches. It generates an HTML report and optionally sends it via email.
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
- Collects host system information
|
||||
- Enumerates all virtual machines and their configurations
|
||||
- Lists VM snapshots and calculates their age
|
||||
- Reports replication status for VMs
|
||||
- Gathers VHDX file details
|
||||
- Extracts VM and management OS network adapter data
|
||||
- Lists virtual switch configurations
|
||||
- Generates a comprehensive HTML report
|
||||
- Sends the report via email using MS Graph or MailKit
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- PowerShell 5.1 or later
|
||||
- Hyper-V role installed
|
||||
- Required modules:
|
||||
- `Hyper-V`
|
||||
- `CimCmdlets`
|
||||
- External scripts in the same directory:
|
||||
- `GlobalVariables.ps1`
|
||||
- `StyleCSS.ps1`
|
||||
- `HtmlCode.ps1`
|
||||
- `Functions.ps1`
|
||||
|
||||
---
|
||||
|
||||
## Script Parameters
|
||||
|
||||
These are expected to be defined in `GlobalVariables.ps1`:
|
||||
|
||||
- `$reportHtmlDir` – Directory to save the HTML report
|
||||
- `$reportHtmlName` – Base name for the report file
|
||||
- `$clusterDeployment` – Boolean flag for cluster support
|
||||
- `$replicationInfoNeeded` – Boolean flag to include replication info
|
||||
- `$vhdxInfoNeeded` – Boolean flag to include VHDX info
|
||||
- `$vmnetInfoNeeded` – Boolean flag to include VM network adapter info
|
||||
- `$osNetInfoNeeded` – Boolean flag to include management OS network adapter info
|
||||
- `$vswitchInfoNeeded` – Boolean flag to include virtual switch info
|
||||
- `$reportHtmlRequired` – Boolean flag to generate HTML report
|
||||
- `$emailReport` – Boolean flag to send report via email
|
||||
- `$emailSystem` – Email system to use (`msgraph` or `mailkit`)
|
||||
|
||||
---
|
||||
|
||||
## Output
|
||||
|
||||
- **HTML Report**: Saved in `$reportHtmlDir` with timestamped filename.
|
||||
- **Console Output**: Displays formatted tables for each section.
|
||||
- **Email**: Sent if `$emailReport` is enabled and `$reportHtmlRequired` is true.
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
```powershell
|
||||
.\Hyper-V-Report.ps1
|
||||
```
|
||||
|
||||
Ensure all required variables and modules are properly configured before execution.
|
||||
|
||||
---
|
||||
|
||||
## Sections in the Report
|
||||
|
||||
1. **Host Info** – CPU, RAM, OS version, VHD volume stats
|
||||
2. **VM Info** – Name, generation, memory, IP, state, uptime, replication
|
||||
3. **Snapshots** – Snapshot name, age, parent snapshot
|
||||
4. **Replication** – Status, health, last replication time
|
||||
5. **VHDX Info** – Format, type, size, fragmentation
|
||||
6. **VM Network Adapters** – MAC, IP, vSwitch, VLAN
|
||||
7. **Management OS Adapters** – IP, MAC, vSwitch, VLAN
|
||||
8. **Virtual Switches** – Name, type, uplinks, SET status
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- Cluster support is marked as "Coming soon".
|
||||
- Email system must be explicitly selected (`msgraph` or `mailkit`).
|
||||
40
StyleCSS.ps1
Normal file
40
StyleCSS.ps1
Normal file
@@ -0,0 +1,40 @@
|
||||
$header = @"
|
||||
<style>
|
||||
body
|
||||
{
|
||||
background-color: White;
|
||||
font-size: 12px;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
table {
|
||||
border: 0.5px solid;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: CornflowerBlue;
|
||||
color: white;
|
||||
padding: 6px;
|
||||
border: 0.5px solid;
|
||||
border-color: #000000;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 6px;
|
||||
margin: 0px;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
h2{
|
||||
background-color: CornflowerBlue;
|
||||
color:white;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
"@
|
||||
Reference in New Issue
Block a user