Hi, I am trying to list all VHDs on hyper-V using Get-VHD, locally on the server it returns good results , here is the command Get-VM -VMName * | Select-Object VMId | Get-VHD | Format-Table
but when I try to run the same command from my laptop using Get-VM -ComputerName myserver -VMName * | Select-Object VMId | Get-VHD | Format-Table
it returns errors as follows
Get-VHD: Hyper-V was unable to find a virtual machine with id “2ba8bbbb-ced9-40ec-832f-501cd97a6a49”.
Get-VHD: Hyper-V was unable to find a virtual machine with id “86ee4914-83a2-4b76-8b5a-db0bbdf90743”.
Get-VHD: Hyper-V was unable to find a virtual machine with id “e5d0d14a-3bed-4a0e-9805-3e7f8522698a”.
…
…
Am I missing something? Thanks for your help
I’m not sure why Get-VHD doesn’t like you piping in the VMID.
However, Get-VHD already has a VMID Paramter so I would just avoid all of that and type. . .
Also on your server(s) when Installing Hyper-V, I recommend adding the role from PowerShell and make sure that you specify the two switches that begin with “include” and thn TAB complete them but here they are. . .
Because I have seen server manager or add/remove programs not always install the PowerShell module for Hyper-V. The sam goes for Windows Clustering, it will miss the PowerShell module unless you force it to or just use PowerShell to add features.
Without having any experience with this module I could imagine that you should help the cmdlet Get-VHD to find the server you’re dealing with … like so …
This is my first thought.
When you run Get-VM and Get-VHD locally on the server it’s all good because you’re referring to VMs and VHDs that exist on that server.
When you run Get-VM -ComputerName myserver it’s correctly going out to the server an enumerating the VMs and returning those objects. But when you pipe those objects to Get-VHD it has no idea they exist on another computer so it’s just looking up those VMIds locally and coming up with nothing.
Try something like this instead:
Ideally I would break up this one-liner in to pieces so I could manually iterate through the results and try things to see where the failure is:
$VMs = Get-VM -ComputerName myserver -VMName *
$VMS
# returns the results of the previous command for me to look at an inspect
$VMs[0] | Get-VHD
# try sending one of those objects to Get-VHD to see what happens, if I don't get the result I expected then I can try something else
$VMs[0] | Get-VHD -ComputerName myserver
# cool, maybe that worked, if it did then I can move on
$VHDs = $VMs | Select-Object VMId | Get-VHD -ComputerName myserver
# now I can call the $VHDs variable and confirm it has what I want
$VHDs
# and then I can do it again and pipe it to Format-Table or Export-Csv, or Out-Gridview, whatever I want, and I don't have to rerun all of the previous commands just to change that last part.
So many thanks, I got it and your suggestions work fine by adding -ComputerName myserver. However, I am trying to write a script to get all details of VMs to do a weekly reporting on Hyper-V VMs
With the following command, I get some fields, not all fields I need
By the end of the day, I need to understand/figure out how to merge or update my scripts to give an output as follows without me needing to copy/paste between 2 files
but I was not able to use this -ExpandProperty HardDrives in my 2 scripts.
I did
Get-Command Get-VM | Get-members
I dont see any indication about all propertied that I can expand, also googled but did not get any useful information. So the question is how can I get a list of all properties that I can expand?
For me that would be the wrong question. I’d ask you what properties do you really need?
If I got you right you just need to combine the queries in a loop and use a PSCustomObject to output it all together.
And BTW:
You should not use backticks as line continuation character. Especially when you have commas there anyway as they are working as line continuation character.
Really thanks for your help, after spending a couple of hours, I managed to create the following script but csv file is empty by the end and no errors generated
edit to add:
Now you’re using PSCustomObject which I think makes it a lot easier to control your output, but the lines preceding it are still very confusing and hard read. I suggest breaking it up more in to chunks. Right now your PSCustomObject has 5 properties but your first array of objects ($VMDetailsProc) has 8 properties. You’re getting a bunch of details and then not using them.
Take that end result spreadsheet you’ve got and figure out every property you want, then right that as your PSCustomObject, then work backwards and figure out how to populate each one of those properties with the required value.
it looks like it’s because you’re doing a Select-Object statement and then adding PScustomObjects to an array. Again, you’ve got too much going on in long one-liners making it difficult to track what you’re doing.
I am trying to gather all details for VMs on a hyper-V host for reporting purposes. Get-VM does not return hard drive details so that is why I using another query to get them and the idea is to merge output for both queries for each VM.
From 1st query, I get some details then I loop on all records and try to get the other missing details in the 2nd query inside the loop
Let me explain.
I’d already written out in a notepad all of the properties I wanted to get for the resulting CSV and that was something like:
ComputerName
Name
ProcessorCount
VMID
MemoryStartup
MemoryAssigned
Uptime
State
Version
Path
Size(GB)
VHDType
First thing I did was something like:
$VMs = Get-VM
And then I explored what kinds of properties those objects had using Get-Member and Select-Object
$VMs[0] | Get-Member
$VMs[0] | Select-Object *
I saw that while there was a HardDrives property those objects didn’t have the file size or VHDType. That info was returned by Get-VHD as you’ve seen. So I made an array of properties that I’m going to select with Select-Object because this allows me to write it vertically and makes it much easier to look at.
Then I do an initial run of Get-VM and pipe it to Select-Object using that array of properties and I store it all in $VMResources. Now i’ve got most of the details I need I just need information about the disks which I’m going to get from Get-VHD.
I again spent some time manually exploring Get-VHD and the output and looking at your picture of your spreadsheet. I don’t want empty cells in Excel for things like VMid or Uptime and such because I want to be able to filter the table on anything and have all the details there. This meant that I would need an object PER vhd that had all of the properties I would ultimately want in the spreadsheet.
I do a foreach loop through my original $VMResources and do a Get-VHD on each one of those VMs, which will likely return multiple VHD objects so I pipe that to a Foreach-Object.
Inside that loop is when I create my PSCustomObjects containing alllll of the properties I’m going to want to output. Some of the values of those properties come from the original $VM object in the outer loop, and some of the properties from from the inner loops “current object” $_ value.
I capture it all in a variable called $VMDetails so I can manually look one more time and make sure that contains all of the things I want an dchange anything I need to change. Then finally I write the standalone line to export that array to a CSV.
Fantastic, it works like a charm, really appreciate your help. I was doing get member on Get-VM and not on VM as you do where we cam see all properties, my bad. A special thanks for the clear and concise explanation.
one note, as indicated earlier, I needed to add -ComputerName SalamCOGRETOUR on line 16 to get-vhd working Get-VHD -ComputerName SalamCOGRETOUR
OK, now I have very simple question: Get-VM ha the argument -ComputerName which can be a collection as follows server1, server2.....
As I have 3 Hyper-V hosts, I need to run the script against the 3 in 1 run
I tried to add a 2nd server to both lines Get-VM and Get-VHD but it errors Line 13 : $VMResources = Get-VM -ComputerName SalamCOGRETOUR, salam7 | Select-Object -Property $Properties
and Line 16 : Get-VHD -ComputerName SalamCOGRETOUR, salam7 -VMid $VM.VMid | Foreach-Object {
I tried the multi server by reading list of hyper-V servers in text file then do a loop before line 14 and it worked wiyhout error but the ouput in the file was for the last hyper-V only, maybe I need an append attribute , not sure
In the easiest way you make the Hyper-V host name a parameter for the hole piece of code and run it in a loop over the 3 hosts. In the end you tell Export-Csv to -Append the results to an existing file and you’re done.
I urgently recommed to read the
By making your code easier to read you make it easier to to understand and to maintain or to extend if needed.