Reputation: 111
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
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