自动化磁盘清理cleanmgr.exe的过程,无需用户干预

26
我正在开发一份powershell脚本文件,该文件将在没有用户干预的情况下执行一些磁盘清理。用户将无法配置任何内容。
当我运行cleanmgr.exe /d c: sageset:1时,会弹出一个窗口来选择要清除的文件/文件夹(清理选项)。
这将创建一个包含清理选项设置的注册表条目,之后您可以运行cleanmgr.exe /sagerun:1,它将实际执行清理操作。
有没有一种方法可以直接使用powershell/command line指定清理选项(而无需手动选择要删除的内容)?

顺便提一下,这个过程已经通过内置的计划任务在Windows 10上自动化了。 - Nathan Hartley
2
@NathanHartley:可能是这样,但我需要在请求时从我的Windows应用程序中显式执行此操作,因此内置的计划任务不足够。 - Pinte Dani
你可以尝试在自己的电脑上运行cleanmgr /SAGESET:1,然后导出HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches,再将该.reg文件导入到你想要运行cleanmgr.exe /sagerun:1的电脑上。如果适用的话,你还可以使用组策略来配置存储感知。 - undefined
9个回答

12
以下是自动化CleanMgr.exe的Powershell脚本。在这种情况下,它会删除临时文件并运行更新清理扩展来清除过时的服务包备份文件(Windows 10现在通过计划任务自动执行此操作)。要自动化其他扩展,请在相应的注册表键中创建“StateFlags0001”属性,如New-ItemProperty行所示。您将在“VolumeCaches”分支中找到注册表键名称。
至于静默,此脚本尝试在隐藏窗口中启动CleanMgr.exe。但是,CleanMgr在某些时候会生成新进程,这些进程是可见的,必须单独等待。
Write-Host 'Clearing CleanMgr.exe automation settings.'
Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\*' -Name StateFlags0001 -ErrorAction SilentlyContinue | Remove-ItemProperty -Name StateFlags0001 -ErrorAction SilentlyContinue

Write-Host 'Enabling Update Cleanup. This is done automatically in Windows 10 via a scheduled task.'
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Update Cleanup' -Name StateFlags0001 -Value 2 -PropertyType DWord

Write-Host 'Enabling Temporary Files Cleanup.'
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Temporary Files' -Name StateFlags0001 -Value 2 -PropertyType DWord

Write-Host 'Starting CleanMgr.exe...'
Start-Process -FilePath CleanMgr.exe -ArgumentList '/sagerun:1' -WindowStyle Hidden -Wait

Write-Host 'Waiting for CleanMgr and DismHost processes. Second wait neccesary as CleanMgr.exe spins off separate processes.'
Get-Process -Name cleanmgr,dismhost -ErrorAction SilentlyContinue | Wait-Process

$UpdateCleanupSuccessful = $false
if (Test-Path $env:SystemRoot\Logs\CBS\DeepClean.log) {
    $UpdateCleanupSuccessful = Select-String -Path $env:SystemRoot\Logs\CBS\DeepClean.log -Pattern 'Total size of superseded packages:' -Quiet
}

if ($UpdateCleanupSuccessful) {
    Write-Host 'Rebooting to complete CleanMgr.exe Update Cleanup....'
    SHUTDOWN.EXE /r /f /t 0 /c 'Rebooting to complete CleanMgr.exe Update Cleanup....'
}

5
对于像我这样初学PS的人,可能会坐在那里犯傻,想知道它是否正在工作?如果你想看到它在做什么,请确保添加$VerbosePreference="Continue"。 - JDPeckham
2
这段代码是从一个带有 -Verbose 参数的高级函数中复制粘贴而来的。尽管 Don Jones 说每次使用 Write-Host 都会杀死一只小狗,但我还是会将其改为 Write-Host。 - Nathan Hartley

