Matthew
Matthew

Reputation: 111

Powershell GetChildItem no path listed

I have a PowerShell script to scan entire shared drives to create a records retention inventory. However, when I run the code, I get several rows back where there is a file name but no directory name.

I thought at first these files were on the main root drive that I was scanning but they're not. Any reason why PowerShell would return a file name, its file size and the associated dates but no directory name?

I've tried manually searching based on the file names but can't locate them.

I'm using variables to path the source and destination information into the script but this should make sense.

$properties = @(
@{ Name = 'File Size (MB)'
    Expression = {[math]::Round(($_.Length / 1MB),2)}
}
'DirectoryName'
'Name'
'CreationTime'
'LastWriteTime'
@{ Name = 'Age'
    Expression = {[math]::Round(([datetime]::Now - $_.LastWriteTime).TotalDays /365,2)}
}
)
$target_files = Get-ChildItem $sourcepath* -recurse -include "*" | Select-Object $properties | 
Export-Csv $destinationpath\${destinationfilename}.csv -NoTypeInformation

thank you in advance, MS

Upvotes: 0

Views: 730

Answers (1)

Theo
Theo

Reputation: 61253

Continuing from my comment.

A FileInfo object has different properties than a DirectoryInfo object. Most notably for your question is the DirectoryName property, which exists on a FileInfo but not on a DirectoryInfo object.

For instance, these properties are returned for a DirectoryInfo object:

PSPath            : Microsoft.PowerShell.Core\FileSystem::D:\Test
PSParentPath      : Microsoft.PowerShell.Core\FileSystem::D:\
PSChildName       : Test
PSDrive           : D
PSProvider        : Microsoft.PowerShell.Core\FileSystem
PSIsContainer     : True
Mode              : d-----
BaseName          : Test
Target            : {}
LinkType          : 
Name              : Test
FullName          : D:\Test
Parent            : 
Exists            : True
Root              : D:\
Extension         : 
CreationTime      : 4-5-2020 15:33:48
CreationTimeUtc   : 4-5-2020 13:33:48
LastAccessTime    : 21-9-2021 15:59:43
LastAccessTimeUtc : 21-9-2021 13:59:43
LastWriteTime     : 19-9-2021 21:41:48
LastWriteTimeUtc  : 19-9-2021 19:41:48
Attributes        : Directory

And here the properties for a FileInfo object:

PSPath            : Microsoft.PowerShell.Core\FileSystem::D:\Test\Blah.txt
PSParentPath      : Microsoft.PowerShell.Core\FileSystem::D:\Test
PSChildName       : Blah.txt
PSDrive           : D
PSProvider        : Microsoft.PowerShell.Core\FileSystem
PSIsContainer     : False
Mode              : -a----
VersionInfo       : File:             D:\Test\Blah.txt
                    InternalName:     
                    OriginalFilename: 
                    FileVersion:      
                    FileDescription:  
                    Product:          
                    ProductVersion:   
                    Debug:            False
                    Patched:          False
                    PreRelease:       False
                    PrivateBuild:     False
                    SpecialBuild:     False
                    Language:         
                    
BaseName          : Blah
Target            : {}
LinkType          : 
Name              : Blah.txt
Length            : 0
DirectoryName     : D:\Test
Directory         : D:\Test
IsReadOnly        : False
Exists            : True
FullName          : D:\Test\Blah.txt
Extension         : .txt
CreationTime      : 21-9-2021 16:04:49
CreationTimeUtc   : 21-9-2021 14:04:49
LastAccessTime    : 21-9-2021 16:04:49
LastAccessTimeUtc : 21-9-2021 14:04:49
LastWriteTime     : 21-9-2021 16:04:49
LastWriteTimeUtc  : 21-9-2021 14:04:49
Attributes        : Archive

The main problem with your code is that you do not use the -File switch on Get-ChildItem and because of that, the cmdlet returns objects for both files and directories.

In your $properties array, replace 'DirectoryName' with 'FullName', remove the asteriks from $sourcepath* and leave out -include "*" :

$properties = @{Name = 'File Size (MB)'; Expression = {[math]::Round(($_.Length / 1MB),2)}},
              'FullName','Name','CreationTime','LastWriteTime',
              @{Name = 'Age'; Expression = {[math]::Round(([datetime]::Now - $_.LastWriteTime).TotalDays / 365,2)}}

# use Join-Path to safely construct the path and filename for the output
$outputPath = Join-Path -Path $destinationpath -ChildPath ('{0}.csv' -f $destinationfilename)
Get-ChildItem $sourcepath -File -Recurse | Select-Object $properties | 
Export-Csv -Path $outputPath -NoTypeInformation

Upvotes: 1

Related Questions