使用PowerShell获取“详细信息”选项卡中列出的属性

blpfk2vs  于 2023-11-18  发布在  Shell
关注(0)|答案(4)|浏览(171)

我试图检索一些扩展文件属性(mp3文件是精确的)中列出的“详细信息”选项卡,部分“媒体”与PowerShell.
还有其他属性,如bitrategenrealbum等。
Get-ItemProperty -Path $pathtofile | Format-List不返回这些。
Get-ItemProperty -Path $pathtofile | Get-Member也没有列出它们。
奇怪的是,Get-ItemProperty返回与Get-ChildItem相同的输出。
我试过不同的文件(甚至非mp3),PowerShell没有列出任何地方的“细节”属性。
windows把这些存储在哪里?如何列出它们?

zi8p0yeb

zi8p0yeb1#

我看了一下艾德威尔逊的帖子。我可以看到他在Windows Vista上写的。从那时起,Powershell已经改变了一点。我已经调整了他写的代码,以便在Win 10上工作。希望这对你有帮助!

# Converted from Ed Wilson: https://devblogs.microsoft.com/scripting/hey-scripting-guy-how-can-i-find-files-metadata/

param($folder = "C:\Test") #end param

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

function funMetaData
{
    foreach($sFolder in $folder)
         {
              $a = 0
              $objShell = New-Object -ComObject Shell.Application
              $objFolder = $objShell.namespace($sFolder)

              foreach ($strFileName in $objFolder.items())
                   { 
                       funLinestrIN( "$($strFileName.name)")
                       for ($a ; $a  -le 266; $a++)
                          { 
                                if($objFolder.getDetailsOf($strFileName, $a))
                                  {
                                        $hash += @{ `
                                              $($objFolder.getDetailsOf($objFolder.items, $a)) = $($objFolder.getDetailsOf($strFileName, $a)) 
                                              } #end hash
                                       $hash
                                       $hash.clear()
                                  } #end if
                            } #end for 
                        $a=0
                    } #end foreach
        } #end foreach
} #end funMetadata
funMetaData # run function

字符串

2admgd59

2admgd592#

更新3;我发现了一个更好的脚本,它应该完全符合你的要求,这是由令人难以置信的“嘿!脚本家伙”博客提供的。
博客文章
https://blogs.technet.microsoft.com/heyscriptingguy/2014/02/05/list-music-file-metadata-in-a-csv-and-open-in-excel-with-powershell/
功能
https://gallery.technet.microsoft.com/scriptcenter/get-file-meta-data-function-f9e8d804

f4t66c6m

f4t66c6m3#

编辑:我将下面的原始代码片段合并到一个函数中,就像RiverHeart建议的那样。

<#
.SYNOPSIS
    Get a list of details with columns [ ID | Name | Value ] of a given file or directory (Name and Value are in system language)
    By default, it selects all fields with ID -1 to 320 (inclusive) that have a Value (same as `Get-Details . false $(-1..320)`)
.DESCRIPTION
    Get a list of details with columns [ ID | Name | Value ] of a given file or directory (Name and Value are in system language)
    By default, it selects all fields with ID -1 to 320 (inclusive) that have a Value (same as `Get-Details . false $(-1..320)`)
    - ID -1 is the "info tip information" of the item
    - Negative IDs except -1 don't exist (when tested with file and folder including empty fields)
    - IDs 37, 38, 39, 40, 41, 59, 170, 171, 205, 206, 207, and 218 don't exist (when tested with file and folder including empty fields)
    - ID 296 has no Name but can have a Value (when tested with file and folder including empty fields)
    - Value of ID -1 of an empty textfile might be "Type: Text Document \n Size: 0 Bytes \n Date modified: 10/21/2023 00:00" (every " \n " indicates a line break)
    - Value of ID -1 of a non-empty directory with mixed files might be "Date created: 10/21/2023 00:00"
.Parameter Item
    An existing and accessible file or directory on this computer (must be within a folder, so no drives)
.Parameter IncludeEmptyFields
    If true, also includes fields with empty Value (never includes fields that have no Name and no Value)
    Default false
.Parameter FieldIDs
    Select only fields that are in this list of IDs (but also according to IncludeEmptyFields)
    Default null (selects fields with IDs -1 to 320 inclusive)
.INPUTS
    Item (file or directory) can be taken from the pipeline
.OUTPUTS
    A list of { ID, Name, Value } for each field selected (where Name and Value are in system language)
.EXAMPLE
    PS> # [file: test.txt] [do include empty fields] [only get fields: file name, file size, media authors, media title]
    PS> Get-Details ".\test.txt" $true 0, 1, 20, 21
    ID Name    Value
    -- ----    -----
     0 Name    test.txt
     1 Size    0 Bytes
    20 Authors
    21 Title
.EXAMPLE
    PS> # same as the previous example, but remove the ID column and sort by the Name column (ascending)
    PS> Get-Details ".\test.txt" $true 0, 1, 20, 21 | Select-Object -ExcludeProperty ID | Sort-Object Name
    Name    Value
    ----    -----
    Authors
    Size    0 Bytes
    Name    test.txt
    Title
.LINK
    https://learn.microsoft.com/en-us/windows/win32/shell/folder-getdetailsof
.LINK
    https://stackoverflow.com/questions/22382010/what-options-are-available-for-shell32-folder-getdetailsof/62279888#62279888
.LINK
    https://stackoverflow.com/questions/49214905/get-attributes-listed-in-the-details-tab-with-powershell/77252825#77252825
#>
function Get-Details{
    [CmdletBinding()]
    param(
        [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true, HelpMessage = "An existing and accessible file or directory on this computer (must be within a folder, so no drives)")]
        [AllowNull()]
        $Item,
        [Parameter(Position = 1, ValueFromPipelineByPropertyName = $true, HelpMessage = "If true, also includes fields with empty Value (never includes fields that have no Name and no Value)")]
        [bool]
        $IncludeEmptyFields = $false,
        [Parameter(Position = 2, ValueFromPipelineByPropertyName = $true, HelpMessage = "Select only fields that are in this list of IDs (but also according to IncludeEmptyFields)")]
        [int[]]
        $FieldIDs = $null
    )
    if($null -eq $Item){ throw "Received null" }
    if($Item -eq ""){ throw "Received an empty string" }
    $fileOrFolder = Get-Item $Item -ErrorAction SilentlyContinue
    if($null -eq $fileOrFolder -or -Not $fileOrFolder.Exists){ throw "Couldn't find item: $Item" }
    $folder = $fileOrFolder.Directory
    if($null -eq $folder){ $folder = $fileOrFolder.Parent }
    if($null -eq $folder){ throw "Item must be within a folder" }
    $objShell = New-Object -ComObject Shell.Application
    $objFolder = $objShell.Namespace($folder.FullName)
    $objFile = $objFolder.ParseName($fileOrFolder.Name)
    [PSCustomObject[]] $list = @()
    if($null -ne $FieldIDs){
        $FieldIDs | Sort-Object | Get-Unique | ForEach-Object {
            $FieldValue = $objFolder.GetDetailsOf($objFile, $_)
            $FieldName = $objFolder.GetDetailsOf($null, $_)
            if($FieldValue -or ($IncludeEmptyFields -and $FieldName)){ $list += [PSCustomObject]@{ ID = $_; Name = $($FieldName); Value = $($FieldValue) } }
        }
    }else{
        foreach($id in -1..320){
            $FieldValue = $objFolder.GetDetailsOf($objFile, $id)
            $FieldName = $objFolder.GetDetailsOf($null, $id)
            if($FieldValue -or ($IncludeEmptyFields -and $FieldName)){ $list += [PSCustomObject]@{ ID = $id; Name = $($FieldName); Value = $($FieldValue) } }
        }
    }
    return $list
}

字符串
请注意,NameValue列使用的是系统语言。
也发现这个答案在一个类似的问题,列出了所有字段名称(英文)的id,除了296没有名称和-1也没有名称(“信息提示信息”根据非常有限的documentation).
根据JefNet的回答。
如果你只需要一个特定文件的信息,那么遍历目录树中的每个文件就太多了(对于大目录需要很长时间),所以这里是这个。
获取所有信息(包括空字段):

$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.Namespace((Get-Item .).FullName)

$filenameWithExtension = "example.mp3"

$objFile = $objFolder.ParseName($filenameWithExtension)
$fileMeta = [ordered]@{}
for($id = 0; $id -le 266; $id++){
    $fileMeta[ $($objFolder.GetDetailsOf($objFolder, $id)) ] = $(
        if($objFolder.GetDetailsOf($objFile, $id)){
            $($objFolder.GetDetailsOf($objFile, $id))
        }else{ "" }
    )
}

# print ordered hashtable
$fileMeta


仅获取非空字段:

$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.Namespace((Get-Item .).FullName)

$filenameWithExtension = "example.mp3"

$objFile = $objFolder.ParseName($filenameWithExtension)
$fileMeta = [ordered]@{}
for($id = 0; $id -le 266; $id++){
    if($objFolder.GetDetailsOf($objFile, $id)){
        $fileMeta[
            $($objFolder.GetDetailsOf($objFolder, $id))
        ] = $($objFolder.GetDetailsOf($objFile, $id))
    }
}

# print ordered hashtable
$fileMeta


附注:$($objFolder.GetDetailsOf($objFolder, $id))以系统语言打印字段名称,而不总是英文,因此如果需要与不同语言保持一致,请使用$id作为键。
PPS.:如果你只想要一个字段值,用这个替换哈希表和for循环

$fileMetaAuthors = $(
    # 20 is the "Authors" field
    if($objFolder.GetDetailsOf($objFile, 20)){
        $($objFolder.GetDetailsOf($objFile, 20))
    }else{ "" }
)

# print "Authors" of the file
$fileMetaAuthors


PPPS.:所有这些都期望文件在当前文件夹中。如果不是这样,请修改Get-Item .以指向正确的文件夹。

slhcrj9b

slhcrj9b4#

这个答案只是为了修复Nick W的答案中的链接。微软杀死了TechNet,但脚本在PowerShell Gallery上。
我在谷歌上搜索了以下内容:PowerShell“Get-FileMetaData”
地址:https://www.powershellgallery.com/packages/FC_SysAdmin/5.0.0/Content/public%5CGet-FileMetaData.ps1
我不能让它工作,哈哈。

相关问题