PowerShell MetaData Module

<#
.SYNOPSIS
Set of tools to help with listing metadata on files.  Importable module (Import-Module -Path and then run the exported
functions)
.NOTES
Name : MultimediaFileLibrary.psm1
Author : HerringsFishBait.com

V1.0 Initial Version
#>Set-StrictMode -version Latest
Function Get-MetaData
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory=$True,ValueFromPipeline=$True)]
        [string[]]$Path
    )
    BEGIN
    {
        function Get-MetadataFromFolder
        {
            param
            (
                [parameter(Mandatory=$True)]
                [string]$FolderPath,
                [string]$FileName=""
            )
            Write-Verbose "Processing $FolderPath"
            Write-Verbose "FileName : $FileName"
            $Shell=New-Object -ComObject Shell.Application
            $Folder=$Shell.namespace($FolderPath)
            #Build the list of files to process;  if the $FileName parameter is provided
            #only include any files with a matching filename
            if ($FileName -ne "")
            {
                $FileItems=$Folder.Items() | ? {$_.Path -like $FileName}
            }else
            {
                $FileItems=$Folder.Items()
            }
            foreach ($FileItem in $FileItems)
            {
                #Only process files (not folders)
                if (Test-Path -PathType Leaf $FileItem.Path)
                {
                    $Count=0
                    $Object=New-Object PSObject
                    $Object | Add-Member NoteProperty FullName $FileItem.Path
                    #Get all the file detail items of the current file and add them to an object.
                    while($Folder.getDetailsOf($Folder.Items, $Count) -ne "")
                    {
 
                        $Object | Add-Member -Force NoteProperty ($Folder.getDetailsOf($Folder.Items, $Count)) ($Folder.getDetailsOf($FileItem, $Count))
                        $Count+=1
                    }
                    $Object
                }
            }
        }
        # Get the metadata for all the files in a folder then recursively call itself for every child folder.
        function Process-SingleFolder
        {
            param
            (
                [parameter(Mandatory=$True)]
                [string]$FolderPath
            )
            Write-Verbose "Processing Folder $FolderPath"
            Get-MetadataFromFolder $FolderPath
            GCI $FolderPath -Directory | % {Process-SingleFolder $_.FullName}
        }
    }
    PROCESS
    {
        #Take all the paths passed from the pipeline.
        foreach ($SinglePath in $Path)
        {
            if (Test-Path -PathType Container $SinglePath)
            {
                Process-SingleFolder $SinglePath
            }elseif (Test-Path -PathType Leaf $SinglePath)
            {
                Write-Verbose "Processing File $SinglePath"
                $CurrentFile=Get-Item $SinglePath
                Get-MetadataFromFolder $CurrentFile.DirectoryName $CurrentFile.FullName
            }else
            {
                Write-Error "Invalid Path : $SinglePath"
            }
        }
    }
}
<#
.SYNOPSIS
Takes a part and exports a CSV of each file with a new column for every tag.
.DESCRIPTION
Takes a part and exports a CSV of each file with a new column for every tag.  This can be written to an
explict CSV file (overwriting it) or defaults to creating a new CSV file in the module folder.
.PARAMETER $Path
The path to the file or folder to export filenames + tags from.
.PARAMETER $CSVFile
The path to the CSV
#> 
Function Export-MetaTagListCSV
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory=$True,ValueFromPipeline=$True)]
        [string[]]$Path,
        [ValidateScript({Test-Path -PathType Leaf -LiteralPath $_ -IsValid})]
        [string]$CSVFile=$PSScriptRoot+"\MetadataList.csv"
    )
    $AllTags=@()
    #Get and sort all the Tags in the passed files.  Keep track off all the Tag names;  they'll be used later
    #to select the properties
    $Data=Get-MetaData $Path | Select-Object -Property FullName, Tags | ForEach {[string[]]$_.Tags = @(($_.Tags.Split(";")).Trim() | Sort-Object);$_} |
        %{Write-Verbose "Processing $($_.FullName)";$Output=New-Object -typename PSObject; $Output | 
        Add-Member -MemberType NoteProperty -Name "FullName" -Value $_.FullName; ForEach ($Tag in $_.Tags){if ($Tag -ne ""){$Output | 
        Add-Member -MemberType NoteProperty -Name $Tag -Value $True;$AllTags+=$Tag}};$Output} 
    [string[]]$AllProperties=@("FullName")+($AllTags | Select-Object -Unique)
    $Data | Select-Object -Property $AllProperties | Export-Csv -NoTypeInformation -Path $CSVFile -Force -Verbose

}

#These are the functions exported in the module (and are useable outside it).
Export-ModuleMember -Function "Get-MetaData"
Export-ModuleMember -Function "Export-MetaTagListCSV"
    
%d bloggers like this: