TL;DR how we migrated the home lab from the formerly free version of ESXi to Hyper-V.
Welcome to Part XVII of our Back to the Basics Series!
Part I: NTDS.dit vs SAM
Part II: Ownership Matters
Part III: Recovering from a Crash
Part IV: Setting up a Simple Honeypot Account
Part V: Automating DC Deployment
Part VI: Sometimes it’s the dumbest thing
Part VII: Merry Christmas, macros, & Base64
Part VIII: Why old 0 Days make great teaching tools
Part IX: PowerShell & PS1s without PowerShell.exe
Part X: Ownership & so called “effective permissions”
Part XI: Windows Event Forwarding & SACLs
Part XII: Poorly planned honeypots & other Bad Ideas
Part XIII: Setting up a simple honey token
Part XIV: Smartcards and Pass-the-Hash
Part XV: Forwarding logs to Sentinel & basic alerts
Part XVI: Automating VM deployments in Hyper-V
Part XVII: Migrating the lab from ESXi to Hyper-V
Part XVIII: Centrally managing Hyper-V & Live Migrations
Background
As most know, Broadcom bought out VMware and almost immediately killed off the free version of ESXi. We had already been preparing for this as it was expected given Broadcom’s less than stellar reputation. We setup Hyper-V on a second refurbished server and automated provisioning VMs with it here.
We migrated the following from running in VMs in ESXi to Hyper-V in this project:
- Entra Connect
- Entra Cloud Sync
- Windows Event Collector
- Microsoft Exchange
- DFSR
- The FSMO roles
Please note that Microsoft has deprecated the term “FSMO” and now calls them “Operations Masters”. For simplicities sake we will use the term FSMO roles throughout this howto.
Please note that when I say we “spun up a VM in Hyper-V” I mean that we ran our automated process here that
- Creates a VM running Windows Server with the specified name
- Configures the VM’s networking configuration as specified
- Joins the VM to our domain
Migrating Entra Connect & Cloud Sync
This role was formerly known as Azure AD Connect, and it still says that in the setup on Windows. As I’m sure everyone knows Microsoft recently renamed Azure AD to Entra ID.
There is an excellent walkthrough of the process here.
We simply followed that guide and:
- Spun up a VM in Hyper-V named TestMEIDC
- Exported the settings from our old TestAADC VM
- Jotted down the AD account TestAADC is using
- Installed MS Entra Connect in staging mode on TestMEIDC
- Put TestAADC in staging mode
- Made TestMEIDC the primary (no staging mode)
- Installed the Cloud Sync Agent on TestMEIDC
- Confirmed everything was syncing in the Azure portal
- De-provisioned the TestAADC VM
That’s it, this part was all GUI based.
Migrating the Windows Event Collector
We went over initial setup of Windows Event Forwarding here. This is just what we did to migrate the WEC role to a new VM.
The GPO for Windows Event Forwarding was already set and I had created a group in AD named “Collectors” for Member Servers that hold the WEC role. Therefore we just had to spin up a VM named TestWECII and add it to the Collectors group.
Get-WindowsFeature | Where-Object {$_.Name -like "*RSAT*"} | Install-WindowsFeature
Add-ADGroupMember -Identity "Collectors" -Members "TestWECII"
Setup the subscription in Event Viewer on TestWECII, exactly the same way we did it on here. This takes about 15 seconds.
Verify:
$Events = Get-WinEvent -Path "$env:SystemRoot\System32\Winevt\Logs\ForwardedEvents.evtx" | Sort-Object MachineName -Unique
$Events | Select-Object TimeCreated, Id, MachineName
We ran the Azure Arc setup PS1 on TestWECII and confirmed it was G2G on the Azure portal. I am not yet paying for Sentinel full time, so I didn’t setup log forwarding from TestWECII to Azure yet. We used a Sentinel trial to run through how to do that here.
DFSR
We had already spun up BackupDC3 while getting Hyper-V up and running and ironing out our VM provisioning process. Hence we just had to add it to the DFSR that handles the lab’s share drive.
New-Item "C:\Test Share" -ItemType Directory
New-SMBShare -Name "Test Share" -Path "C:\Test Share"
Install-WindowsFeature -Name FS-DFS-Namespace, FS-DFS-Replication -IncludeManagementTools
Get-DfsReplicationGroup -GroupName "test.local\Mishky's Share\Test Share" | Get-DfsReplicatedFolder -FolderName "Test Share" | Add-DfsrMember -ComputerName BackupDC3
Add-DfsrConnection -GroupName "test.local\Mishky's Share\Test Share" -SourceComputerName TestDC -DestinationComputerName BackupDC3
Set-DfsrMembership -GroupName "test.local\Mishky's Share\Test Share" -FolderName "Test Share" -ComputerName BackupDC3 -ContentPath "C:\Test Share"
Confirm:
Get-DfsReplicationGroup -GroupName “test.local\Mishky’s Share\Test Share” | Get-DfsReplicatedFolder -FolderName “Test Share” | Get-DfsrMembership
Once DFSR had synced we changed the I drive mapping to BackupDC3 (It’s in the Default Domain Policy).
We then removed the 2 old DCs from DFSR.
Remove-DfsnFolderTarget -Path "\\test.local\Mishky's Share\Test Share" -TargetPath \\TestDC\Test Share
Remove-DfsnFolderTarget -Path "\\test.local\Mishky's Share\Test Share" -TargetPath \\BackupDC\Test Share
Get-DfsReplicationGroup -GroupName "test.local\Mishky's Share\Test Share" | Get-DfsReplicatedFolder -FolderName "Test Share" | Remove-DfsrMember -ComputerName TestDC, BackupDC
Confirm:
Get-DfsrMember -GroupName “test.local\mishky’s share\test share”
FSMO roles
We went over what the roles are and their explanation here.
Move-ADDirectoryServerOperationMasterRole -Identity BackupDC3 -OperationMasterRole pdcemulator, ridmaster, infrastructuremaster, schemamaster, domainnamingmaster
#Confirm
netdom query fsmo
On Mishka’s other domain that handles one desktop we had to spin up a new DC from scratch. This is actually quite simple.
Add-Computer -DomainName "sky.local"
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
Install-ADDSDomainController -DomainName "sky.local" -InstallDns:$true
Move-ADDirectoryServerOperationMasterRole -Identity SkyDCII -OperationMasterRole pdcemulator, ridmaster, infrastructuremaster, schemamaster, domainnamingmaster
#Make sure it's using Microsoft for NTP
w32tm.exe /config /syncfromflags:manual /manualpeerlist:131.107.13.100,0x8 /reliable:yes /update
w32tm.exe /config /update
#Confirm
w32tm /query /configuration
Migrating Exchange
This turned out to be the tricky part of the entire project as I don’t know much about Exchange yet. We originally set it up in the lab as part of this project and put it to use here in order to compare & contrast Get-ADPermission, Get-Acl, and dsacls.
We fired up a VM named TestExchangeII and mounted the Exchange ISO to it.
Add-VMDvdDrive -VMName “TestExchangeII” -Path “C:\VM_Stuff_Share\ExchangeServer2019-x64-CU12.ISO”
Grab the three dependencies including .NET 4.8, then run Exchange Setup.
Migrate the mailboxes from the old Exchange VM to the new one.
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://TestExchangeII.test.local/PowerShell/ -Authentication Kerberos -Credential $UserCredential
Import-PSSession $Session -DisableNameChecking
$DB = (Get-MailboxDatabase | Where-Object {$_.Server -eq "TestExchangeII"}).Name
$Emails = (Get-Mailbox).PrimarySmtpAddress
ForEach($Email in $Emails)
{
New-MoveRequest -Identity $Email -TargetDatabase $DB
}
Errors we hit migrating Exchange
mishky@test.local
Status: Failed
mishky@test.localSkipped item details
Data migrated: 48.76 MB (51,125,505 bytes)
Migration rate: 0 B (0 bytes)
Error: MigrationMRSPermanentException: Informational: The request has been temporarily postponed because Search is not up to date. The Microsoft Exchange Mailbox Replication service will attempt to continue processing the request after 5/11/2024 7:26:15 AM.
Report: mishky@test.localDownload the report for this user
Last successful sync date: 5/11/2024 10:11:15 AM
This was fixed by setting the service specified on TestExchangeII to automatic startup.
Get-Service | Where-Object {$_.DisplayName -like "*Microsoft Exchange Search Host Controller*"} | Set-Service -StartupType Automatic
Get-Service | Where-Object {$_.DisplayName -like "*Microsoft Exchange Search Host Controller*"} | Start-Service
We got another error while connecting to ECP.
A connection couldn’t be made to the Exchange server named TestExchangeII. Verify that the Microsoft Exchange Service Host service is started.
IT turns out I just had to generate a self signed cert in the ECP on TestExchangeII while TestExchange was still running.
BTW, the URLs to connect are
ECP: https://TestExchangeII/ecp
OWA: https://TestExchangeII/owa
I found it best to use Chrome on a domain joined VM to use these.
TestClientIII, our new domain workstation
Speaking of accessing Exchange from a domain joined VM, we setup a Windows 10 Pro domain client named TestClientIII on Hyper-V.
$VMName = "TestClient" ; New-VM -Name $VMName -Path "C:\Hyper-V_VMs\$VMName" -MemoryStartupBytes 8GB -Generation 2
Connect-VMNetworkAdapter -VMName $VMName -Name "Network Adapter" -SwitchName Testing
$vm = Get-Vm -Name $VMName
New-VHD -Path "C:\Hyper-V_VMs\TestClient\TestClient.vhdx" -SizeBytes 200GB
$vm | Add-VMHardDiskDrive -Path "C:\Hyper-V_VMs\TestClient\TestClient.vhdx"
Add-VMDvdDrive -VMName "TestClient" -Path "C:\VM_Stuff_Share\Windows10 from MS x64.iso"
Start-VM -Name "TestClient"
#On the Win10 VM
Add-Computer -DomainName "test.local"
New-Item -Path C:\Temp -ItemType Directory
Set-MpPreference -ExclusionPath C:\Temp
We then copy/pasted the files from \\TestClient\C$\Temp to \\TestClientIII\C$\Temp. These include:
- BloodHound / Neo4j / BlueHound
- John
- Mimikatz
- PowerSploit
- nmap
- Visual Studio
- PowerShell 7
DNS & AD Cleanup
Using the old Entra Connect VM as an example, we remove it’s AD account and DNS record via:
Remove-ADComputer -Identity "TestAADC"
Remove-DnsServerResourceRecord -ZoneName "test.local" -ComputerName BackupDC3 -RRType "A" -Name "TestAADC"
Summary
In the future we are going to de-provision the 2 DCs that are left on ESXi, wipe that server, and install Hyper-V Server on it. We will then provision the DCs TestDC & BackupDC in Hyper-V and start learning how to do VM live migrations. There are some other things we need to learn about availability, redundancy, and so on.
Well that’s another project for another howto. This one has gotten plenty long enough already.
I don’t imagine anyone has actually read the entire thing, it’s more for Ctrl+F while looking for how to do a specific task. I went back over notes I had posted regarding topics like migrating FSMO roles while doing this project, so it helps me. If it helps anyone else out there then I’m flattered.
Time will tell whether Broadcom runs VMware completely into the ground. What I am hearing so far does not sound good for the future of VMware in general. Regardless, we started getting ready to jump ship when we saw the iceberg coming. I wish everyone left on board good luck. They’re going to need it.
References
Moving MS Entra Connect to a new server: https://learn.microsoft.com/en-us/answers/questions/1287797/how-to-migrate-azure-ad-connect-to-a-new-server
https://4sysops.com/archives/migrate-microsoft-entra-connect-azure-ad-connect-to-a-new-server/
Broadcom: https://kicksec.io/broadcom-acquires-vmware/
Generate an answer file for any Windows OS: https://www.windowsafg.com/win10x86_x64_uefi.html
Windows Event Forwarding: https://happycamper84.medium.com/windows-event-forwarding-sacls-5f048f70f63c
Migrate FSMO roles: https://happycamper84.medium.com/transferring-windows-server-roles-to-a-new-server-part-ii-fsmo-d0a84ca85f2
Working with ISOs in Hyper-V: https://www.thomasmaurer.ch/2020/08/add-iso-dvd-drive-to-a-hyper-v-vm-using-powershell/
Migrate Exchange: https://www.techcrafters.com/portal/en/kb/articles/how-to-move-an-existing-exchange-server-to-a-new-computer#Decommissioning_the_old_Exchange_server
Query .NET version installed: https://learn.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed
New-VHD: https://learn.microsoft.com/en-us/powershell/module/hyper-v/new-vhd?view=windowsserver2022-ps
Reddit on Broadcom: https://www.reddit.com/r/vmware/comments/1cmgm4x/called_vmware_support_and_engineer_was_crying/
Connect to Exchange Shell Remotely: https://learn.microsoft.com/en-us/powershell/exchange/connect-to-exchange-servers-using-remote-powershell?view=exchange-ps
Move Exchange mailboxes: https://learn.microsoft.com/en-us/exchange/architecture/mailbox-servers/manage-mailbox-moves?view=exchserver-2019
Migrate Exchange servers: https://www.reddit.com/r/exchangeserver/comments/1amigjr/exchange_migration_from_one_server_to_another/
Hosting DCs in Hyper-V: https://redmondmag.com/articles/2018/02/27/hyper-v-chicken-and-egg.aspx
Exchange mailbox move error fix: https://community.spiceworks.com/t/exchange-2016-to-2019-all-mailbox-move-requests-fail/793199
Get-ExchangeCertificate: https://support.microsoft.com/en-us/topic/you-can-t-access-owa-or-ecp-after-you-install-exchange-server-2016-cu6-88b3fe67-5f97-a8a2-8ed8-70034ff15761