sdelete old files with powershell

Hi,

I’m trying to find old files in several directories and want them to delete securely with sdelete utility.
Also, I want to log that sdelete activity and I noticed on the file on which I do not have permission I got an error:

SDelete is set for 3 passes.

E:\DIR1\TEST\This_is_test_file.exe...
Error opening E:\DIR1\TEST\This_is_test_file.exe for delete:
Access is denied.

No files/folders found that match E:\DIR1\TEST\This_is_test_file.exe.

But, in the sdelete.log I get an output:

----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
Beginning run at: 11/09/2018 14:58:55
Using shred command: C:\ADMIN\sdelete64.exe
Shred iterations: -p 3
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
Shredding file: E:\DIR1\TEST\This_is_test_file.exe
C:\ADMIN\sdelete64.exe -p 3 E:\DIR1\TEST\This_is_test_file.exe
Shred exited: True
Shred return code: 0
Ending at: 11/09/2018 14:58:58
----------------------------------------------------------------------------------------------

Can someone help me with capturing those files that actually not deleted and save it to another log file?

This is what I got so far:

$Now=Get-Date
$Days="30"
$Lastwrite = $Now.AddDays(-$Days)
$dt = (get-date).ToString("ddMMyyyy")
$CSVFile = 'E:\Log\ToDelete_' + $dt + '.csv'
$SdelogFile = 'E:\Log\ShredLog_' + $dt +'.log'
$sdelete = "C:\ADMIN\sdelete64.exe"
$iterations = "-p 3"
$dirs = 'E:\DIR1','E:\DIR2'

Foreach ($dir in $dirs) {
Get-ChildItem $dir -File -Recurse | Where-Object {$.LastwriteTime -le “$Lastwrite”} | Select-Object Name, `
@{ n = ‘FilePath’; e = { Convert-Path $
.PSPath } },`
@{ n = ‘LastWriteTime’ ; e = { $_.LastWriteTime } } |
Export-Csv -Path $CSVFile -Append -Encoding UTF8 -NoTypeInformation
}

$Files = Import-Csv -Path $CSVFile | Select-Object -ExpandProperty FilePath | Where-Object { $_.PSObject.Properties.Value -ne $null}
Add-content $SdelogFile -value “----------------------------------------------------------------------------------------------------”
Add-content $SdelogFile -value “----------------------------------------------------------------------------------------------------”
Add-content $SdelogFile -value “Beginning run at: $Now”
Add-content $SdelogFile -value “Using sdelete command: $sdelete”
Add-content $SdelogFile -value “Sdelete iterations: $iterations”
Add-content $SdelogFile -value “----------------------------------------------------------------------------------------------------”
Add-content $SdelogFile -value “----------------------------------------------------------------------------------------------------”
ForEach ($File in $Files){
Add-content $SdelogFile -value “Shredding file: $file”
Add-content $SdelogFile -value “$sdelete $iterations $file”
$proc = Start-Process -FilePath $sdelete -ArgumentList “$iterations `”$file`"" -Wait -NoNewWindow -PassThru
Add-Content $SdelogFile -value “Sdelete exited: $($proc.HasExited)”
Add-content $SdelogFile -value “Sdelete return code: $($proc.ExitCode)”
}
$end = Get-date
Add-Content $SdelogFile -value “Ending at: $end”
Add-content $SdelogFile -value “----------------------------------------------------------------------------------------------------”

The problem is that Start-Process doesn’t generate the console output and/or Sdelete don’t generate an error exit code (they seem to be ‘0’ always).

What you could do is not use start-process.

E.g.

$result = &$sdelete file_path # note the & to run the command.

if($result -contains 'Access Denied') {
    # Do something else
}
else {
    # Do normal stuff
}

And for logging, you could use transcription using Start-Transcript cmdlet use do write-output or custom logging function print custom messages.

Function Log {
    Param(
       [string]$Message,
       [string]$LogfilePath='c:\tempt\customlogfilename.log'
    )
    Add-Content -Path $LogfilePath -Value $Message
}


..
..

Log "First line"
..
Log "Last line"

Thank you Fredrick, just what I need!

Maybe not the right solution,

In your case, I cannot “-p 3” parameter.

Yes it may be an issue it works if you do:

&$sdelete -p3 c:\tmp\test.txt

Seems to be some sort of issue around quote expand the arguments.

What you could do even though it’s not really best practice is to use Invoke-Expression.
So if you create the command line in a single string and the run Invoke-Expression it also works.

$cmdLine = "$sdelete $iterations path_to_file"

Invoke-Expression $cmdLine

Now, with Invoke-Expression, the script works perfectly.

Thank you Fredrik for your help.