Sorry, I was doing all my testing locally on a single Hyper-V host. I forgot that you’re doing it remotely to Hyper-V hosts. I edited my original shared code to include the -ComputerName
parameter for Get-VHD, and I rewrote it with comments, and an outer loop for going through multiple Hyper-V hosts
# create an array of all the Hyper-V hosts
$Servers = @(
"SalamCOGRETOUR",
"Server2",
"Server3"
)
# create an array of the properties, and calculated properties, to pull from a VM
$Properties = @(
"ComputerName",
"Name",
"ProcessorCount",
"VMID",
@{Name='MemoryStartup';Expression={[math]::Round($_.MemoryStartup/1GB,0).tostring() + ' GB'}},
@{Name='MemoryAssigned';Expression={[math]::Round($_.MemoryAssigned/1GB,0).tostring() + ' GB'}},
@{Name='Uptime';Expression={(Get-Date) - $_.Uptime}},
"State",
"Version"
)
# first loop through all of the Hyper-V hosts. Any output from within will be captured by $VMDetails
$VMDetails = foreach ($Server in $Servers) {
# Get all of the VMs for the host and retrieve the properties from Get-VM we want
$VMResources = Get-VM -ComputerName $Server | Select-Object -Property $Properties
# now loop through each VM for this Hyper-V host, get the VHDs for it and for each VHD
# return a PSCustomObject with all the properties in total we want
Foreach ($VM in $VMResources) {
Get-VHD -ComputerName $Server -VMid $VM.VMid | Foreach-Object {
# for each VHD return a custom object containing all our properties
[PSCustomObject]@{
ComputerName = $VM.ComputerName
Name = $VM.Name
ProcessorCount = $VM.ProcessorCount
VMID = $VM.VMId
MemoryStartup = $VM.MemoryStartup
MemoryAssigned = $VM.MemoryAssigned
Uptime = $VM.Uptime
State = $VM.State
Version = $VM.Version
Path = $_.Path
'Size(GB)' = $_.FileSize/1GB -as [int]
VHDType = $_.VhdType
}
}
}
}
# we're done looping, let's export our array of objects to a CSV
$VMDetails | Export-Csv -Path "outputMerge.csv" -NoTypeInformation