6
以下所提供的PowerShell逻辑是动态的,并且已准备就绪,可以通过选择所有的“Sageset”选项并且不需要用户交互来实现自动化。这是受该帖子多个回答和评论的启发而编写的。
注意:我对其进行了调整以满足我的需求,并在多个远程和本地Windows 10系统上成功使用,没有产生任何问题。
在本地系统上运行。
Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\*' | % {
    New-ItemProperty -Path $_.PSPath -Name StateFlags0001 -Value 2 -PropertyType DWord -Force
   };
Start-Process -FilePath CleanMgr.exe -ArgumentList '/sagerun:1' ##-WindowStyle Hidden

远程运行

$cred = Get-Credential "domain\administrator";
Invoke-Command -ComputerName "computer004" {
    Process {
        Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\*' | % {
            New-ItemProperty -Path $_.PSPath -Name StateFlags0001 -Value 2 -PropertyType DWord -Force
           };
        Start-Process -FilePath CleanMgr.exe -ArgumentList '/sagerun:1' -WindowStyle Hidden
    }
} -AsJob -Credential $cred 

支持资源


5
您可以使用cleanmgr /verylowdisk来自动执行所有清理步骤,且无需用户交互。

不会自动化所有的清理步骤,只有一些! - metamorphosis
3
您可以运行“cleanmgr.exe /AUTOCLEAN”来清理一些未被其他步骤清理的内容。 我将这两个步骤合并了。 - HackSlash

4
我找到的唯一解决方案是手动设置注册表值,如下所示:

...

