2

Below script retrieve specific file types from the I: drive and outputting specific file properties to a delimited CSV file. How to return file owner and authors? Any help is very much appreciated.

PowerShell How to Get File Owner/Author?

<#
https://superuser.com/questions/1732588/powershell-how-to-get-file-owner-author/1733110#1733110
#>
$RB21 = "I:\FIRM\RB\2021"
$Path = "C:\Users\User\Desktop\test\support\rfi\TAC.MS Community"
$ObjectProperties = "Author","Keywords"

$test = "C:\Users\User\Desktop\test\support\rfi\TAC.MS Community\TAC.How to Save MSG to open with original content.pptx"
#$From =  "C:\Users\User\Desktop\test\support\rfi\TAC.MS Community"

$From = $RB21
$FileFilterExtension = '*.ppt*'
Get-ChildItem -Path $From -Filter $FileFilterExtension -Force | 
Select-Object -Property  Fullname, LastAccessTime, LastWriteTime, CreationTime, 
@{Name = 'Owner';Expression = {$PSItem.GetAccessControl().Owner}}

$Application = New-Object -ComObject PowerPoint.Application
$Application.Visible = $false
$Binding = "System.Reflection.BindingFlags" -as [type]

$Select = "Name","Created"
$Select += $ObjectProperties
$Document = $Application.Documents.Open($test)


ForEach ($File in (Get-ChildItem $Path -Include *.pptx -Recurse))
{   $Document = $Application.Documents.Open($File.Fullname)
    $Properties = $Document.BuiltInDocumentProperties
    $Hash = @{}
    $Hash.Add("Name",$File.FullName)
    $Hash.Add("Created",$File.CreationTime)
    ForEach ($Property in $ObjectProperties)
    {   $DocProperties = [System.__ComObject].InvokeMember("item",$Binding::GetProperty,$null,$Properties,$Property)
        Try {
            $Value = [System.__ComObject].InvokeMember("value",$binding::GetProperty,$null,$DocProperties,$null)
        }
        Catch {
            $Value = $null
        }
        $Hash.Add($Property,$Value)
    }
    $Document.Close()
    [System.Runtime.InteropServices.Marshal]::ReleaseComObject($Properties) | Out-Null
    [System.Runtime.InteropServices.Marshal]::ReleaseComObject($Document) | Out-Null
    New-Object PSObject -Property $Hash | Select $Select
}
$Application.Quit()
1
  • You have two good responses, please accept one as the answer
    – DBADon
    Commented Jul 27, 2022 at 16:16

2 Answers 2

1

Owner and author are different things.

Yet, why overcomplicate the first part, meaning base file properties and ACL stuff? Why not just this for file properties and access control details. No Get-Acl needed.

Clear-Host

$From                = 'D:\Temp'
$FileFilterExtension = '*.ppt*'

Get-ChildItem -Path $From -Filter $FileFilterExtension -Force | 
Select-Object -Property  Fullname, LastAccessTime, LastWriteTime, CreationTime, 
@{Name = 'Owner';Expression = {$PSItem.GetAccessControl().Owner}}

    # Results
    <#
    FullName       : D:\Temp\PresentationNotProtected.pptx
    LastAccessTime : 15-Apr-21 00:39:32
    LastWriteTime  : 11-Dec-20 20:05:42
    CreationTime   : 11-Dec-20 20:05:42
    Owner          : O:S-1-5-21-3...
    
    FullName       : D:\Temp\PresentationProtected.pptx
    LastAccessTime : 23-Jun-22 13:54:28
    LastWriteTime  : 11-Dec-20 19:51:11
    CreationTime   : 11-Dec-20 19:49:41
    Owner          : O:S-1-5-21-3...
    
    FullName       : D:\Temp\Test.pptx
    LastAccessTime : 23-Jun-22 13:54:28
    LastWriteTime  : 12-Jun-21 15:17:57
    CreationTime   : 04-Feb-20 16:45:18
    Owner          : BUILTIN\Administrators
    #>

You cannot get 'Author' from file properties as it does not exist there. What you are seeing in that dialog is the OS being helpful. You have to use MS Office COM to get to that other data. So, that means calling into PowerPoint, or whatever to get that detail.

For example the code from here: https://community.spiceworks.com/topic/421503-powershell-help-getting-file-details

$Path = "S:\it\documentation"
$ObjectProperties = "Author","Keywords"

$Application = New-Object -ComObject Word.Application
$Application.Visible = $false
$Binding = "System.Reflection.BindingFlags" -as [type]

