Skip to content

Instantly share code, notes, and snippets.

@HenkPoley
Created October 10, 2025 08:25
Show Gist options
  • Select an option

  • Save HenkPoley/4aedc30e5c8506450a66988bb560df5e to your computer and use it in GitHub Desktop.

Select an option

Save HenkPoley/4aedc30e5c8506450a66988bb560df5e to your computer and use it in GitHub Desktop.
Easus Disk Copy missing uninstaller PowerShell script; based on a Process Monitor trace of version the 6.7.1 installer
<#
EaseUS Disk Copy Cleanup Script
Generated: 2025-10-10T07:55:30
What it does:
- Enumerates and (optionally) removes EaseUS Disk Copy files/folders, registry keys/values, shortcuts.
- Handles multiple versions by matching directories like "EaseUSDiskCopy6.*" under ProgramData.
- Locates related services/tasks/processes whose executable paths point into those folders.
Safety:
- Shows a scrollable list (Out-GridView if available) of planned deletions first.
- Prompts for confirmation before deleting.
- Can export the list to a timestamped file for manual deletion.
#>
[CmdletBinding(SupportsShouldProcess = $true)]
param(
[switch]$ListOnly,
[string]$ExportListPath
)
function Test-Admin {
$currentIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object System.Security.Principal.WindowsPrincipal($currentIdentity)
return $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
}
if (-not (Test-Admin)) {
Write-Warning "Please run this script in an elevated PowerShell (Run as administrator)."
return
}
# --- Patterns and targets (derived from your install logs) ---
$BaseDirPatterns = @('C:\ProgramData\EaseUSDiskCopy*')
# Shortcuts
$Shortcuts = @('C:\Users\Public\Desktop\EaseUS Disk Copy.lnk')
# Registry keys
$RegKeysHKCU = @(
'HKCU:\Software\Classes\AppID\edc.exe',
'HKCU:\Software\EASEUS\EaseUS Disk Copy',
'HKCU:\Software\EaseUS',
'HKCU:\Software\EaseUS\EaseUS Disk Copy'
)
$RegKeysHKLM = @(
'HKCR:\AppID\edc.exe',
'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\edc.exe',
'HKLM:\SOFTWARE\WOW6432Node\EaseUS',
'HKLM:\SOFTWARE\WOW6432Node\EaseUS\EaseUS Disk Copy'
)
$AppCompatLayersKey = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers'
# --- Discover current system matches ---
$planned = @()
# Expand directories (including all versioned EaseUSDiskCopy*)
foreach ($pattern in $BaseDirPatterns) {
Get-ChildItem -Path $pattern -Directory -ErrorAction SilentlyContinue | ForEach-Object {
$planned += [pscustomobject]@{ Type = 'Directory'; Path = $_.FullName }
# Include subtree files too
Get-ChildItem -Path $_.FullName -Recurse -Force -ErrorAction SilentlyContinue | ForEach-Object {
if (-not $_.PSIsContainer) {
$planned += [pscustomobject]@{ Type = 'File'; Path = $_.FullName }
}
else {
$planned += [pscustomobject]@{ Type = 'Directory'; Path = $_.FullName }
}
}
}
}
# Include shortcuts if they exist
foreach ($lnk in $Shortcuts) {
if (Test-Path $lnk) { $planned += [pscustomobject]@{ Type = 'Shortcut'; Path = $lnk } }
}
# Registry keys (existence check)
foreach ($rk in $RegKeysHKCU + $RegKeysHKLM) {
try {
if (Test-Path -LiteralPath $rk) { $planned += [pscustomobject]@{ Type = 'RegistryKey'; Path = $rk } }
}
catch { }
}
# AppCompatFlags\Layers values pointing to EaseUSDiskCopy paths
if (Test-Path -LiteralPath $AppCompatLayersKey) {
try {
# $layersKey = Get-Item -LiteralPath $AppCompatLayersKey
# $vals = (Get-ItemProperty -LiteralPath $layersKey.PSPath) | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name
$rk = Get-Item -LiteralPath $AppCompatLayersKey
$vals = $rk.GetValueNames()
foreach ($name in $vals) {
if ($name -match '(?i)\\EaseUSDiskCopy') {
$planned += [pscustomobject]@{ Type = 'RegistryValue'; Path = ($AppCompatLayersKey + ' (ValueName) ' + $name) }
}
}
}
catch { }
}
# Services whose binary path points inside EaseUSDiskCopy
try {
$svcCandidates = Get-CimInstance Win32_Service -ErrorAction SilentlyContinue | Where-Object {
($_.PathName -match '(?i)\\EaseUSDiskCopy') -or ($_.Name -match '(?i)EaseUS|DiskCopy|edc')
}
foreach ($svc in $svcCandidates) {
$planned += [pscustomobject]@{ Type = 'Service'; Path = $svc.Name; Detail = $svc.PathName }
}
}
catch { }
# Scheduled tasks that reference EaseUSDiskCopy paths
try {
if (Get-Command Get-ScheduledTask -ErrorAction SilentlyContinue) {
$tasks = Get-ScheduledTask | Where-Object {
$_.TaskPath -match '(?i)EaseUS' -or $_.TaskName -match '(?i)EaseUS|DiskCopy' -or (($_.Actions | Out-String) -match '(?i)EaseUSDiskCopy')
}
foreach ($t in $tasks) {
$planned += [pscustomobject]@{ Type = 'ScheduledTask'; Path = $t.TaskName; Detail = $t.TaskPath }
}
}
}
catch { }
# De-duplicate planned items
$planned = $planned | Sort-Object Type, Path -Unique
# --- Present planned actions ---
if ($planned.Count -eq 0) {
Write-Host "No EaseUS Disk Copy related items found to remove based on current patterns."
return
}
# Optional export of list
function Export-PlannedList([string]$OutPath) {
$dir = Split-Path -Parent $OutPath
if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Force -Path $dir | Out-Null }
$planned | ConvertTo-Json -Depth 4 | Out-File -FilePath $OutPath -Encoding UTF8
Write-Host "Saved planned list to $OutPath"
}
$timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
if (-not $ExportListPath) { $ExportListPath = Join-Path -Path (Get-Location) -ChildPath ("EaseUS-DiskCopy-PlannedRemovals-$timestamp.json") }
try {
if (Get-Command Out-GridView -ErrorAction SilentlyContinue) {
$null = $planned | Out-GridView -Title "Planned removals (review and close to continue)"
}
else {
Write-Host "Planned removals:"
$planned | Format-Table -AutoSize | Out-Host
}
}
catch { }
Write-Host ""
Write-Host "Options: [Y] Proceed with deletion [N] Cancel [S] Save list only to file"
if ($ListOnly) { $resp = 'S' } else { $resp = Read-Host "Choose Y/N/S" }
if ($resp -match '^[sS]$') {
Export-PlannedList -OutPath $ExportListPath
return
}
elseif ($resp -notmatch '^[yY]$') {
Write-Host "Cancelled."
return
}
# --- Stop related processes ---
# Any process whose module path is within EaseUSDiskCopy base directories
$baseDirs = @()
foreach ($pattern in $BaseDirPatterns) {
Get-ChildItem -Path $pattern -Directory -ErrorAction SilentlyContinue | ForEach-Object { $baseDirs += $_.FullName }
}
$baseDirs = $baseDirs | Sort-Object -Unique
if ($baseDirs.Count -gt 0) {
Get-Process | ForEach-Object {
try {
$p = $_
$path = $p.Path
if ($path) {
foreach ($bd in $baseDirs) {
if ($path -like ($bd + '*')) {
Write-Host "Stopping process $($p.Name) ($($p.Id))"
Stop-Process -Id $p.Id -Force -ErrorAction SilentlyContinue
break
}
}
}
}
catch { }
}
}
# --- Remove scheduled tasks ---
try {
if (Get-Command Unregister-ScheduledTask -ErrorAction SilentlyContinue) {
$planned | Where-Object Type -eq 'ScheduledTask' | ForEach-Object {
$tn = $_.Path
try { Unregister-ScheduledTask -TaskName $tn -Confirm:$false -ErrorAction SilentlyContinue } catch { }
}
}
}
catch { }
# --- Stop & delete services ---
$planned | Where-Object Type -eq 'Service' | ForEach-Object {
$svcName = $_.Path
try { Stop-Service -Name $svcName -Force -ErrorAction SilentlyContinue } catch { }
try { sc.exe delete $svcName | Out-Null } catch { }
}
# --- Remove registry values in AppCompatFlags\Layers ---
if (Test-Path -LiteralPath $AppCompatLayersKey) {
try {
# $reg = Get-Item -LiteralPath $AppCompatLayersKey
# $props = (Get-ItemProperty -LiteralPath $reg.PSPath) | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name
$rk = Get-Item -LiteralPath $AppCompatLayersKey
$props = $rk.GetValueNames()
foreach ($name in $props) {
if ($name -match '(?i)\\EaseUSDiskCopy') {
try { Remove-ItemProperty -LiteralPath $AppCompatLayersKey -Name $name -ErrorAction SilentlyContinue } catch { }
}
}
}
catch { }
}
# --- Remove registry keys ---
function Remove-KeyIfExists([string]$keyPath) {
try {
if (Test-Path -LiteralPath $keyPath) {
Remove-Item -LiteralPath $keyPath -Recurse -Force -ErrorAction SilentlyContinue
}
}
catch { }
}
# Remove product-specific subkeys first, then vendor roots if empty
foreach ($rk in ($RegKeysHKCU + $RegKeysHKLM)) {
Remove-KeyIfExists -keyPath $rk
}
# Attempt to remove empty vendor keys
foreach ($vendorKey in @('HKCU:\Software\EaseUS', 'HKCU:\Software\EASEUS', 'HKLM:\SOFTWARE\WOW6432Node\EaseUS')) {
try {
if (Test-Path $vendorKey) {
$sub = Get-ChildItem -LiteralPath $vendorKey -ErrorAction SilentlyContinue
if ($null -eq $sub -or $sub.Count -eq 0) {
Remove-Item -LiteralPath $vendorKey -Force -ErrorAction SilentlyContinue
}
}
}
catch { }
}
# --- Remove files & directories ---
# Remove shortcuts
foreach ($lnk in $Shortcuts) {
try { if (Test-Path $lnk) { Remove-Item -LiteralPath $lnk -Force -ErrorAction SilentlyContinue } } catch { }
}
# Remove versioned root directories
foreach ($pattern in $BaseDirPatterns) {
Get-ChildItem -Path $pattern -Directory -ErrorAction SilentlyContinue | ForEach-Object {
try { Remove-Item -LiteralPath $_.FullName -Recurse -Force -ErrorAction SilentlyContinue } catch { }
}
}
Write-Host "Removal completed."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment