HiveBrain v1.2.0
Get Started
← Back to all entries
patternshellMinor

Inspecting properties of files

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
propertiesfilesinspecting

Problem

Function Enumerate-Properties($fileName)
{
    $path = (Get-Item $fileName).FullName
    $shell = New-Object -COMObject Shell.Application
    $folder = Split-Path $path
    $file = Split-Path $path -Leaf
    $shellfolder = $shell.Namespace($folder)
    0..287 | Foreach-Object {'{0} = {1}' -f $_, $shellfolder.GetDetailsOf($null, $_)}
}
Function Find-Property($fileName, $PropertyName)
{
    $shell = New-Object -COMObject Shell.Application
    $path = (Get-Item $fileName).FullName
    $folder = Split-Path $path
    $file = Split-Path $path -Leaf
    $shellfolder = $shell.Namespace($folder)
    $shellfile = $shellfolder.ParseName($file)
    $found = $false
    0..287 | Foreach-Object {
        $test1 = $shellfolder.GetDetailsOf($null, $_)
        if($PropertyName -eq $shellfolder.GetDetailsOf($null, $_))
        {
            $found = $true
            return $_
            break
        }
    }
    if(!$found)
    {
        Write-Host "Property "$PropertyName " was not found"
    }
}
Function Get-PropertyValue($fileName, $property)
{
    $shell = New-Object -COMObject Shell.Application
    $path = (Get-Item $fileName).FullName
    $folder = Split-Path $path
    $file = Split-Path $path -Leaf
    $shellfolder = $shell.Namespace($folder)
    $shellfile = $shellfolder.ParseName($file)
    return $shellfolder.GetDetailsOf($shellfile,$property)
}
Function Create-List3($files, $property)
{
    $array = @()
    $propertyNum = Find-Property $files[0] $property
    foreach($file in $files)
    {
        $file | Add-Member -MemberType noteproperty -Name $property -Value (Get-PropertyValue $file $propertyNum).toString() -force
        $array = $array + $file
    }
    return $array
}


This code is designed to be used in something like the following fashion:

$files = dir *.mp4
$propery = "Bit rate"
$array = Create-List3 $files $property
$array | Format-Table Name, Length, $property -auto


As far as I can tell, this code works when you give it a nice amount of .mp4

Solution

A first thing to note is that you are creating a lot of COMObjects in a similar manner, we can simply extract that behavior as a separate function. Then, we note that you are expecting file names as parameters where you could expect an item instead; that allows you to pass on items to Create-List3 instead, thus allowing for piping Get-ChildItem into rather than doing extra conversion calls back and forth.

As a result of this two things we're left with a lot of Split-Path calls, we can simply port them over to extracted function as well, it appared that you only needed one of the Split-Pat calls only once. After that, some small cleanup has been done (removing $test1, adding extra newlines and spaces for readability) and we already have much cleaner code to continue from:

Function Get-ShellFolder($fileItem)
{
    $folder = Split-Path $fileItem.FullName

    $shell = New-Object -COMObject Shell.Application
    return $shell.Namespace($folder)
}

Function Enumerate-Properties($fileItem)
{
    $shellfolder = Get-ShellFolder $fileItem

    0..287 | Foreach-Object {'{0} = {1}' -f $_, $shellfolder.GetDetailsOf($null, $_)}
}

Function Find-Property($fileItem, $PropertyName)
{
    $shellfolder = Get-ShellFolder $fileItem

    $found = false
    0..287 | Foreach-Object {
        if ($PropertyName -eq $shellfolder.GetDetailsOf($null, $_))
        {
            $found = true
            return $_
            break
        }
    }

    if (!$found) {
        Write-Host "Property " $PropertyName " was not found"
    }
}
Function Get-PropertyValue($fileItem, $property)
{
    $shellfolder = Get-ShellFolder $fileItem

    $file = Split-Path $fileItem.FullName -Leaf
    $shellfile = $shellfolder.ParseName($file)

    return $shellfolder.GetDetailsOf($shellfile, $property)
}
Function Create-List3($files, $property)
{
    $array = @()
    $propertyNum = Find-Property $files[0] $property
    foreach($file in $files)
    {
        $file | Add-Member -MemberType noteproperty -Name $property -Value (Get-PropertyValue $file $propertyNum).toString() -force
        $array = $array + $file
    }
    return $array
}


From here on, you could look for things that are already implemented in Powershell to make the code even more simple, as well as adding documentation to make some less obvious things easier to understand for fellow readers.

Code Snippets

Function Get-ShellFolder($fileItem)
{
    $folder = Split-Path $fileItem.FullName

    $shell = New-Object -COMObject Shell.Application
    return $shell.Namespace($folder)
}

Function Enumerate-Properties($fileItem)
{
    $shellfolder = Get-ShellFolder $fileItem

    0..287 | Foreach-Object {'{0} = {1}' -f $_, $shellfolder.GetDetailsOf($null, $_)}
}

Function Find-Property($fileItem, $PropertyName)
{
    $shellfolder = Get-ShellFolder $fileItem

    $found = false
    0..287 | Foreach-Object {
        if ($PropertyName -eq $shellfolder.GetDetailsOf($null, $_))
        {
            $found = true
            return $_
            break
        }
    }

    if (!$found) {
        Write-Host "Property " $PropertyName " was not found"
    }
}
Function Get-PropertyValue($fileItem, $property)
{
    $shellfolder = Get-ShellFolder $fileItem

    $file = Split-Path $fileItem.FullName -Leaf
    $shellfile = $shellfolder.ParseName($file)

    return $shellfolder.GetDetailsOf($shellfile, $property)
}
Function Create-List3($files, $property)
{
    $array = @()
    $propertyNum = Find-Property $files[0] $property
    foreach($file in $files)
    {
        $file | Add-Member -MemberType noteproperty -Name $property -Value (Get-PropertyValue $file $propertyNum).toString() -force
        $array = $array + $file
    }
    return $array
}

Context

StackExchange Code Review Q#13816, answer score: 4

Revisions (0)

No revisions yet.