Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Subscribe
Archives
September 19, 2023

Setting Extended Properties with PowerShell

We've been looking at working with extended file properties with PowerShell using the Shell.Application COM object.

$shellApp = New-Object -ComObject 'Shell.Application'
$path = 'C:\work'
$shellFolder = $shellApp.NameSpace($Path)
$file = $shellFolder.Items() | where { $_.name -eq 'PHI_4928.jpg' }

Once you know the attributes you want, you can create custom output.

[PSCustomObject]@{
    Name = $shellFolder.GetDetailsOf($file, 0)
    Size = $shellFolder.GetDetailsOf($file, 1)
    Dimensions =$shellFolder.GetDetailsOf($file, 31)
    BitDepth = $shellFolder.GetDetailsOf($file, 174)
    Camera = $shellFolder.GetDetailsOf($file, 30)
}
Name       : PHI_4928.jpg
Size       : 926 KB
Dimensions : 1414 x 2121
BitDepth   : 24
Camera     : NIKON D850

But what if you want to set a property? Unfortunately, the COM object has no methods you can use for this task. In fact, this is not an easy task without additional tools. Fortunately, these tools aren't difficult to use, and the techniques I will show you apply to any .NET resource you might need to script with.

TagLib-Sharp

If you need to manage media files like video, audio, and graphics, I'm going to recommend using the TagLib-Sharp library. This is an open-source project. While I know you can use many graphical utilities, you could also create your own PowerShell tools using this library.

The first thing you need to do is install it. It is important to remember that libraries like this are designed for developers and intended to be used in a development IDE like Visual Studio. But we can use it in PowerShell. The library is a package that you can find and install.

PS C:\>  Find-Package TagLibSharp

Name             Version          Source           Summary
----             -------          ------           -------
TagLibSharp      2.3.0            NuGet.org        A library for for reading and writing …

Install the package.

Install-Package TagLibSharp

The download is a Nuget package.

PS C:\> Get-Package TagLibSharp | Select-Object -ExpandProperty Source | Get-ChildItem

    Directory: C:\Program Files\PackageManagement\NuGet\Packages\TagLibSharp.2.3.0

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           9/15/2023  4:56 AM        1378355 TagLibSharp.2.3.0.nupkg

We're not using this in a normal development environment, so we need to take a few extra steps. The file is a zip file with a different extension. I'm going to create a copy and extract the contents.

New-Item -path C:\temp -Name TagLibSharp -ItemType Directory

Get-ChildItem (Get-Package TagLibSharp).source |
Copy-Item -Destination C:\temp\TagLibSharp.zip -PassThru |
Expand-Archive -DestinationPath C:\temp\TagLibSharp -Force

What did we get?

PS C:\> dir C:\temp\TagLibSharp

    Directory: C:\temp\TagLibSharp
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         9/15/2023   5:00 AM                _rels
d-----         9/15/2023   5:00 AM                lib
d-----         9/15/2023   5:00 AM                package
-a----         7/29/2022   5:05 PM           9464 .signature.p7s
-a----         7/29/2022   6:03 PM            591 [Content_Types].xml
-a----         7/29/2022   6:03 PM           2642 TagLibSharp.nuspec

The bits we want are in the lib folder.

PS C:\> dir C:\temp\TagLibSharp\lib


    Directory: C:\temp\TagLibSharp\lib


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         9/15/2023   5:00 AM                net462
d-----         9/15/2023   5:00 AM                netstandard2.0

In this library, there are versions for Windows PowerShell under net462and PowerShell 7 under netstandard2.0. I'm using PowerShell 7.

PS C:\> dir C:\temp\TagLibSharp\lib\netstandard2.0\


    Directory: C:\temp\TagLibSharp\lib\netstandard2.0


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         7/30/2022  12:03 AM        2195366 TagLibSharp.xml
-a----         7/30/2022  12:03 AM         245720 TagLibSharp.pdb
-a----         7/30/2022  12:03 AM         500224 TagLibSharp.dll

The DLL file is what we need. I extracted the zip file to a temp folder. You can extract it to wherever it makes sense for your project. But you'll need to make sure you load the version-appropriate assembly.

$WinPS = "C:\temp\TagLibSharp\lib\net462\TagLibSharp.dll"
$PS7 = "C:\temp\TagLibSharp\lib\netstandard2.0\TagLibSharp.dll"

Add-Type -Path $PS7

Now, we're ready to use it.

Want to read the full issue?
GitHub Bluesky LinkedIn About Jeff
This email brought to you by Buttondown, the easiest way to start and grow your newsletter.