USB Enable Selective Suspend

sjbesenski

Member
Joined
Nov 21, 2025
Messages
71
I am looking for a way to programmatically Uncheck Enable Selective Suspend on all USB Serial Ports in device manager. I changed the value of DeviceSelectiveSuspend to 0 in the registry manager but the change doesn't persist over a reboot. I have also changed my power settings to disable USB selective suspend. I cannot get this change to persist any way other than opening device manager going to advanced settings and actually unchecking Enable Selective Suspend in each COM port device. I have a large number of devices and PCs I need to do this for and do not want to manually uncheck this box on every device on every PC. Happy to share photos of everything I have tried in the registry editor that has not worked yet. This is specifically for FTDI devices if that help. Windows 11 Desktop PC.
 
Thanks — I patched your script to use a robust method for building the Device Parameters candidate paths (it searches the Enum tree for the matching node(s) first, then falls back to the constructed path). That avoids the Join-Path System.Object[] error and handles machines where the Enum layout differs.
Save this whole block as Fix-FTDI-FullFlow-Patched.ps1 and run it elevated (Run as Administrator). Use -WhatIf to dry-run.
Key fixes:
  • Look up Enum nodes by InstanceId tail first (so we build string paths, not arrays).
  • Coerce any path pieces to strings and avoid passing arrays to Join-Path.
  • Use $ in interpolated strings where helpful so PowerShell doesn't misparse tokens.
  • Same behavior as before: creates Device Parameters if missing, writes PortName (from FriendlyName or WMI) only if missing, creates selective-suspend DWords only if missing, rescans devices and schedules a 15s reboot if changes were made (abortable with shutdown /a).
Patched script (copy entire file):
Code:
<#
Fix-FTDI-FullFlow-Patched.ps1
- Create Device Parameters if missing, write PortName if missing (from FriendlyName or WMI), and set selective-suspend values only if missing.
- Does NOT change COM assignments.
- Logs to Desktop and rescans/devices + schedules reboot if changes occurred.
Run as Administrator.
#> param( [switch]$WhatIf, # dry run: show actions, do not write or reboot [switch]$NoReboot # suppress scheduling a reboot even if changes were made) # Verify elevation
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) { Write-Error "Script must be run elevated (Run as Administrator). Exiting." exit 1
} $timestamp = (Get-Date).ToString('yyyyMMdd_HHmmss')
$logFile = Join-Path $env:USERPROFILE ("Desktop\FTDI_FullFlow_$timestamp.log")
"Started: $(Get-Date -Format u)" | Out-File -FilePath $logFile -Encoding UTF8 # Helper: detect COM for PnP instance via Win32_SerialPort
function Get-ComForInstance { param([string]$instanceId) try { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -eq $instanceId } if ($sp) { return $sp.DeviceID } # e.g. "COM4" # Tail match fallback $tail = ($instanceId -split '\\')[-1] if ($tail) { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -like "*$tail*" } if ($sp) { return $sp.DeviceID } } } catch { # ignore } return $null
} # Find FTDI COM ports
$ports = Get-PnpDevice -Class Ports -PresentOnly -ErrorAction SilentlyContinue | Where-Object { ($_.Manufacturer -and $_.Manufacturer -like '*FTDI*') -or ($_.InstanceId -and $_.InstanceId -match 'VID_0403') } if (-not $ports -or $ports.Count -eq 0) { "No FTDI COM ports found." | Tee-Object -FilePath $logFile -Append Write-Output "No FTDI COM ports found. See log: $logFile" exit 0
} "Found $($ports.Count) FTDI COM port(s)." | Tee-Object -FilePath $logFile -Append $createdCount = 0
$errors = @ # Pre-cache Enum base for search
$enumBase = 'HKLM:\SYSTEM\CurrentControlSet\Enum' foreach ($p in $ports) { "----" | Tee-Object -FilePath $logFile -Append "Device FriendlyName: $($p.FriendlyName)" | Tee-Object -FilePath $logFile -Append "InstanceId: $($p.InstanceId)" | Tee-Object -FilePath $logFile -Append $inst = $p.InstanceId if ([string]::IsNullOrWhiteSpace($inst) { "InstanceId empty; skipping" | Tee-Object -FilePath $logFile -Append continue } # Find matching Enum node(s) first (more robust than direct string build) $dpCandidates = @ try { $tail = ($inst -split '\\')[-1] # search for nodes that match the instance or the tail (case-insensitive) $matches = Get-ChildItem -Path $enumBase -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.PSPath -match [regex]::Escape($inst) -or ($tail -and ($_.PSPath -match [regex]::Escape($tail) } foreach ($m in $matches) { $nodePath = $m.PSPath # ensure nodePath is a single string $nodePathStr = [string]$nodePath $dpCandidates += Join-Path $nodePathStr 'Device Parameters' $dpCandidates += Join-Path (Join-Path $nodePathStr '0000') 'Device Parameters' } } catch { # ignore search errors, we'll fallback to constructed path } # Fallback: construct the expected path if search didn't find nodes if ($dpCandidates.Count -eq 0) { $parts = $inst -split '\\' $subpath = [string]($parts -join '\') $regPathBase = Join-Path $enumBase $subpath $regPathBase = [string]$regPathBase $dpCandidates += Join-Path $regPathBase 'Device Parameters' $dpCandidates += Join-Path (Join-Path $regPathBase '0000') 'Device Parameters' } $dpFound = $false foreach ($dp in $dpCandidates) { "Checking: $dp" | Tee-Object -FilePath $logFile -Append if (Test-Path $dp) { $dpFound = $true "Using Device Parameters: $dp" | Tee-Object -FilePath $logFile -Append # 1) PortName: write only if missing try { $portVal = $null try { $portVal = (Get-ItemProperty -Path $dp -Name 'PortName' -ErrorAction SilentlyContinue).PortName } catch { $portVal = $null } if ([string]::IsNullOrWhiteSpace($portVal) { # Try FriendlyName first (e.g. "USB Serial Port (COM4)") $friendly = $p.FriendlyName $detectedCom = $null if ($friendly -and ($friendly -match '\(COM(\d+)\)') { $detectedCom = "COM$($matches[1])" "Detected COM from FriendlyName: $detectedCom" | Tee-Object -FilePath $logFile -Append } else { # fallback: WMI lookup $detectedCom = Get-ComForInstance -instanceId $inst if ($detectedCom) { "Detected COM via WMI: $detectedCom" | Tee-Object -FilePath $logFile -Append } } if ($detectedCom) { if ($WhatIf) { "WhatIf: would write PortName = $detectedCom at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } else { try { New-Item -Path $dp -Force | Out-Null New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null "WROTE PortName = $detectedCom at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing PortName at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName write error for $inst : $($_.Exception.Message)" } } } else { "Could not detect COM for $inst; PortName not written." | Tee-Object -FilePath $logFile -Append } } else { "PortName already exists at $($dp): $portVal (no change)" | Tee-Object -FilePath $logFile -Append } } catch { "Error reading/writing PortName at $($dp): $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName error for $inst : $($_.Exception.Message)" } # 2) Ensure selective-suspend properties exist (create only if missing) $props = @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 } foreach ($kv in $props.GetEnumerator { $name = $kv.Key; $val = $kv.Value try { $exists = (Get-ItemProperty -Path $dp -Name $name -ErrorAction SilentlyContinue) -ne $null } catch { $exists = $false } if ($exists) { "$name already present at $($dp) - skipping" | Tee-Object -FilePath $logFile -Append } else { if ($WhatIf) { "WhatIf: would create $name = $val at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } else { try { New-Item -Path $dp -Force | Out-Null New-ItemProperty -Path $dp -Name $name -PropertyType DWord -Value $val -Force -ErrorAction Stop | Out-Null "Created $name = $val at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR creating $name at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create $name error for $inst : $($_.Exception.Message)" } } } } break } else { "Not found: $($dp)" | Tee-Object -FilePath $logFile -Append } } # foreach candidate if (-not $dpFound) { # Create primary Device Parameters and repeat actions $dp = Join-Path $regPathBase 'Device Parameters' "Device Parameters not found - creating $($dp)" | Tee-Object -FilePath $logFile -Append if ($WhatIf) { "WhatIf: would create key $($dp) and attempt writes" | Tee-Object -FilePath $logFile -Append $createdCount++ } else { try { New-Item -Path $dp -Force | Out-Null "Created key $($dp)" | Tee-Object -FilePath $logFile -Append } catch { "ERROR creating key $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create key error for $inst : $($_.Exception.Message)" continue } # Attempt PortName detection/writes as above $detectedCom = $null $friendly = $p.FriendlyName if ($friendly -and ($friendly -match '\(COM(\d+)\)') { $detectedCom = "COM$($matches[1])" } if (-not $detectedCom) { $detectedCom = Get-ComForInstance -instanceId $inst } if ($detectedCom) { try { New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null "WROTE PortName = $detectedCom at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing PortName at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName write error for $inst : $($_.Exception.Message)" } } else { "Could not detect COM for $inst after creating key." | Tee-Object -FilePath $logFile -Append } # create selective-suspend props foreach ($kv in @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }.GetEnumerator { try { New-ItemProperty -Path $dp -Name $kv.Key -PropertyType DWord -Value $kv.Value -Force -ErrorAction Stop | Out-Null "Created $($kv.Key) = $($kv.Value) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR creating $($kv.Key) at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create prop error $($kv.Key) for $inst : $($_.Exception.Message)" } } } }
} # foreach port "Created/changed count: $createdCount" | Tee-Object -FilePath $logFile -Append
if ($errors.Count -gt 0) { "Errors: $($errors.Count)" | Tee-Object -FilePath $logFile -Append; $errors | Tee-Object -FilePath $logFile -Append } # Rescan devices (pnputil /scan-devices) and schedule reboot if changes were made
try { Write-Output "Running device rescan: pnputil /scan-devices" | Tee-Object -FilePath $logFile -Append Start-Process -FilePath 'pnputil.exe' -ArgumentList '/scan-devices' -NoNewWindow -Wait
} catch { "pnputil failed: $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
} if (($createdCount -gt 0) -and (-not $WhatIf) -and (-not $NoReboot) { "Scheduling reboot in 15 seconds so changes take effect (abort with 'shutdown /a')." | Tee-Object -FilePath $logFile -Append Start-Process -FilePath 'shutdown.exe' -ArgumentList @('/r','/t','15','/c','Applying FTDI Device Parameter changes') -NoNewWindow
} else { "No reboot scheduled. If you created properties and want immediate recognition, run: pnputil /scan-devices or reboot manually." | Tee-Object -FilePath $logFile -Append
} "Completed: $(Get-Date -Format u)" | Tee-Object -FilePath $logFile -Append
Write-Output "Done. Log saved to: $logFile"
How to run
  • Save as Fix-FTDI-FullFlow-Patched.ps1
  • Dry run:
    PowerShell -ExecutionPolicy Bypass -File "C:\Users\<you>\Documents\Fix-FTDI-FullFlow-Patched.ps1" -WhatIf
  • Apply:
    PowerShell -ExecutionPolicy Bypass -File "C:\Users\<you>\Documents\Fix-FTDI-FullFlow-Patched.ps1"
If you run it and still see any errors, paste the exact console error and the final 40 lines of the log file (the path printed at the end) and I’ll fix the remaining edge case immediately.
 
At C:\Users\kioskuser2\Documents\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1:60 char:24
+ foreach ($p in $ports) {
+ ~
Missing closing '}' in statement block or type definition.
+ CategoryInfo : ParserError: ) [], ParseException
+ FullyQualifiedErrorId : MissingEndCurlyBrace
 
Thanks — that parser error means PowerShell found an unmatched brace in the file you executed. I’ve done a careful pass and produced a fully balanced, cleaned script you can save and run. Please overwrite the file you were running (Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1) with the text below, then run the dry run first.
Also before running, you can do a quick parse-only check (won’t execute) to confirm the file has valid PowerShell syntax:
powershell -NoProfile -Command "[scriptblock]::Create((Get-Content -Raw 'C:\Users\kioskuser2\Documents\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1')"
If that command returns no error, the script parses. Then run the dry run:
powershell -ExecutionPolicy Bypass -File "C:\Users\kioskuser2\Documents\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1" -WhatIf
Now save this exact script (replace your file) and run it elevated:
Code:
<#
Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1
- Creates Device Parameters if missing, writes PortName (from FriendlyName or WMI) if missing, and creates selective-suspend values only if missing.
- Does NOT change actual COM assignment.
- Logs to Desktop and rescans devices; schedules a 15s reboot if changes were made (abort with shutdown /a).
Run as Administrator. Use -WhatIf to dry-run.
#> param( [switch]$WhatIf, [switch]$NoReboot) # require elevation
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) { Write-Error "Run this script elevated (Run as Administrator). Exiting." exit 1
} $timestamp = (Get-Date).ToString('yyyyMMdd_HHmmss')
$logFile = Join-Path $env:USERPROFILE ("Desktop\FTDI_ApplyIfMissing_WithPortName_$timestamp.log")
"Started: $(Get-Date -Format u)" | Out-File -FilePath $logFile -Encoding UTF8 function Get-ComForInstance { param([string]$instanceId) try { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -eq $instanceId } if ($sp) { return $sp.DeviceID } $tail = ($instanceId -split '\\')[-1] if ($tail) { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -like "*$tail*" } if ($sp) { return $sp.DeviceID } } } catch { } return $null
} # Find FTDI ports
$ports = Get-PnpDevice -Class Ports -PresentOnly -ErrorAction SilentlyContinue | Where-Object { ($_.Manufacturer -and $_.Manufacturer -like '*FTDI*') -or ($_.InstanceId -and $_.InstanceId -match 'VID_0403') } if (-not $ports -or $ports.Count -eq 0) { "No FTDI COM ports found." | Tee-Object -FilePath $logFile -Append Write-Output "No FTDI COM ports found. See log: $logFile" exit 0
} "Found $($ports.Count) FTDI COM port(s)." | Tee-Object -FilePath $logFile -Append $createdCount = 0
$errors = @
$enumBase = 'HKLM:\SYSTEM\CurrentControlSet\Enum' foreach ($p in $ports) { "----" | Tee-Object -FilePath $logFile -Append "Device FriendlyName: $($p.FriendlyName)" | Tee-Object -FilePath $logFile -Append "InstanceId: $($p.InstanceId)" | Tee-Object -FilePath $logFile -Append $inst = $p.InstanceId if ([string]::IsNullOrWhiteSpace($inst) { "InstanceId empty; skipping" | Tee-Object -FilePath $logFile -Append continue } # Build candidate Device Parameters paths (search Enum first to avoid array/join issues) $dpCandidates = @ try { $tail = ($inst -split '\\')[-1] $matches = Get-ChildItem -Path $enumBase -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.PSPath -match [regex]::Escape($inst) -or ($tail -and ($_.PSPath -match [regex]::Escape($tail) } foreach ($m in $matches) { $node = [string]$m.PSPath $dpCandidates += Join-Path $node 'Device Parameters' $dpCandidates += Join-Path (Join-Path $node '0000') 'Device Parameters' } } catch { # fallback handled below } if ($dpCandidates.Count -eq 0) { $parts = $inst -split '\\' $subpath = [string]($parts -join '\') $regPathBase = Join-Path $enumBase $subpath $regPathBase = [string]$regPathBase $dpCandidates += Join-Path $regPathBase 'Device Parameters' $dpCandidates += Join-Path (Join-Path $regPathBase '0000') 'Device Parameters' } $dpFound = $false foreach ($dp in $dpCandidates) { "Checking: $dp" | Tee-Object -FilePath $logFile -Append if (Test-Path $dp) { $dpFound = $true "Using Device Parameters: $dp" | Tee-Object -FilePath $logFile -Append # PortName - create only if missing try { $portVal = $null try { $portVal = (Get-ItemProperty -Path $dp -Name 'PortName' -ErrorAction SilentlyContinue).PortName } catch { $portVal = $null } if ([string]::IsNullOrWhiteSpace($portVal) { $friendly = $p.FriendlyName $detectedCom = $null if ($friendly -and ($friendly -match '\(COM(\d+)\)') { $detectedCom = "COM$($matches[1])" "Detected COM from FriendlyName: $detectedCom" | Tee-Object -FilePath $logFile -Append } else { $detectedCom = Get-ComForInstance -instanceId $inst if ($detectedCom) { "Detected COM via WMI: $detectedCom" | Tee-Object -FilePath $logFile -Append } } if ($detectedCom) { if ($WhatIf) { "WhatIf: would write PortName = $detectedCom at $dp" | Tee-Object -FilePath $logFile -Append $createdCount++ } else { try { New-Item -Path $dp -Force | Out-Null New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null "WROTE PortName = $detectedCom at $dp" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing PortName at $dp : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName write error for $inst : $($_.Exception.Message)" } } } else { "Could not detect COM for $inst; PortName not written." | Tee-Object -FilePath $logFile -Append } } else { "PortName already exists at $dp: $portVal (no change)" | Tee-Object -FilePath $logFile -Append } } catch { "Error reading/writing PortName at $dp: $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName error for $inst : $($_.Exception.Message)" } # selective-suspend props (create only if missing) $props = @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 } foreach ($kv in $props.GetEnumerator { $name = $kv.Key; $val = $kv.Value try { $exists = (Get-ItemProperty -Path $dp -Name $name -ErrorAction SilentlyContinue) -ne $null } catch { $exists = $false } if ($exists) { "$name already present at $dp - skipping" | Tee-Object -FilePath $logFile -Append } else { if ($WhatIf) { "WhatIf: would create $name = $val at $dp" | Tee-Object -FilePath $logFile -Append $createdCount++ } else { try { New-Item -Path $dp -Force | Out-Null New-ItemProperty -Path $dp -Name $name -PropertyType DWord -Value $val -Force -ErrorAction Stop | Out-Null "Created $name = $val at $dp" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR creating $name at $dp : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create $name error for $inst : $($_.Exception.Message)" } } } } break } else { "Not found: $dp" | Tee-Object -FilePath $logFile -Append } } # end foreach dpCandidates if (-not $dpFound) { # Create primary Device Parameters and repeat actions $parts = $inst -split '\\' $subpath = [string]($parts -join '\') $regPathBase = Join-Path $enumBase $subpath $dp = Join-Path $regPathBase 'Device Parameters' "Device Parameters not found - creating $dp" | Tee-Object -FilePath $logFile -Append if ($WhatIf) { "WhatIf: would create key $dp and attempt writes" | Tee-Object -FilePath $logFile -Append $createdCount++ } else { try { New-Item -Path $dp -Force | Out-Null "Created key $dp" | Tee-Object -FilePath $logFile -Append } catch { "ERROR creating key $dp : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create key error for $inst : $($_.Exception.Message)" continue } # PortName detection and writes $detectedCom = $null $friendly = $p.FriendlyName if ($friendly -and ($friendly -match '\(COM(\d+)\)') { $detectedCom = "COM$($matches[1])" } if (-not $detectedCom) { $detectedCom = Get-ComForInstance -instanceId $inst } if ($detectedCom) { try { New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null "WROTE PortName = $detectedCom at $dp" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing PortName at $dp : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName write error for $inst : $($_.Exception.Message)" } } else { "Could not detect COM for $inst after creating key." | Tee-Object -FilePath $logFile -Append } # create selective-suspend props foreach ($kv in @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }.GetEnumerator { try { New-ItemProperty -Path $dp -Name $kv.Key -PropertyType DWord -Value $kv.Value -Force -ErrorAction Stop | Out-Null "Created $($kv.Key) = $($kv.Value) at $dp" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR creating $($kv.Key) at $dp : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create prop error $($kv.Key) for $inst : $($_.Exception.Message)" } } } } } # end foreach ports "Created/changed count: $createdCount" | Tee-Object -FilePath $logFile -Append
if ($errors.Count -gt 0) { "Errors: $($errors.Count)" | Tee-Object -FilePath $logFile -Append; $errors | Tee-Object -FilePath $logFile -Append } # Rescan devices
try { "Running device rescan: pnputil /scan-devices" | Tee-Object -FilePath $logFile -Append Start-Process -FilePath 'pnputil.exe' -ArgumentList '/scan-devices' -NoNewWindow -Wait
} catch { "pnputil failed: $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
} if (($createdCount -gt 0) -and (-not $WhatIf) -and (-not $NoReboot) { "Scheduling reboot in 15 seconds so changes take effect (abort with 'shutdown /a')." | Tee-Object -FilePath $logFile -Append Start-Process -FilePath 'shutdown.exe' -ArgumentList @('/r','/t','15','/c','Applying FTDI Device Parameter changes') -NoNewWindow
} else { "No reboot scheduled. If you created properties and want immediate recognition, run: pnputil /scan-devices or reboot manually." | Tee-Object -FilePath $logFile -Append
} "Completed: $(Get-Date -Format u)" | Tee-Object -FilePath $logFile -Append
Write-Output "Done. Log saved to: $logFile"
If you still get a parser error after saving and running this file, paste the exact error text and tell me the exact command you used to run it — I’ll debug the remaining issue immediately.
 
At C:\Users\kioskuser2\Documents\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1:135 char:39
+ "PortName already exists at $dp: $portVal (no change)" | Te ...
+ ~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using ${} to
delimit the name.
At C:\Users\kioskuser2\Documents\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1:138 char:44
+ "Error reading/writing PortName at $dp: $($_.Exception.Messag ...
+ ~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using ${} to
delimit the name.
+ CategoryInfo : ParserError: ) [], ParseException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive
 
The error is because PowerShell sees "$dp:" inside a double‑quoted string and tries to parse "$dp:" as a single variable name. Quick fix: delimit the variable before the colon — use $($dp) (or ${dp}). I'll give you a safe automated patch you can run (no manual editing), then show how to check the script parses and run a dry run.
1) Auto‑patch the file (run this in an elevated PowerShell)
This replaces occurrences of "$dp:" with "$($dp):" in your script file.
Run exactly (in an elevated PowerShell):
$file = 'C:\Users\kioskuser2\Documents\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1'
(Get-Content -Raw $file) -replace '\$dp:', '$($dp):' | Set-Content $file -Encoding UTF8
Write-Output "Patched $file"
2) Quick parse check (doesn't execute the script)
Run this to ensure the script is syntactically valid:
powershell -NoProfile -Command "[scriptblock]::Create((Get-Content -Raw 'C:\Users\kioskuser2\Documents\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1'); Write-Output 'Parse OK'"
If you see "Parse OK", the file is syntactically valid.
3) Dry run (no writes, no reboot)
If parse OK, run the script in WhatIf mode first:
PowerShell -ExecutionPolicy Bypass -File "C:\Users\kioskuser2\Documents\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1" -WhatIf
4) Run for real (if dry run looks good)
Run the script (this may create keys and schedule a reboot):
PowerShell -ExecutionPolicy Bypass -File "C:\Users\kioskuser2\Documents\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1"
If you want to avoid an automatic reboot, add -NoReboot when running.
If anything still errors, paste the new console error and the last ~40 lines of the script log (the path printed at the end), and I’ll fix the remaining issues.
 
