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
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:
/BrianG
is it possible to have this script change the NMEA port and the ublox port at the same time to different port numbers.
Tim, This was the exact purpose of this article. Are you having issues with it?
yes its not doing both I want ublox com3 and sierra nmea com5 , its only doing one or the other, not both
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.