#Set StateFlags0012 setting for each item in Windows 8.1 disk cleanup utility
if (-not (get-itemproperty -path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Active Setup Temp Folders' -name StateFlags0012 -ErrorAction SilentlyContinue)) {
set-itemproperty -path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Active Setup Temp Folders' -name StateFlags0012 -type DWORD -Value 2
set-itemproperty -path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\BranchCache' -name StateFlags0012 -type DWORD -Value 2
set-itemproperty -path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Downloaded Program Files' -name StateFlags0012 -type DWORD -Value 2

查看完整示例


2

1

我已经尝试在Windows 10和11测试虚拟机上使用此方法,既可以从我的RMM工具(该工具在系统上本地运行脚本),也可以在两者上都作为.PS1在管理员权限的Powershell会话中本地运行,并将ExecutionPolicy设置为Bypass。(注意:我的RMM工具将脚本作为SYSTEM运行;当我使用PS1时,我作为系统的本地管理员运行)。

在我尝试过的几乎每个系统上,cleanmgr第一次都会挂起,永远无法完成。我尝试了使用/sageset /sagerun设置或仅使用/verylowdisk的cleanmgr。我使用了辅助等待命令,或者没有使用它。当我将其作为.PS1执行时,即使使用-WindowStyle Hidden,Cleanmgr仍然会显示一个弹出窗口,在某些时候会消失,但脚本仍然卡住,停留在那里一个小时或更长时间(测试系统有SSD,因此不慢),然后我放弃了。当我通过RMM工具执行时,它要么像.PS1一样挂起,要么偶尔会输出“对象引用未设置为对象实例”或其他错误。 在某些系统上,如果我结束脚本,它就会在后续尝试中运行。但我无法让它始终如一地运行。真是令人沮丧。

我快要放弃使用一堆脚本化的Remove-Item命令并完全跳过CLEANMGR.EXE,因为至少那些是有效的。否则,我不确定该去哪里。

编辑:答案是只有在使用-PassThru时才有效。否则,它完全是个抛硬币。所以我添加了这个选项。但我担心它不会在我的脚本的下一个部分完成(添加“-Wait”会导致问题回来),因此我添加了“Start-Sleep -Seconds 300”以确保在继续计算清理期间释放了多少磁盘空间之前,给予足够的时间。


1

我在最新的Win11中进行了几次测试,所有参数都已经添加。每当我添加参数'/sagerun:...'时,该进程就不再隐藏。唯一可行的解决方案是与任务计划程序相同的精确调用,带有参数'/autocleanstoragesense /d C:'。

如果我想添加一个sagerun参数,我必须以不同的用户上下文(这里是本地系统)启动该进程:

$reg = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches'
$null = Get-ItemProperty -Path "$reg\*" -Name StateFlags0001 -ea 0 | Remove-ItemProperty -Name StateFlags0001 -ea 0
$null = New-ItemProperty -Path "$reg\Update Cleanup" -Name StateFlags0001 -Value 2 -PropertyType DWord
$null = New-ItemProperty -Path "$reg\Temporary Files" -Name StateFlags0001 -Value 2 -PropertyType DWord
$null = New-ItemProperty -Path "$reg\Previous Installations" -Name StateFlags0001 -Value 2 -PropertyType DWord
$null = New-ItemProperty -Path "$reg\Recycle Bin" -Name StateFlags0001 -Value 2 -PropertyType DWord

# start cleanup as local system (requires admin-rights):
$task      = "Start Disk Cleanup"
$trigger   = New-ScheduledTaskTrigger -Once -At (get-date)
$action    = New-scheduledTaskAction -Execute "C:\Windows\System32\cleanmgr.exe" -Argument "/sagerun:1"
$settings  = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 20) -StartWhenAvailable -Hidden
$principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -RunLevel Highest
$task1     = Register-ScheduledTask -trigger $trigger -Action $action -TaskName $task -Settings $settings -Principal $principal -TaskPath "CustomTasks" -Force 0 -ea 0
$result    = Start-ScheduledTask -TaskName $task -TaskPath "CustomTasks"
$result    = Unregister-ScheduledTask -TaskName $task -Confirm:0

# we can now remove the scheduled task folder (if empty):
$scheduler = New-Object -ComObject Schedule.Service
$scheduler.connect()
$rootDir = $scheduler.GetFolder('\')
try {$rootDir.DeleteFolder("CustomTasks", $null)} catch {}

Get-Process -Name cleanmgr,dismhost -ea 0 | Wait-Process
'done.'

0

在powershell脚本中或单独运行CleanMgr.exe似乎很正常,只要您使用具有本地管理员权限的帐户在本地运行它即可。但是尝试通过任何远程管理工具或远程脚本命令(Invoke-Command)远程运行它时,它不会运行。您可能会看到进程在远程系统上运行,但似乎没有清理任何内容,而且该进程永远不会结束。如果有人能够在没有任何用户交互的情况下远程运行cleanmgr.exe,例如ConfigMgr右键单击工具、ConfigMgr应用程序或PKG、任务计划程序,我会很感兴趣。


是的,我一直成功地远程运行它,使用以下命令并确认它只在使用域管理员凭据的数百台机器上使用invoke-command时没有任何问题。我也注意到它似乎会在 RAM 中冻结。当我远程运行它时,我通常会使用 DISM 和 cleanmgr.exe 的混合。在具有缓慢 HDD 物理磁盘而不是更快的 SSD 的机器上,根据需要清理的内容多少,可能需要更长时间才能运行。我想我知道你在说什么,但耐心对我有所帮助。也许是权限问题? - Bitcoin Murderous Maniac

0

这个脚本将从注册表中获取所有卷缓存,使它们可以被清理并运行CLEANMGR.EXE来清理所有缓存。

$VolumeCachesRegDir = "hklm:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches"
$CacheDirItemNames = Get-ItemProperty "$VolumeCachesRegDir\*" | select -ExpandProperty PSChildName

$CacheDirItemNames | 
    %{
        $exists = Get-ItemProperty -Path "$VolumeCachesRegDir\$_" -Name "StateFlags6553" -ErrorAction SilentlyContinue
        If (($exists -ne $null) -and ($exists.Length -ne 0))
            {
                Set-ItemProperty -Path "$VolumeCachesRegDir\$_" -Name StateFlags6553 -Value 2
            }
        else
            {
                New-ItemProperty -Path "$VolumeCachesRegDir\$_" -Name StateFlags6553 -Value 0 -PropertyType DWord
            }
     }
Start-Sleep -Seconds 3


Write-Host 'Running CleanMgr.exe...'
Start-Process -FilePath CleanMgr.exe -ArgumentList '/sagerun:65535' -WindowStyle Hidden -PassThru
cls

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接