DNS names for Hyper-V client machines

So, running a couple of Hyper-V machines, and needing to determine their local IP addresses to connect to them.

As long as the Hyper-V Integration Services are installed (apt-get install hyperv-daemons on Debian-based distributions), PowerShell on the host machine will have access to the IP addresses of the client machine.

Without the Integration Services, PowerShell will not show any IP addresses for the client machine.

Anyway, after making sure the integration services were installed on all the clients, I wrote this little script, which I run in the background, as an Administrator, with Task Scheduler, to keep the Windows hosts file updated: vm_hosts.ps1

You can download it from the above link, or copy/paste it from here:

$ErrorActionPreference = "Stop"
$hosts = "$($env:windir)\System32\drivers\etc\hosts"

while ($true)
{
    Write-Host -ForegroundColor Yellow "Scanning for Virtual Machines"
    $content = Get-Content $hosts
    Get-VM | ForEach-Object `
    {
        $vm = $_
        $regex = '^\s*\S+\s+' + $vm.Name + '$'
        Write-Host -ForegroundColor Magenta "VM: $($vm.Name)"
        $ips = @($vm.NetworkAdapters | Select -ExpandProperty IPAddresses)
        if ($ips.Count)
        {
            $matches = $content | Select-String -Pattern $regex | ForEach-Object { $_.Line } | Out-String
            $wanted = $ips | ForEach-Object { $_ + ' ' + $vm.Name } | Out-String
            if ($matches -ne $wanted)
            {
                $content = ($content | Select-String -Pattern $regex -NotMatch | ForEach-Object { $_.Line } | Out-String).Trim()
                $content += "`n" + $wanted
            }
        }
    }

    $content | Set-Content "${hosts}.tmp"
    if ((Get-FileHash "$hosts").Hash -ne (Get-FileHash "${hosts}.tmp").Hash)
    {
        Move-Item -Path "${hosts}.tmp" -Destination "$hosts" -Force
        Write-Host -ForegroundColor Yellow "Hosts file updated!"
    }

    Write-Host -ForegroundColor DarkGray "Sleeping..."
    Start-Sleep -Seconds 60
    Write-Host
}

In case you’re interested, it’s running as a Scheduled Task, triggering Daily at 00:00, repeated every 5 minutes, for a duration of 1 day, but set to not start another instance if it is already running. This will make sure it is always restarted after 5 minutes if any of the PowerShell commands throw an error, such as when Hyper-V decides to throw up for some reason. The Action is set to start PowerShell.exe with the following arguments:

-WindowStyle Hidden -NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File "C:\custom\vm_hosts.ps1"

Now I can easily connect to my virtual machines whenever I need to, without knowing their IP address.

1 Trackback

Leave a Reply

Your email address will not be published. Required fields are marked *