-
Notifications
You must be signed in to change notification settings - Fork 3
PowerShell Primer
This guide is intended to get you up and running with PowerShell Audio if you've never used PowerShell before. For a more comprehensive introduction, visit http://technet.microsoft.com/en-ca/scriptcenter/powershell.aspx and watch some of the webcasts.
PowerShell is the new command line and scripting environment for Windows. Traditional console applications simply read and/or write text to and from the console. PowerShell works with objects instead of text, and instead of executables like lame.exe, it uses cmdlets, like Get-AudioFile.
Cmdlets are easier to learn than executables, because they behave consistently no matter who developed them.
In the console world, there are dozens of different ways to specify options, even for just getting help (--help, -h, -?, /?). In PowerShell, you can always get help for a cmdlet by using another cmdlet: Get-Help. For example:
Get-Help Export-AudioFile
Cmdlets are always named with a verb-noun pair. In PowerShell Audio, the noun always begins with Audio. So if you want to get something audio-related, type Get-Audio and then hit tab to cycle through the available options.
See the complete list of PowerShell Audio cmdlets.
Cmdlet parameters are always specified using the same syntax. For example, Get-AudioFile -Path "filename.wav" sets the Path parameter. Often, one or more parameters are considered "default", and the names can be omitted (as long as they are provided in the expected order). So Get-AudioFile "filename.wav" also works just fine. The quotes can also be left out, assuming there are no spaces in the path.
Some parameters are simply switches, so no value needs to be provided. The Export-AudioFile -Replace switch is an example.
To cycle through the available parameters, type the - and then hit tab to cycle through.
Usually you'll work with PowerShell Audio by getting some AudioFiles, then "piping" them into one or more other cmdlets for processing. This is indicated with the | (pipe) character. It says, "take the preceding cmdlet's output, and use it as input for the next one."
Sometimes a cmdlet doesn't provide output, at least by default. For example, the Measure-AudioFile cmdlet adds ReplayGain metadata to the input AudioFile object. It doesn't actually output anything. If you want to then save the changes to disk, you can use the -PassThru switch along with a pipe. For example:
Get-AudioFile "input.flac" | Measure-AudioFile "ReplayGain" -PassThru | Save-Metadata
You aren't limited to working with files one at a time. PowerShell is smart enough to deal with whole lists of objects. Instead of using the above example on each file in a directory, you could use:
Get-AudioFile "*.flac" | Measure-AudioFile "ReplayGain" -PassThru | Save-Metadata
In fact, PowerShell Audio will process these files concurrently using multiple threads, and calculate the album ReplayGain value as well.
Because PowerShell works with objects, you're typically sending objects from one cmdlet to another. In PowerShell Audio, those objects are usually of the class AudioFile. An AudioFile object has properties, like a FileInfo object (itself containing properties like the file name), an AudioInfo object (containing useful stuff like the bitrate and sample rate) and a Metadata object (containing tags like the artist and title).
Objects can also have methods on them, like SaveMetadata. In fact, all the Save-Metadata cmdlet really does is call the provided AudioFile's own SaveMetadata method.
If you send an object to the console, you do get text, but that's because PowerShell calls the object's ToString method by default when displaying it.
Let's say you want to temporarily store a cmdlet's output object, instead of piping it into another cmdlet right away. You might want to pipe it into multiple objects, or compare some properties on the object before passing it on. You can store output by assigning a variable. For example:
$file = Get-AudioFile "filename.wav"
You can then pipe it into another cmdlet:
$file | Export-AudioFile "FLAC"
print the object's AudioInfo property to the console:
$file.AudioInfo
or just print the AudioFile to the console as-is:
$file
In some advanced scenarios, you might want to loop through a whole directory tree, and process each directory as a separate album. For that, you can use a combination of the Get-ChildItem cmdlet (which supports recursive searches) and the ForEach-Object cmdlet.
Get-ChildItem C:\Users\Myself\Music -Directory -Recurse | ForEach-Object { $_ | Get-ChildItem -File -Filter *.flac | Measure-AudioFile ReplayGain -PassThru | Save-AudioMetadata }
First, every directory under C:\Users\Myself\Music is recursively found, and then each directory object has a code block (indicated with the curly braces) executed on it. The directory object for each iteration is referred to by the special $_ variable.
The ForEach-Object cmdlet is used often enough that a special alias, %, can be used instead of typing the full cmdlet name.