Labs: Windows Server 2022 Active Directory, Windows 11 domain join, and Ubuntu 22.04 domain join in HyperV

Updated by CH 05/05/23 - Add Register-PSRepository & change NugGet install command

Overview

In modern network infrastructure, the ability to connect and manage different devices and platforms seamlessly is essential. Windows Server 2022 Active Directory, Windows 11 domain join, and Ubuntu 22.04 domain join in HyperV are three powerful tools that can be used to achieve this goal. In this blog post, step-by-step instructions on how to implement them.

Whether you're a seasoned IT professional or a novice user, this post will provide valuable insights into how to make the first steps to leverage these tools to create a robust and interconnected IT environment.

We are of course a cloud-first company but there are still many scenarios where on-premise infrastructure is needed and still needs to be supported.

HyperV host

Whilst this can be done in other Hypervisors like VirtualBox (using NAT network and not NAT) but here we will be working with HyperV running on a Windows 11 Enterprise workstation.

We are assuming the HyperV role is installed and configured.

Let’s get started. In order to create an isolated lab environment in HyperV that allows the guests in the lab to communicate with each other, and access the internet via the host we need to:

  • Create an internal Virtual Switch in HyperV

  • Create a NAT Network in HyperV

Use the Virtual Switch Manager in the GUI to create a new switch. We will name ours LAB1-InternalSwitch. Select the connection type Internal Network.

New-VMSwitch -SwitchName "LAB1-InternalSwitch" -SwitchType Internal

Note: From here on we will be using PowerShell and Terminal commands wherever possible.

By default Internal Switches allow guests on that network to communicate with each other but cannot break out to the internet via the host. It also does not provide any DHCP functionality so we will deal with DHCP later. Alternatives such as an external switch will place the lab guests onto the host network, which will get messy and more complex. It’s important here to keep the lab completely separate and straightforward.

Next, we need to manually create a NAT gateway and a NAT Network to allow the guests connected to that network to NAT through to the internet via the physical host. This can only be currently done via PowerShell.

From an administrative PowerShell run Get-NetAdapter. Find the interface index of the virtual switch you just created.

PS C:\Users\PaulBarton> Get-NetAdapter

