I've been struggling with finding a way to read Folder Tags from an external script. I want to use this data so I can trigger automated tasks in other systems when a folder is discovered with specific tags. I am using PowerShell, although I am not tied to it.
I know the folder tags are stored in the OpusMetaInformation Alternate Data Stream, but the various native command line tools struggle reading it. I am able to see the stream in some UI based tools, but that does not help me for scripting. I was able to use DOpusRT.exe to write the tags, which is nice, however I could not find a way to read the tags using that tool.
This forum thread is very helpful, but I was not able to translate the provided details into usable code:
It seems the original poster was hitting the same problem trying to read the values in PowerShell and ended up settling on a script triggered from within Directory Opus.
Next I am going to look into creating a custom internal DO command that I can hopefully call externally from DOpusRT.exe, but I have spent countless hours going down various dead ends and before I go down this next path I am hoping to see if others here have a solution to this problem already, or have advice on a better approach.
I ended up using the following approach. This is my first time scripting with DOpus, so there might be a better way. I would not consider this "Production Ready" in any sense, but it works for my needs and others may get some use out of it, or at least it provides a starting point.
The DOpus script
// ExportTags.js
// NathanN 2024
function OnInit(initData) {
initData.name = "Export Tags";
initData.desc = "Creates an internal ExportTags command to export file and Folder tags to a separate file, for use with external scripts.";
initData.default_enable = true;
var cmd = initData.AddCommand();
cmd.name = "ExportTags";
cmd.method = "OnExportTags";
cmd.desc = initData.desc;
cmd.label = "Export Tags";
cmd.template = "FILE,EXPORTFILE/O";
}
function OnExportTags(scriptCmdData) {
ExportFile = "C:\\DOpusTagExport.txt"; //default location to save file when one is not passed in the ExportFile argument.
if ( scriptCmdData.func.args.got_arg.exportfile ) ExportFile = scriptCmdData.func.args.exportfile;
var sourceFile = DOpus.FSUtil.GetItem(scriptCmdData.func.args.file)
// Get Tags from source file/folder
var ItemTags = sourceFile.metadata.tags;
// Flatten ItemTags array in preparation for single line file output
var tagList = "";
for ( i = 0; i < ItemTags.count; i++ ) { tagList += ItemTags(i) + "; " };
//Optionally Output to script logs for troubleshooting.
//DOpus.Output(tagList);
//Open file for reading and writing.
ExportFileObj = DOpus.FSUtil.OpenFile(ExportFile, "rwo");
// Reads current file contents.
// This also moves the file pointer to the end of the file before writing.
// If the preference is to overwrite then this, along with the file open method can be modified.
// Alternatively, the external script can delete the file before calling this Opus command.
var stt = DOpus.Create().StringTools();
CurrentFileContents = stt.Decode(ExportFileObj.Read(), 'utf8');
// This next line can be modified for the preferred output string
var FinalOutput = sourceFile + ": " + tagList + "\n"
ExportFileObj.Write(FinalOutput)
ExportFileObj.close
}
Here is an example PowerShell script that pulls the tags from the produced export file into an array.
It accepts 2 parameters, the first being the target file/folder to pull tags from.
The second being the Export File path. The Export path defaults to the root of the C: drive if not otherwise specified.
There is a 3rd parameter to set the location of dopusrt.exe, but that should only need to get set once.
# getTags.ps1
# NathanN (2024)
#
# Gets File and Folder tags from any file or folder.
# Returns an array of tags.
#
# Expects Opus Export file to produce lines in this format:
# <TargetFile>: <Tag1>; <Tag2>; <Tag3>; ...
#
# Depends on ExportTags.js to be imported into Directory Opus
Param (
$TargetFile,
$ExportFile = "C:\DOpusTagExport.txt",
$DOpusRT = "C:\Program Files\GPSoftware\Directory Opus\dopusrt.exe"
)
# Optionally delete the Export file (if it exists) so we have a clean lookup
if (Test-Path -Path $ExportFile) {Remove-Item $ExportFile}
# Trigger DOpus command
& $DOpusRT /acmd ExportTags File $TargetFile ExportFile $ExportFile
# This block attempts to find tags in the export file based on Target File path (for up to 10 seconds).
# This is needed since it's unknown how long DO will take to output the results.
# If the path already exists in the file then this can lead to stale matches.
# Deleting the file prior to the check insures we have only one hit.
$Match = ""
while (!$Match) {
if (Test-Path -Path $ExportFile) {
$Match = Get-Content $ExportFile | Where-Object { $_.StartsWith($TargetFile + ':') } | Select-Object -Last 1
#Break out of while loop when we find what we need
if ($Match){Break}
}
# Wait half second before next try
Start-Sleep .5
}
# Return an array of tags
$Tags = $Match.Split(':')[2].Split(";").Trim()
Return $Tags
For immediate output this PowerShell script can be ran as-is, but it's probably better to put into a variable as in this example:
$MyTags = .\getTags.ps1 "D:\People\testfolder\NewTextDocument.txt"
Then you can read using the array syntax: $MyTags[0]