Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Requires -Version 5.1
- <#
- .SYNOPSIS
- Disables AMD's process watcher for the currently installed display driver.
- .DESCRIPTION
- Resolves each present AMD PCI display device to its current display-class key
- and service. No driver version, class instance number or service suffix is
- hardcoded. Run again after driver updates, because AMD may create a new service.
- Run in an elevated PowerShell. Use -WhatIf for read-only discovery.
- Backups and results are saved under mem\amd-process-watcher beside this script.
- The script never restarts Windows, Docker or the graphics device.
- .EXAMPLE
- .\DisableProcessWatcherSupport.ps1
- .EXAMPLE
- .\DisableProcessWatcherSupport.ps1 -WhatIf
- #>
- [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')]
- param()
- $ErrorActionPreference='Stop'
- $valueName='Gmx_MgpuProcessWatcherSupport'
- $displayClass='{4d36e968-e325-11ce-bfc1-08002be10318}'
- $principal=New-Object Security.Principal.WindowsPrincipal ([Security.Principal.WindowsIdentity]::GetCurrent())
- if(-not $WhatIfPreference -and -not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)){
- throw 'Run this script in PowerShell as Administrator. Use -WhatIf for discovery without changes.'
- }
- # Device -> Enum\PCI binding -> current display-class instance -> active service.
- # Enumerating service names alone would include obsolete driver installations.
- $devices=@(Get-CimInstance Win32_PnPEntity -Filter "PNPClass = 'Display'" |
- Where-Object {$_.PNPDeviceID -match '^PCI\\VEN_1002&' -and $_.Present -ne $false})
- if(-not $devices.Count){throw 'No present AMD PCI display device was found.'}
- $targets=@{}
- foreach($device in $devices){
- $enumKey='HKLM:\SYSTEM\CurrentControlSet\Enum\'+$device.PNPDeviceID
- $binding=Get-Item -LiteralPath $enumKey
- if([string]$binding.GetValue('ClassGUID') -ine $displayClass){throw ('Unexpected device class: '+$device.PNPDeviceID)}
- $classReference=[string]$binding.GetValue('Driver')
- if($classReference -notmatch ('^'+[regex]::Escape($displayClass)+'\\[0-9]+$')){
- throw ('The display device has no valid current class-instance binding: '+$device.PNPDeviceID)
- }
- $classKey='HKLM:\SYSTEM\CurrentControlSet\Control\Class\'+$classReference
- # Read only the needed values; unrelated AMD class values can have malformed
- # registry types that make Get-ItemProperty over the entire key fail.
- $class=Get-Item -LiteralPath $classKey
- $provider=[string]$class.GetValue('ProviderName')
- if($provider -notmatch 'AMD|Advanced Micro Devices'){
- throw ('The active display driver is not supplied by AMD: '+$classKey)
- }
- $service=[string]$binding.GetValue('Service')
- if($service -notmatch '^[a-zA-Z0-9_.-]+$'){throw 'The active AMD device has no valid service binding.'}
- $serviceKey='HKLM:\SYSTEM\CurrentControlSet\Services\'+$service
- $serviceInfo=Get-Item -LiteralPath $serviceKey
- $imagePath=[string]$serviceInfo.GetValue('ImagePath')
- if([string]::IsNullOrWhiteSpace($imagePath)){
- throw ('The current AMD service has no driver image: '+$service)
- }
- if(-not $targets.ContainsKey($service)){
- $targets[$service]=[ordered]@{
- Service=$service;Key=$serviceKey+'\Parameters';Name=$valueName
- ImagePath=$imagePath;Devices=@()
- }
- }
- $targets[$service].Devices+=,[ordered]@{
- Name=$device.Name;InstanceId=$device.PNPDeviceID;DisplayClassKey=$classKey
- DriverVersion=[string]$class.GetValue('DriverVersion');InfPath=[string]$class.GetValue('InfPath')
- ProviderName=$provider
- }
- }
- $runDirectory=$null
- $results=New-Object 'System.Collections.Generic.List[object]'
- foreach($target in @($targets.Values|Sort-Object Service)){
- Write-Host ('AMD service: '+$target.Service)
- foreach($device in $target.Devices){Write-Host (' '+$device.Name+' -> '+$device.DisplayClassKey)}
- if(-not $PSCmdlet.ShouldProcess(($target.Key+'\'+$valueName),'Set REG_DWORD to 0')){continue}
- if(-not $runDirectory){
- $runDirectory=Join-Path $PSScriptRoot ('mem\amd-process-watcher\'+[datetime]::UtcNow.ToString('yyyyMMdd-HHmmss-fff')+'-'+[guid]::NewGuid().ToString('N').Substring(0,8))
- New-Item -ItemType Directory -Path $runDirectory -Force|Out-Null
- }
- $keyExists=Test-Path -LiteralPath $target.Key
- $item=if($keyExists){Get-Item -LiteralPath $target.Key}else{$null}
- $exists=$keyExists -and ($item.GetValueNames() -contains $valueName)
- $before=[ordered]@{
- Service=$target.Service;Key=$target.Key;Name=$valueName;KeyExisted=$keyExists
- ValueExisted=$exists;Kind=$null;Value=$null;Devices=$target.Devices
- ImagePath=$target.ImagePath;Utc=[datetime]::UtcNow.ToString('o')
- }
- if($exists){$before.Kind=$item.GetValueKind($valueName).ToString();$before.Value=$item.GetValue($valueName)}
- $backup=Join-Path $runDirectory ($target.Service+'-before.json')
- $before|ConvertTo-Json -Depth 7|Set-Content -LiteralPath $backup -Encoding UTF8
- $result=[ordered]@{Service=$target.Service;Key=$target.Key;Name=$valueName;Kind='DWord';Value=0;Changed=$false;Verified=$false;Backup=$backup;Error=$null}
- try{
- if(-not ($exists -and $before.Kind -eq 'DWord' -and $before.Value -eq 0)){
- if(-not $keyExists){New-Item -Path $target.Key -Force|Out-Null}
- New-ItemProperty -LiteralPath $target.Key -Name $valueName -PropertyType DWord -Value 0 -Force|Out-Null
- $result.Changed=$true
- }
- $after=Get-Item -LiteralPath $target.Key
- if(-not ($after.GetValueNames() -contains $valueName) -or $after.GetValueKind($valueName).ToString() -ne 'DWord' -or $after.GetValue($valueName) -ne 0){
- throw ('Registry verification failed: '+$target.Key)
- }
- $result.Verified=$true
- Write-Host ('Verified REG_DWORD 0: '+$target.Key+'\'+$valueName)
- }catch{$result.Error=$_.Exception.ToString();throw}
- finally{
- $results.Add([pscustomobject]$result)
- $results|ConvertTo-Json -Depth 7|Set-Content -LiteralPath (Join-Path $runDirectory 'result.json') -Encoding UTF8
- }
- }
- if($runDirectory){
- Write-Host ('Backup and verification: '+$runDirectory)
- Write-Host 'Restart Windows yourself to reload the driver setting. No restart was performed.'
- $results
- }
Advertisement