I am attempting to create a powershell script to both shutdown the windows update service as well as clear out the update cache in C:\Windows\SoftwareDistribution\ on a large list of devices that I am connecting to with PSSession. Sounds easy enough however I cant seem to get Remove-Item to delete all the files and folders in this directory. Below is the main part of the script showing the commands I am issuing on each machine:
# Attempts to reset the Windows Update service on all machines in the CSV file
foreach ($machine in $csv)
{
try
{
# Attempts to create a powershell session on the machine to remotely issue commands
$session = New-PSSession -ComputerName $machine.Name -ErrorAction Stop
# Attempts to shutdown the Windows Update service
Invoke-Command -Session $session -ScriptBlock {Stop-Service -Name 'wuauserv' -Force}
# Deletes the Windows Update cache folder
Invoke-Command -Session $session -ScriptBlock {
Start-Sleep -Seconds 1
#Remove-Item -Path 'C:\Windows\SoftwareDistribution\' -Recurse -Force
Get-ChildItem -Path 'C:\Windows\SoftwareDistribution\' -Recurse -Force | Remove-Item -Recurse -Force
}
# Restarts the Windows Update service
Invoke-Command -Session $session -ScriptBlock {
Start-Sleep -Seconds 1
Start-Service -Name 'wuauserv'
}
# Schedules a system reboot at 9pm for good measure
Invoke-Command -Session $session -ScriptBlock{
[datetime]$restartTime = '9PM'
[datetime]$currentTime = Get-Date
[int]$restartDelay = ($restartTime - $currentTime).TotalSeconds
shutdown -r -t $restartDelay
}
# Closes the Powershell session
Remove-PSSession $session
# Sets the outcome of the machine to be written to WindowsUpdateReset.csv
[string]$outcome = 'Completed'
}
At first I was attempting to use Remove-Item -Path 'C:\Windows\SoftwareDistribution\' -Recurse -Force
to recursively delete all the files but kept running into errors stating that the path couldn't be found or the directory was not empty, after looking around I found lots of mentions that this doesn't work consistently and that Get-ChildItem -Path 'C:\Windows\SoftwareDistribution\' -Recurse -Force | Remove-Item -Recurse -Force
would work better. This did resolve those errors but now I get access denied errors. I tried using Get-ChildItem -Path 'C:\Windows\SoftwareDistribution\' -Recurse | foreach { Remove-Item $_.FullName -Recurse -Force }
but this didn't change the outcome. I am a local admin with full rights on all of these machines, I can delete the files without any issues both in file explorer and with Remove-Item if I do each file individually but as soon as I attempt to run it recursively on all the files I get access denied errors. Ive even tried to run this locally on the device to see if maybe PSSession was causing an issue but no changes. I saw that this could potentially be caused by file locking but after messing with this I found the files weren't locked, especially since I can delete them individually. Ive been banging my head against this for a bit now and figured I may need some additional insight.
Instead of piping the output from Get-ChildItem
, let Remove-Item
traverse the given path, most likely what is happening is that a parent folder is being removed together with all its children but then those already deleted items are being piped again to Remove-Item
.
In summary, change:
Get-ChildItem -Path 'C:\Windows\SoftwareDistribution\' -Recurse -Force | Remove-Item -Recurse -Force
To use only Remove-Item
with the *
at the end of your path symbolizing you only want to get rid of child items in SoftwareDistribution
but not the folder itself:
Remove-Item 'C:\Windows\SoftwareDistribution\*' -Recurse -Force
Alternatively, what should also work is to remove -Recurse
from Get-ChildItem
so only immediate child items are piped:
Get-ChildItem -Path 'C:\Windows\SoftwareDistribution\' -Force | Remove-Item -Recurse -Force