Get Hyper-V VM Tag - powershell

I can set a tag for the VM through Windows Admin Center, but I can't find how to view this tag through powershell.
I need this for a script so that I take all VM names with a specific tag
UPD:
I am using hyper-v server core 2019

Thanks to #zett42, I solved the problem, albeit in a different way
$vm = Get-VM my_vm
$vm | Set-VM -Notes "mytag" -Confirm:$false
$VMs = Get-VM | Where-Object Notes -match "mytag" | Select-Object -Expand Name
$VMs | Out-File ./vms.txt

Related

Getting list of specific attributes for all Hyper-V VMs on Windows Server

Let's start off on the right foot. I'm not looking for someone to write the script discussed below for us. What I'd like is a pointer or pointers that can quickly get me up to speed on just the PowerShell parts I need in order to accomplish this task without first becoming an expert in PowerShell and then in use of Get-VM. That said, please read on.
We are attempting to do a virtual machine inventory on several VM hosts in a network of computers. To that end, we would like to write a script that writes a .CSV file containing the host name, and specific attributes for each VM defined on that host. So, for example:
HostName, VMName, ComputerName, ID, Maximum memory, Minimum meomry, ...
VMH1, VM1, DATACENTER1, 54324ebe-f167-..., 1099511627776, 536870912, ...
and so on, for each VM under this host... and we'd run the command on each of our hosts to get the inventory into files we could merge for an enterprise view.
Where I need help, is with PowerShell scripting. I'm highly skilled with KornShell and many other scripting languages, but I've avoided PS all these years. Now the piper is at my door.
Trying to understand how to tie these two things together:
I can get a list of VMs with the
Get-VM | ft Name
Given a VM, I can get the details I want with
Get-VM <vmname> |
Select-Object Name, etc...
I believe I'd need to pipe the command into the command, but that's not working for me. And then once that's done, need to manipulate the output so that %COMPUTERNAME% is at the front of the output, so a simple Export-Csv won't work for us either.
Again, I don't want this to be a "here's my homework - do it for me" entry; just looking for pointers.
THanks for your time.
All of what you are after are in the examples in the PowerShell Help Files for that cmdlet.
# Get specifics for a module, cmdlet, or function
(Get-Command -Name Get-VM).Parameters
(Get-Command -Name Get-VM).Parameters.Keys
Get-help -Name Get-VM -Examples
# Results
<#
Get-VM -ComputerName Server1 |
Where-Object {$_.State -eq 'Running'}
Get-ClusterGroup |
Where {$PSItem.GroupType -eq 'VirtualMachine' } |
Get-VM
#>
Get-help -Name Get-VM -Full
Get-help -Name Get-VM -Online
As for your code in the comment section, this ...
Get-VM |
ForEach-Object Get-VM |
Select-Object *
and/or this ...
Get-VM |
ft Name|
ForEach-Object Get-VM |
Select-Object *
... both are syntactically wrong. If you use the PowerShell_ISE or VSCode editor they would immediately flag these as errors. If you are prone to staying in the console host, then use the Invoke-ScriptAnalyzer cmdlet to check your code and Trace-Command to see all it is doing. See the help file for details.
(Get-Command -Name Invoke-ScriptAnalyzer).Parameters
(Get-Command -Name Invoke-ScriptAnalyzer).Parameters.Keys
Get-help -Name Invoke-ScriptAnalyzer -Examples
Get-help -Name Invoke-ScriptAnalyzer -Full
Get-help -Name Invoke-ScriptAnalyzer -Online
(Get-Command -Name Trace-Command).Parameters
(Get-Command -Name Trace-Command).Parameters.Keys
Get-help -Name Trace-Command -Examples
Get-help -Name Trace-Command -Full
Get-help -Name Trace-Command -Online
Thus should be this
Get-VM |
ForEach-Object {
$PSItem |
Select-Object -Property '*'
}
Never do '*' for all properties, unless that is what you really want. Always select only what you need.
To see all the properties of on the first VM, just to this
(Get-VM)[0] |
Select-Object -Property '*'
To see all the properties of all the VM's, just remove the [0].
You easily leverage the Out-GtidView cmdlet for selecting VM and viewing details.
(Get-VM)[0] |
Select-Object -Property '*' |
Out-GridView -Title 'Showing Virtual Machines'
see:
https://mcpmag.com/articles/2016/02/17/creating-a-gui-using-out-gridview.aspx
https://spiderzebra.com/2020/05/26/utilizing-powershell-out-gridview-as-a-gui-alternative
https://mikefrobbins.com/2014/09/11/creating-a-simplistic-gui-interface-with-out-gridview
Lastly, you are also saying, you want a list of VMHosts, that you are then trying to get the VM Guest off those hosts. That is not what Get-VM is for.
If your VMHosts are Windows Servers, joined to your domain, you'd use Get-ADComputer to get a list of VMHost names (however you have them named), then pass that to Get-VM to get the guests.
Example:
Get-ADComputer -Identity 'VMHost*' |
ForEach-Object {Get-VM -ComputerName $PSitem}
If they are not windows machines, use your chosen method to get that hostname, then pass that to Get-VM.
Doing this on my local Hyper-V machine
$env:COMPUTERNAME, 'Localhost' |
ForEach {
Get-VM -ComputerName $PSItem |
Select-Object -Property Name, State, Status, Version
}
# Results
<#
Name State Status Version
---- ----- ------ -------
WS2K16 Off Operating normally 9.0
...
#>
$env:COMPUTERNAME, 'Localhost' |
ForEach-Object {
$VMHostName = $PSItem
Get-VM -ComputerName $VMHostName |
Select-Object -Property #{
Name = 'VMHost'
Expression = {$VMHostName }
}, Name, State, Status, Version |
Export-Csv -Path 'D:\Temp\VMGuestReport.Csv' -Append
}
Import-Csv -Path 'D:\Temp\VMGuestReport.Csv' |
Format-Table -AutoSize
# Results
<#
VMHost Name State Status Version
------ ---- ----- ------ -------
SRV1 WS2K16 Off Operating normally 9.0
...
Localhost WS2K16 Off Operating normally 9.0
...
#>

Merge Powershell Output - Get-VM, Get-VHD

I would like to export some Server Statistics from a Failover Cluster System.
My plan is to show with the Get-VHD command all VHD used on the VMs on my host.
So I was Trying to use:
Get-VM | select-object VMID |get-vhd |ft
This gives me a list the
"ComputerName, Path, VHDFormat,VHDType,FileSize,MinimumSize, LogicalSectorSize, PhysicalSectorSize"
Sadly the ComputerName is not the VMName but just the Name of the Host.
Now when I run the Get-VM command I get the Name and here it is actually the VMName.
Is there a nice way to get the real VMnames in the Output of Get-VHD?
I am fairly new to Powershell and I could not find a solution that worked... Most of the "sniplets" found here did not work at all or did not return the VMname...
Thank you for your suggestions =)
Sorry, I think my Title is not that well described, I was not sure how this funktion is called.
Untested, but you could use a ForEach-Object loop and capture the Name property from the Get-VM cmdlet. Then go on with Get-VHD and combine the output:
Get-VM | ForEach-Object {
$name = $_.Name
$_ | Get-VHD | Select-Object #{Name = 'Name'; Expression = {$name}}, *
} | Format-Table -AutoSize

Remove Multiple Snapshots at once in PowerCLI

I am trying to delete old snapshots after patching using PowerCLI. The code i am using now is:
Get-VM | Get-Snapshot | Remove-Snapshot -confirm$false
It works great...but it only removes one at a time, and i would like it to do 2-3 at a time. Is this possible?
Thanks in advance!
This code will remove multiple snapshots from all virtual machines:
Get-VM | Get-Snapshot | % { Remove-Snapshot $_ -Confirm:$false }
I would recommend selecting a single virtual machine and testing first:
$VM = Get-VM -Name 'My Virtual Machine'
$VM | Get-Snapshot | % { Remove-Snapshot $_ -Confirm:$false }
Tested to work on PowerCLI 6.5.
I would recommend taking a look at the 'RunAsync' parameter. This will create the task and then move onto the next task without waiting for the prior task to complete.
Example:
Get-VM | Get-Snapshot | Remove-Snapshot -RunAsync -Confirm:$false

List name column of Hyper-V VM using powershell

This powershell command shows all Hyper-V VM which are running (with more columns: Name, State, CPU Usage, etc.):
Get-VM | where {$_.State -eq 'Running'}
How can I get list only with name column of all running Hyper-V VM?
To do that just select the property you need.
Get-VM | where {$_.State -eq 'Running'} | select Name
or VmName, not sure what's the proper property name

Get startup type of Windows service using PowerShell

How can I get the Windows service startup type using PowerShell and not using WMI?
I looked inside the Get-Service command, and it does not provide something to display the "startup type".
With PowerShell version 4:
You can run a command as given below:
Get-Service | select -property name,starttype
WMI is the way to do this.
Get-WmiObject -Query "Select StartMode From Win32_Service Where Name='winmgmt'"
Or
Get-WmiObject -Class Win32_Service -Property StartMode -Filter "Name='Winmgmt'"
In PowerShell you can use the command Set-Service:
Set-Service -Name Winmgmt -StartupType Manual
I haven't found a PowerShell command to view the startup type though. One would assume that the command Get-Service would provide that, but it doesn't seem to.
You can use also:
(Get-Service 'winmgmt').StartType
It returns just the startup type, for example, disabled.
As far as I know there is no “native” PowerShell way of getting this information. And perhaps it is rather the .NET limitation than PowerShell.
Here is the suggestion to add this functionality to the version next:
https://connect.microsoft.com/PowerShell/feedback/details/424948/i-would-like-to-see-the-property-starttype-added-to-get-services
The WMI workaround is also there, just in case. I use this WMI solution for my tasks and it works.
Once you've upgraded to PowerShell version 5 you can get the startup type.
To check the version of PowerShell you're running, use $PSVersionTable.
The examples below are for the Windows Firewall Service:
For the local system
Get-Service | Select-Object -Property Name,Status,StartType | where-object {$_.Name -eq "MpsSvc"} | Format-Table -auto
For one remote system
Get-Service -ComputerName HOSTNAME_OF_SYSTEM | Select-Object -Property MachineName,Name,Status,StartType | where-object {$_.Name -eq "MpsSvc"} | Format-Table -auto
For multiple systems (must create the systems.txt)
Get-Service -ComputerName (Get-content c:\systems.txt) | Select-Object -Property MachineName,Name,Status,StartType | where-object {$_.Name -eq "MpsSvc"} | Format-Table -auto
Use:
Get-Service BITS | Select StartType
Or use:
(Get-Service -Name BITS).StartType
Then
Set-Service BITS -StartupType xxx
[PowerShell 5.1]
If you update to PowerShell 5 you can query all of the services on the machine and display Name and StartType and sort it by StartType for easy viewing:
Get-Service |Select-Object -Property Name,StartType |Sort-Object -Property StartType
You can also use the sc tool to set it.
You can also call it from PowerShell and add additional checks if needed.
The advantage of this tool vs. PowerShell is that the sc tool can also set the start type to auto delayed.
# Get Service status
$Service = "Wecsvc"
sc.exe qc $Service
# Set Service status
$Service = "Wecsvc"
sc.exe config $Service start= delayed-auto
It is possible with PowerShell 4.
Get-Service *spool* | select name,starttype | ft -AutoSize
screenshot
By default StartType is not shown by Get-Service, but you can always explicitly ask for it:
Get-Service | select StartType,DisplayName | sort StartType,DisplayName
Use Get-Service | Get-Member to see all available fields.