PowerShell Tag
Let's continue my process of using PowerShell to manage my MuseScore related files. Obviously, I don't expect you to need to do this, but I am trusting you will learn something from the process. The last part of my process is to update the associated MP3 file. However, after I finished the last article, I discovered I needed to revise the function that gets score information.
I was testing with files created from MuseScore v3 and realized that I shouldn't rely solely on processing the XML file for details. I should modify the function to accepts a few properties as parameters.
Param(
[Parameter(
Position = 0,
ValueFromPipeline,
HelpMessage = 'Enter the PATH to the MuseScore files.'
)]
[ValidateScript({ Test-Path $_ }, ErrorMessage = 'Path {0} was not found')]
[string]$Path = '.',
[Parameter(
HelpMessage = 'Enter the path to the preferred cover art file.'
)]
[ValidateNotNullOrEmpty()]
[ValidateScript({ Test-Path $_ }, ErrorMessage = 'Cover art path {0} was not found')]
[string]$CoverArt,
[string]$Title,
[string]$SubTitle
)
In the function I added logic to parse the XML file if a value wasn't passed from the parameter.
Try {
[xml]$score = Get-Content $ZipDestination\*.xml -ErrorAction Stop
Write-Information $score -Tags Data
$software = $score.'score-partwise'.identification.encoding.software.Trim()
#10 March 2025 - if the user specifies a title, use that otherwise look for one in the XML file
if (-Not $PSBoundParameters.ContainsKey("Title")) {
$TitleNode = $score.'score-partwise'.credit.where({ $_.'credit-type' -eq 'title' })
$title = $titleNode.'credit-words'.'#text'.Trim()
}
If (-Not $PSBoundParameters.ContainsKey("SubTitle")) {
$subTitleNode = $score.'score-partwise'.credit.where({ $_.'credit-type' -eq 'subtitle' })
#10 March 2025 - some scores may not have a subtitle
if ($subTitleNode) {
$subTitle = $subTitleNode.'credit-words'.'#text'.Trim()
}
else {
$subTitle = $null
}
}
...
} #Try
Catch {
#10 March 2025 - revise the warning message with more detail.
Write-Warning "Can't find the XML file in $ZipDestination or there was an error in processing. $($_.Exception.Message)"
}
Here's an example of the problem.

But with the revised function, I can manually fill in the gaps.
PS C:\Users\Jeff\Documents\MuseScore3\Scores\Nocturne for Flute> $info = Get-MuseScoreProperty -Title "Nocturne for Flute" -SubTitle "in Bb Min"
PS C:\Users\Jeff\Documents\MuseScore3\Scores\Nocturne for Flute> $info
Path: C:\Users\Jeff\Documents\MuseScore3\Scores\Nocturne for Flute
Date Title SubTitle Duration
---- ----- -------- --------
8/25/2022 Nocturne for Flute in Bb Min 05:33
Now that I have this corrected let's turn to managing the MP3 file.
TagLib Re-Visited
Once again, I will use the TagLib library to manage the audio file. I have already saved a the DLL file in my scripts folder.
Add-Type -Path C:\scripts\TagLibSharp.dll
I will need to create an instance of the TagLib.File
class.
PS C:\Users\Jeff\Documents\MuseScore3\Scores\Nocturne for Flute> $file = [TagLib.file]::Create($(Convert-Path '.\Nocturne for Flute.mp3'))