$Select = "Name","Created"
$Select += $ObjectProperties

ForEach ($File in (Get-ChildItem $Path -Include *.doc -Recurse))
{   $Document = $Application.Documents.Open($File.Fullname)
    $Properties = $Document.BuiltInDocumentProperties
    $Hash = @{}
    $Hash.Add("Name",$File.FullName)
    $Hash.Add("Created",$File.CreationTime)
    ForEach ($Property in $ObjectProperties)
    {   $DocProperties = [System.__ComObject].InvokeMember("item",$Binding::GetProperty,$null,$Properties,$Property)
        Try {
            $Value = [System.__ComObject].InvokeMember("value",$binding::GetProperty,$null,$DocProperties,$null)
        }
        Catch {
            $Value = $null
        }
        $Hash.Add($Property,$Value)
    }
    $Document.Close()
    [System.Runtime.InteropServices.Marshal]::ReleaseComObject($Properties) | Out-Null
    [System.Runtime.InteropServices.Marshal]::ReleaseComObject($Document) | Out-Null
    New-Object PSObject -Property $Hash | Select $Select
}
$Application.Quit()

Of course, you are going to have to tweak this to your use case.

3
  • Thanks for prompt support ; How to change above script for PowerPoint? "$Application = New-Object -ComObject PowerPoint.Application" and "ForEach ($File in (Get-ChildItem $Path -Include *.pptx -Recurse))" did not work Commented Jul 25, 2022 at 6:51
  • No worries. In the post MSWord code, you have to refactor/change all the COM calls and references from MSWord to MS PowerPoint attributes.
    – postanote
    Commented Jul 25, 2022 at 7:13
  • Thanks ; I need help on refactoring; my latest code shown in my latest edit. Error <<Exception setting "Visible": "Cannot convert value "False" to type "Microsoft.Office.Core.MsoTriState". Error: "Invalid cast from 'System.Boolean' to 'Microsoft.Office.Core.MsoTriState'."" At T:\Disk\Authors\GetAuthors.ps1:19 char:1 + $Application.Visible = $false + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], SetValueInvocationException + FullyQualifiedErrorId : ExceptionWhenSetting You cannot call a method on a null-valued expression. Commented Jul 27, 2022 at 6:16
1

Owner and Author can be retrieved using the Shell com object:

$shell = New-Object -com shell.application
gci | select name,
    @{N='Author';E={$shell.NameSpace(($_.DirectoryName)).ParseName(($_.Name)).ExtendedProperty("System.Author")}},
    @{N='Owner';E={ If ($_.PSIsContainer) {
        $Shell.NameSpace(($_.FullName)).Self.ExtendedProperty("System.FileOwner")
    } Else {
        $shell.NameSpace(($_.DirectoryName)).ParseName(($_.Name)).ExtendedProperty("System.FileOwner")
    }}}

Console Capture:

PS Downloads> gci | select name ,
>>     @{N='Author';E={$shell.NameSpace(($_.DirectoryName)).ParseName(($_.Name)).extendedProperty("System.Author")}},
>>     @{N='Owner';E={$shell.NameSpace(($_.DirectoryName)).ParseName(($_.Name)).extendedProperty("System.FileOwner")}} | fl

Name   : keyboardtestutility.exe
Author :
Owner  : JP\keith

Name   : LibreOffice_5.1.6_Win_x86.msi
Author : The Document Foundation
Owner  : JP\keith

Name   : LibreOffice_5.1.6_Win_x86_helppack_en-US.msi
Author : The Document Foundation
Owner  : JP\keith

Name   : LibreOffice_5.4.1_Win_x64.msi
Author : The Document Foundation
Owner  : JP\keith

Name   : LibreOffice_5.4.1_Win_x64_helppack_en-US.msi
Author : The Document Foundation
Owner  : JP\keith

Name   : Medium_Icons_Dialogs_SearchResults_AllUssers.reg
Author :
Owner  : JP\keith

Name   : Medium_Icons_Dialogs_SearchResults_Per-User.reg
Author :
Owner  : JP\keith

Name   : Michigan-Services-Schedule-071618.pdf
Author :
Owner  : JP\keith

Name   : mig_-win-3_3_0-ea31_2.exe
Author :
Owner  : JP\keith

Name   : Miller Keith Health Care POA.odt
Author : Presbyterian Church
Owner  : JP\keith

Name   : Miller Keith POA for Property.odt
Author : Jill Gilpin
Owner  : JP\keith

Name   : Miller Keith Will.odt
Author : krouland
Owner  : JP\keith

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .