Hey Checkyourlogs Fans,
I’m Writing you here tonight with some great news about a new Hyper-V and Azure Stack HCI report that I’ve been working on.
I had a customer ask me to get them a list of all Virtual Machines running on Hyper-V Servers in their Domain.
The problem was that they didn’t know how many Hyper-V Servers or VM’s they had running.
This customer wasn’t using SCVMM, so that wasn’t an option.
Off to PowerShell.
First Off à In Researching how to write crisp reports using PowerShell I found the ultimate repository.

It was courtesy of Klys Przemyslaw. Please follow him on Twitter – @przemyslawklys
He has written a ton of open source modules for reporting in HTML, Word, Excel, and many other sources.
The module of his that I leveraged for this report was PSWriteHTML.
It can be found at:

My Script is pretty straight forward and has 2 functions:
- Test-Server – Which tests connectivity to the Server Found
- Get-HyperVServersinAD – Which hunts for the Service Connection Point “Microsoft Hyper-V” object
Here is the Github Link to my Script.
Here is a current working copy of the code
#Install the Required Modules for this Script
Install-Module PSWriteHTML
Install-WindowsFeature -Name RSAT-AD-PowerShell
Install-WindowsFeature -Name Hyper-V-PowerShell
#Test Server Function to check connectivity
Function Test-Server {
[CmdletBinding()]
# Parameters used in this function
param
(
[Parameter(Position=0, Mandatory = $true, HelpMessage="Provide server names", ValueFromPipeline = $false)]
$ComputerName
)
$Array = @()
ForEach($Server in $ComputerName)
{
$Server = $Server.Trim()
Write-Verbose "Checking $Server"
$SMB = $null
$Object = $null
$Status = $null
$SMB = Test-Path "\\$server\c$"
If($SMB -eq "True")
{
Write-Verbose "$Server is up"
$Status = "True"
$Object = New-Object PSObject -Property ([ordered]@{
Server = $Server
"Is Online?" = $Status
})
$Array += $Object
}
Else
{
Write-Verbose "$Server is down"
$Status = "False"
$Object = New-Object PSObject -Property ([ordered]@{
Server = $Server
"Is Online?" = $Status
})
$Array += $Object
}
}
If($Array)
{
return $Array
}
}
#Get-HyperVServersinAD
#I had an issue where the SCP's were not defined on two of my cluster nodes
#Had to manually create the object and then the script worked
function Get-HyperVServersInAD {
[cmdletbinding()]
param(
)
try {
Import-Module ActiveDirectory -ErrorAction Stop
} catch {
Write-Warning "Failed to import Active Directory module. Exiting"
return
}
try {
$Hypervs = Get-ADObject -Filter 'ObjectClass -eq "serviceConnectionPoint" -and Name -eq "Microsoft Hyper-V"' -ErrorAction Stop
} catch {
Write-Error "Failed to query active directory. More details : $_"
}
foreach($Hyperv in $Hypervs) {
$temp = $Hyperv.DistinguishedName.split(",")
$HypervDN = $temp[1..$temp.Count] -join ","
$Comp = Get-ADComputer -Id $HypervDN -Prop *
$OutputObj = New-Object PSObject -Prop (
@{
HyperVName = $Comp.Name
OSVersion = $($comp.operatingSystem)
})
$OutputObj
}
}
$HyperVServers = Get-HyperVServersInAD
$HyperVServers1 = $HypervServers.HyperVName
$HyperVServers1
ForEach ($HyperVNode in $HyperVServers1) {
Try{
Write-Host "Gathering VM INfo for $HyperVNode"
$HypervVms += Invoke-Command $HyperVNode {Get-VM}
#$output += $HypervVMs | ConvertTo-Html
}
Catch{
"Connection Error: $HyperVNode"
$ConnectionErrors += "Connection Error: $HyperVNode"
}
}
$HypervVms | Where VMName -notlike *Replica* | Select VMName,PSComputerName,State,UpTime,Version,Generation,IntegrationServiceState,OperationalStatus,CPUUsage,ProcessorCount,MemoryAssigned,MemoryDemand,MemoryStatus,MemoryStartup,DynamicMemoryEnabled,MemoryMinimum,MemoryMaximum,IntegrationServicesVersion,ResourceMeteringEnabled,ConfigurationLocation,SnapshotFileLocation,AutomaticStartAction,AutomaticStopAction,AutomaticStartDelay,SmartPagingFilePath,NumaAligned,NumaNodesCount,NumaSocketCount,IsClustered,SizeofSystemFiles,ParentSnapshotId,ParentSnapshotName| Out-GridHtml -Title "Standalone HVHosts"
$HypervVms | Where VMName -like *Replica* | Select VMName,PSComputerName,State,UpTime,Version,Generation,IntegrationServiceState,OperationalStatus,CPUUsage,ProcessorCount,MemoryAssigned,MemoryDemand,MemoryStatus,MemoryStartup,DynamicMemoryEnabled,MemoryMinimum,MemoryMaximum,IntegrationServicesVersion,ResourceMeteringEnabled,ConfigurationLocation,SnapshotFileLocation,AutomaticStartAction,AutomaticStopAction,AutomaticStartDelay,SmartPagingFilePath,NumaAligned,NumaNodesCount,NumaSocketCount,IsClustered,SizeofSystemFiles,ParentSnapshotId,ParentSnapshotName| Out-GridHtml -Title "Replica VMs"
$HypervVms | Where IsClustered -eq True | Select VMName,PSComputerName,State,UpTime,Version,Generation,IntegrationServiceState,OperationalStatus,CPUUsage,ProcessorCount,MemoryAssigned,MemoryDemand,MemoryStatus,MemoryStartup,DynamicMemoryEnabled,MemoryMinimum,MemoryMaximum,IntegrationServicesVersion,ResourceMeteringEnabled,ConfigurationLocation,SnapshotFileLocation,AutomaticStartAction,AutomaticStopAction,AutomaticStartDelay,SmartPagingFilePath,NumaAligned,NumaNodesCount,NumaSocketCount,IsClustered,SizeofSystemFiles,ParentSnapshotId,ParentSnapshotName| Out-GridHtml -Title "HCI Clusters"
$TestConnectivity | Test-Server -ComputerName $HyperVServers1 -verbose | Out-GridHtml -Title "Connectivity Checks"
$ConnectionErrors | Out-GridHtml -Title "Connection Errors"
I haven’t added a mailto function into this script. What I wanted to show you want the output using PSWriteHTML’s (Out-GridViewHTML), which is a killer alternative to Out-Gridview.
This Function not only build up the HTML Code required; it also gives buttons on the webpage to export to CSV,Excel,or PDF.
Check it out below (The Search Box works great)
Here is code I used to generate this:
$HypervVms | Where VMName -notlike *Replica* | Select VMName,PSComputerName,State,UpTime,Version,Generation,IntegrationServiceState,OperationalStatus,CPUUsage,ProcessorCount,MemoryAssigned,MemoryDemand,MemoryStatus,MemoryStartup,DynamicMemoryEnabled,MemoryMinimum,MemoryMaximum,IntegrationServicesVersion,ResourceMeteringEnabled,ConfigurationLocation,SnapshotFileLocation,AutomaticStartAction,AutomaticStopAction,AutomaticStartDelay,SmartPagingFilePath,NumaAligned,NumaNodesCount,NumaSocketCount,IsClustered,SizeofSystemFiles,ParentSnapshotId,ParentSnapshotName| Out-GridHtml -Title "Standalone HVHosts" $HypervVms | Where VMName -like *Replica* | Select VMName,PSComputerName,State,UpTime,Version,Generation,IntegrationServiceState,OperationalStatus,CPUUsage,ProcessorCount,MemoryAssigned,MemoryDemand,MemoryStatus,MemoryStartup,DynamicMemoryEnabled,MemoryMinimum,MemoryMaximum,IntegrationServicesVersion,ResourceMeteringEnabled,ConfigurationLocation,SnapshotFileLocation,AutomaticStartAction,AutomaticStopAction,AutomaticStartDelay,SmartPagingFilePath,NumaAligned,NumaNodesCount,NumaSocketCount,IsClustered,SizeofSystemFiles,ParentSnapshotId,ParentSnapshotName| Out-GridHtml -Title "Replica VMs" $HypervVms | Where IsClustered -eq True | Select VMName,PSComputerName,State,UpTime,Version,Generation,IntegrationServiceState,OperationalStatus,CPUUsage,ProcessorCount,MemoryAssigned,MemoryDemand,MemoryStatus,MemoryStartup,DynamicMemoryEnabled,MemoryMinimum,MemoryMaximum,IntegrationServicesVersion,ResourceMeteringEnabled,ConfigurationLocation,SnapshotFileLocation,AutomaticStartAction,AutomaticStopAction,AutomaticStartDelay,SmartPagingFilePath,NumaAligned,NumaNodesCount,NumaSocketCount,IsClustered,SizeofSystemFiles,ParentSnapshotId,ParentSnapshotName| Out-GridHtml -Title "HCI Clusters"

Here is an example of the .XLS export feature

I hope you enjoy the report and a new modern way of building HTML Reports.
Thanks,
Dave

Trackbacks/Pingbacks