apply fix to this script

<#
Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1
- Creates Device Parameters if missing, writes PortName (from FriendlyName or WMI) if missing,
and creates selective-suspend values only if missing.
- Does NOT change actual COM assignment.
- Logs to Desktop and rescans devices; schedules a 15s reboot if changes were made (abort with shutdown /a).
Run as Administrator. Use -WhatIf to dry-run.
#>

param(
[switch]$WhatIf,
[switch]$NoReboot
)

# require elevation
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)) {
Write-Error "Run this script elevated (Run as Administrator). Exiting."
exit 1
}

$timestamp = (Get-Date).ToString('yyyyMMdd_HHmmss')
$logFile = Join-Path $env:USERPROFILE ("Desktop\FTDI_ApplyIfMissing_WithPortName_$timestamp.log")
"Started: $(Get-Date -Format u)" | Out-File -FilePath $logFile -Encoding UTF8

function Get-ComForInstance {
param([string]$instanceId)
try {
$sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue |
Where-Object { $_.PNPDeviceID -eq $instanceId }
if ($sp) { return $sp.DeviceID }
$tail = ($instanceId -split '\\')[-1]
if ($tail) {
$sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue |
Where-Object { $_.PNPDeviceID -like "*$tail*" }
if ($sp) { return $sp.DeviceID }
}
} catch { }
return $null
}

# Find FTDI ports
$ports = Get-PnpDevice -Class Ports -PresentOnly -ErrorAction SilentlyContinue |
Where-Object { ($_.Manufacturer -and $_.Manufacturer -like '*FTDI*') -or ($_.InstanceId -and $_.InstanceId -match 'VID_0403') }

if (-not $ports -or $ports.Count -eq 0) {
"No FTDI COM ports found." | Tee-Object -FilePath $logFile -Append
Write-Output "No FTDI COM ports found. See log: $logFile"
exit 0
}

"Found $($ports.Count) FTDI COM port(s)." | Tee-Object -FilePath $logFile -Append

$createdCount = 0
$errors = @()
$enumBase = 'HKLM:\SYSTEM\CurrentControlSet\Enum'

foreach ($p in $ports) {
"----" | Tee-Object -FilePath $logFile -Append
"Device FriendlyName: $($p.FriendlyName)" | Tee-Object -FilePath $logFile -Append
"InstanceId: $($p.InstanceId)" | Tee-Object -FilePath $logFile -Append

$inst = $p.InstanceId
if ([string]::IsNullOrWhiteSpace($inst)) {
"InstanceId empty; skipping" | Tee-Object -FilePath $logFile -Append
continue
}

# Build candidate Device Parameters paths (search Enum first to avoid array/join issues)
$dpCandidates = @()
try {
$tail = ($inst -split '\\')[-1]
$matches = Get-ChildItem -Path $enumBase -Recurse -ErrorAction SilentlyContinue |
Where-Object { $_.PSPath -match [regex]::Escape($inst) -or ($tail -and ($_.PSPath -match [regex]::Escape($tail))) }
foreach ($m in $matches) {
$node = [string]$m.PSPath
$dpCandidates += Join-Path $node 'Device Parameters'
$dpCandidates += Join-Path (Join-Path $node '0000') 'Device Parameters'
}
} catch {
# fallback handled below
}

if ($dpCandidates.Count -eq 0) {
$parts = $inst -split '\\'
$subpath = [string]($parts -join '\')
$regPathBase = Join-Path $enumBase $subpath
$regPathBase = [string]$regPathBase
$dpCandidates += Join-Path $regPathBase 'Device Parameters'
$dpCandidates += Join-Path (Join-Path $regPathBase '0000') 'Device Parameters'
}

$dpFound = $false

foreach ($dp in $dpCandidates) {
"Checking: $dp" | Tee-Object -FilePath $logFile -Append
if (Test-Path $dp) {
$dpFound = $true
"Using Device Parameters: $dp" | Tee-Object -FilePath $logFile -Append

# PortName - create only if missing
try {
$portVal = $null
try { $portVal = (Get-ItemProperty -Path $dp -Name 'PortName' -ErrorAction SilentlyContinue).PortName } catch { $portVal = $null }

if ([string]::IsNullOrWhiteSpace($portVal)) {
$friendly = $p.FriendlyName
$detectedCom = $null
if ($friendly -and ($friendly -match '\(COM(\d+)\)')) {
$detectedCom = "COM$($matches[1])"
"Detected COM from FriendlyName: $detectedCom" | Tee-Object -FilePath $logFile -Append
} else {
$detectedCom = Get-ComForInstance -instanceId $inst
if ($detectedCom) { "Detected COM via WMI: $detectedCom" | Tee-Object -FilePath $logFile -Append }
}

if ($detectedCom) {
if ($WhatIf) {
"WhatIf: would write PortName = $detectedCom at $dp" | Tee-Object -FilePath $logFile -Append
$createdCount++
} else {
try {
New-Item -Path $dp -Force | Out-Null
New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null
"WROTE PortName = $detectedCom at $dp" | Tee-Object -FilePath $logFile -Append
$createdCount++
} catch {
"ERROR writing PortName at $dp : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "PortName write error for $inst : $($_.Exception.Message)"
}
}
} else {
"Could not detect COM for $inst; PortName not written." | Tee-Object -FilePath $logFile -Append
}
} else {
"PortName already exists at $($dp): $portVal (no change)" | Tee-Object -FilePath $logFile -Append
}
} catch {
"Error reading/writing PortName at $($dp): $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "PortName error for $inst : $($_.Exception.Message)"
}

# selective-suspend props (create only if missing)
$props = @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }
foreach ($kv in $props.GetEnumerator()) {
$name = $kv.Key; $val = $kv.Value
try {
$exists = (Get-ItemProperty -Path $dp -Name $name -ErrorAction SilentlyContinue) -ne $null
} catch { $exists = $false }

if ($exists) {
"$name already present at $dp - skipping" | Tee-Object -FilePath $logFile -Append
} else {
if ($WhatIf) {
"WhatIf: would create $name = $val at $dp" | Tee-Object -FilePath $logFile -Append
$createdCount++
} else {
try {
New-Item -Path $dp -Force | Out-Null
New-ItemProperty -Path $dp -Name $name -PropertyType DWord -Value $val -Force -ErrorAction Stop | Out-Null
"Created $name = $val at $dp" | Tee-Object -FilePath $logFile -Append
$createdCount++
} catch {
"ERROR creating $name at $dp : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "Create $name error for $inst : $($_.Exception.Message)"
}
}
}
}

break
} else {
"Not found: $dp" | Tee-Object -FilePath $logFile -Append
}
} # end foreach dpCandidates

if (-not $dpFound) {
# Create primary Device Parameters and repeat actions
$parts = $inst -split '\\'
$subpath = [string]($parts -join '\')
$regPathBase = Join-Path $enumBase $subpath
$dp = Join-Path $regPathBase 'Device Parameters'
"Device Parameters not found - creating $dp" | Tee-Object -FilePath $logFile -Append

if ($WhatIf) {
"WhatIf: would create key $dp and attempt writes" | Tee-Object -FilePath $logFile -Append
$createdCount++
} else {
try {
New-Item -Path $dp -Force | Out-Null
"Created key $dp" | Tee-Object -FilePath $logFile -Append
} catch {
"ERROR creating key $dp : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "Create key error for $inst : $($_.Exception.Message)"
continue
}

# PortName detection and writes
$detectedCom = $null
$friendly = $p.FriendlyName
if ($friendly -and ($friendly -match '\(COM(\d+)\)')) { $detectedCom = "COM$($matches[1])" }
if (-not $detectedCom) { $detectedCom = Get-ComForInstance -instanceId $inst }

if ($detectedCom) {
try {
New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null
"WROTE PortName = $detectedCom at $dp" | Tee-Object -FilePath $logFile -Append
$createdCount++
} catch {
"ERROR writing PortName at $dp : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "PortName write error for $inst : $($_.Exception.Message)"
}
} else {
"Could not detect COM for $inst after creating key." | Tee-Object -FilePath $logFile -Append
}

# create selective-suspend props
foreach ($kv in @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }.GetEnumerator()) {
try {
New-ItemProperty -Path $dp -Name $kv.Key -PropertyType DWord -Value $kv.Value -Force -ErrorAction Stop | Out-Null
"Created $($kv.Key) = $($kv.Value) at $dp" | Tee-Object -FilePath $logFile -Append
$createdCount++
} catch {
"ERROR creating $($kv.Key) at $dp : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "Create prop error $($kv.Key) for $inst : $($_.Exception.Message)"
}
}
}
}

} # end foreach ports

"Created/changed count: $createdCount" | Tee-Object -FilePath $logFile -Append
if ($errors.Count -gt 0) { "Errors: $($errors.Count)" | Tee-Object -FilePath $logFile -Append; $errors | Tee-Object -FilePath $logFile -Append }

# Rescan devices
try {
"Running device rescan: pnputil /scan-devices" | Tee-Object -FilePath $logFile -Append
Start-Process -FilePath 'pnputil.exe' -ArgumentList '/scan-devices' -NoNewWindow -Wait
} catch {
"pnputil failed: $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
}

if (($createdCount -gt 0) -and (-not $WhatIf) -and (-not $NoReboot)) {
"Scheduling reboot in 15 seconds so changes take effect (abort with 'shutdown /a')." | Tee-Object -FilePath $logFile -Append
Start-Process -FilePath 'shutdown.exe' -ArgumentList @('/r','/t','15','/c','Applying FTDI Device Parameter changes') -NoNewWindow
} else {
"No reboot scheduled. If you created properties and want immediate recognition, run: pnputil /scan-devices or reboot manually." | Tee-Object -FilePath $logFile -Append
}

"Completed: $(Get-Date -Format u)" | Tee-Object -FilePath $logFile -Append
Write-Output "Done. Log saved to: $logFile"
 
Thanks — I patched the interpolation issues and a few other places so the script parses cleanly. Save the block below over your current Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1, then run a dry run first (-WhatIf), then run for real if output looks correct.
Key fixes I applied
  • Replaced "$dp:" / "$($dp):" occurrences so PowerShell doesn’t try to parse "$dp:" as a variable name.
  • Ensured all Join-Path calls receive string arguments (no arrays).
  • Kept behavior unchanged: only creates missing Device Parameters keys and properties, does not change COM assignments, writes PortName from FriendlyName or WMI if missing, logs to Desktop, rescans devices and schedules a 15s reboot only if changes were made.
Save this as Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1 and run elevated.
Script (copy whole file and save as .ps1):
Code:
<#
Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1
- Creates Device Parameters if missing, writes PortName (from FriendlyName or WMI) if missing, and creates selective-suspend values only if missing.
- Does NOT change actual COM assignment.
- Logs to Desktop and rescans devices; schedules a 15s reboot if changes were made (abort with shutdown /a).
Run as Administrator. Use -WhatIf to dry-run.
#> param( [switch]$WhatIf, [switch]$NoReboot) # require elevation
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) { Write-Error "Run this script elevated (Run as Administrator). Exiting." exit 1
} $timestamp = (Get-Date).ToString('yyyyMMdd_HHmmss')
$logFile = Join-Path $env:USERPROFILE ("Desktop\FTDI_ApplyIfMissing_WithPortName_$timestamp.log")
"Started: $(Get-Date -Format u)" | Out-File -FilePath $logFile -Encoding UTF8 function Get-ComForInstance { param([string]$instanceId) try { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -eq $instanceId } if ($sp) { return $sp.DeviceID } $tail = ($instanceId -split '\\')[-1] if ($tail) { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -like "*$tail*" } if ($sp) { return $sp.DeviceID } } } catch { } return $null
} # Find FTDI ports
$ports = Get-PnpDevice -Class Ports -PresentOnly -ErrorAction SilentlyContinue | Where-Object { ($_.Manufacturer -and $_.Manufacturer -like '*FTDI*') -or ($_.InstanceId -and $_.InstanceId -match 'VID_0403') } if (-not $ports -or $ports.Count -eq 0) { "No FTDI COM ports found." | Tee-Object -FilePath $logFile -Append Write-Output "No FTDI COM ports found. See log: $logFile" exit 0
} "Found $($ports.Count) FTDI COM port(s)." | Tee-Object -FilePath $logFile -Append $createdCount = 0
$errors = @
$enumBase = 'HKLM:\SYSTEM\CurrentControlSet\Enum' foreach ($p in $ports) { "----" | Tee-Object -FilePath $logFile -Append "Device FriendlyName: $($p.FriendlyName)" | Tee-Object -FilePath $logFile -Append "InstanceId: $($p.InstanceId)" | Tee-Object -FilePath $logFile -Append $inst = $p.InstanceId if ([string]::IsNullOrWhiteSpace($inst) { "InstanceId empty; skipping" | Tee-Object -FilePath $logFile -Append continue } # Build candidate Device Parameters paths (search Enum first to avoid array/join issues) $dpCandidates = @ try { $tail = ($inst -split '\\')[-1] $matches = Get-ChildItem -Path $enumBase -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.PSPath -match [regex]::Escape($inst) -or ($tail -and ($_.PSPath -match [regex]::Escape($tail) } foreach ($m in $matches) { $node = [string]$m.PSPath $dpCandidates += Join-Path $node 'Device Parameters' $dpCandidates += Join-Path (Join-Path $node '0000') 'Device Parameters' } } catch { # fallback handled below } if ($dpCandidates.Count -eq 0) { $parts = $inst -split '\\' $subpath = [string]($parts -join '\') $regPathBase = Join-Path $enumBase $subpath $regPathBase = [string]$regPathBase $dpCandidates += Join-Path $regPathBase 'Device Parameters' $dpCandidates += Join-Path (Join-Path $regPathBase '0000') 'Device Parameters' } $dpFound = $false foreach ($dp in $dpCandidates) { "Checking: $dp" | Tee-Object -FilePath $logFile -Append if (Test-Path $dp) { $dpFound = $true "Using Device Parameters: $($dp)" | Tee-Object -FilePath $logFile -Append # PortName - create only if missing try { $portVal = $null try { $portVal = (Get-ItemProperty -Path $dp -Name 'PortName' -ErrorAction SilentlyContinue).PortName } catch { $portVal = $null } if ([string]::IsNullOrWhiteSpace($portVal) { $friendly = $p.FriendlyName $detectedCom = $null if ($friendly -and ($friendly -match '\(COM(\d+)\)') { $detectedCom = "COM$($matches[1])" "Detected COM from FriendlyName: $($detectedCom)" | Tee-Object -FilePath $logFile -Append } else { $detectedCom = Get-ComForInstance -instanceId $inst if ($detectedCom) { "Detected COM via WMI: $($detectedCom)" | Tee-Object -FilePath $logFile -Append } } if ($detectedCom) { if ($WhatIf) { "WhatIf: would write PortName = $($detectedCom) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } else { try { New-Item -Path $dp -Force | Out-Null New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null "WROTE PortName = $($detectedCom) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing PortName at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName write error for $inst : $($_.Exception.Message)" } } } else { "Could not detect COM for $inst; PortName not written." | Tee-Object -FilePath $logFile -Append } } else { "PortName already exists at $($dp): $($portVal) (no change)" | Tee-Object -FilePath $logFile -Append } } catch { "Error reading/writing PortName at $($dp): $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName error for $inst : $($_.Exception.Message)" } # selective-suspend props (create only if missing) $props = @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 } foreach ($kv in $props.GetEnumerator { $name = $kv.Key; $val = $kv.Value try { $exists = (Get-ItemProperty -Path $dp -Name $name -ErrorAction SilentlyContinue) -ne $null } catch { $exists = $false } if ($exists) { "$($name) already present at $($dp) - skipping" | Tee-Object -FilePath $logFile -Append } else { if ($WhatIf) { "WhatIf: would create $($name) = $($val) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } else { try { New-Item -Path $dp -Force | Out-Null New-ItemProperty -Path $dp -Name $name -PropertyType DWord -Value $val -Force -ErrorAction Stop | Out-Null "Created $($name) = $($val) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR creating $($name) at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create $($name) error for $inst : $($_.Exception.Message)" } } } } break } else { "Not found: $($dp)" | Tee-Object -FilePath $logFile -Append } } # end foreach dpCandidates if (-not $dpFound) { # Create primary Device Parameters and repeat actions $parts = $inst -split '\\' $subpath = [string]($parts -join '\') $regPathBase = Join-Path $enumBase $subpath $dp = Join-Path $regPathBase 'Device Parameters' "Device Parameters not found - creating $($dp)" | Tee-Object -FilePath $logFile -Append if ($WhatIf) { "WhatIf: would create key $($dp) and attempt writes" | Tee-Object -FilePath $logFile -Append $createdCount++ } else { try { New-Item -Path $dp -Force | Out-Null "Created key $($dp)" | Tee-Object -FilePath $logFile -Append } catch { "ERROR creating key $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create key error for $inst : $($_.Exception.Message)" continue } # PortName detection and writes $detectedCom = $null $friendly = $p.FriendlyName if ($friendly -and ($friendly -match '\(COM(\d+)\)') { $detectedCom = "COM$($matches[1])" } if (-not $detectedCom) { $detectedCom = Get-ComForInstance -instanceId $inst } if ($detectedCom) { try { New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null "WROTE PortName = $($detectedCom) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing PortName at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName write error for $inst : $($_.Exception.Message)" } } else { "Could not detect COM for $inst after creating key." | Tee-Object -FilePath $logFile -Append } # create selective-suspend props foreach ($kv in @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }.GetEnumerator { try { New-ItemProperty -Path $dp -Name $kv.Key -PropertyType DWord -Value $kv.Value -Force -ErrorAction Stop | Out-Null "Created $($kv.Key) = $($kv.Value) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR creating $($kv.Key) at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create prop error $($kv.Key) for $inst : $($_.Exception.Message)" } } } } } # end foreach ports "Created/changed count: $createdCount" | Tee-Object -FilePath $logFile -Append
if ($errors.Count -gt 0) { "Errors: $($errors.Count)" | Tee-Object -FilePath $logFile -Append; $errors | Tee-Object -FilePath $logFile -Append } # Rescan devices
try { "Running device rescan: pnputil /scan-devices" | Tee-Object -FilePath $logFile -Append Start-Process -FilePath 'pnputil.exe' -ArgumentList '/scan-devices' -NoNewWindow -Wait
} catch { "pnputil failed: $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
} if (($createdCount -gt 0) -and (-not $WhatIf) -and (-not $NoReboot) { "Scheduling reboot in 15 seconds so changes take effect (abort with 'shutdown /a')." | Tee-Object -FilePath $logFile -Append Start-Process -FilePath 'shutdown.exe' -ArgumentList @('/r','/t','15','/c','Applying FTDI Device Parameter changes') -NoNewWindow
} else { "No reboot scheduled. If you created properties and want immediate recognition, run: pnputil /scan-devices or reboot manually." | Tee-Object -FilePath $logFile -Append
} "Completed: $(Get-Date -Format u)" | Tee-Object -FilePath $logFile -Append
Write-Output "Done. Log saved to: $logFile"
 
Found 12 FTDI COM port(s).
----
Device FriendlyName: USB Serial Port (COM4)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5SA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM4
WhatIf: would write PortName = COM4 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM7)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5LA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM7
WhatIf: would write PortName = COM7 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM12)
InstanceId: FTDIBUS\VID_0403+PID_6001+A9009WEMA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM12
WhatIf: would write PortName = COM12 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM2)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5XA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM2
WhatIf: would write PortName = COM2 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM10)
InstanceId: FTDIBUS\VID_0403+PID_6001+A10LY4Z7A\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM10
WhatIf: would write PortName = COM10 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM8)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5KA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM8
WhatIf: would write PortName = COM8 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM1)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5WA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM1
WhatIf: would write PortName = COM1 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM11)
InstanceId: FTDIBUS\VID_0403+PID_6001+LW9O7PCGA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM11
WhatIf: would write PortName = COM11 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM3)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5PA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM3
WhatIf: would write PortName = COM3 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM14)
InstanceId: FTDIBUS\VID_0403+PID_6014+FT78J2CLA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM14
WhatIf: would write PortName = COM14 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM6)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5OA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM6
WhatIf: would write PortName = COM6 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM5)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5TA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM5
WhatIf: would write PortName = COM5 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
WhatIf: would create DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created/changed count: 60
Running device rescan: pnputil /scan-devices
Microsoft PnP Utility

PS C:\Users\kioskuser2\Documents> ^C
PS C:\Users\kioskuser2\Documents> ^C
PS C:\Users\kioskuser2\Documents> .\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1
Found 12 FTDI COM port(s).
----
Device FriendlyName: USB Serial Port (COM4)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5SA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM4
WROTE PortName = COM4 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM7)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5LA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM7
WROTE PortName = COM7 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM12)
InstanceId: FTDIBUS\VID_0403+PID_6001+A9009WEMA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM12
WROTE PortName = COM12 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM2)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5XA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM2
WROTE PortName = COM2 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM10)
InstanceId: FTDIBUS\VID_0403+PID_6001+A10LY4Z7A\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM10
WROTE PortName = COM10 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM8)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5KA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM8
WROTE PortName = COM8 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM1)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5WA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM1
WROTE PortName = COM1 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM11)
InstanceId: FTDIBUS\VID_0403+PID_6001+LW9O7PCGA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM11
WROTE PortName = COM11 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM3)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5PA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM3
WROTE PortName = COM3 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM14)
InstanceId: FTDIBUS\VID_0403+PID_6014+FT78J2CLA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM14
WROTE PortName = COM14 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM6)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5OA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM6
WROTE PortName = COM6 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
----
Device FriendlyName: USB Serial Port (COM5)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5TA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM5
WROTE PortName = COM5 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created UserSetDeviceIdleEnabled = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created SSIdleTimeout = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created DefaultIdleState = 0 at Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Created/changed count: 60
Running device rescan: pnputil /scan-devices
Microsoft PnP Utility



Script doesn't finish running
 
Thanks — good news: the script did its work (you see many “WROTE …” / “Created …” lines and Created/changed count: 60). The reason the script appears to “not finish” is because the pnputil /scan-devices call at the end is running synchronously and is waiting — it prints the header ("Microsoft PnP Utility") and can take some time on some systems. You also pressed Ctrl+C earlier which interrupted it.
Options and next steps (pick one)
1) Let pnputil finish (quickest, safest)
  • If you can, just wait a minute or two — pnputil can take a little time to scan drivers and update device state. When it finishes the script will continue and schedule the reboot (if applicable).
2) If you want to stop pnputil now and finish quickly
  • Check whether pnputil is still running:
    Get-Process pnputil -ErrorAction SilentlyContinue
  • If it is running and you want to stop it:
    Stop-Process -Name pnputil -Force
  • Then trigger a device rescan non-blocking (or run devcon rescan if you have devcon):
    Start-Process -FilePath 'pnputil.exe' -ArgumentList '/scan-devices' -NoNewWindow

    or if devcon is available:​

    devcon rescan​

    The Start-Process call above will launch pnputil and not make your PowerShell session wait.
3) If you prefer an immediate reboot instead of rescan
  • (This will restart the machine immediately; cancelable only if you give a timeout.
    Start-Process -FilePath 'shutdown.exe' -ArgumentList @('/r','/t','0','/f','/c','Applying FTDI Device Parameter changes') -NoNewWindow
    (Or use a 15s countdown: replace '0' with '15' so you can abort with shutdown /a.
4) Verify the changes were written (will confirm GUI should now show COM)
  • Inspect one device’s Device Parameters to confirm PortName and selective-suspend values were created. Replace the InstanceId below with one from your log:
    Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters" | Format-List
    Or for the exact instance from your log (example):
    Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Enum\FTDIBUS\VID_0403+PID_6001+B0007E5SA\0000\Device Parameters' | Format-List
  • After rescan or reboot open Device Manager → Ports → <device> → Properties → Advanced and the COM Port Number should now be shown.
5) Patch suggestion (script improvement)
  • I can patch the script so pnputil is launched non-blocking (Start-Process without -Wait) and the script finishes quickly, then optionally schedule the reboot. If you want that I’ll post the small change now.
Quick recommended immediate command (safe):
  • If pnputil is stuck now and you want to finish quickly:
    Stop-Process -Name pnputil -Force
    Start-Process -FilePath 'pnputil.exe' -ArgumentList '/scan-devices' -NoNewWindow
Then check one device in registry as shown in step 4.
Would you like me to:
  • (A) Patch the script now so pnputil runs non-blocking and send you the updated script, or
  • (B) give the exact one‑line to stop pnputil and rerun the rescan non-blocking on your box, or
  • (C) walk through verifying one device’s registry values and confirm the Advanced dialog shows the COM?
Tell me which and I’ll give the exact command/snippet.
 
Got it — below is the small patched script that runs pnputil non‑blocking so the script finishes immediately instead of hanging waiting for pnputil. It’s the same Fix-FTDI flow you already have; I only changed the device rescan call to launch pnputil asynchronously and report the PID.
Save this over your existing Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1, then run a dry run first (-WhatIf), then run for real.
Patched script (replace the file contents with this):
Code:
<#
Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1
Patched: runs pnputil non-blocking so script doesn't hang.
Run elevated. Use -WhatIf to dry-run.
#> param( [switch]$WhatIf, [switch]$NoReboot) if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) { Write-Error "Run this script elevated (Run as Administrator). Exiting." exit 1
} $timestamp = (Get-Date).ToString('yyyyMMdd_HHmmss')
$logFile = Join-Path $env:USERPROFILE ("Desktop\FTDI_ApplyIfMissing_WithPortName_$timestamp.log")
"Started: $(Get-Date -Format u)" | Out-File -FilePath $logFile -Encoding UTF8 function Get-ComForInstance { param([string]$instanceId) try { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -eq $instanceId } if ($sp) { return $sp.DeviceID } $tail = ($instanceId -split '\\')[-1] if ($tail) { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -like "*$tail*" } if ($sp) { return $sp.DeviceID } } } catch { } return $null
} $ports = Get-PnpDevice -Class Ports -PresentOnly -ErrorAction SilentlyContinue | Where-Object { ($_.Manufacturer -and $_.Manufacturer -like '*FTDI*') -or ($_.InstanceId -and $_.InstanceId -match 'VID_0403') } if (-not $ports -or $ports.Count -eq 0) { "No FTDI COM ports found." | Tee-Object -FilePath $logFile -Append Write-Output "No FTDI COM ports found. See log: $logFile" exit 0
} "Found $($ports.Count) FTDI COM port(s)." | Tee-Object -FilePath $logFile -Append $createdCount = 0
$errors = @
$enumBase = 'HKLM:\SYSTEM\CurrentControlSet\Enum' foreach ($p in $ports) { "----" | Tee-Object -FilePath $logFile -Append "Device FriendlyName: $($p.FriendlyName)" | Tee-Object -FilePath $logFile -Append "InstanceId: $($p.InstanceId)" | Tee-Object -FilePath $logFile -Append $inst = $p.InstanceId if ([string]::IsNullOrWhiteSpace($inst) { "InstanceId empty; skipping" | Tee-Object -FilePath $logFile -Append continue } $dpCandidates = @ try { $tail = ($inst -split '\\')[-1] $matches = Get-ChildItem -Path $enumBase -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.PSPath -match [regex]::Escape($inst) -or ($tail -and ($_.PSPath -match [regex]::Escape($tail) } foreach ($m in $matches) { $node = [string]$m.PSPath $dpCandidates += Join-Path $node 'Device Parameters' $dpCandidates += Join-Path (Join-Path $node '0000') 'Device Parameters' } } catch { } if ($dpCandidates.Count -eq 0) { $parts = $inst -split '\\' $subpath = [string]($parts -join '\') $regPathBase = Join-Path $enumBase $subpath $regPathBase = [string]$regPathBase $dpCandidates += Join-Path $regPathBase 'Device Parameters' $dpCandidates += Join-Path (Join-Path $regPathBase '0000') 'Device Parameters' } $dpFound = $false foreach ($dp in $dpCandidates) { "Checking: $dp" | Tee-Object -FilePath $logFile -Append if (Test-Path $dp) { $dpFound = $true "Using Device Parameters: $($dp)" | Tee-Object -FilePath $logFile -Append try { $portVal = $null try { $portVal = (Get-ItemProperty -Path $dp -Name 'PortName' -ErrorAction SilentlyContinue).PortName } catch { $portVal = $null } if ([string]::IsNullOrWhiteSpace($portVal) { $friendly = $p.FriendlyName $detectedCom = $null if ($friendly -and ($friendly -match '\(COM(\d+)\)') { $detectedCom = "COM$($matches[1])" "Detected COM from FriendlyName: $($detectedCom)" | Tee-Object -FilePath $logFile -Append } else { $detectedCom = Get-ComForInstance -instanceId $inst if ($detectedCom) { "Detected COM via WMI: $($detectedCom)" | Tee-Object -FilePath $logFile -Append } } if ($detectedCom) { if ($WhatIf) { "WhatIf: would write PortName = $($detectedCom) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } else { try { New-Item -Path $dp -Force | Out-Null New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null "WROTE PortName = $($detectedCom) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing PortName at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName write error for $inst : $($_.Exception.Message)" } } } else { "Could not detect COM for $inst; PortName not written." | Tee-Object -FilePath $logFile -Append } } else { "PortName already exists at $($dp): $($portVal) (no change)" | Tee-Object -FilePath $logFile -Append } } catch { "Error reading/writing PortName at $($dp): $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName error for $inst : $($_.Exception.Message)" } $props = @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 } foreach ($kv in $props.GetEnumerator { $name = $kv.Key; $val = $kv.Value try { $exists = (Get-ItemProperty -Path $dp -Name $name -ErrorAction SilentlyContinue) -ne $null } catch { $exists = $false } if ($exists) { "$($name) already present at $($dp) - skipping" | Tee-Object -FilePath $logFile -Append } else { if ($WhatIf) { "WhatIf: would create $($name) = $($val) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } else { try { New-Item -Path $dp -Force | Out-Null New-ItemProperty -Path $dp -Name $name -PropertyType DWord -Value $val -Force -ErrorAction Stop | Out-Null "Created $($name) = $($val) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR creating $($name) at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create $($name) error for $inst : $($_.Exception.Message)" } } } } break } else { "Not found: $($dp)" | Tee-Object -FilePath $logFile -Append } } if (-not $dpFound) { $parts = $inst -split '\\' $subpath = [string]($parts -join '\') $regPathBase = Join-Path $enumBase $subpath $dp = Join-Path $regPathBase 'Device Parameters' "Device Parameters not found - creating $($dp)" | Tee-Object -FilePath $logFile -Append if ($WhatIf) { "WhatIf: would create key $($dp) and attempt writes" | Tee-Object -FilePath $logFile -Append $createdCount++ } else { try { New-Item -Path $dp -Force | Out-Null "Created key $($dp)" | Tee-Object -FilePath $logFile -Append } catch { "ERROR creating key $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create key error for $inst : $($_.Exception.Message)" continue } $detectedCom = $null $friendly = $p.FriendlyName if ($friendly -and ($friendly -match '\(COM(\d+)\)') { $detectedCom = "COM$($matches[1])" } if (-not $detectedCom) { $detectedCom = Get-ComForInstance -instanceId $inst } if ($detectedCom) { try { New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null "WROTE PortName = $($detectedCom) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing PortName at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName write error for $inst : $($_.Exception.Message)" } } else { "Could not detect COM for $inst after creating key." | Tee-Object -FilePath $logFile -Append } foreach ($kv in @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }.GetEnumerator { try { New-ItemProperty -Path $dp -Name $kv.Key -PropertyType DWord -Value $kv.Value -Force -ErrorAction Stop | Out-Null "Created $($kv.Key) = $($kv.Value) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR creating $($kv.Key) at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create prop error $($kv.Key) for $inst : $($_.Exception.Message)" } } } } } "Created/changed count: $createdCount" | Tee-Object -FilePath $logFile -Append
if ($errors.Count -gt 0) { "Errors: $($errors.Count)" | Tee-Object -FilePath $logFile -Append; $errors | Tee-Object -FilePath $logFile -Append } # Rescan devices (launch pnputil asynchronously so script finishes)
try { "Launching device rescan (pnputil /scan-devices) in background" | Tee-Object -FilePath $logFile -Append $proc = Start-Process -FilePath 'pnputil.exe' -ArgumentList '/scan-devices' -NoNewWindow -PassThru "pnputil started (PID $($proc.Id)" | Tee-Object -FilePath $logFile -Append
} catch { "pnputil failed to start: $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
} if (($createdCount -gt 0) -and (-not $WhatIf) -and (-not $NoReboot) { "Scheduling reboot in 15 seconds so changes take effect (abort with 'shutdown /a')." | Tee-Object -FilePath $logFile -Append Start-Process -FilePath 'shutdown.exe' -ArgumentList @('/r','/t','15','/c','Applying FTDI Device Parameter changes') -NoNewWindow
} else { "No reboot scheduled. If you created properties and want immediate recognition, run: pnputil /scan-devices or reboot manually." | Tee-Object -FilePath $logFile -Append
} "Completed: $(Get-Date -Format u)" | Tee-Object -FilePath $logFile -Append
Write-Output "Done. Log saved to: $logFile"
How to run
  1. Save file.
  2. Dry run:
    PowerShell -ExecutionPolicy Bypass -File "C:\Users\<you>\Documents\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1" -WhatIf
  3. Apply:
    PowerShell -ExecutionPolicy Bypass -File "C:\Users\<you>\Documents\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1"
If you want, I can also:
  • Remove the scheduled reboot and just rely on the background pnputil + a short message; or
  • Add a check that waits up to N seconds for pnputil to exit (non-blocking but waiting a little), if you'd like a compromise.
Which variant do you prefer?
 
Change this script so that it only changes the items if they do not exist or if they are a different value

<#
Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1
Patched: runs pnputil non-blocking so script doesn't hang.
Run elevated. Use -WhatIf to dry-run.
#>

param(
[switch]$WhatIf,
[switch]$NoReboot
)

if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)) {
Write-Error "Run this script elevated (Run as Administrator). Exiting."
exit 1
}

$timestamp = (Get-Date).ToString('yyyyMMdd_HHmmss')
$logFile = Join-Path $env:USERPROFILE ("Desktop\FTDI_ApplyIfMissing_WithPortName_$timestamp.log")
"Started: $(Get-Date -Format u)" | Out-File -FilePath $logFile -Encoding UTF8

function Get-ComForInstance {
param([string]$instanceId)
try {
$sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue |
Where-Object { $_.PNPDeviceID -eq $instanceId }
if ($sp) { return $sp.DeviceID }
$tail = ($instanceId -split '\\')[-1]
if ($tail) {
$sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue |
Where-Object { $_.PNPDeviceID -like "*$tail*" }
if ($sp) { return $sp.DeviceID }
}
} catch { }
return $null
}

$ports = Get-PnpDevice -Class Ports -PresentOnly -ErrorAction SilentlyContinue |
Where-Object { ($_.Manufacturer -and $_.Manufacturer -like '*FTDI*') -or ($_.InstanceId -and $_.InstanceId -match 'VID_0403') }

if (-not $ports -or $ports.Count -eq 0) {
"No FTDI COM ports found." | Tee-Object -FilePath $logFile -Append
Write-Output "No FTDI COM ports found. See log: $logFile"
exit 0
}

"Found $($ports.Count) FTDI COM port(s)." | Tee-Object -FilePath $logFile -Append

$createdCount = 0
$errors = @()
$enumBase = 'HKLM:\SYSTEM\CurrentControlSet\Enum'

foreach ($p in $ports) {
"----" | Tee-Object -FilePath $logFile -Append
"Device FriendlyName: $($p.FriendlyName)" | Tee-Object -FilePath $logFile -Append
"InstanceId: $($p.InstanceId)" | Tee-Object -FilePath $logFile -Append

$inst = $p.InstanceId
if ([string]::IsNullOrWhiteSpace($inst)) {
"InstanceId empty; skipping" | Tee-Object -FilePath $logFile -Append
continue
}

$dpCandidates = @()
try {
$tail = ($inst -split '\\')[-1]
$matches = Get-ChildItem -Path $enumBase -Recurse -ErrorAction SilentlyContinue |
Where-Object { $_.PSPath -match [regex]::Escape($inst) -or ($tail -and ($_.PSPath -match [regex]::Escape($tail))) }
foreach ($m in $matches) {
$node = [string]$m.PSPath
$dpCandidates += Join-Path $node 'Device Parameters'
$dpCandidates += Join-Path (Join-Path $node '0000') 'Device Parameters'
}
} catch { }

if ($dpCandidates.Count -eq 0) {
$parts = $inst -split '\\'
$subpath = [string]($parts -join '\')
$regPathBase = Join-Path $enumBase $subpath
$regPathBase = [string]$regPathBase
$dpCandidates += Join-Path $regPathBase 'Device Parameters'
$dpCandidates += Join-Path (Join-Path $regPathBase '0000') 'Device Parameters'
}

$dpFound = $false

foreach ($dp in $dpCandidates) {
"Checking: $dp" | Tee-Object -FilePath $logFile -Append
if (Test-Path $dp) {
$dpFound = $true
"Using Device Parameters: $($dp)" | Tee-Object -FilePath $logFile -Append

try {
$portVal = $null
try { $portVal = (Get-ItemProperty -Path $dp -Name 'PortName' -ErrorAction SilentlyContinue).PortName } catch { $portVal = $null }

if ([string]::IsNullOrWhiteSpace($portVal)) {
$friendly = $p.FriendlyName
$detectedCom = $null
if ($friendly -and ($friendly -match '\(COM(\d+)\)')) {
$detectedCom = "COM$($matches[1])"
"Detected COM from FriendlyName: $($detectedCom)" | Tee-Object -FilePath $logFile -Append
} else {
$detectedCom = Get-ComForInstance -instanceId $inst
if ($detectedCom) { "Detected COM via WMI: $($detectedCom)" | Tee-Object -FilePath $logFile -Append }
}

if ($detectedCom) {
if ($WhatIf) {
"WhatIf: would write PortName = $($detectedCom) at $($dp)" | Tee-Object -FilePath $logFile -Append
$createdCount++
} else {
try {
New-Item -Path $dp -Force | Out-Null
New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null
"WROTE PortName = $($detectedCom) at $($dp)" | Tee-Object -FilePath $logFile -Append
$createdCount++
} catch {
"ERROR writing PortName at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "PortName write error for $inst : $($_.Exception.Message)"
}
}
} else {
"Could not detect COM for $inst; PortName not written." | Tee-Object -FilePath $logFile -Append
}
} else {
"PortName already exists at $($dp): $($portVal) (no change)" | Tee-Object -FilePath $logFile -Append
}
} catch {
"Error reading/writing PortName at $($dp): $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "PortName error for $inst : $($_.Exception.Message)"
}

$props = @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }
foreach ($kv in $props.GetEnumerator()) {
$name = $kv.Key; $val = $kv.Value
try {
$exists = (Get-ItemProperty -Path $dp -Name $name -ErrorAction SilentlyContinue) -ne $null
} catch { $exists = $false }

if ($exists) {
"$($name) already present at $($dp) - skipping" | Tee-Object -FilePath $logFile -Append
} else {
if ($WhatIf) {
"WhatIf: would create $($name) = $($val) at $($dp)" | Tee-Object -FilePath $logFile -Append
$createdCount++
} else {
try {
New-Item -Path $dp -Force | Out-Null
New-ItemProperty -Path $dp -Name $name -PropertyType DWord -Value $val -Force -ErrorAction Stop | Out-Null
"Created $($name) = $($val) at $($dp)" | Tee-Object -FilePath $logFile -Append
$createdCount++
} catch {
"ERROR creating $($name) at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "Create $($name) error for $inst : $($_.Exception.Message)"
}
}
}
}

break
} else {
"Not found: $($dp)" | Tee-Object -FilePath $logFile -Append
}
}

if (-not $dpFound) {
$parts = $inst -split '\\'
$subpath = [string]($parts -join '\')
$regPathBase = Join-Path $enumBase $subpath
$dp = Join-Path $regPathBase 'Device Parameters'
"Device Parameters not found - creating $($dp)" | Tee-Object -FilePath $logFile -Append

if ($WhatIf) {
"WhatIf: would create key $($dp) and attempt writes" | Tee-Object -FilePath $logFile -Append
$createdCount++
} else {
try {
New-Item -Path $dp -Force | Out-Null
"Created key $($dp)" | Tee-Object -FilePath $logFile -Append
} catch {
"ERROR creating key $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "Create key error for $inst : $($_.Exception.Message)"
continue
}

$detectedCom = $null
$friendly = $p.FriendlyName
if ($friendly -and ($friendly -match '\(COM(\d+)\)')) { $detectedCom = "COM$($matches[1])" }
if (-not $detectedCom) { $detectedCom = Get-ComForInstance -instanceId $inst }

if ($detectedCom) {
try {
New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null
"WROTE PortName = $($detectedCom) at $($dp)" | Tee-Object -FilePath $logFile -Append
$createdCount++
} catch {
"ERROR writing PortName at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "PortName write error for $inst : $($_.Exception.Message)"
}
} else {
"Could not detect COM for $inst after creating key." | Tee-Object -FilePath $logFile -Append
}

foreach ($kv in @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }.GetEnumerator()) {
try {
New-ItemProperty -Path $dp -Name $kv.Key -PropertyType DWord -Value $kv.Value -Force -ErrorAction Stop | Out-Null
"Created $($kv.Key) = $($kv.Value) at $($dp)" | Tee-Object -FilePath $logFile -Append
$createdCount++
} catch {
"ERROR creating $($kv.Key) at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "Create prop error $($kv.Key) for $inst : $($_.Exception.Message)"
}
}
}
}

}

"Created/changed count: $createdCount" | Tee-Object -FilePath $logFile -Append
if ($errors.Count -gt 0) { "Errors: $($errors.Count)" | Tee-Object -FilePath $logFile -Append; $errors | Tee-Object -FilePath $logFile -Append }

# Rescan devices (launch pnputil asynchronously so script finishes)
try {
"Launching device rescan (pnputil /scan-devices) in background" | Tee-Object -FilePath $logFile -Append
$proc = Start-Process -FilePath 'pnputil.exe' -ArgumentList '/scan-devices' -NoNewWindow -PassThru
"pnputil started (PID $($proc.Id))" | Tee-Object -FilePath $logFile -Append
} catch {
"pnputil failed to start: $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
}

if (($createdCount -gt 0) -and (-not $WhatIf) -and (-not $NoReboot)) {
"Scheduling reboot in 15 seconds so changes take effect (abort with 'shutdown /a')." | Tee-Object -FilePath $logFile -Append
# Restart-Computer -force
} else {
"No reboot scheduled. If you created properties and want immediate recognition, run: pnputil /scan-devices or reboot manually." | Tee-Object -FilePath $logFile -Append
}

"Completed: $(Get-Date -Format u)" | Tee-Object -FilePath $logFile -Append
Write-Output "Done. Log saved to: $logFile"
 
Thanks — I updated your script so it will only write a property when:
  • the property does not exist, OR
  • the property exists but its current value differs from the desired value.
Behavior summary (unchanged otherwise)
  • PortName: will be written if missing or different from detected COM (FriendlyName or WMI). It will not attempt to reassign COMs — it only records the current COM.
  • Selective-suspend DWords: DeviceIdleEnabled, DefaultIdleState, UserSetDeviceIdleEnabled, SSIdleTimeout — will be written if missing or if their numeric value differs from 0.
  • The script still logs everything to a Desktop log, launches pnputil non-blocking, and schedules a 15s reboot only if any actual changes were performed (or would have been performed in -WhatIf).
  • -WhatIf simulates changes (logs what it would change) but does not write or schedule reboot.
Save the following as Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1 (overwrite your existing file), then run a dry run first:
PowerShell -ExecutionPolicy Bypass -File .\Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1 -WhatIf
When the dry-run looks correct, run without -WhatIf to apply.
Patched script (copy entire block and save as .ps1):
Code:
<#
Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName.ps1
- Only writes properties if missing OR if current value differs from desired.
- Writes PortName (from FriendlyName or WMI) only when missing or different.
- Creates selective-suspend DWords only if missing or different from 0.
- Does NOT change actual COM assignment.
- Logs to Desktop; launches pnputil non-blocking; schedules a 15s reboot if real changes occurred.
Run elevated. Use -WhatIf to dry-run.
#> param( [switch]$WhatIf, [switch]$NoReboot) # require elevation
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) { Write-Error "Run this script elevated (Run as Administrator). Exiting." exit 1
} $timestamp = (Get-Date).ToString('yyyyMMdd_HHmmss')
$logFile = Join-Path $env:USERPROFILE ("Desktop\FTDI_ApplyIfMissing_WithPortName_$timestamp.log")
"Started: $(Get-Date -Format u)" | Out-File -FilePath $logFile -Encoding UTF8 function Get-ComForInstance { param([string]$instanceId) try { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -eq $instanceId } if ($sp) { return $sp.DeviceID } $tail = ($instanceId -split '\\')[-1] if ($tail) { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -like "*$tail*" } if ($sp) { return $sp.DeviceID } } } catch { } return $null
} # Helper: set property only if missing or value differs. Returns $true if written (or would be written under -WhatIf)
function Ensure-Property { param( [string]$Path, [string]$Name, [ValidateSet('String','DWord')] [string]$Type, $DesiredValue) # read existing $existing = $null try { $prop = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue if ($prop -ne $null) { $existing = $prop.$Name } } catch { $existing = $null } # Normalize for comparison: DWord -> int, String -> string if ($Type -eq 'DWord') { if ($null -ne $existing) { try { $existingInt = [int]$existing } catch { $existingInt = $null } } else { $existingInt = $null } $desiredInt = [int]$DesiredValue if ($existingInt -ne $null -and $existingInt -eq $desiredInt) { # already same return $false } else { if ($WhatIf) { "$Name would be set to $desiredInt at $Path (existing: $existingInt)" | Tee-Object -FilePath $logFile -Append return $true } else { try { New-Item -Path $Path -Force | Out-Null New-ItemProperty -Path $Path -Name $Name -PropertyType DWord -Value $desiredInt -Force -ErrorAction Stop | Out-Null "$Name set to $desiredInt at $Path" | Tee-Object -FilePath $logFile -Append return $true } catch { "ERROR writing $Name at $Path : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append return $false } } } } else { # string type compare (case-insensitive) $existingStr = $null if ($null -ne $existing) { $existingStr = [string]$existing } $desiredStr = [string]$DesiredValue if ($existingStr -ne $null -and $existingStr.Equals($desiredStr, [System.StringComparison]::OrdinalIgnoreCase) { return $false } else { if ($WhatIf) { "$Name would be set to '$desiredStr' at $Path (existing: '$existingStr')" | Tee-Object -FilePath $logFile -Append return $true } else { try { New-Item -Path $Path -Force | Out-Null New-ItemProperty -Path $Path -Name $Name -PropertyType String -Value $desiredStr -Force -ErrorAction Stop | Out-Null "$Name set to '$desiredStr' at $Path" | Tee-Object -FilePath $logFile -Append return $true } catch { "ERROR writing $Name at $Path : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append return $false } } } }
} # find FTDI ports
$ports = Get-PnpDevice -Class Ports -PresentOnly -ErrorAction SilentlyContinue | Where-Object { ($_.Manufacturer -and $_.Manufacturer -like '*FTDI*') -or ($_.InstanceId -and $_.InstanceId -match 'VID_0403') } if (-not $ports -or $ports.Count -eq 0) { "No FTDI COM ports found." | Tee-Object -FilePath $logFile -Append Write-Output "No FTDI COM ports found. See log: $logFile" exit 0
} "Found $($ports.Count) FTDI COM port(s)." | Tee-Object -FilePath $logFile -Append $createdCount = 0
$errors = @
$enumBase = 'HKLM:\SYSTEM\CurrentControlSet\Enum' foreach ($p in $ports) { "----" | Tee-Object -FilePath $logFile -Append "Device FriendlyName: $($p.FriendlyName)" | Tee-Object -FilePath $logFile -Append "InstanceId: $($p.InstanceId)" | Tee-Object -FilePath $logFile -Append $inst = $p.InstanceId if ([string]::IsNullOrWhiteSpace($inst) { "InstanceId empty; skipping" | Tee-Object -FilePath $logFile -Append continue } # build candidate Device Parameters paths (search Enum first) $dpCandidates = @ try { $tail = ($inst -split '\\')[-1] $matches = Get-ChildItem -Path $enumBase -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.PSPath -match [regex]::Escape($inst) -or ($tail -and ($_.PSPath -match [regex]::Escape($tail) } foreach ($m in $matches) { $node = [string]$m.PSPath $dpCandidates += Join-Path $node 'Device Parameters' $dpCandidates += Join-Path (Join-Path $node '0000') 'Device Parameters' } } catch { } if ($dpCandidates.Count -eq 0) { $parts = $inst -split '\\' $subpath = [string]($parts -join '\') $regPathBase = Join-Path $enumBase $subpath $regPathBase = [string]$regPathBase $dpCandidates += Join-Path $regPathBase 'Device Parameters' $dpCandidates += Join-Path (Join-Path $regPathBase '0000') 'Device Parameters' } $dpFound = $false foreach ($dp in $dpCandidates) { "Checking: $($dp)" | Tee-Object -FilePath $logFile -Append if (Test-Path $dp) { $dpFound = $true "Using Device Parameters: $($dp)" | Tee-Object -FilePath $logFile -Append # detect COM (FriendlyName first, then WMI) $friendly = $p.FriendlyName $detectedCom = $null if ($friendly) { $m = [regex]::Match($friendly,'\(COM(\d+)\)') if ($m.Success) { $detectedCom = "COM$($m.Groups[1].Value)" ; "Detected COM from FriendlyName: $($detectedCom)" | Tee-Object -FilePath $logFile -Append } } if (-not $detectedCom) { $detectedCom = Get-ComForInstance -instanceId $inst if ($detectedCom) { "Detected COM via WMI: $($detectedCom)" | Tee-Object -FilePath $logFile -Append } } # PortName: only change if missing or different if ($detectedCom) { $changed = Ensure-Property -Path $dp -Name 'PortName' -Type 'String' -DesiredValue $detectedCom if ($changed) { $createdCount++ } } else { "Could not detect COM for $inst; PortName left alone." | Tee-Object -FilePath $logFile -Append } # selective-suspend DWords: ensure exist and equal 0 foreach ($kv in @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }.GetEnumerator { $name = $kv.Key; $val = $kv.Value $changed = Ensure-Property -Path $dp -Name $name -Type 'DWord' -DesiredValue $val if ($changed) { $createdCount++ } } break } else { "Not found: $($dp)" | Tee-Object -FilePath $logFile -Append } } if (-not $dpFound) { # create primary Device Parameters key and retry $parts = $inst -split '\\' $subpath = [string]($parts -join '\') $regPathBase = Join-Path $enumBase $subpath $dp = Join-Path $regPathBase 'Device Parameters' "Device Parameters not found - creating $($dp)" | Tee-Object -FilePath $logFile -Append if ($WhatIf) { "WhatIf: would create key $($dp) and attempt writes" | Tee-Object -FilePath $logFile -Append } else { try { New-Item -Path $dp -Force | Out-Null "Created key $($dp)" | Tee-Object -FilePath $logFile -Append } catch { "ERROR creating key $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create key error for $inst : $($_.Exception.Message)" continue } } # same writes after creating key $friendly = $p.FriendlyName $detectedCom = $null if ($friendly) { $m = [regex]::Match($friendly,'\(COM(\d+)\)') if ($m.Success) { $detectedCom = "COM$($m.Groups[1].Value)" ; "Detected COM from FriendlyName: $($detectedCom)" | Tee-Object -FilePath $logFile -Append } } if (-not $detectedCom) { $detectedCom = Get-ComForInstance -instanceId $inst if ($detectedCom) { "Detected COM via WMI: $($detectedCom)" | Tee-Object -FilePath $logFile -Append } } if ($detectedCom) { $changed = Ensure-Property -Path $dp -Name 'PortName' -Type 'String' -DesiredValue $detectedCom if ($changed) { $createdCount++ } } else { "Could not detect COM for $inst after creating key." | Tee-Object -FilePath $logFile -Append } foreach ($kv in @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }.GetEnumerator { $changed = Ensure-Property -Path $dp -Name $kv.Key -Type 'DWord' -DesiredValue $kv.Value if ($changed) { $createdCount++ } } } } # end foreach ports "Created/changed count: $createdCount" | Tee-Object -FilePath $logFile -Append
if ($errors.Count -gt 0) { "Errors: $($errors.Count)" | Tee-Object -FilePath $logFile -Append; $errors | Tee-Object -FilePath $logFile -Append } # Rescan devices (launch pnputil asynchronously so script finishes)
try { "Launching device rescan (pnputil /scan-devices) in background" | Tee-Object -FilePath $logFile -Append $proc = Start-Process -FilePath 'pnputil.exe' -ArgumentList '/scan-devices' -NoNewWindow -PassThru "pnputil started (PID $($proc.Id)" | Tee-Object -FilePath $logFile -Append
} catch { "pnputil failed to start: $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
} if (($createdCount -gt 0) -and (-not $WhatIf) -and (-not $NoReboot) { "Scheduling reboot in 15 seconds so changes take effect (abort with 'shutdown /a')." | Tee-Object -FilePath $logFile -Append Start-Process -FilePath 'shutdown.exe' -ArgumentList @('/r','/t','15','/c','Applying FTDI Device Parameter changes') -NoNewWindow
} else { "No reboot scheduled. If you created properties and want immediate recognition, run: pnputil /scan-devices or reboot manually." | Tee-Object -FilePath $logFile -Append
} "Completed: $(Get-Date -Format u)" | Tee-Object -FilePath $logFile -Append
Write-Output "Done. Log saved to: $logFile"
Notes
  • I added Ensure-Property to centralize the compare-and-write logic and to correctly handle both string and DWord types. That function also respects -WhatIf.
  • createdCount increments only when a property would be written (WhatIf) or was actually written.
  • Run the -WhatIf dry run first and inspect the Desktop log file. If it looks good, run without -WhatIf.
  • If you prefer the script not to schedule the reboot at all, run with -NoReboot or I can remove the reboot line.
If you want, I can also:
  • Provide a version that force-overwrites values unconditionally, or
  • Add an option to only change PortName when it's missing (not when different), or
  • Produce a signed INF AddReg solution for persistence (recommended for large deployments).
 
Thanks — that explains it. Two things were causing the repeated “60 changes”:
  • The script was attempting the same Device Parameters path multiple times (your Enum search matched a single ACPI node that the script then used for many FTDI InstanceIds), so the same DP was processed repeatedly for each device.
  • The script’s existence check and the WhatIf branch incremented the created count in ways that made the report show changes every run.
Fix I’ll apply for you now (what this new script does)
  • Tracks which Device Parameters registry paths were already processed in this run and skips them on subsequent devices (so the same DP isn’t re-processed).
  • Uses a reliable existence test (checks the property name list in the registry key) so it only writes a value if it truly does not exist.
  • Only increments the created/changed counter when an actual write occurs (not during -WhatIf simulation).
  • Launches pnputil /scan-devices in the background (non-blocking) so the script finishes quickly.
  • Keeps the policy of NOT overwriting existing values and NOT changing PortName if it already exists.
Save this as Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName-Patched.ps1 and run elevated. Use -WhatIf to dry-run.
Script (copy entire file and save as .ps1):
Code:
<#
Disable-FTDI-SelectiveSuspend-ApplyIfMissing-WithPortName-Patched.ps1
- Idempotent: only creates missing registry values and skips already-processed Device Parameters keys.
- Does NOT overwrite existing values, does NOT change PortName if present.
- Writes PortName from FriendlyName or WMI only when missing.
- Launches pnputil in background so script exits quickly.
Run as Administrator. Use -WhatIf to dry-run.
#> param( [switch]$WhatIf, [switch]$NoReboot) if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) { Write-Error "Run elevated (Run as Administrator). Exiting." exit 1
} $timestamp = (Get-Date).ToString('yyyyMMdd_HHmmss')
$logFile = Join-Path $env:USERPROFILE ("Desktop\FTDI_ApplyIfMissing_WithPortName_Patched_$timestamp.log")
"Started: $(Get-Date -Format u)" | Out-File -FilePath $logFile -Encoding UTF8 function Get-ComForInstance { param([string]$instanceId) try { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -eq $instanceId } if ($sp) { return $sp.DeviceID } $tail = ($instanceId -split '\\')[-1] if ($tail) { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -like "*$tail*" } if ($sp) { return $sp.DeviceID } } } catch { } return $null
} # Discover FTDI COM ports
$ports = Get-PnpDevice -Class Ports -PresentOnly -ErrorAction SilentlyContinue | Where-Object { ($_.Manufacturer -and $_.Manufacturer -like '*FTDI*') -or ($_.InstanceId -and $_.InstanceId -match 'VID_0403') } if (-not $ports -or $ports.Count -eq 0) { "No FTDI COM ports found." | Tee-Object -FilePath $logFile -Append Write-Output "No FTDI COM ports found. See log: $logFile" exit 0
} "Found $($ports.Count) FTDI COM port(s)." | Tee-Object -FilePath $logFile -Append $createdCount = 0
$errors = @
$enumBase = 'HKLM:\SYSTEM\CurrentControlSet\Enum'
$processedDp = @{} # hashset of DP paths already processed this run foreach ($p in $ports) { "----" | Tee-Object -FilePath $logFile -Append "Device FriendlyName: $($p.FriendlyName)" | Tee-Object -FilePath $logFile -Append "InstanceId: $($p.InstanceId)" | Tee-Object -FilePath $logFile -Append $inst = $p.InstanceId if ([string]::IsNullOrWhiteSpace($inst) { "InstanceId empty; skipping" | Tee-Object -FilePath $logFile -Append continue } # Build candidate Device Parameters paths (try to find matching Enum nodes) $dpCandidates = @ try { $tail = ($inst -split '\\')[-1] $matches = Get-ChildItem -Path $enumBase -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.PSPath -match [regex]::Escape($inst) -or ($tail -and ($_.PSPath -match [regex]::Escape($tail) } foreach ($m in $matches) { $node = [string]$m.PSPath $dpCandidates += Join-Path $node 'Device Parameters' $dpCandidates += Join-Path (Join-Path $node '0000') 'Device Parameters' } } catch { } if ($dpCandidates.Count -eq 0) { $parts = $inst -split '\\' $subpath = [string]($parts -join '\') $regPathBase = Join-Path $enumBase $subpath $regPathBase = [string]$regPathBase $dpCandidates += Join-Path $regPathBase 'Device Parameters' $dpCandidates += Join-Path (Join-Path $regPathBase '0000') 'Device Parameters' } $dpFoundForInstance = $false foreach ($dp in $dpCandidates) { # Normalize dp to plain registry path string for use in hashset $dpStr = [string]$dp "Checking: $dpStr" | Tee-Object -FilePath $logFile -Append if ($processedDp.ContainsKey($dpStr) { "Already processed $dpStr in this run - skipping." | Tee-Object -FilePath $logFile -Append # mark that we found a DP for this instance, but skip actual processing $dpFoundForInstance = $true break } if (Test-Path $dpStr) { $dpFoundForInstance = $true "Using Device Parameters: $dpStr" | Tee-Object -FilePath $logFile -Append # mark as processed so other instances that resolve to same DP won't redo it $processedDp[$dpStr] = $true # 1) PortName - write only if property name not present try { $item = Get-ItemProperty -Path $dpStr -ErrorAction SilentlyContinue $props = if ($item) { $item.PSObject.Properties | ForEach-Object { $_.Name } } else { @ } if (-not ($props -contains 'PortName') { # detect COM from FriendlyName or WMI $friendly = $p.FriendlyName $detectedCom = $null if ($friendly -and ($friendly -match '\(COM(\d+)\)') { $detectedCom = "COM$($matches[1])" "Detected COM from FriendlyName: $($detectedCom)" | Tee-Object -FilePath $logFile -Append } else { $detectedCom = Get-ComForInstance -instanceId $inst if ($detectedCom) { "Detected COM via WMI: $($detectedCom)" | Tee-Object -FilePath $logFile -Append } } if ($detectedCom) { if (-not $WhatIf) { try { New-Item -Path $dpStr -Force | Out-Null New-ItemProperty -Path $dpStr -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null "WROTE PortName = $($detectedCom) at $($dpStr)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing PortName at $($dpStr) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName write error for $inst : $($_.Exception.Message)" } } else { "WhatIf: would write PortName = $($detectedCom) at $($dpStr)" | Tee-Object -FilePath $logFile -Append } } else { "Could not detect COM for $inst; PortName not written." | Tee-Object -FilePath $logFile -Append } } else { "PortName already present at $($dpStr): $((Get-ItemProperty -Path $dpStr -Name 'PortName' -ErrorAction SilentlyContinue).PortName) - not changed" | Tee-Object -FilePath $logFile -Append } } catch { "Error reading/writing PortName at $($dpStr): $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName error for $inst : $($_.Exception.Message)" } # 2) selective-suspend props - create only if the property name does not exist $propsToCreate = @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 } foreach ($kv in $propsToCreate.GetEnumerator { $name = $kv.Key; $val = $kv.Value try { $existsName = $false $item = Get-ItemProperty -Path $dpStr -ErrorAction SilentlyContinue if ($item) { $existsName = ($item.PSObject.Properties | ForEach-Object { $_.Name }) -contains $name } } catch { $existsName = $false } if ($existsName) { "$($name) already present at $($dpStr) - skipping" | Tee-Object -FilePath $logFile -Append } else { if (-not $WhatIf) { try { New-Item -Path $dpStr -Force | Out-Null New-ItemProperty -Path $dpStr -Name $name -PropertyType DWord -Value $val -Force -ErrorAction Stop | Out-Null "Created $($name) = $($val) at $($dpStr)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR creating $($name) at $($dpStr) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create $($name) error for $inst : $($_.Exception.Message)" } } else { "WhatIf: would create $($name) = $($val) at $($dpStr)" | Tee-Object -FilePath $logFile -Append } } } break } else { "Not found: $($dp)" | Tee-Object -FilePath $logFile -Append } } # end foreach dpCandidates if (-not $dpFoundForInstance) { # create primary Device Parameters and perform same operations once $parts = $inst -split '\\' $subpath = [string]($parts -join '\') $regPathBase = Join-Path $enumBase $subpath $dp = Join-Path $regPathBase 'Device Parameters' $dp = [string]$dp if ($processedDp.ContainsKey($dp) { "Primary DP $dp already processed - skipping." | Tee-Object -FilePath $logFile -Append continue } "Device Parameters not found - creating primary $($dp)" | Tee-Object -FilePath $logFile -Append $processedDp[$dp] = $true if ($WhatIf) { "WhatIf: would create key $($dp) and attempt writes" | Tee-Object -FilePath $logFile -Append } else { try { New-Item -Path $dp -Force | Out-Null "Created key $($dp)" | Tee-Object -FilePath $logFile -Append } catch { "ERROR creating key $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create key error for $inst : $($_.Exception.Message)" continue } # PortName detection/write $detectedCom = $null $friendly = $p.FriendlyName if ($friendly -and ($friendly -match '\(COM(\d+)\)') { $detectedCom = "COM$($matches[1])" } if (-not $detectedCom) { $detectedCom = Get-ComForInstance -instanceId $inst } if ($detectedCom) { try { New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null "WROTE PortName = $($detectedCom) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing PortName at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName write error for $inst : $($_.Exception.Message)" } } else { "Could not detect COM for $inst after creating key." | Tee-Object -FilePath $logFile -Append } # create selective-suspend props foreach ($kv in @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }.GetEnumerator { try { New-ItemProperty -Path $dp -Name $kv.Key -PropertyType DWord -Value $kv.Value -Force -ErrorAction Stop | Out-Null "Created $($kv.Key) = $($kv.Value) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR creating $($kv.Key) at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create prop error $($kv.Key) for $inst : $($_.Exception.Message)" } } } } } # end foreach ports "Created/changed count: $createdCount" | Tee-Object -FilePath $logFile -Append
if ($errors.Count -gt 0) { "Errors: $($errors.Count)" | Tee-Object -FilePath $logFile -Append; $errors | Tee-Object -FilePath $logFile -Append } # Launch pnputil asynchronously so script ends quickly
try { "Launching device rescan (pnputil /scan-devices) in background" | Tee-Object -FilePath $logFile -Append $proc = Start-Process -FilePath 'pnputil.exe' -ArgumentList '/scan-devices' -NoNewWindow -PassThru "pnputil started (PID $($proc.Id)" | Tee-Object -FilePath $logFile -Append
} catch { "pnputil failed to start: $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
} if (($createdCount -gt 0) -and (-not $WhatIf) -and (-not $NoReboot) { "Scheduling reboot in 15 seconds so changes take effect (abort with 'shutdown /a')." | Tee-Object -FilePath $logFile -Append Start-Process -FilePath 'shutdown.exe' -ArgumentList @('/r','/t','15','/c','Applying FTDI Device Parameter changes') -NoNewWindow
} else { "No reboot scheduled. If you created properties and want immediate recognition, run: pnputil /scan-devices or reboot manually." | Tee-Object -FilePath $logFile -Append
} "Completed: $(Get-Date -Format u)" | Tee-Object -FilePath $logFile -Append
Write-Output "Done. Log saved to: $logFile"
Notes
  • This prevents processing the same DP more than once in a single run and fixes the false “60 changes” behavior.
  • After running once (not -WhatIf), re-running should show 0 created/changed (or only a small number if a new device appeared).
  • If you still see unexpected repeated changes after this patch, paste the new log and I’ll inspect the processed DP list and values to find why the script still thinks a write is needed.
Would you like me to also (optionally):
  • add a toggle to force‑overwrite values (set them even if present), or
  • add a preview summary that lists distinct DP paths that would be changed (before making changes)?
 
Found 12 FTDI COM port(s).
----
Device FriendlyName: USB Serial Port (COM4)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5SA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM4
----
Device FriendlyName: USB Serial Port (COM7)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5LA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM7
----
Device FriendlyName: USB Serial Port (COM12)
InstanceId: FTDIBUS\VID_0403+PID_6001+A9009WEMA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM12
----
Device FriendlyName: USB Serial Port (COM2)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5XA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM2
----
Device FriendlyName: USB Serial Port (COM10)
InstanceId: FTDIBUS\VID_0403+PID_6001+A10LY4Z7A\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM10
----
Device FriendlyName: USB Serial Port (COM8)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5KA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM8
----
Device FriendlyName: USB Serial Port (COM1)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5WA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM1
----
Device FriendlyName: USB Serial Port (COM11)
InstanceId: FTDIBUS\VID_0403+PID_6001+LW9O7PCGA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM11
----
Device FriendlyName: USB Serial Port (COM3)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5PA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM3
----
Device FriendlyName: USB Serial Port (COM14)
InstanceId: FTDIBUS\VID_0403+PID_6014+FT78J2CLA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM14
----
Device FriendlyName: USB Serial Port (COM6)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5OA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM6
----
Device FriendlyName: USB Serial Port (COM5)
InstanceId: FTDIBUS\VID_0403+PID_6001+B0007E5TA\0000
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Not found: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\0000\Device Parameters
Checking: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Using Device Parameters: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0000\4&144cc003&0\Device Parameters
Detected COM from FriendlyName: COM5
Created/changed count: 60
Launching device rescan (pnputil /scan-devices) in background
pnputil started (PID 10932)
Scheduling reboot in 15 seconds so changes take effect (abort with 'shutdown /a').
Completed: 2025-11-24 21:57:24Z
Done. Log saved to: C:\Users\kioskuser2\Desktop\FTDI_ApplyIfMissing_WithPortName_20251124_215719.log
PS C:\Users\kioskuser2\Documents> Microsoft PnP Utility

Still writing 60 items everytime the script is run.
 
Thanks — I tracked the cause. Your InstanceId already contains the correct enum path (FTDIBUS\VID_0403+..., but the earlier “search the Enum tree by tail” logic sometimes matched an unrelated ACPI node (PNP0000) and the script then wrote the properties into that ACPI Device Parameters key. Because that ACPI key didn’t have the properties the script thought missing, it kept creating values there every run — which is why you always saw “60 changes.”
Fix: stop searching by tail and use the actual InstanceId to build the registry path for that device. That guarantees we only touch the per-device Enum key Windows associates with that specific FTDI instance.
Save this as Disable-FTDI-SelectiveSuspend-Final.ps1 and run it elevated. Use -WhatIf for a dry run first.
Script (copy whole file and save as .ps1):
Code:
<#
Disable-FTDI-SelectiveSuspend-Final.ps1
- Uses the device InstanceId directly to target HKLM:\SYSTEM\CurrentControlSet\Enum\<Instance>\Device Parameters
- Creates Device Parameters if missing, sets PortName (from FriendlyName or WMI) if missing, and creates selective-suspend values only if missing.
- Idempotent: will not overwrite existing values and will not re-process the same Device Parameters path multiple times per run.
- Launches pnputil in background and schedules a 15s reboot if changes were made (abortable with shutdown /a).
Run as Administrator. Use -WhatIf to dry-run.
#> param( [switch]$WhatIf, [switch]$NoReboot) # require elevation
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) { Write-Error "Run this script elevated (Run as Administrator). Exiting." exit 1
} $timestamp = (Get-Date).ToString('yyyyMMdd_HHmmss')
$logFile = Join-Path $env:USERPROFILE ("Desktop\FTDI_DisableSelectiveSuspend_Final_$timestamp.log")
"Started: $(Get-Date -Format u)" | Out-File -FilePath $logFile -Encoding UTF8 function Get-ComForInstance { param([string]$instanceId) try { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -eq $instanceId } if ($sp) { return $sp.DeviceID } $tail = ($instanceId -split '\\')[-1] if ($tail) { $sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue | Where-Object { $_.PNPDeviceID -like "*$tail*" } if ($sp) { return $sp.DeviceID } } } catch { } return $null
} # Find FTDI ports
$ports = Get-PnpDevice -Class Ports -PresentOnly -ErrorAction SilentlyContinue | Where-Object { ($_.Manufacturer -and $_.Manufacturer -like '*FTDI*') -or ($_.InstanceId -and $_.InstanceId -match 'VID_0403') } if (-not $ports -or $ports.Count -eq 0) { "No FTDI COM ports found." | Tee-Object -FilePath $logFile -Append Write-Output "No FTDI COM ports found. See log: $logFile" exit 0
} "Found $($ports.Count) FTDI COM port(s)." | Tee-Object -FilePath $logFile -Append $createdCount = 0
$errors = @
$processedDp = @{} # track DP paths already processed this run foreach ($p in $ports) { "----" | Tee-Object -FilePath $logFile -Append "Device FriendlyName: $($p.FriendlyName)" | Tee-Object -FilePath $logFile -Append "InstanceId: $($p.InstanceId)" | Tee-Object -FilePath $logFile -Append $inst = $p.InstanceId if ([string]::IsNullOrWhiteSpace($inst) { "InstanceId empty; skipping" | Tee-Object -FilePath $logFile -Append continue } # Build exact registry path from InstanceId (do NOT search Enum by tail) $enumBase = 'HKLM:\SYSTEM\CurrentControlSet\Enum' # Escape and join safely $regPathBase = "HKLM:\SYSTEM\CurrentControlSet\Enum\$inst" $regPathBase = [string]$regPathBase # Candidate Device Parameters locations for this instance $dpCandidates = @( "$regPathBase\Device Parameters", "$regPathBase\0000\Device Parameters") $dpFoundForInstance = $false foreach ($dp in $dpCandidates) { $dpStr = [string]$dp "Checking: $dpStr" | Tee-Object -FilePath $logFile -Append if ($processedDp.ContainsKey($dpStr) { "Already processed $dpStr this run - skipping." | Tee-Object -FilePath $logFile -Append $dpFoundForInstance = $true break } if (Test-Path $dpStr) { $dpFoundForInstance = $true "Using Device Parameters: $dpStr" | Tee-Object -FilePath $logFile -Append # Mark as processed so other devices won't reprocess the same DP $processedDp[$dpStr] = $true # Get existing property names for accurate checks $existingProps = @ try { $item = Get-ItemProperty -Path $dpStr -ErrorAction SilentlyContinue if ($item) { $existingProps = $item.PSObject.Properties | ForEach-Object { $_.Name } } } catch { $existingProps = @ } # PortName - create only if missing if (-not ($existingProps -contains 'PortName') { $friendly = $p.FriendlyName $detectedCom = $null if ($friendly -and ($friendly -match '\(COM(\d+)\)') { $detectedCom = "COM$($matches[1])" "Detected COM from FriendlyName: $($detectedCom)" | Tee-Object -FilePath $logFile -Append } else { $detectedCom = Get-ComForInstance -instanceId $inst if ($detectedCom) { "Detected COM via WMI: $($detectedCom)" | Tee-Object -FilePath $logFile -Append } } if ($detectedCom) { if (-not $WhatIf) { try { New-Item -Path $dpStr -Force | Out-Null New-ItemProperty -Path $dpStr -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null "WROTE PortName = $($detectedCom) at $($dpStr)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing PortName at $($dpStr) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName write error for $inst : $($_.Exception.Message)" } } else { "WhatIf: would write PortName = $($detectedCom) at $($dpStr)" | Tee-Object -FilePath $logFile -Append } } else { "Could not detect COM for $inst; PortName not written." | Tee-Object -FilePath $logFile -Append } } else { "PortName already present at $($dpStr): $((Get-ItemProperty -Path $dpStr -Name 'PortName' -ErrorAction SilentlyContinue).PortName) - not changed" | Tee-Object -FilePath $logFile -Append } # selective-suspend props - create only if property name not present $propsToCreate = @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 } foreach ($kv in $propsToCreate.GetEnumerator { $name = $kv.Key; $val = $kv.Value if ($existingProps -contains $name) { "$($name) already present at $($dpStr) - skipping" | Tee-Object -FilePath $logFile -Append } else { if (-not $WhatIf) { try { New-Item -Path $dpStr -Force | Out-Null New-ItemProperty -Path $dpStr -Name $name -PropertyType DWord -Value $val -Force -ErrorAction Stop | Out-Null "Created $($name) = $($val) at $($dpStr)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR creating $($name) at $($dpStr) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create $($name) error for $inst : $($_.Exception.Message)" } } else { "WhatIf: would create $($name) = $($val) at $($dpStr)" | Tee-Object -FilePath $logFile -Append } } } break } else { "Not found: $($dpStr)" | Tee-Object -FilePath $logFile -Append } } # end foreach dpCandidates if (-not $dpFoundForInstance) { "No Device Parameters found for instance $inst (expected path: $regPathBase). Creating primary DP." | Tee-Object -FilePath $logFile -Append $dp = "$regPathBase\Device Parameters" $dp = [string]$dp if ($processedDp.ContainsKey($dp) { "Primary DP $dp already processed - skipping creation." | Tee-Object -FilePath $logFile -Append continue } $processedDp[$dp] = $true if ($WhatIf) { "WhatIf: would create key $($dp) and attempt writes" | Tee-Object -FilePath $logFile -Append } else { try { New-Item -Path $dp -Force | Out-Null "Created key $($dp)" | Tee-Object -FilePath $logFile -Append } catch { "ERROR creating key $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create key error for $inst : $($_.Exception.Message)" continue } # PortName detection & selective-suspend creation (same logic) $detectedCom = $null $friendly = $p.FriendlyName if ($friendly -and ($friendly -match '\(COM(\d+)\)') { $detectedCom = "COM$($matches[1])" } if (-not $detectedCom) { $detectedCom = Get-ComForInstance -instanceId $inst } if ($detectedCom) { try { New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null "WROTE PortName = $($detectedCom) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing PortName at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "PortName write error for $inst : $($_.Exception.Message)" } } else { "Could not detect COM for $inst after creating key." | Tee-Object -FilePath $logFile -Append } foreach ($kv in @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }.GetEnumerator { try { New-ItemProperty -Path $dp -Name $kv.Key -PropertyType DWord -Value $kv.Value -Force -ErrorAction Stop | Out-Null "Created $($kv.Key) = $($kv.Value) at $($dp)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR creating $($kv.Key) at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Create prop error $($kv.Key) for $inst : $($_.Exception.Message)" } } } } } # end foreach ports "Created/changed count: $createdCount" | Tee-Object -FilePath $logFile -Append
if ($errors.Count -gt 0) { "Errors: $($errors.Count)" | Tee-Object -FilePath $logFile -Append $errors | Tee-Object -FilePath $logFile -Append
} # Launch pnputil asynchronously so script ends quickly
try { "Launching device rescan (pnputil /scan-devices) in background" | Tee-Object -FilePath $logFile -Append $proc = Start-Process -FilePath 'pnputil.exe' -ArgumentList '/scan-devices' -NoNewWindow -PassThru "pnputil started (PID $($proc.Id)" | Tee-Object -FilePath $logFile -Append
} catch { "pnputil failed to start: $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
} if (($createdCount -gt 0) -and (-not $WhatIf) -and (-not $NoReboot) { "Scheduling reboot in 15 seconds so changes take effect (abort with 'shutdown /a')." | Tee-Object -FilePath $logFile -Append Start-Process -FilePath 'shutdown.exe' -ArgumentList @('/r','/t','15','/c','Applying FTDI Device Parameter changes') -NoNewWindow
} else { "No reboot scheduled. If you created properties and want immediate recognition, run: pnputil /scan-devices or reboot manually." | Tee-Object -FilePath $logFile -Append
} "Completed: $(Get-Date -Format u)" | Tee-Object -FilePath $logFile -Append
Write-Output "Done. Log saved to: $logFile"
How to run
  • Dry run first:
    PowerShell -ExecutionPolicy Bypass -File .\Disable-FTDI-SelectiveSuspend-Final.ps1 -WhatIf
  • If dry-run looks correct, run without -WhatIf.
  • The script will set values only when they are missing; re-running should report 0 created/changed unless a new device appears or a DP key was removed.
If you run this and it still reports many changes, paste the last ~50 lines of the generated log and I’ll read the actual DP paths and property names and correct the remaining edge case.
 
If i check enable selective suspend in the advanced options this script does not detect any changes to the parameters and does not uncheck the enable selective suspend

<#
Disable-FTDI-SelectiveSuspend-Final.ps1
- Uses the device InstanceId directly to target HKLM:\SYSTEM\CurrentControlSet\Enum\<Instance>\Device Parameters
- Creates Device Parameters if missing, sets PortName (from FriendlyName or WMI) if missing,
and creates selective-suspend values only if missing.
- Idempotent: will not overwrite existing values and will not re-process the same Device Parameters path multiple times per run.
- Launches pnputil in background and schedules a 15s reboot if changes were made (abortable with shutdown /a).
Run as Administrator. Use -WhatIf to dry-run.
#>

param(
[switch]$WhatIf,
[switch]$NoReboot
)

# require elevation
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)) {
Write-Error "Run this script elevated (Run as Administrator). Exiting."
exit 1
}

