Thanks — I fixed the bracket mistakes and prepared a safe overwrite so you don’t have to edit the file manually.
Please run the following in an elevated PowerShell (Run as Administrator). It will overwrite C:\Users\spencer.besenski\Documents\Disable_Selective_Suspend.ps1 with a corrected, parse‑clean script, then print "WROTE SCRIPT". After that I show the command to verify parsing (won’t execute the script).
1) Paste & run (elevated) — this writes the corrected script file:
$script = @'
<#
Disable_Selective_Suspend.ps1
- Force-overwrite selective-suspend properties (DeviceIdleEnabled, DefaultIdleState, UserSetDeviceIdleEnabled, SSIdleTimeout)
- Ensure ConfigData first 4 bytes are 01 00 3F 3F (modify only those bytes)
- Keep PortName behavior (write only if missing)
- Launch pnputil /scan-devices in background and optionally schedule reboot
- Supports -WhatIf for dry-run
Run as Administrator.
>
param(
[switch]$WhatIf,
[switch]$NoReboot)
ensure elevated
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) {
Write-Error "This script must be run as Administrator. Exiting."
exit 1
}
$timestamp = (Get-Date).ToString('yyyyMMdd_HHmmss')
$logFile = Join-Path $env:USERPROFILE ("Desktop\Disable_Selective
Suspend$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
}
desired first 4 bytes (01 00 3F 3F)
$desiredBytes = [byte[] (0x01,0x00,0x3F,0x3F)
corresponding little-endian DWORD
$desiredDword = [uint32]0x3F3F0001
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 = @
$processedDp = @{} # avoid reprocessing same DP
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 }
$regPathBase = "HKLM:\SYSTEM\CurrentControlSet\Enum\$inst"
$dpCandidates = @("$regPathBase\Device Parameters","$regPathBase\0000\Device Parameters")
$dpFoundForInstance = $false
foreach ($dp in $dpCandidates) {
$dpStr = [string]$dp
"Checking: $dpStr" | Tee-Object -FilePath $logFile -Append
Code:
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 $processedDp[$dpStr] = $true # Read existing properties try { $item = Get-ItemProperty -Path $dpStr -ErrorAction SilentlyContinue $existingProps = if ($item) { $item.PSObject.Properties | ForEach-Object { $_.Name } } else { @ } } catch { $existingProps = @ } # PortName: write 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 ($WhatIf) { "WhatIf: would write PortName = $($detectedCom) at $($dpStr)" | Tee-Object -FilePath $logFile -Append } else { 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 { "Could not detect COM for $inst; PortName not written." | Tee-Object -FilePath $logFile -Append } } else { $currPort = (Get-ItemProperty -Path $dpStr -Name 'PortName' -ErrorAction SilentlyContinue).PortName "PortName already present at $($dpStr): $($currPort) - not changed" | Tee-Object -FilePath $logFile -Append } # Force-selective-suspend writes if missing or not 0 $toForce = @{ DeviceIdleEnabled = 0; DefaultIdleState = 0; UserSetDeviceIdleEnabled = 0; SSIdleTimeout = 0 } foreach ($kv in $toForce.GetEnumerator { $name = $kv.Key; $desired = [int]$kv.Value try { $existingVal = (Get-ItemProperty -Path $dpStr -Name $name -ErrorAction SilentlyContinue).$name } catch { $existingVal = $null } $needWrite = $false if ($existingVal -eq $null) { $needWrite = $true } else { try { if ([int]$existingVal -ne $desired) { $needWrite = $true } } catch { $needWrite = $true } } if ($needWrite) { if ($WhatIf) { "WhatIf: would set $($name) = $desired at $($dpStr)" | Tee-Object -FilePath $logFile -Append } else { try { New-Item -Path $dpStr -Force | Out-Null New-ItemProperty -Path $dpStr -Name $name -PropertyType DWord -Value $desired -Force -ErrorAction Stop | Out-Null "WROTE $($name) = $desired at $($dpStr)" | Tee-Object -FilePath $logFile -Append $createdCount++ } catch { "ERROR writing $($name) at $($dpStr) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "Write $($name) error for $inst : $($_.Exception.Message)" } } } else { "$($name) already = $existingVal at $($dpStr) - not changed" | Tee-Object -FilePath $logFile -Append } } # ConfigData: ensure first 4 bytes are 01 00 3F 3F try { $cfgRaw = $null try { $cfgRaw = (Get-ItemProperty -Path $dpStr -Name 'ConfigData' -ErrorAction SilentlyContinue).ConfigData } catch { $cfgRaw = $null } } catch { $cfgRaw = $null } if ($cfgRaw -ne $null) { if ($cfgRaw -is [byte[]) { $bytes = [byte[]$cfgRaw $origType = 'Binary' } elseif ($cfgRaw -is [int] -or $cfgRaw -is [uint32] -or $cfgRaw -is [long]) { $bytes = [BitConverter]::GetBytes([uint32]$cfgRaw) $origType = 'DWord' } else { try { $bytes = [byte[]$cfgRaw; $origType='Binary' } catch { $bytes = @; $origType='Unknown' } } } else { # not present -> create empty array (we'll pad to 4) $bytes = @ $origType = 'Missing' } if ($bytes.Length -lt 4) { $newBytes = New-Object byte[] 4 if ($bytes.Length -gt 0) { $bytes.CopyTo($newBytes,0) } $bytes = $newBytes } $needCfgWrite = $false for ($i=0; $i -lt 4; $i++) { if ($bytes[$i] -ne $desiredBytes[$i]) { $needCfgWrite = $true; break } } if ($needCfgWrite) { for ($i=0; $i -lt 4; $i++) { $bytes[$i] = $desiredBytes[$i] } if ($WhatIf) { "WhatIf: would update ConfigData first 4 bytes at $($dpStr) (orig type: $origType)" | Tee-Object -FilePath $logFile -Append } else { try { if ($origType -eq 'DWord') { $newDword = [BitConverter]::ToUInt32($bytes,0) New-Item -Path $dpStr -Force | Out-Null New-ItemProperty -Path $dpStr -Name 'ConfigData' -PropertyType DWord -Value $newDword -Force -ErrorAction Stop | Out-Null "WROTE ConfigData (DWORD) = 0x$([Convert]::ToString($newDword,16).ToUpper at $($dpStr)" | Tee-Object -FilePath $logFile -Append } else { New-Item -Path $dpStr -Force | Out-Null Set-ItemProperty -Path $dpStr -Name 'ConfigData' -Value $bytes -ErrorAction Stop "WROTE ConfigData (Binary) first 4 bytes updated at $($dpStr)" | Tee-Object -FilePath $logFile -Append } $createdCount++ } catch { "ERROR writing ConfigData at $($dpStr) : $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append $errors += "ConfigData write error for $inst : $($_.Exception.Message)" } } } else { "ConfigData first 4 bytes already match desired pattern at $($dpStr) (no change)." | Tee-Object -FilePath $logFile -Append } break
} else { "Not found: $($dpStr)" | Tee-Object -FilePath $logFile -Append
}
}
if (-not $dpFoundForInstance) {
"No Device Parameters found for instance $inst (expected path: $regPathBase). Skipping." | Tee-Object -FilePath $logFile -Append
}
} # 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"
'@
Set-Content -Path 'C:\Users\spencer.besenski\Documents\Disable_Selective_Suspend.ps1' -Value $script -Encoding UTF8
Write-Output 'WROTE SCRIPT'
2) Parse-check (no execution)
Run this to ensure the file parses:
powershell -NoProfile -Command "[scriptblock]::Create((Get-Content -Raw 'C:\Users\spencer.besenski\Documents\Disable_Selective_Suspend.ps1'); Write-Output 'Parse OK'"
If you see "Parse OK", run a dry run:
powershell -ExecutionPolicy Bypass -File 'C:\Users\spencer.besenski\Documents\Disable_Selective_Suspend.ps1' -WhatIf
If anything still errors, paste the exact new console error output and I’ll patch immediately.