File is being updated even logic returns false

I want to add new lines after the <seq> tag only if $mp3File.FullName is not equal to $currentFileInPlaylist. However, when the script logic returns false (echoing "nothing to add"), file 1.wpl is still updating. Below is the complete code:

$folderPath = "C:\Users\user\Downloads\"
$playList = "C:\Users\user\Music\Playlists\1.wpl"

# If File with datetime when script was executed exists, get mp3 files created after script ran last time and store them in the $mp3Files variable

$scriptRunLastTimePath = "$folderPath\1.txt"

if (Test-Path $scriptRunLastTimePath -PathType Leaf) {
    $dateToCompareWith = Get-Content -Path $folderPath\1.txt
    $culture = [System.Globalization.CultureInfo]::InvariantCulture
    $format = 'dd.MM.yyyy HH:mm:ss'
    $storedDateTime = [DateTime]::ParseExact($dateToCompareWith, $format, $culture)
    $mp3Files = @(Get-ChildItem -Path $folderPath -Filter "*.mp3" -File |
            Where-Object { $_.LastWriteTime -gt $storedDateTime })
} else {
    $mp3Files = Get-ChildItem -Path $folderPath -Filter "*.mp3" -File
}

($xml = [xml]::new()).Load($playList)
$currentFilesInPlaylist = $xml.SelectNodes("//seq/*").src

# If mp3 file is present in folder and not in 1.wpl, add the full file name to playlist file after the <seq> tag

foreach ($currentFileInPlaylist in $currentFilesInPlaylist) {
    foreach ($mp3File in $mp3Files) {
        if ($mp3File.FullName -ne $currentFileInPlaylist) {
            (Get-Content $playlist) | Foreach-Object {
                $_ # send the current line to output
                if ($_ -match "<seq>") {
                    # Add lines after the selected pattern
                    '             <media src="' + $mp3File.FullName + '"/>'
                }
            } | Set-Content $playList -Force
        } else {
            echo "nothing to add"
        }
    }
}

# Create a "checkpoint" file: Export the date and time the script was last run to the file

(Get-Date).ToString('dd/MM/yyyy HH:mm:ss') | Out-File -FilePath $scriptRunLastTimePath

1.wfl file:

<?wpl version="1.0"?>
<smil>
    <head>
        <meta name="Generator" content="Microsoft Windows Media Player -- 12.0.22621.1"/>
        <meta name="ItemCount" content="2"/>
        <title>Untitled playlist</title>
    </head>
    <body>
        <seq>
            <media src="C:\Users\user\Downloads\Katzianerova vojna.mp3"/>
            <media src="C:\Users\user\Downloads\Rat i mir u povijesti III- dio.mp3"/>
        </seq>
    </body>
</smil>

EDIT

This approach also gives same results:

foreach ($currentFileInPlaylist in $currentFilesInPlaylist) {
    foreach ($mp3File in $mp3Files) {
        if ($mp3File.FullName -eq $currentFileInPlaylist) {
            $updatedPlaylist = $updatedPlaylist -ne $currentFileInPlaylist  # Remove matching file from updated playlist
            echo "nothing to add"
        }
    }
}

foreach ($mp3File in $mp3Files) {
    if ($updatedPlaylist -notcontains $mp3File.FullName) {
        $mediaElement = '<media src="{0}"/>' -f $mp3File.FullName
        (Get-Content -Path $playlist) | ForEach-Object {
            $_
            if ($_ -match "<seq>") {
                $mediaElement
            }
        } | Set-Content -Path $playlist
        Write-Host "Added file '$($mp3File.Name)' to the playlist."
    } else {
        Write-Host "File '$($mp3File.Name)' already exists in the playlist."
    }
}

Even when variable content is in wpl file, file is being updated

output:

nothing to add
nothing to add
Added file 'Katzianerova vojna.mp3' to the playlist.
Added file 'Rat i mir u povijesti III- dio.mp3' to the playlist.

EDIT 2:

Made a small progress:

script now reports only one "loop" needs to be added to the file:

$filesAdded = $false  # Initialize flag to track whether any files were added

foreach ($mp3File in $mp3Files) {
    if ($currentFileInPlaylist -notcontains $mp3File.FullName) {
        $mediaElement = '<media src="{0}"/>' -f $mp3File.FullName
        (Get-Content -Path $playlist) | ForEach-Object {
            $_
            if ($_ -match "<seq>") {
                $mediaElement
                $filesAdded = $true  # Set flag to indicate files were added
            }
        } | Set-Content -Path $playlist
        Write-Host "Added file '$($mp3File.Name)' to the playlist."
    } else {
        Write-Host "File '$($mp3File.Name)' already exists in the playlist."
    }
}

if (-not $filesAdded) {
    Write-Host "No files were added to the playlist."
}

Output:

Added file 'Katzianerova vojna.mp3' to the playlist.
File 'Rat i mir u povijesti III- dio.mp3' already exists in the playlist.

>Solution :

The problem is that you compare each .mp3 file path from your disk against each and every file path from the playlist: Even if you find a given file in the playlist and therefore skip it, all the other iterations of your loop will not skip it.

You can avoid the problem by:

  • omitting the outer foreach loop altogether

  • using the -notin operator to test the presence of a given file in the playlist.

    foreach ($mp3File in $mp3Files) {
        # Note the use of -notin and the *whole array* of files in the playlist.
        if ($mp3File.FullName -notin $currentFilesInPlaylist) {
            (Get-Content $playlist) | Foreach-Object {
                $_ # send the current line to output
                if ($_ -match "<seq>") {
                    # Add lines after the selected pattern
                    '             <media src="' + $mp3File.FullName + '"/>'
                }
            } | Set-Content $playList -Force
        } else {
            echo "nothing to add"
        }
    }

Leave a Reply