I am looking to see what VMs I have that are Windows 2012 R2. I wrote a quick script (below) to list all of my 2012 VMs, but there are over 50 and I was looking for an easy way to only list the VMs that are 2012 R2. Anyone have any ideas?
get-vm | where {$_.Guest.OSFullName -like "Microsoft Windows Server 2012 (64-bit)"} | Select Name | export-csv -notypeinformation c:\Win2012_VMs.csv
Thanks in advance,
Try like this.
With the -match operator you can use a RegEx expression on the right-hand side.
So, every string that contains '2012' will pass.
Get-VM |
where{$_.Guest.GuestFullName -match '2012 R2'} |
Select Name,
@{Name="Config GuestFullName";Expression={$_.ExtensionData.Config.GuestFullName}},
@{Name="Guest OS";Expression={$_.ExtensionData.Guest.GuestFullName}}
The 2nd problem is that the VMware Tools do not distinguish between W2K12 and W2K12R2.
The only way to find out is through a WMI call to the guest OS.
You can use Invoke-VMScript for that, like this
Get-VM |
where{$_.Guest.OSFullName -match '2012'} |
Select Name,
@{N='OS';E={
Invoke-VMScript -VM $_ -ScriptText {Get-WmiObject -class Win32_OperatingSystem | select -ExpandProperty Caption} |
select -ExpandProperty ScriptOutput}} |
where{$_.OS -match '2012 R2'}
If your VM are reachable over the network, you can do the WMI call directly, like this.
Get-VM |
where{$_.Guest.OSFullName -match '2012'} |
Select Name,
@{N='OS';E={
Get-WmiObject -class Win32_OperatingSystem -ComputerName $_.Guest.HostName | select -ExpandProperty Caption}} |
where{$_.OS -match '2012 R2'}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
If you have VMware Tools installed on all the VMs, and the VMs are powered on, that property should contain the OS name as it is known by the guest OS.
That property should in fact be the same as in $_.ExtensionData.Guest.GuestFullName
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Cool, thanks! This is what I'm trying to run to gather that info, what am I doing wrong? I'm trying to list everything that's 2012 AND R2...
Get-VM | Select Name, `
@{Name="Config GuestFullName";Expression={$_.ExtensionData.Config.GuestFullName}},`
@{Name="Guest OS";Expression={$_.ExtensionData.Guest.GuestFullName}} `
| Where-Object { "$_.Config GuestFullName" -contains "2012" } | Where-Object { "$_.Config GuestFullName" -contains "R2" }
Try like this.
With the -match operator you can use a RegEx expression on the right-hand side.
So, every string that contains '2012' will pass.
Get-VM |
where{$_.Guest.GuestFullName -match '2012 R2'} |
Select Name,
@{Name="Config GuestFullName";Expression={$_.ExtensionData.Config.GuestFullName}},
@{Name="Guest OS";Expression={$_.ExtensionData.Guest.GuestFullName}}
The 2nd problem is that the VMware Tools do not distinguish between W2K12 and W2K12R2.
The only way to find out is through a WMI call to the guest OS.
You can use Invoke-VMScript for that, like this
Get-VM |
where{$_.Guest.OSFullName -match '2012'} |
Select Name,
@{N='OS';E={
Invoke-VMScript -VM $_ -ScriptText {Get-WmiObject -class Win32_OperatingSystem | select -ExpandProperty Caption} |
select -ExpandProperty ScriptOutput}} |
where{$_.OS -match '2012 R2'}
If your VM are reachable over the network, you can do the WMI call directly, like this.
Get-VM |
where{$_.Guest.OSFullName -match '2012'} |
Select Name,
@{N='OS';E={
Get-WmiObject -class Win32_OperatingSystem -ComputerName $_.Guest.HostName | select -ExpandProperty Caption}} |
where{$_.OS -match '2012 R2'}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Get-VM |
where{$_.Guest.OSFullName -match '2012'} |
Select Name,
@{N='OS';E={
Invoke-VMScript -VM $vm -ScriptText {Get-WmiObject -class Win32_OperatingSystem | select -ExpandProperty Caption} |
select -ExpandProperty ScriptOutput}} |
where{$_.OS -match '2012 R2'}
This one didn't return any results for me. I also don't have the $vm variable assigned anywhere, so I replaced it with $_.Guest.HostName and that worked!
Get-VM | Where{$_.Guest.OSFullName -match '2012'}
Select Name,
@{N='OS';E={
Invoke-VMScript -VM $_.Guest.HostName -ScriptText {Get-WmiObject -class Win32_OperatingSystem | select -ExpandProperty Caption} |
select -ExpandProperty ScriptOutput}} | Where{$_.OS -match '2012 R2'}
This gave me the list I was looking for ... doesn't want to let me pipe it to CSV though.
Get-VM |
where{$_.Guest.OSFullName -match '2012'} |
Select Name,
@{N='OS';E={
Get-WmiObject -class Win32_OperatingSystem -ComputerName $_.Guest.HostName | select -ExpandProperty Caption}} |
where{$_.OS -match '2012 R2'}
This one returned 2 VMs as 2012 R2, but the list should be more like 40-50.
Thank you, sir!!
That first one was my typo, corrected it.
In fact $_ alone is sufficient.
Did you try like this for the CSV export?
Get-VM | Where{$_.Guest.OSFullName -match '2012'}
Select Name,
@{N='OS';E={
Invoke-VMScript -VM $_ -ScriptText {Get-WmiObject -class Win32_OperatingSystem | select -ExpandProperty Caption} |
select -ExpandProperty ScriptOutput}} |
Where{$_.OS -match '2012 R2'} |
Export-Csv -Path report.csv -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Nope, it dumps the results in the PowerCLi window and doesn't write to the CSV... very strange!
Can you attach the file with the code you are using?
I guess something must gone wrong with the copy/paste.
Are the pipeline symbols at the end included?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
here is the exact code ...
Get-VM | Where{$_.Guest.OSFullName -match '2012'}
Select Name,
@{N='OS';E={
Invoke-VMScript -VM $_ -ScriptText {Get-WmiObject -class Win32_OperatingSystem | select -ExpandProperty Caption} |
select -ExpandProperty ScriptOutput}} |
Where{$_.OS -match '2012 R2'} | Export-Csv -Path c:\ben\vmware\Win2012R2_VMs.csv -NoTypeInformation -UseCulture
There's a pipeline ('|') missing at the end of the first line
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
KNEW it was something simple that I was missing!
Thanks!
Very strange... I get a bunch of lines returned that seem like it's gathering the full list in the window, but the export only has 2 VMs listed. I cropped the screenshot as not to list VM names...
This is normally just a warning, but can you try with one of those VMs and Invoke-VMScript to check if the call actually returns anything?
If you only have 2 entries in the CSV, it looks like it is not returning the info.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Strange, because all of the ones displaying that warning ARE running 2012 R2.
I'll try running the invoke-script command alone and see...
Okay, I think I see what's happening... the account i'm running the script as doesn't have rights to the OS.
ScriptOutput
-------------------------------------------------------------------------------
| Get-WmiObject : Access denied
| At line:1 char:4
| + & {Get-WmiObject -class Win32_OperatingSystem | select -ExpandProperty
| Caption}
| + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| + CategoryInfo : InvalidOperation: (:) [Get-WmiObject],
Managemen
| tException
| + FullyQualifiedErrorId :
GetWMIManagementException,Microsoft.PowerShell.C
| ommands.GetWmiObjectCommand
|
|
-------------------------------------------------------------------------------
Yes; looks like it's a permissions thing.
You can pass other credentials (if you have them) via the GuestCredential parameter on the Invoke-VMScript cmdlet.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I ended up having it prompt me as I'm dealing with VMs in multiple domains.
Get-VM | Where{$_.Guest.OSFullName -match '2012'} |
Select Name,
@{N='OS';E={Invoke-VMScript -VM $_ -GuestCredential ($Host.UI.PromptForCredential("Please enter credentials", "Enter Guest credentials for $_", "", "")) -ScriptText {Get-WmiObject -class Win32_OperatingSystem | select -ExpandProperty Caption} | select -ExpandProperty ScriptOutput}} | Where{$_.OS -match '2012 R2'} | Export-Csv -Path c:\ben\vmware\Win2012R2_VMs.csv -NoTypeInformation -UseCulture
Thanks for the assistance!!