$timestamp = (Get-Date).ToString('yyyyMMdd_HHmmss')
$logFile = Join-Path $env:USERPROFILE ("Desktop\FTDI_DisableSelectiveSuspend_Final_$timestamp.log")
"Started: $(Get-Date -Format u)" | Out-File -FilePath $logFile -Encoding UTF8

function Get-ComForInstance {
param([string]$instanceId)
try {
$sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue |
Where-Object { $_.PNPDeviceID -eq $instanceId }
if ($sp) { return $sp.DeviceID }
$tail = ($instanceId -split '\\')[-1]
if ($tail) {
$sp = Get-CimInstance -ClassName Win32_SerialPort -ErrorAction SilentlyContinue |
Where-Object { $_.PNPDeviceID -like "*$tail*" }
if ($sp) { return $sp.DeviceID }
}
} catch { }
return $null
}

# Find FTDI ports
$ports = Get-PnpDevice -Class Ports -PresentOnly -ErrorAction SilentlyContinue |
Where-Object { ($_.Manufacturer -and $_.Manufacturer -like '*FTDI*') -or ($_.InstanceId -and $_.InstanceId -match 'VID_0403') }

if (-not $ports -or $ports.Count -eq 0) {
"No FTDI COM ports found." | Tee-Object -FilePath $logFile -Append
Write-Output "No FTDI COM ports found. See log: $logFile"
exit 0
}

"Found $($ports.Count) FTDI COM port(s)." | Tee-Object -FilePath $logFile -Append

$createdCount = 0
$errors = @()
$processedDp = @{} # track DP paths already processed this run

foreach ($p in $ports) {
"----" | Tee-Object -FilePath $logFile -Append
"Device FriendlyName: $($p.FriendlyName)" | Tee-Object -FilePath $logFile -Append
"InstanceId: $($p.InstanceId)" | Tee-Object -FilePath $logFile -Append

$inst = $p.InstanceId
if ([string]::IsNullOrWhiteSpace($inst)) {
"InstanceId empty; skipping" | Tee-Object -FilePath $logFile -Append
continue
}

# Build exact registry path from InstanceId (do NOT search Enum by tail)
$enumBase = 'HKLM:\SYSTEM\CurrentControlSet\Enum'
# Escape and join safely
$regPathBase = "HKLM:\SYSTEM\CurrentControlSet\Enum\$inst"
$regPathBase = [string]$regPathBase

# Candidate Device Parameters locations for this instance
$dpCandidates = @(
"$regPathBase\Device Parameters",
"$regPathBase\0000\Device Parameters"
)

$dpFoundForInstance = $false

foreach ($dp in $dpCandidates) {
$dpStr = [string]$dp
"Checking: $dpStr" | Tee-Object -FilePath $logFile -Append

if ($processedDp.ContainsKey($dpStr)) {
"Already processed $dpStr this run - skipping." | Tee-Object -FilePath $logFile -Append
$dpFoundForInstance = $true
break
}

if (Test-Path $dpStr) {
$dpFoundForInstance = $true
"Using Device Parameters: $dpStr" | Tee-Object -FilePath $logFile -Append

# Mark as processed so other devices won't reprocess the same DP
$processedDp[$dpStr] = $true

# Get existing property names for accurate checks
$existingProps = @()
try {
$item = Get-ItemProperty -Path $dpStr -ErrorAction SilentlyContinue
if ($item) { $existingProps = $item.PSObject.Properties | ForEach-Object { $_.Name } }
} catch {
$existingProps = @()
}

# PortName - create only if missing
if (-not ($existingProps -contains 'PortName')) {
$friendly = $p.FriendlyName
$detectedCom = $null
if ($friendly -and ($friendly -match '\(COM(\d+)\)')) {
$detectedCom = "COM$($matches[1])"
"Detected COM from FriendlyName: $($detectedCom)" | Tee-Object -FilePath $logFile -Append
} else {
$detectedCom = Get-ComForInstance -instanceId $inst
if ($detectedCom) { "Detected COM via WMI: $($detectedCom)" | Tee-Object -FilePath $logFile -Append }
}

if ($detectedCom) {
if (-not $WhatIf) {
try {
New-Item -Path $dpStr -Force | Out-Null
New-ItemProperty -Path $dpStr -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null
"WROTE PortName = $($detectedCom) at $($dpStr)" | Tee-Object -FilePath $logFile -Append
$createdCount++
} catch {
"ERROR writing PortName at $($dpStr) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "PortName write error for $inst : $($_.Exception.Message)"
}
} else {
"WhatIf: would write PortName = $($detectedCom) at $($dpStr)" | Tee-Object -FilePath $logFile -Append
}
} else {
"Could not detect COM for $inst; PortName not written." | Tee-Object -FilePath $logFile -Append
}
} else {
"PortName already present at $($dpStr): $((Get-ItemProperty -Path $dpStr -Name 'PortName' -ErrorAction SilentlyContinue).PortName) - not changed" | Tee-Object -FilePath $logFile -Append
}

# selective-suspend props - create only if property name not present
$propsToCreate = @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }
foreach ($kv in $propsToCreate.GetEnumerator()) {
$name = $kv.Key; $val = $kv.Value
if ($existingProps -contains $name) {
"$($name) already present at $($dpStr) - skipping" | Tee-Object -FilePath $logFile -Append
} else {
if (-not $WhatIf) {
try {
New-Item -Path $dpStr -Force | Out-Null
New-ItemProperty -Path $dpStr -Name $name -PropertyType DWord -Value $val -Force -ErrorAction Stop | Out-Null
"Created $($name) = $($val) at $($dpStr)" | Tee-Object -FilePath $logFile -Append
$createdCount++
} catch {
"ERROR creating $($name) at $($dpStr) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "Create $($name) error for $inst : $($_.Exception.Message)"
}
} else {
"WhatIf: would create $($name) = $($val) at $($dpStr)" | Tee-Object -FilePath $logFile -Append
}
}
}

break
} else {
"Not found: $($dpStr)" | Tee-Object -FilePath $logFile -Append
}
} # end foreach dpCandidates

