Combine Get-ChildItem and Test-Path


I currently try to move some old cmd/batch scripts to PS, finally! Currently I have a script that finds all .bak-files and creates a 7ziped file along with it if it does not exist.

My current script looks like this:

for /R "E:\Backup" %%f in (*.bak) do (
    echo %%f
    if not exist "%%f.7z" (
        7Z a "%%f.7z" "%%f"

So I’m trying to rewrite in PS.

This will give me the list of all .back-files, but how do I add .7z to the filename and test it it does exist (Test-Path):

$path = "E:\Backup"
Get-ChildItem -Path $path -Recurse -Filter *.bak | Test-Path -Path %{$_.FullName} # Add .7z here?

And in the next step I’ll run the command to create the 7z-file:

7z.exe a "file.bak.7z" "file.bak"

Should I store all found files in an array and iterate the array, or should I use the ‘|’ to chain the commands?

Thanks for advice!

# If .7z file does not exist, create archive
$path = "E:\Backup"
Get-ChildItem -Path $path -Recurse -Filter *.bak | ForEach-Object {
    $file = ($_.FullName -replace '\.bak$','.bak.7z')
    If (!(Test-Path -Path $file)){
        Write-Verbose "Creating Archive: $(Split-Path $file -Leaf)" -Verbose
        7z.exe a "$file" "$($_.FullName)"

Thanks for the guidance and ideas!

My final PS looks like this:

$path = "E:\Backup"
$7z = "C:\Program Files\7-Zip\7z.exe"
$filter = "*.bak"

# Compress files not already compressed.
Get-ChildItem -Path $path -Filter $filter -File -Recurse |
ForEach-Object {
    $archive = $_.FullName + '.7z'
    If (!(Test-Path -Path $archive -PathType Leaf)){
        & @7z a "$archive" "$($_.FullName)"