Hi,
if you use some image based technology to deploy your Windows installation, for example SCCM, MDT, Acronis and/or sysprep based, and OpenVPM is already included, the MAC Address of the TAP LAN interface isn’t changed by that way. But a unique MAC Address is requiered if the clients conntects to the same OpenVPN server. If multiple clients have the same MAC Address ping from VPN Clients sometimes fails with error “TTL expired in transit” and the VPN connection is unstable.
This powershellscript sets a MAC Address for each OpenVPN TAP adapter. In detail:
- Creating a Eventlog TAPsetMAC
- Get all instances for TAP Adapters by reading HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\MatchingDeviceID == “tap0901”
- Generate a random MAC Address. Starting with Prefix defined in $sMACPrefix.
- Writing the MAC to each Adapter
- Log the result to the EventLog
######################################################## # Generate a random MAC for all OpenVPN tap LAN interfaces # Michael Albert # 05.04.2013 # License: GPLv2 ######################################################## # HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318} # MatchingDeviceID tap0901 # REG_SZ MAC=00-FF-8F-E3-A1-AE $oRandom=New-Object System.random function fGetRandomMAC([string]$sMACStart){ if($sMACStart.length -ge 0 -and $sMACStart.length -le 11){ for($iLoop=$sMACStart.length; $iLoop -le 11; $iLoop++){ $iChar=$oRandom.Next(16) $sMACStart+=[String]::Format("{0:x}", $iChar).ToUpper() } return($sMACStart) } else{ return $false } } function fConvert2MAC16([string]$sMAC12){ [string]$sMAC16="" if($sMAC12.length -eq 12){ for($iLoop=0;$iLoop -le 11;$iLoop++){ $sMAC16+=$sMAC12.SubString($iLoop,1) if((($iLoop+1) % 2) -eq 0 -and ($iLoop+1) -lt 12){ $sMAC16+="-" } } return $sMAC16 } else{ return $false } } ############################################################################### # Currently not used but defined :-) function fValidMAC([system.string]$sMAC){ $RegExIP=new-object System.Text.RegularExpressions.Regex("^([0-9a-fA-F]{2}\-){5}([0-9a-fA-F]{2})$") return($RegExIP.IsMatch($sMAC)) } ############################################################################### ## MAIN ############################################################################### $sMACPrefix="00FF8F" if(! [System.Diagnostics.EventLog]::SourceExists("TAPsetMAC")){ New-EventLog -Source TAPsetMAC -Log Application } $aTAPAdapter=Get-ChildItem "registry::HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}" -ErrorAction SilentlyContinue |where-object{$_.GetValue("MatchingDeviceID") -eq "tap0901"} foreach($rTAPAdapter in $aTAPAdapter){ # Get-ItemProperty -Path "registry::HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}" if(! ($rTAPAdapter.GetValue("MAC"))){ #$rTAPAdapter #$rTAPAdapter.Name # Get-ItemProperty -Path ("registry::"+$rTAPAdapter.Name) $sMAC=fGetRandomMAC $sMACPrefix if($sMAC16=fConvert2MAC16 $sMAC){ Write-Host -NoNewline "Set MAC of TAP Adaper to" $sMAC16 "..." $Error.Clear() New-ItemProperty -Path ("registry::"+$rTAPAdapter.Name) -Force -Name MAC -PropertyType String -Value $sMAC16|Out-Null if(! $Error){ Write-Host "ok" Write-EventLog -LogName Application -Source TAPsetMAC -EntryType Information -EventID 666 -Message ("TAP LAN Adapter: Altered MAC Address to "+$sMAC16) } else{ Write-EventLog -LogName Application -Source TAPsetMAC -EntryType Warning -EventID 666 -Message ("TAP LAN Adapter: Failed to altered MAC Address to "+$sMAC16) } } } }
Michael
You might also want to automatically run the command:
“C:\Program Files\TAP-Windows\bin\tapinstall.exe” restart tap0901
after mucking with the registry. Otherwise the MAC address change won’t take effect until the next reboot.