Как извлечь метаданные, используя определенное имя файла (get-childitem), а не циклически перебирая элементы пространства имен ComObject

Я нашел несколько фрагментов кода для прокрутки папки и отображения метаданных каждого элемента в папке, например:

function funLine($strIN) 
{
    $strLine = "=" * $strIn.length
    Write-Host -ForegroundColor Yellow "`n$strIN"
    Write-Host -ForegroundColor Cyan $strLine
}

$sfolder = "S:\Temp"
$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.namespace($sFolder)
foreach ($strFileName in $objFolder.items())
    {funline "$($strFileName.name)"
    for ($a ; $a  -le 266; $a++)
    { 
        $a
        if($objFolder.getDetailsOf($strFileName, $a))
        {
            $hash += @{ $($objFolder.getDetailsOf($objFolder.items, $a)) = $a.tostring() + $($objFolder.getDetailsOf($strFileName, $a)) }
            $hash | out-file c:\temp\output.txt -Append
            $hash.clear()
        }
    }
    $a=0
}

Но в моем сценарии я хотел бы перебрать папку (и) с помощью Get-ChildItem, а для выбранных файлов я бы хотел использовать getDetailsOf() для извлечения авторов документов MS Office.

Итак, зная имя файла (пример: $strFileName, можно ли пропустить цикл по каждому $ strFileName в $objFolder.items() и просто получить доступ к деталям метаданных (где $a = 20) для авторов $sFileName?

Я видел, как это делается с помощью "New-Object -ComObject word.application", но я считаю, что это открывает документ, поэтому в большой файловой системе, где многие файлы заблокированы пользователями, это может быть медленным и болезненным.

Могу ли я просто перейти к индексу $objFolder.items() для выбранного файла?

2 ответа

Здесь мне было любопытно, как это будет сделано, поэтому я посмотрел его и сделал функцию, которая добавит это свойство к вашему [FileInfo] объект (что обычно передается для файла Get-ChildItem Командлет).

Function Get-CreatedBy{
[cmdletbinding()]
Param(
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [Alias("Path")]
    [string[]]$FullName
)
Begin{
    $Shell = New-Object -ComObject Shell.Application
}
Process{
    ForEach($FilePath in $FullName){
        $NameSpace = $Shell.NameSpace((Split-Path $FilePath))
        $File = $NameSpace.ParseName((Split-Path $FilePath -Leaf))
        $CreatedBy = $NameSpace.GetDetailsOf($File,20)
        [System.IO.FileInfo]$FilePath|Add-Member 'CreatedBy' $CreatedBy -PassThru
    }
}
}

Затем вы можете просто передать это или указать путь, например:

Get-ChildItem *.docx | Get-CreatedBy | FT Name,CreatedBy

или же

Get-CreatedBy 'C:\Temp\File.docx' | Select -Expand CreatedBy

Редактировать: Исправлено для массивов файлов! Извините за предыдущую ошибку.

Спасибо, Мэтт! Хотя этот вопрос был другим, у него был один кусок, который я искал - как ссылаться $objFolder.items().item($_.Name)

Так что это небольшой быстрый фрагмент для отображения авторов (или любого другого поля метаданных):

$FullName = "S:\Temp\filename.xlsx"

$Folder = Split-Path $FullName
$File = Split-Path $FullName -Leaf

$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.namespace($Folder)

$Item = $objFolder.items().item($File)
$Author = $objFolder.getDetailsOf($Item, 20)

Write-Host "$FullName is owned by $Author"

Где Автор - 20-й элемент метаданных.

Другие вопросы по тегам