{"id":69100,"date":"2016-11-18T11:28:48","date_gmt":"2016-11-18T11:28:48","guid":{"rendered":"https:\/\/www.simple-talk.com\/?p=69100"},"modified":"2018-06-04T14:22:25","modified_gmt":"2018-06-04T14:22:25","slug":"hyper-v-powershell-basics","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/hyper-v-powershell-basics\/","title":{"rendered":"Hyper-V and PowerShell: The Basics"},"content":{"rendered":"<p><strong>The series so far:<\/strong><\/p>\n<ol>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/hyper-v-powershell-basics\/\">Hyper-V and PowerShell: The Basics<\/a><\/li>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/hyper-v-and-powershell-shielded-virtual-machines\/\">Hyper-V and PowerShell: Shielded Virtual Machines<\/a><\/li>\n<\/ol>\n\n<h1>Introduction<\/h1>\n<p>Hyper-V is Microsoft&#8217;s hypervisor that lets you run multiple virtual machines on a single physical host. Microsoft introduced Hyper-V in Windows Server 2008. Today, there are several ways to manage Hyper-V hosts:<\/p>\n<ul>\n<li><strong>Hyper-V manager<\/strong>: This is the default tool used to manage Hyper-V. This tool also manages remote hosts. It allows you to manage virtual machines, but also the network configuration and all Hyper-V settings.<\/li>\n<li><strong>System Center Virtual Machine Manager<\/strong>: This tool is part of the Microsoft System Center products. VMM centrally manages one or more Hyper-V hosts. It provides advanced Hyper-V administration and you can also manage VMware hosts by integrating your VMware vCenter.<\/li>\n<li><strong>Windows PowerShell<\/strong>: To simplify the management, it is possible to use the Hyper-V PowerShell module to configure and work with your virtual machines. With PowerShell, you can accomplish most of the tasks that you can accomplish with the GUI.<\/li>\n<\/ul>\n<p><strong>PowerShell and Hyper-V<\/strong><\/p>\n<p>Why use PowerShell to manage Hyper-V? Of course, you can use the GUI to perform most of the actions that we will describe in this article. However, PowerShell has several advantages. It allows you to automate the tasks and gives you more flexibility. In some cases, you have no option to using PowerShell because Microsoft does not automatically include all the features of Hyper-V in the GUI.<\/p>\n<p>The first step is to install Hyper-V on your Windows machine. Remember that it is possible to install Hyper-V not just on a Windows server, but also on Windows 10. Use this command to install it on Windows Server:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Install-WindowsFeature -Name Hyper-V -IncludeManagementTools -Restart<\/pre>\n<p>Make sure that you include the <strong>-IncludeManagementTools<\/strong> parameter. This will install the Hyper-V Manager console and the Windows PowerShell module for Hyper-V.<\/p>\n<p>Use this command to activate the role on Windows 10:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All<\/pre>\n<p> By Installing Hyper-V on Windows 10, you can use your own machine to test, and become familiar with, Hyper-V without any additional cost. All you need is a Windows machine with enough memory and processor to work comfortably.<\/p>\n<p>Now you can use the <strong>Get-Command<\/strong> cmdlet to check if the PowerShell Hyper-V module is available:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; get-command -module Hyper-V\r\n\r\nCommandType     Name                                               Version    Source\r\n-----------     ----                                               -------    ------\r\nCmdlet          Add-VMAssignableDevice                             2.0.0.0    Hyper-V\r\nCmdlet          Add-VMDvdDrive                                     2.0.0.0    Hyper-V\r\nCmdlet          Add-VMFibreChannelHba                              2.0.0.0    Hyper-V\r\nCmdlet          Add-VMGpuPartitionAdapter                          2.0.0.0    Hyper-V\r\nCmdlet          Add-VMGroupMember                                  2.0.0.0    Hyper-V\r\nCmdlet          Add-VMHardDiskDrive                                2.0.0.0    Hyper-V\r\nCmdlet          Add-VMHostAssignableDevice                         2.0.0.0    Hyper-V\r\nCmdlet          Add-VMKeyStorageDrive                              2.0.0.0    Hyper-V\r\nCmdlet          Add-VMMigrationNetwork                             2.0.0.0    Hyper-V\r\nCmdlet          Add-VMNetworkAdapter                               2.0.0.0    Hyper-V\r\nCmdlet          Add-VMNetworkAdapterAcl                            2.0.0.0    Hyper-V\r\nCmdlet          Add-VMNetworkAdapterExtendedAcl                    2.0.0.0    Hyper-V\r\nCmdlet          Add-VMNetworkAdapterRoutingDomainMapping           2.0.0.0    Hyper-V\r\nCmdlet          Add-VMRemoteFx3dVideoAdapter                       2.0.0.0    Hyper-V\r\nCmdlet          Add-VMScsiController                               2.0.0.0    Hyper-V\r\n\u2026\r\n\r\nPS &gt; get-command -module Hyper-V | Out-GridView\r\n<\/pre>\n<p>To make it easier to search for commands, pipe the output to the <strong>Out-GridView<\/strong> cmdlet. It also pays to update the help files before you begin with Hyper-V and PowerShell.<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Update-Help -Module Hyper-V<\/pre>\n<p>Ok, let\u2019s explore how you can automate many of your Hyper-V maintenance tasks with PowerShell.<\/p>\n<h1>Configuring Hyper-V Host<\/h1>\n<p>Although you have installed Hyper-V on your machine, it is not yet completely configured and adapted to your environment. Firstly, let us see the characteristics of our Host with the <strong>Get-VMHost <\/strong>cmdlet, not to be confused with <strong>Get-VM<\/strong> cmdlet which displays the VMs that are running on the host. I will come back to the latter command in the next section:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-VMHost\r\n\r\nName            LogicalProcessorCount MemoryCapacity(M) VirtualMachineMigrationEnabled\r\n----            --------------------- ----------------- ------------------------------\r\nDESKTOP-CAKCHQH 4                     3975.2734375      False\r\n\r\nPS &gt; Get-VMHost | Select *\r\n<\/pre>\n<p>Most cmdlets do not display all the available properties. To change this, we must add the <strong>Select-Object<\/strong> cmdlet and then add the wildcard *.<\/p>\n<p>What are these properties?<\/p>\n<ul>\n<li>The name of the server (In my case it is my Windows 10 laptop),<\/li>\n<li>The number of logical processors it has,<\/li>\n<li>The amount of memory,<\/li>\n<li>And finally, whether the live migration is enabled.<\/li>\n<\/ul>\n<p>This <strong>cmdlet<\/strong> accepts the <strong>-ComputerName<\/strong> parameter to query a remote host.<\/p>\n<p>Note that the virtual switches are not included in the previous result. To display them, you must use the <strong>Get-VMSwitch<\/strong> cmdlet. You will find that this command returns no result, which is normal.<\/p>\n<p>The communication between the Hyper-V host and its VMs is based on the concept of the VMSwitch. Here is a very simple diagram:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"542\" height=\"391\" class=\"wp-image-69101\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image.jpeg\" \/><\/p>\n<p>Figure 1 \u2013 Hyper-V Virtual Switch<\/p>\n<p>When a VMSwitch is linked to a Physical Network Adapter, then VMs will use this VMSwitch to be connected to the network; so we must identify which one will be used via the <strong>Get-NetAdapter<\/strong> cmdlet:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Get-NetAdapter\r\n\r\nName      InterfaceDescription                    ifIndex Status       MacAddress             LinkSpeed\r\n----      --------------------                    ------- ------       ----------             ---------\r\nEthernet  Realtek PCIe GBE Family Controller            6 Up           54-63-ED-4D-74-70         1 Gbps\r\nWi-Fi     Qualcomm Atheros AR9485WB-EG Wireles...      12 Disconnected 08-9E-2E-C4-2F-A4          0 bps\r\n<\/pre>\n<p>In the example, the adapter is called &#8220;Ethernet&#8221;. You can use the <strong>New-VMSwitch<\/strong> cmdlet to create a new virtual switch using Windows PowerShell. In my case, the following command is used to create a VMSwitch named \u201cMy Virtual Switch\u201d that is assigned to the physical network adapter named &#8220;Ethernet\u201d:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; New-VMSwitch -Name \"My Virtual Switch\" -NetAdapterName \"Ethernet\"\r\n\r\nName              SwitchType NetAdapterInterfaceDescription\r\n----              ---------- ------------------------------\r\nMy Virtual Switch External   Realtek PCIe GBE Family Controller\r\n<\/pre>\n<p>For help with the syntax of this cmdlet, use the <strong>Get-Help New-VMSwitch<\/strong> command.<\/p>\n<h1>Creating VMs<\/h1>\n<p>We have configured the essentials for using our host. Here&#8217;s how to deploy a virtual machine. The first thing is to list the virtual machines already running on the host. For this, use the <strong>Get-VM<\/strong> cmdlet, which does exactly what its name implies:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-VM\r\n\r\nName        State   CPUUsage(%) MemoryAssigned(M) Uptime      Status\r\n----        -----   ----------- ----------------- ------      ------\r\nprodIIStest Off     0           0                 00:00:00    Operating normally\r\nTest02      Running 0           4096              79.03:30:33 Operating normally\r\nVMWEB01     Running 0           4096              9.23:57:25  Operating normally\r\n<\/pre>\n<p>This PowerShell cmdlet returns an object, so if you need more information about a VM, add the <strong>-Name<\/strong> parameter and you can pipe the previous cmdlets output to the <strong>Format-List<\/strong> cmdlet:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Get-VM -Name VMWEB01 | Format-List *\r\n\r\n\r\nVMName                      : VMWEB01\r\nVMId                        : c52a5b53-844b-4d49-9c96-f85801c34a95\r\nId                          : c52a5b53-844b-4d49-9c96-f85801c34a95\r\nName                        : VMWEB01\r\nState                       : Running\r\nIntegrationServicesState    : Up to date\r\nOperationalStatus           : {Ok}\r\nPrimaryOperationalStatus    : Ok\r\nSecondaryOperationalStatus  :\r\nStatusDescriptions          : {Operating normally}\r\nPrimaryStatusDescription    : Operating normally\r\nSecondaryStatusDescription  :\r\nStatus                      : Operating normally\r\nHeartbeat                   : OkApplicationsHealthy\r\nReplicationState            : Disabled\r\nReplicationHealth           : NotApplicable\r\nReplicationMode             : None\r\nCPUUsage                    : 0\r\nMemoryAssigned              : 4294967296\r\n\u2026\r\n<\/pre>\n<p>You then get a set of very interesting properties. The output was truncated but here are some examples of the most commonly used properties:<\/p>\n<ul>\n<li><strong>IntegrationServicesState<\/strong>: Allows you to verify whether the <strong>Integration Services<\/strong> are installed. For those using VMware, this is the equivalent of VMware Tools.<\/li>\n<li><strong>Generation<\/strong>: Displays the version of the virtual machine (1 or 2)<\/li>\n<li><strong>State \/ Status \/ OperationalStatus<\/strong>: Several properties allow to precisely verify the health of the virtual machine.<\/li>\n<li><strong>Uptime<\/strong>: Execution time of the VM<\/li>\n<li><strong>MemoryAssigned<\/strong>: Memory assigned to the virtual machine<\/li>\n<li><strong>Path<\/strong>: Where the *.VHDX files are located<\/li>\n<li><strong>ProcessorCount<\/strong>: The number of processors assigned to the virtual machine<\/li>\n<\/ul>\n<p>For PowerShell One-Liners, you can easily get these properties for all your VMs:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Get-VM | where {$_.state -eq 'running'} | sort Uptime | select Name,Uptime,ProcessorCount,@{N=\"MemoryMB\";E={$_.MemoryAssigned\/1MB}},Status,Generation,Path,IntegrationServicesState | Format-Table \u2013AutoSize\r\n\r\nName     Uptime      ProcessorCount MemoryMB \t\t Status Generation  Path  IntegrationServicesState\r\n----     ------      -------------- -------- ------------------ ----------  ----  -----------------------\r\nVMWEB01  10.00:46:01              2     4096 Operating normally \t\t 1  D:\\VM\\VMWEB01     Up to date\r\nTest02   79.04:19:09              2     4096 Operating normally \t\t 1  D:\\VM\\TEST\\Test02 Up to date\r\n<\/pre>\n<p>Let us now see the next administration task that you will use: Create your first VM. We use several parameters:<\/p>\n<ul>\n<li><strong>Name<\/strong>: corresponds to the name of the VM<\/li>\n<li><strong>MemoryStartupBytes<\/strong>: corresponds to the amount of memory allocated<\/li>\n<li><strong>SwitchName<\/strong>: corresponds to the VMSwitch name previously created<\/li>\n<li><strong>NewVHDPath<\/strong>: corresponds to the location where the VHDX file will be stored (This file corresponds to the VMDK file for VMware)<\/li>\n<li><strong>NewVHDSizeBytes<\/strong>: corresponds to the VHDX file size<\/li>\n<\/ul>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; New-VM -Name \"VMTest\" -MemoryStartupBytes 1GB `\r\n  \t-SwitchName \"My Virtual Switch\" `\r\n  \t-NewVHDPath \"C:\\users\\Nicolas\\Documents\\Hyper-v\\VMTest.vhdx\" `\r\n  \t-NewVHDSizeBytes 20GB\r\n\r\nName   State CPUUsage(%) MemoryAssigned(M) Uptime   Status             Version\r\n----   ----- ----------- ----------------- ------   ------             -------\r\nVMTest Off   0           0                 00:00:00 Operating normally 8.0\r\n<\/pre>\n<p>The machine is created and is stopped. Some actions can only be made after the creation of the VM, such as increasing the number of processors, increasing memory. Here are some basic actions that will be helpful for your daily tasks:<\/p>\n<h2><strong>Create a second disk<\/strong><\/h2>\n<pre class=\"lang:tsql decode:true \">PS &gt; New-VHD -Path \"C:\\users\\Nicolas\\Documents\\Hyper-v\\Virtual Hard Disks\\VMTest2.vhdx\" -SizeBytes 10GB -Fixed\r\n\r\nComputerName            : DESKTOP-CAKCHQH\r\nPath                    : C:\\users\\Nicolas\\Documents\\Hyper-v\\Virtual Hard Disks\\VMTest2.vhdx\r\nVhdFormat               : VHDX\r\nVhdType                 : Fixed\r\nFileSize                : 10741612544\r\nSize                    : 10737418240\r\nMinimumSize             :\r\nLogicalSectorSize       : 512\r\nPhysicalSectorSize      : 4096\r\nBlockSize               : 0\r\nParentPath              :\r\nDiskIdentifier          : 43046EE3-656D-454A-A273-3B3B34DEF1D7\r\nFragmentationPercentage : 0\r\nAlignment               : 1\r\nAttached                : False\r\nDiskNumber              :\r\nNumber                  :\r\n<\/pre>\n<p>The file is created, all that remains is to attach it to our VM:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Add-VMHardDiskDrive -VMName VMTest -Path \"C:\\users\\Nicolas\\Documents\\Hyper-v\\Virtual Hard Disks\\VMTest2.vhdx\"<\/pre>\n<p>PowerShell does not return us any information. So how to know if the disc is actually attached? Well, simply run the following command:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; (Get-VM \u2013VMName VMTest | Select-Object VMId | Get-VHD).Path\r\nC:\\users\\Nicolas\\Documents\\Hyper-v\\VMTest.vhdx\r\nC:\\users\\Nicolas\\Documents\\Hyper-v\\Virtual Hard Disks\\VMTest2.vhdx\r\n<\/pre>\n<h2><strong>Increase the number of processors<\/strong><\/h2>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Set-VMProcessor \"VMTest\" -Count 2<\/pre>\n<h2><strong>Increase the memory<\/strong><\/h2>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Set-VMMemory \"VMTest\" -DynamicMemoryEnabled $true -MaximumBytes 1GB<\/pre>\n<p>To check if previous actions were applied, you can of course use the Hyper-V console:<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" width=\"542\" height=\"416\" class=\"wp-image-69102\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-49.png\" \/><\/strong><\/p>\n<p>Figure 2 \u2013 VM settings from Hyper-V GUI<\/p>\n<h1>Working With VMs<\/h1>\n<p>Ok, let us summarize the steps made so far:<\/p>\n<ol>\n<li>Installing the Hyper-V role<\/li>\n<li>Configuring the Network<\/li>\n<li>Creating a VM<\/li>\n<li>Configuring the VM<\/li>\n<\/ol>\n<p>The next step is to start and shut down our VMs. The following cmdlets are very easy to use, so let us first see an example:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Start-VM -name VMTest<\/pre>\n<p>Stopping the machine is done via the <strong>Stop-VM<\/strong> cmdlet. This action makes the machine stop through the operating system. For those using VMware, this is equivalent of the \u201cGuest Shutdown\u201d option.<\/p>\n<p>You may get the following error message:<\/p>\n<pre class=\"crayon:false\" style=\"color: white; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #1F3864; margin: 4px 0in 4px 0px;\">\r\nPS > Stop-VM -name VMTest\r\n<span style=\"color:red;\">Stop-VM : The virtual machine is locked. An interactive shutdown cannot proceed while the virtual machine is locked.\r\nAt line:1 char:1\r\n+ Stop-VM -name VMTest\r\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~\r\n    + CategoryInfo          : NotSpecified: (Microsoft.HyperV.PowerShell.ShutdownTask:ShutdownTask) [Stop-VM], Virtual\r\n   izationOperationFailedException\r\n    + FullyQualifiedErrorId :\r\nUnspecified,Microsoft.HyperV.PowerShell.Commands.StopVMCommand<\/span>\r\n<\/pre>\n<p>This means that the machine is in use by another process. To work around this, the <strong>-force<\/strong> parameter can be used:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Stop-VM -name VMTest -Force<\/pre>\n<p>Note: the <strong>-TurnOff<\/strong> parameter can also be used. This is the equivalent of &#8220;<strong>PowerOff<\/strong>&#8221; via VMware.<\/p>\n<p>More information is available here: <a href=\"https:\/\/technet.microsoft.com\/fr-fr\/library\/hh848468.aspx\">https:\/\/technet.microsoft.com\/fr-fr\/library\/hh848468.aspx<\/a><\/p>\n<p>Let us finish by touching on the Hyper-V \u2018checkpoints\u2019 concept. Checkpoints are not considered as backups, but you will still find them to be very useful. Indeed, they are regularly used before performing an action on a VM such as an update, by saving the state of the virtual machine. In this way, it is very easy to roll back to the previous state if the update fails. The official term is &#8220;Checkpoint&#8221; but cmdlets also uses the term &#8220;Snapshot&#8221; that is well known to any VMware sysadmin.<\/p>\n<p>To create a checkpoint, select the virtual machine using the <strong>Get-VM<\/strong> cmdlet and pipe this to the <strong>Checkpoint-VM<\/strong> cmdlet. Use the <strong>\u2013SnapshotName<\/strong> parameter to give a name. The complete command looks like the following:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Get-VM -Name VMTest | Checkpoint-VM -SnapshotName \u201cBefore Upgrade\u201d<\/pre>\n<p>You can easily view the checkpoints with the <strong>Get-VMCheckpoint<\/strong> cmdlet and remove them with <strong>Remove-VMCheckpoint:<\/strong><\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Remove-VMCheckpoint -VMName VMTest -Name \"Before Upgrade\"<\/pre>\n<h1>To Go Further<\/h1>\n<p>The Hyper-V console is limited because it only allows you to work on a single VM at a time, unlike PowerShell which you can use to interact with multiple machines simultaneously. So, you can easily create scripts to automate tasks. Consider the following example where you want to configure all your VMs with 4 processors:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true  \">PS &gt; Get-VM | select name, processorcount\r\n\r\nName   ProcessorCount\r\n----   --------------\r\ntest                1\r\nVMTest              2\r\n\r\n\r\nPS &gt; Get-VM | Set-VMProcessor -Count 4\r\nPS &gt; Get-VM | select name, processorcount\r\n\r\nName   ProcessorCount\r\n----   --------------\r\ntest                4\r\nVMTest              4\r\n<\/pre>\n<p>Another example for creating a Checkpoint on all your VMs at once:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Get-VM | Checkpoint-VM -SnapshotName \"Weekly Checkpoint\"\r\nPS &gt; Get-VM | Get-VMCheckpoint\r\n\r\nVMName Name              SnapshotType CreationTime        ParentSnapshotName\r\n------ ----              ------------ ------------        ------------------\r\ntest   Weekly Checkpoint Standard     30.10.2016 20:12:40\r\nVMTest Weekly Checkpoint Standard     30.10.2016 20:12:42\r\n<\/pre>\n<p>Finally, you will be able to plan an export of your VMS in a regular manner to backup them. Save the following lines in \u201cExportVM.ps1\u201d file:<\/p>\n<pre class=\"theme:powershell-ise lang:ps decode:true \"># Backup Folder\r\n$Backup = \"C:\\Backup\"\r\n# Get VMs Name\r\n$VMs = Get-VM | select name\r\n\r\n# Delete Backup Folder and create it again\r\nif((Test-Path -Path $Backup)){\r\n    Remove-Item $Backup -force -recurse -erroraction:SilentlyContinue\r\n} else {\r\n    New-Item $Backup -type directory\r\n}\r\n# Export all the VMs\r\nforeach ($VM in $VMs)\r\n{ \r\n    Export-VM -Name $VM.Name -Path $Backup\r\n} \r\n<\/pre>\n<p>All that remains to do is to schedule this script to be triggered at the frequency you need:<\/p>\n<pre class=\"lang:tsql decode:true\">PS &gt; $trigger = New-JobTrigger -Weekly -DaysOfWeek Sunday -WeeksInterval 2 -At 12:00AM\r\n$options = New-ScheduledJobOption -RunElevated\r\n\r\nRegister-ScheduledJob -Name \"Weekly VM Export\" -FilePath C:\\Scripts\\ExportVM.ps1 -Trigger $trigger -ScheduledJobOption $options\r\n\r\n\r\nId         Name            JobTriggers     Command                                  Enabled   \r\n--         ----            -----------     -------                                  -------   \r\n1          Weekly VM Ex... 1               C:\\Scripts\\ExportVM.ps1                  True      \r\n<\/pre>\n<h1>Conclusion<\/h1>\n<p>We have described the basic cmdlets to manage Hyper-V environment. PowerShell will help you to automate various repetitive tasks such as configuring Hyper-V in either a standalone host or Hyper-V cluster, provisioning a virtual machine or managing Checkpoints.<\/p>\n<p>Each example used in this guide can be applied in bulk mode to automate the management of your environment. If you want to read more about working with Hyper-V using PowerShell, you can start with this\u00a0article: <a href=\"https:\/\/technet.microsoft.com\/en-us\/library\/hh848559.aspx\">https:\/\/technet.microsoft.com\/en-us\/library\/hh848559.aspx<\/a>. To learn more about a particular PowerShell command use, <strong>Get-Help<\/strong>.<\/p>\n<p>Finally, if you want to go even further in the management and automation of Hyper-V with PowerShell, I advise you to study the new &#8220;PowerShell Desired State Configuration&#8221; feature. Indeed, DSC provides a resource named <strong>xHyper-V <\/strong>that will allow you to completely automate Hyper-V management. For this, I redirect you to the following article about DSC resources: https:\/\/www.simple-talk.com\/sysadmin\/powershell\/powershell-desired-state-configuration-dsc-resources\/<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Because it is important with maintaining Virtual Machine environments to be able to repeat routine tasks completely accurately, Windows PowerShell has grown in importance for the job. Now you can  manage the Hyper-V environment via PowerShell without needing to use the Hyper-V Manager console. It opens up many opportunities for automation.&hellip;<\/p>\n","protected":false},"author":158223,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[35],"tags":[5970,4635],"coauthors":[6804],"class_list":["post-69100","post","type-post","status-publish","format-standard","hentry","category-powershell","tag-devops","tag-powershell"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/69100","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/158223"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=69100"}],"version-history":[{"count":13,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/69100\/revisions"}],"predecessor-version":[{"id":79115,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/69100\/revisions\/79115"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=69100"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=69100"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=69100"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=69100"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}