Force a GPS port to a desired Port in Windows 7/8/10.

By | July 15, 2016
Share

Force a GPS port to a desired Port in Windows.

In a recent scenario, I needed to force to the Gobi 5000’s (WWAN) GPS to use COM3 in Windows 7 x64.  Here are the steps I took to accomplish this.  This process was also tested and worked on moving a “u-blox virtual..” to COM, and moving a COM2 device to use COM3.

1. BEFORE your drivers are installed, you must tell the Windows OS that the desired COM port is “In-Use”. I accomplished this by importing the following REG, which sets COM1-5 to “In-Use”:
https://github.com/brianfgonzalez/Scripts/blob/master/COM01-05-InUse.reg

LockoutCOM1-5

2. Reboot the system.

3. Next, Install any/all drivers that may occupy COM ports, incl. Gobi 5000.

4. Lastly, Edit and run the “ForceCOM.ps1” script, and then reboot before usage:
https://github.com/brianfgonzalez/Scripts/blob/master/ForceCOM.ps1

Additional Files:
https://github.com/brianfgonzalez/Scripts/blob/master/SetACL.exe
https://github.com/brianfgonzalez/Scripts/blob/master/subinacl.exe

# Changelog:
# 7/11/2016 - BFG
#	- Changed query to use "Caption" instead of "Name".
#	- Added code to strip " (COM[0-9]{1,2})" from device name using -replace.
#	- Created block of code to update ComDB to set target COMPort to "In-Use".
#	- Added permission change calls inside of function due to issue with permissions editing the Reg.
#	- Replaced regini.exe with SetACL.exe, which worked consistantly for reg perm changes.

#$DeviceName = "Communications Port (COM3)"
$DeviceName = "u-blox Virtual COM Port"
$ComPort = "COM4"


#Grab script directory
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
#Add Administrators to "ENUM" and "COM NAME Arbiter" key parents
Start-Process -FilePath "$scriptPath\SetACL.exe" -ArgumentList @('-on "HKEY_LOCAL_MACHINE\System\CurrentControlSet\ENUM" -ot reg -actn setowner -ownr "n:Administrators"') -Wait -WindowStyle Minimized
Start-Process -FilePath "$scriptPath\subinacl.exe" -ArgumentList @('/subkeyreg "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum" /grant=administrators=f /setowner=administrators') -Wait -WindowStyle Minimized
Start-Process -FilePath "$scriptPath\subinacl.exe" -ArgumentList @('/subkeyreg "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\COM NAME Arbiter" /grant=administrators=f /setowner=administrators') -Wait -WindowStyle Minimized

function Change-ComPort {

 	Param ($Name,$NewPort)

 	#Queries WMI for Device Caption
	#$WMIQuery = 'Select * from Win32_PnPEntity where Descripition = "' + $Name + '"'
	$Device = Get-WmiObject -Class Win32_PnPEntity | Where-Object { $_.Caption -like "*$($Name)*" } 

 	#Execute only if device is present
	if ($Device) {
		
        #Give Permissions to Administrators for desired ENUM key
        Start-Process "$scriptPath\SetACL.exe" @('-on "HKEY_LOCAL_MACHINE\System\CurrentControlSet\ENUM\'+$Device.DeviceID+'" -ot reg -actn setowner -ownr n:Administrators') -Wait -WindowStyle Minimized
        Start-Process "$scriptPath\subinacl.exe" @('/subkeyreg "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\'+$Device.DeviceID+'" /grant=administrators=f /setowner=administrators') -Wait -WindowStyle Minimized
        
		#Get current device info
		$DeviceKey = "HKLM:\SYSTEM\CurrentControlSet\Enum\" + $Device.DeviceID
		$PortKey = "HKLM:\SYSTEM\CurrentControlSet\Enum\" + $Device.DeviceID + "\Device Parameters"
		$Port = get-itemproperty -path $PortKey -Name PortName
		$OldPort = [convert]::ToInt32(($Port.PortName).Replace("COM",""))
		
		#Set new port and update Friendly Name
        $Name = $Name -replace " \(COM[0-9]{1,2}\)", ""
		$FriendlyName = $Name + " (" + $NewPort + ")"
		New-ItemProperty -Path $PortKey -Name "PortName" -PropertyType String -Value $NewPort -Force
		New-ItemProperty -Path $DeviceKey -Name "FriendlyName" -PropertyType String -Value $FriendlyName -Force

 		#Set old Com Port as available
		$Byte = ($OldPort - ($OldPort % 8))/8
		$Bit = 8 - ($OldPort % 8)
		if ($Bit -eq 8) {
			$Bit = 0 
			$Byte = $Byte - 1
		}
		$ComDB = get-itemproperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\COM Name Arbiter" -Name ComDB
		$ComBinaryArray = ([convert]::ToString($ComDB.ComDB[$Byte],2)).ToCharArray()
		while ($ComBinaryArray.Length -ne 8) {
			$ComBinaryArray = ,"0" + $ComBinaryArray
		}
        #Flip bit to 0 for Available
		$ComBinaryArray[$Bit] = "0"
		$ComBinary = [string]::Join("",$ComBinaryArray)
		$ComDB.ComDB[$Byte] = [convert]::ToInt32($ComBinary,2)
		Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\COM Name Arbiter" -Name ComDB -Value ([byte[]]$ComDB.ComDB)

 		#Set the new Com Port from ComDB is set to InUse
		$NewPort = $NewPort.Replace("COM","")
		$Byte = ($NewPort - ($NewPort % 8))/8
		$Bit = 8 - ($NewPort % 8)
		if ($Bit -eq 8) { 
			$Bit = 0 
			$Byte = $Byte - 1
		}
		$ComDB = get-itemproperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\COM Name Arbiter" -Name ComDB
		$ComBinaryArray = ([convert]::ToString($ComDB.ComDB[$Byte],2)).ToCharArray()
		while ($ComBinaryArray.Length -ne 8) {
			$ComBinaryArray = ,"0" + $ComBinaryArray
		}
        #Flip bit to 1 for In-Use
		$ComBinaryArray[$Bit] = "1"
		$ComBinary = [string]::Join("",$ComBinaryArray)
		$ComDB.ComDB[$Byte] = [convert]::ToInt32($ComBinary,2)
		Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\COM Name Arbiter" -Name ComDB -Value ([byte[]]$ComDB.ComDB)
		
	}
}

Change-ComPort $DeviceName $ComPort

If you need a batch to call the Powershell, here is what I used:

Call Force COM

/BrianG

4 thoughts on “Force a GPS port to a desired Port in Windows 7/8/10.

  1. tim

    is it possible to have this script change the NMEA port and the ublox port at the same time to different port numbers.

    Reply
      1. tim

        yes its not doing both I want ublox com3 and sierra nmea com5 , its only doing one or the other, not both

        Reply
  2. Tim

    is there a way to change the ublox and nmea port to different ports in one script. I tried running two copies of the script back to back but that didnt seem to work.

    Reply

Leave a Reply

Your email address will not be published.

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.