Configuring a Hyper-V Host with PowerShell DSC (Part 1)

Hello, my name is Michael Godfrey and I am a Platform’s Premier Field Engineer (PFE) at Microsoft. I have been a Fabric Administrator for the past few years and have made it a habit of building quite a few Hyper-V Hosts. I was always looking for a way to ensure my team and I knew the exact way to build a Hyper-V or ESXi host in the same way, consistently. I used many different methods of deploying hosts, including the Bare-Metal Deployment method in System Center Virtual Machine Manager. Yet I was always looking for the next great method of deployments, one that could be used not just for Hypervisors, but for virtual machines and physical machines and in varying different methods of configurations.

Recently, I started to learn PowerShell DSC for one of my customers and we came across an issue regarding Hypervisor Host health. We were finding inconsistencies in the way the hosts were built and we wanted a way to streamline the deployment process for our hosts, as well as a way to monitor their compliance. So, naturally I decided to build out a DSC Configuration for a Hyper-V Host.

I wanted to share that process, and start with a several part series on deploying a Hyper-V Host via DSC. I want to let the code do the work for me, so that I can scale this solution for future builds. So, I wanted to set some goals in the deployment and will use this series to track my progress:

  • Deploy Hyper-V Role and PowerShell Modules for Management
  • Deploy Failover Clustering Role and PowerShell Modules for Management
  • Ensure Remote Management is enabled and Basic OS Security/Compliance settings are present.
  • Set default folder locations for VM and VM Checkpoints
  • Ensure SCVMM Agent is installed and Running
  • Ensure OMS Agent is installed and Running
  • Configure a Highly Available Cluster with Cluster Shared Volumes and Quorum
  • Set Software Defined Networking vSwitches, in a HA configuration

In each blog posting, I will address another item in our checklist and by the end, we should have a Highly Available Server 2016 Hyper-V Cluster with a well-defined cluster network and storage solution. This will be fun.

To start, let’s begin with the configuration itself. We need to define the configuration name and node definitions. We will be using a single configuration, so we will not need to define node variables, but if we wanted, we could use a technique called Partial Configurations. Here is a great article on that:

https://docs.microsoft.com/en-us/powershell/dsc/partialconfigs

In our example though, we will be keeping things simple and defining our configuration for one purpose, to deploy a Hyper-V host.

 

The host will need a few roles, like Hyper-V, Failover clustering and the PowerShell modules for each installed. For this we will be using the Windows Feature Resource in DSC.

https://docs.microsoft.com/en-us/powershell/dsc/windowsfeatureresource

Here are the roles I am installing on this Hyper-V Host to start with:

 

I am utilizing the Windows Feature Resource in DSC to Declaratively say, I would like to ensure each Feature is installed or “Present,” and I am including the sub features included for the Role/Feature. This configuration will ensure the Hyper-V Role, as well as the Features like Failover-Clustering, Multipath-IO and the PowerShell Modules for managing Hyper-V and Failover Clustering, are installed on every Server that is configured to “Pull” this DSC Configuration.

The next item on our list is to ensure that Remote Management of our Host is enabled and that we have settings like UAC configured. We will be using a few modules to accomplish this, so you will need to define these as DSC Resource. We will Import these resources at the beginning of our configuration and you can see that in my configuration here:

I also went ahead and created a default folder for our VMs to be stored in, outside of the Cluster Shared Volumes we will be creating in a subsequent post. In addition, I have given you an idea of how we can use the xHyper-V module to create an Internal VSwitch on our Hyper-V host.

 

I am happy with the results so far, we now have a DSC configuration that will install and ensure all the Roles and Features we need for a Hyper-Visor are present. We also have some basic settings like Time Zone and Remote Management set as well, and we started some of the configuration we will need by creating a default location for Virtual Machines on our Hosts, as well as a Virtual Switch for our VMs to utilize. I am only using this in a stand-alone configuration. In a Hyper-V Cluster configuration, this would be one of the Cluster Shared Volumes (CSVs).

The last thing we need to do is to compile our Configuration and Publish it to our Pull server. To compile our configuration, we need to “dot-source” the script in PowerShell by running the script. This will resolve all of our variables, and create the folder location and file itself for a MOF document. The MOF is the configuration document that we will be publishing to our DSC Pull server.

I will leave you with the full configuration I have written so far, so that you can use it in your examples and testing. In the next post, we will begin configuring our node(s) to be members of a Hyper-V Cluster and begin setting the Highly Available aspect of our Hyper-V Hosts. I look forward to your comments and questions. Happy Scripting!


#BEGIN POWERSHELL SCRIPT

Configuration Hypervisor {

Import-DscResource -ModuleName 'PSDesiredStateConfiguration', 'xRemoteDesktopAdmin', 'xTimezone','xHyper-V', 'xComputerManagement'

Node Hypervisor{

#Windows Features Installations
WindowsFeature Hyper-V {
Ensure = 'Present'
Name = "Hyper-V"
IncludeAllSubFeature = $true
}

WindowsFeature Failover-Clustering {
Ensure = 'Present'
Name ='Failover-Clustering'
}
        
WindowsFeature  Multipath-IO {
Ensure = 'Present'
Name=' Multipath-IO'
IncludeAllSubFeature = $true
} 

WindowsFeature RSAT-Shielded-VM-Tools{
Ensure = 'Present'
Name='RSAT-Shielded-VM-Tools'
IncludeAllSubFeature = $true
}

WindowsFeature RSAT-Clustering-Powershell{
Ensure = 'Present'
Name='RSAT-Clustering-Powershell'
IncludeAllSubFeature = $true
}

WindowsFeature Hyper-V-PowerShell{
Ensure = 'Present'
Name='Hyper-V-PowerShell'
IncludeAllSubFeature = $true
}


#Base OS Settings
        {
xUAC UAC{
Setting = "NotifyChanges"         
}
 
xTimeZone ServerTime{
TimeZone = "Eastern Standard Time"
}
 
xRemoteDesktopAdmin RemoteDesktopSettings {
Ensure = 'Present'
UserAuthentication = 'secure'
}
 
        }

#HyperVisor Host Settings {        
#VM Folder Directory 
    File VMs {
    Ensure = 'Present'
    Type = 'Directory'
     DestinationPath = "$($env:SystemDrive)\VMs"
}


#VM Host Switch 
    xVMSwitch InternalVSwitch {
        DependsOn = '[WindowsFeature]Hyper-V'
        Name = 'IntvSwitch'
        Ensure = 'Present'
        Type = 'Internal'
}
}



}

Hypervisor 

#END POWERSHELL SCRIPT