if (-not $dpFoundForInstance) {
"No Device Parameters found for instance $inst (expected path: $regPathBase). Creating primary DP." | Tee-Object -FilePath $logFile -Append
$dp = "$regPathBase\Device Parameters"
$dp = [string]$dp

if ($processedDp.ContainsKey($dp)) {
"Primary DP $dp already processed - skipping creation." | Tee-Object -FilePath $logFile -Append
continue
}

$processedDp[$dp] = $true

if ($WhatIf) {
"WhatIf: would create key $($dp) and attempt writes" | Tee-Object -FilePath $logFile -Append
} else {
try {
New-Item -Path $dp -Force | Out-Null
"Created key $($dp)" | Tee-Object -FilePath $logFile -Append
} catch {
"ERROR creating key $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "Create key error for $inst : $($_.Exception.Message)"
continue
}

# PortName detection & selective-suspend creation (same logic)
$detectedCom = $null
$friendly = $p.FriendlyName
if ($friendly -and ($friendly -match '\(COM(\d+)\)')) { $detectedCom = "COM$($matches[1])" }
if (-not $detectedCom) { $detectedCom = Get-ComForInstance -instanceId $inst }

if ($detectedCom) {
try {
New-ItemProperty -Path $dp -Name 'PortName' -PropertyType String -Value $detectedCom -Force -ErrorAction Stop | Out-Null
"WROTE PortName = $($detectedCom) at $($dp)" | Tee-Object -FilePath $logFile -Append
$createdCount++
} catch {
"ERROR writing PortName at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "PortName write error for $inst : $($_.Exception.Message)"
}
} else {
"Could not detect COM for $inst after creating key." | Tee-Object -FilePath $logFile -Append
}

foreach ($kv in @{ DeviceIdleEnabled=0; DefaultIdleState=0; UserSetDeviceIdleEnabled=0; SSIdleTimeout=0 }.GetEnumerator()) {
try {
New-ItemProperty -Path $dp -Name $kv.Key -PropertyType DWord -Value $kv.Value -Force -ErrorAction Stop | Out-Null
"Created $($kv.Key) = $($kv.Value) at $($dp)" | Tee-Object -FilePath $logFile -Append
$createdCount++
} catch {
"ERROR creating $($kv.Key) at $($dp) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
$errors += "Create prop error $($kv.Key) for $inst : $($_.Exception.Message)"
}
}
}
}

} # end foreach ports

"Created/changed count: $createdCount" | Tee-Object -FilePath $logFile -Append
if ($errors.Count -gt 0) {
"Errors: $($errors.Count)" | Tee-Object -FilePath $logFile -Append
$errors | Tee-Object -FilePath $logFile -Append
}

# Launch pnputil asynchronously so script ends quickly
try {
"Launching device rescan (pnputil /scan-devices) in background" | Tee-Object -FilePath $logFile -Append
$proc = Start-Process -FilePath 'pnputil.exe' -ArgumentList '/scan-devices' -NoNewWindow -PassThru
"pnputil started (PID $($proc.Id))" | Tee-Object -FilePath $logFile -Append
} catch {
"pnputil failed to start: $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
}

if (($createdCount -gt 0) -and (-not $WhatIf) -and (-not $NoReboot)) {
"Scheduling reboot in 15 seconds so changes take effect (abort with 'shutdown /a')." | Tee-Object -FilePath $logFile -Append
Start-Process -FilePath 'shutdown.exe' -ArgumentList @('/r','/t','15','/c','Applying FTDI Device Parameter changes') -NoNewWindow
} else {
"No reboot scheduled. If you created properties and want immediate recognition, run: pnputil /scan-devices or reboot manually." | Tee-Object -FilePath $logFile -Append
}

"Completed: $(Get-Date -Format u)" | Tee-Object -FilePath $logFile -Append
Write-Output "Done. Log saved to: $logFile"
 
Thanks — that explains the problem. The Device Manager checkbox is driver‑specific: it may be writing a different property name (or writing somewhere else) than the four names we set. So when you toggle the checkbox the script doesn’t see any change because it’s looking for the wrong registry value.
Next step — run a before/after registry diff for the exact device instance so we can see the exact value Device Manager changes. Run the short elevated PowerShell below, toggle the “Enable Selective Suspend” checkbox in Device Manager for one COM device while prompted, then press Enter. The script will save the before/after Device Parameters content and show any property names/values that changed.
1) How to run
  • Open PowerShell as Administrator (right‑click → Run as administrator).
  • Copy/paste the whole block below and run it.
2) The script (copy/paste and run elevated)
Code:
# Run as Administrator
# Save this entire block in an elevated PowerShell session and run it. # Find one FTDI COM device (or change filter if needed)
$dev = Get-PnpDevice -Class Ports -PresentOnly | Where-Object { ($_.Manufacturer -and $_.Manufacturer -like '*FTDI*') -or ($_.InstanceId -and $_.InstanceId -match 'VID_0403') } | Select-Object -First 1 if (-not $dev) { Write-Error "No FTDI COM device found. Run Get-PnpDevice -Class Ports to inspect." break
} $inst = $dev.InstanceId
Write-Output "Using device: $($dev.FriendlyName) ; InstanceId: $inst" # Build Device Parameters path candidates
$base = "HKLM:\SYSTEM\CurrentControlSet\Enum\$inst"
$candidates = @("$base\Device Parameters","$base\0000\Device Parameters") # Pick the first existing DP path or the first candidate if none exist
$dp = $candidates | Where-Object { Test-Path $_ } | Select-Object -First 1
if (-not $dp) { $dp = $candidates[0]; Write-Output "Device Parameters not found; will inspect/create at: $dp" }
else { Write-Output "Inspecting Device Parameters at: $dp" } $beforeFile = Join-Path $env:USERPROFILE "Desktop\FTDI_DP_before.json"
$afterFile = Join-Path $env:USERPROFILE "Desktop\FTDI_DP_after.json"
$diffFile = Join-Path $env:USERPROFILE "Desktop\FTDI_DP_diff.txt" # capture before
if (Test-Path $dp) { $before = Get-ItemProperty -Path $dp -ErrorAction SilentlyContinue
} else { $before = @{ } # empty
}
$before | ConvertTo-Json -Depth 5 | Out-File -FilePath $beforeFile -Encoding utf8
Write-Output "Saved BEFORE to $beforeFile" Write-Output "Now open Device Manager → Ports → select this device → Properties → Advanced. TOGGLE the 'Enable Selective Suspend' checkbox (check or uncheck) and click OK. When done, come back here and press Enter."
Read-Host -Prompt "Press Enter after toggling the checkbox" # capture after
if (Test-Path $dp) { $after = Get-ItemProperty -Path $dp -ErrorAction SilentlyContinue
} else { $after = @{ } # empty
}
$after | ConvertTo-Json -Depth 5 | Out-File -FilePath $afterFile -Encoding utf8
Write-Output "Saved AFTER to $afterFile" # compute differences (names and values)
$beforeObj = if ((Get-Content $beforeFile -Raw) -ne '') { ConvertFrom-Json (Get-Content $beforeFile -Raw) } else { @{} }
$afterObj = if ((Get-Content $afterFile -Raw) -ne '') { ConvertFrom-Json (Get-Content $afterFile -Raw) } else { @{} } $allNames = (@($beforeObj | Get-Member -MemberType NoteProperty | Select-Object -Expand Name) + @($afterObj | Get-Member -MemberType NoteProperty | Select-Object -Expand Name) | Sort-Object -Unique
$changes = @
foreach ($n in $allNames) { $bv = $null; $av = $null try { $bv = $beforeObj.$n } catch {} try { $av = $afterObj.$n } catch {} if ($bv -ne $av) { $changes += [PSCustomObject]@{ Property = $n; Before = $bv; After = $av } }
} if ($changes.Count -eq 0) { "No property values changed under $dp. If that happens, try toggling again and ensure you toggled the Advanced checkbox for the same instance; alternatively run a broader Enum search." | Out-File -FilePath $diffFile -Encoding utf8 Get-Content $diffFile
} else { $changes | Format-Table -AutoSize $changes | Out-File -FilePath $diffFile -Encoding utf8 Write-Output "Saved diff to $diffFile"
}
3) What you’ll see and next steps
  • The script will produce three files on your Desktop:
    • FTDI_DP_before.json
    • FTDI_DP_after.json
    • FTDI_DP_diff.txt
  • If the checkbox changed a registry value, FTDI_DP_diff.txt will list the property name and the before/after values.
  • Paste the content of FTDI_DP_diff.txt here (or paste the property name and before/after values). I’ll then:
    • tell you the exact New-ItemProperty line to set that property across all devices (and update your main script so it sets/clears the correct property), or
    • patch your script to set the exact property name automatically.
4) If the diff shows nothing changed
  • Possible reasons:
    • Device Manager writes to a different place (e.g. the driver's private store) — in that case run this broader search (admin) to find any Device Parameters keys that changed under Enum in the last few minutes:
    • I can give that command and parse results for you — say “run broad diff” and I’ll provide it.
    • The driver may not write until device is reinstalled — then the INF governs the default and you must update the INF AddReg for persistent change. I can produce an INF AddReg snippet if needed.
5) If you want me to patch the script immediately
  • If you prefer, run the diagnostic once and paste the diff file here and I’ll update the main script to set that exact registry property (and whether to set to 0 or remove/clear it depending on the driver behavior).
Would you like the broader Enum diff command now (search entire Enum for any Device Parameters values that changed after a timestamp) or run the per‑device before/after above and paste the diff?
 
Property Before
-------- ------
ConfigData
LatencyTimer
MinReadTimeout
MinWriteTimeout
PSDrive @{CurrentLocation=; Name=HKLM; Provider=; Root=HKEY_LOCAL_MACHINE; Description=The configuration set...
PSProvider @{ImplementingType=; HelpFile=System.Management.Automation.dll-Help.xml; Name=Registry; PSSnapIn=; M...
SSIdleTimeout 0