1

I want to delete files in my subfolders with a PowerShell script.

I already tried using Remove-Item in PowerShell, but failed to set it up correctly...

This is the code I use for encoding:

Get-ChildItem *.mkv | where BaseName -notlike '*`[HEVC]' | foreach {
ffmpeg -i $_ -c:v libx265 -c:a copy -x265-params crf=25 "$($_.BaseName) [HEVC].mkv" -n
}

I want to either include Remove-Item [source file] in this script to delete the source files by checking the name of the file.

How would I do that?

Compo
  • 36,585
  • 5
  • 27
  • 39
WorldTeacher
  • 93
  • 1
  • 10

1 Answers1

0

Make your pipeline output the file-info objects of those input files whose conversion via ffmpeg was successful (as implied by automatic variable $LASTEXITCODE equaling 0), and pipe them to Remove-Item:

The command below sends ffmpeg's (stdout) output to the display only, via Write-Host, so as not to "pollute" the pipeline with its stdout output and only output the file-info objects; the alternative is to simply suppress ffmpeg's output (error messages still print): $null = ffmpeg ...:

Get-ChildItem *.mkv | where BaseName -notlike '*`[HEVC]' | foreach {
  # Convert the input file and send ffmpeg's output to the display,
  # by piping to Write-Host, rather than trough the pipeline.
  ffmpeg -i $_ -c:v libx265 -c:a copy -x265-params crf=25 "$($_.BaseName) [HEVC].mkv" -n |
    Write-Host
  # Conversion OK? Output the file-info object, which pipes it to Remove-Item.
  if ($LASTEXITCODE -eq 0) { $_ } 
} | Remove-Item -WhatIf

Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.

Note: Since Write-Host in PowerShell version 5 or above writes to the information stream (stream number 6), which goes to the display by default, it is still possible to capture ffmpeg's output from inside PowerShell, namely via redirection 6>&1; by contrast, a caller from outside PowerShell (such as a batch file) receives even Write-Host output directly via stdout.


In PowerShell 7+ you can simplify the code inside the foreach loop via &&, the pipeline-chain AND operator (its complementary OR (else) operator is ||):

# (Details of the ffmpeg command omitted for brevity).
... | foreach {
  # The RHS of && is only executed if the command on the LHS succeeded, 
  # which in the case of external programs means: $LASTEXITCODE equals 0.
  ffmpeg $_ ... | Write-Host && $_
} | ...
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • if some fioles don't get deleted with this, would adding -f after Remove-Item do the trick? – WorldTeacher Nov 03 '20 at 06:02
  • @WorldTeacher: It _may_ help, but only if those files happen to have the read-only attribute set (and aren't also still in use by another process). – mklement0 Nov 03 '20 at 13:13
  • I tried using your provided script as a standalone, which worked fine, but when I started using it in my main script, which calls the script to start in a folder, I got an error stating that I don't have the necessary permissions. Any ideas as to how to fix this? – WorldTeacher Nov 03 '20 at 17:29
  • @WorldTeacher: That sounds like a file-system permissions problem unrelated to PowerShell, so perhaps your script needs to run with elevation (as admin). If you need further assistance with this, please ask a _new_ question. – mklement0 Nov 03 '20 at 17:56