Dmitry Leskov
 

PowerShell Script to Fix VirtualBox ‘Unidentified Network’ Issue in Windows 7 and Vista

Windows 7 and Vista by default try to detect the type of external network (home/work/public) behind each network adapter. If the detection fails, an “Unidentified Network” entry appears in the Network and Sharing Center. The problem is that Windows makes the worst-case assumption that unidentified = public, and activates the public Windows Firewall profile even if you are at home.

This is exactly what happens when you enable host-only networking in VirtualBox. Fortunately, there is a way to tell Windows that there is in fact no true connection to an external network. Unfortunately, it requires manually editing the registry and disabling/enabling VirtualBox host-only adapters each time you upgrade VirtualBox.

Thijs Kroesbergen has put together a short PowerShell script that unconditionally makes the necessary changes to the registry and reinitializes all VirtualBox adapters. He also points to the more sophisticated script for fixing VMware virtual adapters by Oisin Grehan. To exercise a bit in PowerShell programming, I have taken the latter script and adapted it back to VirtualBox:

# Adaptation of the VMware adapters fix script by Oisin Grehan:
# http://www.nivot.org/post/2008/09/05/VMWareVMNETAdaptersTriggeringPublicProfileForWindowsFirewall.aspx

# see http://msdn2.microsoft.com/en-us/library/bb201634.aspx
#
# *NdisDeviceType
#
# The type of the device. The default value is zero, which indicates a standard
# networking device that connects to a network.
#
# Set *NdisDeviceType to NDIS_DEVICE_TYPE_ENDPOINT (1) if this device is an
# endpoint device and is not a true network interface that connects to a network.
# For example, you must specify NDIS_DEVICE_TYPE_ENDPOINT for devices such as
# smart phones that use a networking infrastructure to communicate to the local
# computer system but do not provide connectivity to an external network.
#
# Usage: run in an elevated shell (vista/longhorn) or as adminstrator (xp/2003).
#
# PS> .\fix-vbox-adapters.ps1

# boilerplate elevation check

$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = new-object Security.Principal.WindowsPrincipal $identity
$elevated = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if (-not $elevated) {
    $error = "Sorry, you need to run this script"
    if ([System.Environment]::OSVersion.Version.Major -gt 5) {
        $error += " in an elevated shell."
    } else {
        $error += " as Administrator."
    }
    throw $error
}

$entryName = '*NdisDeviceType'

$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
    "Set the '$entryName' entry for this adapter to 1."
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
    "Skip this adapter."

$reset = $false

# adapters key
pushd 'hklm:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}'

# ignore and continue on error
dir -ea 0 | % {
    $key = $_.pspath
    $desc = gp $key -name driverdesc -ea 0
    if ($desc.driverdesc -eq "VirtualBox Host-Only Ethernet Adapter") {
        write-host "`nFound adapter: $($desc.driverdesc)" -ForegroundColor White
        $state = "Registry entry '$entryName' "
        $entry = gp $key -name $entryName -ea 0
        if ($entry -eq $null) {
            $value = $null
            $state = $state + "does not exist for this adapter"
        } else {
            $value = $entry.$entryName
            if ($value -eq 1) {
                $state = $state + "already exists and is set to '1'."
            } else {
                $state = $state + "exists, but is set to '$value', not'1'"
            }
        }

        if ($value -eq 1) {
            write-host $state -ForegroundColor White
        } else {
            if ($host.ui.PromptForChoice(
                  $state,
                  "`nDo you want to fix it?`n`n",
                  [Management.Automation.Host.ChoiceDescription[]]@($yes, $no),
                  1) -eq 0) {
                $reset = $true
                write-host ""
                if ($entry -eq $null) {
                    write-host -nonew "Creating $entryName entry ... "
                    $entry = new-itemproperty $key -name $entryName -propertytype dword -value 1 
                    if ($entry.$entryName -eq 1) { write-host " success." } else { write-host " failed." }
                } else {
                    write-host -nonew "Modifying $entryName entry ... "
                    $entry = set-itemproperty $key -name $entryName -value 1
                    if ($entry.$entryName -eq 1) { write-host " success." } else { write-host " failed." }
                }
            }
        } 

        write-host ""
    }
}
popd

if ($reset) {
    # if there were registry changes, disable/enable network adapters

    gwmi win32_networkadapter | ? {$_.name -like "VirtualBox Host-Only Ethernet Adapter*" } | % {

        # disable
        write-host -nonew "Disabling $($_.name) ... "
        $result = $_.Disable()
        if ($result.ReturnValue -eq -0) { write-host " success." } else { write-host " failed." }

        # enable
        write-host -nonew "Enabling $($_.name) ... "
        $result = $_.Enable()
        if ($result.ReturnValue -eq -0) { write-host " success." } else { write-host " failed." }
    }
} else {
    write-host "No registry changes were made." -ForegroundColor White
}

Hint: Issue the following command to check which Windows Firewall profile is currently active:

netsh advfirewall show currentprofile
« | »

Talkback

* Copy This Password *

* Type Or Paste Password Here *