Name                      InterfaceDescription                    ifIndex 
----                      --------------------                    ------- 
vEthernet (NAT-Switch)    Hyper-V Virtual Ethernet Adapter #2          30 
vEthernet (External Sw... Hyper-V Virtual Ethernet Adapter #8          25 
Bluetooth Network Conn... Bluetooth Device (Personal Area Netw...      22 
vEthernet (Ext Virtual... Hyper-V Virtual Ethernet Adapter #4          14 
vEthernet (LAB1-Intern... Hyper-V Virtual Ethernet Adapter #5          43 
Ethernet                  Realtek PCIe GbE Family Controller           12 
Network Bridge            Microsoft Network Adapter Multiplexo...      10 
Wi-Fi                     Intel(R) Wi-Fi 6 AX201 160MHz                 7

The ifIndex of our virtual switch is 43. Configure the NAT gateway using New-NetIPAddress

New-NetIPAddress -IPAddress 10.0.2.1 -PrefixLength 24 -InterfaceIndex 43

Unless you are unfortunate enough that 10.0.2.0/24 conflicts with your host network, you can use this unless you have a specific reason to do otherwise. It will make the rest of the lab setup simpler.

Configure the NAT Network using New-NetNat:

New-NetNat -Name LAB1-NatNetwork -InternalIPInterfaceAddressPrefix 10.0.2.0/24

That’s it. We are ready to start building the VMs.

Other prerequisites

You’ll need the following ISOs on hand:

Windows Server 2022
Windows 11 Pro/Workstation/Education/Enterprise
Ubuntu Desktop 22.04

Windows 11 home edition cannot join a domain and cannot be used.

Optionally Ubuntu Server 22.04 if you want to continue on with adding an Ubuntu member server, with SAMBA etc. That’s beyond the scope of this blog though. Perhaps for another blog post.

Evaluation ISOs for Microsoft are available from the Microsoft website.

When creating your VMs use the ISO media and create the VMs manually rather than using the rather tempting quick create feature in HyperV. Also, avoid the unattended setup option if using a different hypervisor like VirtualBox.

Use Generation 2 VMs, and if using secure boot in HyperV, ensure that for Ubuntu that Microsoft UEFI Certificate Authority is selected as the template. Otherwise, the VM will not boot into the installer. There is no need to disable secure boot as all our lab VMs support it. It’s a bad habit to get into, lab or not.

When connecting to Windows VMs ensure you are using “Enhanced Session” to allow bidirectional copy/paste and other guest features.

Windows 11 “lab config” to bypass system requirements.

Windows 11 has specific system requirements when used in production and other supported scenarios. However, lab environments tend not to meet those requirements. Thankfully Microsoft thought of that. Note: this should not be used in production. It’s not supported.

We can use Windows 11 lab config to bypass system requirements. You may need more than one of these depending on your circumstances. The TPM check is the most likely to fail.

During the Windows 11 setup process if you are warned the system does not meet the requirements press SHIFT + F10 to open a command prompt. You can either import the following entries by putting them in a .reg file and importing them with regedit /s bypass.reg or use the GUI (run regedit from the prompt) to manually create them.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\Setup\LabConfig]
"BypassTPMCheck"=dword:00000001
"BypassSecureBootCheck"=dword:00000001
"BypassRAMCheck"=dword:00000001
"BypassStorageCheck"=dword:00000001
"BypassCPUCheck"=dword:00000001

Firstly build your Active Directory Domain Controller using the server ISO. At this stage connect the server VM to an external virtual switch to allow internet access. We will move it to the LAB1-InternalSwitch just after we set a static IP address for the server.

We’ll be using the desktop experience here for simplicity, however, there’s nothing in this lab that won’t work on Server Core and indeed in a production environment that would be highly preferable to reduce the attack surface, reduce update burden and rebooting, and discourage bad habits like using a browser.

Once done and you are at the desktop open a PowerShell as an administrator and proceed through the steps below. You can skip the Windows/Microsoft update part if you are in a hurry and do it at the end.

# Force TLS 1.2 for this session
# It seems installing the PackageProvider and some modules fail otherwise
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

#This script should run on servers but will require the following for desktop OS
Set-ExecutionPolicy RemoteSigned -Scope Process -Force

# Set the time zone to London and configure an internet time source
Set-TimeZone -Name "GMT Standard Time"
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DateTime\Servers" -Name "1" -Value "time.windows.com"

# Install modules etc
Register-PSRepository -Default
Find-PackageProvider -Name 'Nuget' -ForceBootstrap -IncludeDependencies
Install-Module -Name "PSWindowsUpdate" -Force
Install-Module -Name "PowerShellGet" -Force

# As this is a lab set repo to trusted
Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted

# Install Windows updates
Import-Module PSWindowsUpdate
Install-WindowsUpdate -MicrosoftUpdate -AcceptAll -Verbose

At this point, you will probably want to reboot the VM to complete the update installation. And check again for more updates until there are no more to install.

# Set a static IP address
# 1.1.1.3 is Cloudflare's DNS - blocking malware and adult
# At this point you should change the switch to LAB1-InternalSwitch
# This can be done with the VM running
$ipAddress = "10.0.2.254"
$subnetMask = "255.255.255.0"
$gateway = "10.0.2.1"
$dns1 = "127.0.0.1"
$dns2 = "1.1.1.3"

New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress $ipAddress -PrefixLength 24 -DefaultGateway $gateway
Set-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress $ipAddress -PrefixLength 24
Set-NetIPInterface -InterfaceAlias "Ethernet" -InterfaceMetric 10
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses $dns1,$dns2

# Verify the IP address and DNS settings
Get-NetIPAddress | Where-Object {$_.AddressFamily -eq "IPv4"}
Get-DnsClientServerAddress -AddressFamily IPv4

# Set the new hostname for the server and reboot
$hostname = "ad1"
Rename-Computer -NewName $hostname -Restart

The hostname is ad1 and the IP is 10.0.2.254 with a gateway of 10.0.2.1 as we configured in an earlier step. For now, we have configured the DNS to point to itself and Cloudflare. The Domain Controller promotion process will take care of this later when we install DNS. At this point change the network switch to LAB1-InternalSwitch using the HyperV GUI on the host. Internet access should be restored.

In the next step, we will install Active Directory Domain Service and DNS.

Bear in mind these passwords are obviously not suitable to go anywhere near production or internet-facing (including if you are building this in a public cloud).

We will install DHCP to facilitate IP addressing when we start to build clients.

# Install the AD DS, DNS and DHCP Server roles
Install-WindowsFeature -Name AD-Domain-Services, DNS, DHCP -IncludeManagementTools
# We need DHCP becuase the HyperV NAT Network does not provide one

# Create a new forest
$domainName = "365labs.uk"
$domainNetBIOSName = "365LABS"
$adminPassword = "P@ssword123" | ConvertTo-SecureString -AsPlainText -Force
$domainMode = "WinThreshold"
$forestMode = "WinThreshold"

# Setup the Forest. The password is not secure the DSRM password should be strong and unique in production.
Install-ADDSForest `
    -CreateDnsDelegation:$false `
    -DatabasePath "C:\Windows\NTDS" `
    -DomainMode $domainMode `
    -DomainName $domainName `
    -DomainNetbiosName $domainNetBIOSName `
    -ForestMode $forestMode `
    -InstallDns:$true `
    -LogPath "C:\Windows\NTDS" `
    -NoRebootOnCompletion:$true `
    -SysvolPath "C:\Windows\SYSVOL" `
    -Force:$true `
    -SafeModeAdministratorPassword $adminPassword

At this point reboot and remember that you will be logging in with the domain administrator password now which is the same password used for the local administrator account.

The DHCP server role has been installed but needs to be configured. We will create a scope to allocate addresses between 10.0.2.100 and 10.0.2.200 and the gateway and DNS settings as above.

The second DNS is again Cloudflare. In production, this will be one of your other domain controllers.

# Configure the DHCP server settings
$dhcpServer = "ad1"
$ipAddress = "10.0.2.254"
$subnetMask = "255.255.255.0"
$gateway = "10.0.2.1"
$dns1 = "10.0.2.254"
$dns2 = "1.1.1.3"
$scopeName = "LAN"
$scopeStart = "10.0.2.100"
$scopeEnd = "10.0.2.200"

Add-DhcpServerv4Scope -Name $scopeName -StartRange $scopeStart -EndRange $scopeEnd -SubnetMask $subnetMask -State Active
Set-DhcpServerv4OptionValue -DnsServer $dns1,$dns2 -Router $gateway 

# Authorize the DHCP server in Active Directory
Import-Module DhcpServer
Add-DhcpServerInDC -DnsName "ad1.365labs.uk" -IPAddress "10.0.2.254"

# Create a reverse lookup zone in DNS
Add-DnsServerPrimaryZone -NetworkID "10.0.2.0" -ReplicationScope "Domain"

#Create DNS forwarders
#1.1.1.3 should already be present as DCPromo will have removed it from the ethernet adapter and created the forwarder.
Import-Module DnsServer
$CloudflareIP1 = "1.1.1.3"
$CloudflareIP2 = "1.0.0.3"
Add-DnsServerForwarder -IPAddress $CloudflareIP1,$CloudflareIP2
Get-DnsServerForwarder

# Restart the server
Restart-Computer -Force

That’s the domain controller for the lab setup. You can now start installing your clients while completing the other steps.#

Next we will populate the Active Directory with some fictitious data.

# Import the Active Directory module
Import-Module ActiveDirectory

# Create the Sales group in the Sales OU
New-ADGroup -Name "Sales" -GroupCategory Security -GroupScope Global -Path "OU=Sales,OU=Departments,DC=365labs,DC=uk" -Description "Sales department group"

# Create the IT group in the IT OU
New-ADGroup -Name "IT" -GroupCategory Security -GroupScope Global -Path "OU=IT,OU=Departments,DC=365labs,DC=uk" -Description "IT department group"

# Create the Finance group in the Finance OU
New-ADGroup -Name "Finance" -GroupCategory Security -GroupScope Global -Path "OU=Finance,OU=Departments,DC=365labs,DC=uk" -Description "Finance department group"

# Set the password for the new user accounts
$password = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force

# Create the user accounts for the Sales department
New-ADUser -Name "John Doe" -SamAccountName "jdoe" -UserPrincipalName "jdoe@365labs.uk" -AccountPassword $password -ChangePasswordAtLogon $false -DisplayName "John Doe" -GivenName "John" -Surname "Doe" -Path "OU=Sales,OU=Departments,DC=365labs,DC=uk" -Enabled $true
Add-ADGroupMember -Identity "Sales" -Members "jdoe"

New-ADUser -Name "Jane Wilson" -SamAccountName "jwilson" -UserPrincipalName "jwilson@365labs.uk" -AccountPassword $password -ChangePasswordAtLogon $false -DisplayName "Jane Wilson" -GivenName "Jane" -Surname "Wilson" -Path "OU=Sales,OU=Departments,DC=365labs,DC=uk" -Enabled $true
Add-ADGroupMember -Identity "Sales" -Members "jwilson"

# Create the user accounts for the IT department
New-ADUser -Name "Alice Smith" -SamAccountName "asmith" -UserPrincipalName "asmith@365labs.uk" -AccountPassword $password -ChangePasswordAtLogon $false -DisplayName "Alice Smith" -GivenName "Alice" -Surname "Smith" -Path "OU=IT,OU=Departments,DC=365labs,DC=uk" -Enabled $true
Add-ADGroupMember -Identity "IT" -Members "asmith"

New-ADUser -Name "Tom Brown" -SamAccountName "tbrown" -UserPrincipalName "tbrown@365labs.uk" -AccountPassword $password -ChangePasswordAtLogon $false -DisplayName "Tom Brown" -GivenName "Tom" -Surname "Brown" -Path "OU=IT,OU=Departments,DC=365labs,DC=uk" -Enabled $true
Add-ADGroupMember -Identity "IT" -Members "tbrown"

# Create the user account for the Finance department
New-ADUser -Name "Bob Johnson" -SamAccountName "bjohnson" -UserPrincipalName "bjohnson@365labs.uk" -AccountPassword $password -ChangePasswordAtLogon $false -DisplayName "Bob Johnson" -GivenName "Bob" -Surname "Johnson" -Path "OU=Finance,OU=Departments,DC=365labs,DC=uk" -Enabled $true
Add-ADGroupMember -Identity "Finance" -Members "bjohnson"

And for the purposes of the lab we are going to add Domain Users to the Remote Desktop Users group on all workstations to permit remote logins to all our client guest VMs. We will do this via Group Policy.

First, let's create an OU for Workstations rather than using the Computers container and move all Windows computer objects to it if there are any. Group policies can be applied on OU containers but not on CN class containers. Then set the default OU for new computer objects to be this OU. While we are here we will create one for Ubuntu Workstations as well but bear in mind the computer object will likely need to be moved to this OU manually after Domain Join. You could use a script to move OSs matching ‘pc-linux-gnu’ or schedule it to run on a Domain Controller regularly.

If you prefer to move computer objects manually after domain join leave the step out.

Anyway:

New-ADOrganizationalUnit -Name "Windows Workstations" -Path "DC=365labs,DC=uk"

New-ADOrganizationalUnit -Name "Ubuntu Workstations" -Path "DC=365labs,DC=uk"

Get-ADComputer -SearchBase "CN=Computers,DC=365labs,DC=uk" -Filter { OperatingSystem -like "Windows*" } | Move-ADObject -TargetPath "OU=Windows Workstations,DC=365labs,DC=uk"

redircmp "OU=Windows Workstations,DC=365labs,DC=uk"

Open the Group Policy Editor. Right-click on the ‘Windows Workstations’ OU and ‘Create a GPO…..’ and call it ‘Add Domain Users to local RD Users’.

Right click and ‘Edit’ the policy. Navigate to Computer Configuration > Policies > Windows Settings > Security Settings > Restricted Groups.

Right-click "Restricted Groups" and select "Add Group". Enter "Remote Desktop Users" and click OK. In the "Members of this group" section, click "Add". In the "Select Groups" dialog box, enter "Domain Users" and click OK.

Once your Windows 11 client is built and at the Windows desktop. Run the following from an administrative PowerShell:

Add-Computer -DomainName "365labs.uk" -Credential "365labs\Administrator" -Restart

Once rebooted the machine will be joined to the domain and the computer object should now be in the ‘Windows Workstations’ OU.

You should now be able to connect remotely to the workstation using one of the user credentials we created earlier.

Further info:

https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/deploy/install-active-directory-domain-services--level-100-

https://ubuntu.com/landscape

https://ubuntu.com/blog/tag/ubuntu-advantage

https://ubuntu.com/pro (free for 5 installations for personal use)

Previous
Previous

Protect Your Business Future

Next
Next

What is it with websites and their infuriating password requirements?