0

I am working on a disk space script for our clients in my off time. I just tested it using the ISE, and it looks like it was working until I checked the transcript.

There are sections during the first removal cycle around line 32 where it is removing files in C:\Windows\System32\, which of course I didn't want it to. I am sure I did something wrong, but I have checked for typos, and I do not understand how it can get %system32% from a users directory.

If (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))
    {
        $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + ' (Elevated)'
        $Host.UI.RawUI.BackgroundColor = 'DarkBlue'
        Clear-Host
    }
Else
    {
        $newProcess = New-Object Diagnostics.ProcessStartInfo 'PowerShell'
        $newProcess.Arguments = "& '" + $script:MyInvocation.MyCommand.Path + "'"
        $newProcess.Verb = 'runas'
        [Diagnostics.Process]::Start($newProcess) | Out-Null
        exit
    }
If ((Test-Path "C:\DiskSpaceCleanupLog\") -eq $False)
    {
        New-Item -ItemType Directory -Path "C:\DiskSpaceCleanupLog\"
    }
$Date = [string]::Format( "{0:dd-MM-yyyy}", [datetime]::Now.Date )
$LogName = "C:\DiskSpaceCleanupLog\" + $Date + "Log.txt"
Start-Transcript $LogName
$Path = @()
$Array = @(Get-ChildItem C:\Users | Select-Object Name)
Read-Host -Verbose "Removing User Account temp files..."
Foreach ($Name IN $Array)
    {

        $Path = ("C:\Users\" + $Name.Name + "\AppData\Local\Temp\")
    }              
Foreach ($Path IN $Array)
    {
        Get-ChildItem | Remove-Item -Recurse -WhatIf
    }
Remove-Variable Path
Read-Host -Verbose "Removing User Account crash dumps..."
Foreach ($Name IN $Array)
    {
        $Path = ("C:\Users\" + $Name.Name + "\AppData\Local\CrashDumps\")
    }
Foreach ($Path IN $Array)
    {
        Get-ChildItem | Remove-Item -Recurse -WhatIf
    }
Remove-Variable Path
Read-Host -Verbose "Removing User Account reporting files..."
Foreach ($Name IN $Array)
    {
        $Path = ("C:\Users\" + $Name.Name + "\AppData\Local\Microsoft\Windows\WER\ReportArchive\")
    }              
Foreach ($Temp IN $Path)
    {
        Get-ChildItem | Remove-Item -Recurse -WhatIf
    }
Remove-Variable Path
Read-Host -Verbose "Removing User Account temp files from Internet Explorer..."
Foreach ($Name IN $Array)
    {
        $Path = ("C:\Users\" + $Name.Name + "\AppData\Local\Microsoft\Windows\Temporary Internet Files\")
    }              
Foreach ($Temp IN $Path)
    {
        Get-ChildItem | Remove-Item -Recurse -WhatIf
    }
Read-Host -Verbose "Removing Recycle Bin files..."
Remove-Item -LiteralPath 'C:\$Recycle.Bin\' -Recurse -WhatIf
Read-Host -Verbose "Removing global crash dumps..."
Remove-Item "C:\ProgramData\Microsoft\Windows\WER\ReportQueue" -Recurse -WhatIf
Remove-Item "C:\ProgramData\Microsoft\Windows\WER\ReportArchive" -Recurse -WhatIf
Read-Host -Verbose "Removing Windows Update cached files..."
Stop-Service -DisplayName 'Windows Update'
Remove-Item "C:\Windows\SoftwareDistribution\Download\*" -Recurse -WhatIf
Start-Service -DisplayName 'Windows Update'
Remove-Variable Array, Path
Read-Host -Verbose "Cleaning base image of update cache..."
DISM.exe /Online /Cleanup-Image /SPSuperseded
Read-Host -Verbose "Running Windows Clean Manager..."
$OSVersion = Get-WMIObject -Class Win32_OperatingSystem | Format-Table Version
If ($OSVersion -le 6.1)
    {
        cleanmgr.exe /verylowdisk
    }
Read-Host -Verbose "Removal is complete. Sending logs..."
Stop-Transcript
$SecurePassword = ConvertTo-SecureString "InsertPasswordHere" -AsPlainText -Force
$emailcredential = New-Object System.Management.Automation.PSCredential ("email@domain.com", $SecurePassword)
Send-MailMessage -To "Name Here <email@domain.com>" -From "Name Here <email@domain.com>" -Subject ("Disk Space Cleanup Log - " + $Date) -Body "Attached is the log from the script." -Attachments $LogName -SmtpServer "smtp.office365.com" -Credential $emailcredential -UseSSL -Port "587" -DeliveryNotificationOption OnFailure

Line 32 is Get-ChildItem | Remove-Item -Recurse -WhatIf

Matt
  • 45,022
  • 8
  • 78
  • 119
Moridn
  • 35
  • 6
  • Perhaps a user has a shortcut to C:\Windows\System32 somewhere in their directory? – Ken Clubok Feb 26 '16 at 01:10
  • I am testing on my PC, and I don't have any links like that. Or junction points either. I didnt think of that though. – Moridn Feb 26 '16 at 01:17

2 Answers2

1

The are several things that should be adjusted in your code but the issue that is befalling you now is that you have not specified a -Path. Therefore Get-ChildItem will be returning items from the working directory!

 Get-ChildItem | Remove-Item -Recurse -WhatIf

Should be instead

 Get-ChildItem $path | Remove-Item -Recurse -WhatIf

Like I said though there are several potential pitfalls and areas of improvement there to be addressed. You use the same loop 5 times. A couple are exactly the same.

Matt
  • 45,022
  • 8
  • 78
  • 119
  • Doh! Well that's one. Can you see any others? Using writing these as a learning experience. – Moridn Feb 26 '16 at 02:00
  • @Moridn If you get the script working then I would suggest going to CodeReview.SE. StackOverlflow is more geared to specific problems and answers. – Matt Feb 26 '16 at 02:02
0

I believe the issue is on line 23, where the code is not populating the array with full pathnames. See Get full path of the files in PowerShell for some advice on how to get the full pathnames instead.

Community
  • 1
  • 1
Ken Clubok
  • 1,238
  • 6
  • 11
  • I added the full name modifier to the path, and it is still attempting to delete files in the system32 directory. To clarify, #32 looks like this now. Get-ChildItem | % { $_.FullName } | Remove-Item -Recurse -WhatIf – Moridn Feb 26 '16 at 01:30