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 net462
and 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.