I am brand new to PowerShell and have gone through tutorials to learn the basics. I'm now at the point where it's a step beyond my knowledge and could use some guidance.
Scenario: I have a Projects folder with about 250 individual project folders using the Project ID as the name of the folder. Since Microsoft File Explorer does not update the modified date on the parent folder to the most recent date of the child files/folders, I am trying to run a script that will export a Get-childitem on each folder. I have the code for doing one folder at a time (see below), but I would like to have this loop and export a csv for each project folder and name the csv as the project ID. Project Folders named with IDs in E:\Projects
Alternative Scenario: I am doing all of this to find the most recent modified date within each of these project folders so I can archive those before 2022 and keep the others in this location. If there is a script that would give me an output of the most recent lastwritetime for all files in the project ID folders and list them. This would be very beneficial as well.
Get-ChildItem -Path "E:\Projects\1033-001" -Recurse |`
foreach {
$Item = $_
$Type = $_.Extension
$Path = $_.FullName
$ParentS = ($_.Fullname).split("\")
$Parent = $ParentS[@($ParentS.Length - 2)]
$Folder = $_.PSIsContainer
$Age = $_.LastWriteTime
$Path | Select-Object `
@{n="filePath";e={$Path}},`
@{n="Name";e={$Item}},`
@{n="Last Modified";e={$Age}},`
@{n="Folder Name";e={if($Parent){$Parent}else{$Parent}}},`
@{n="Extension";e={if($Folder){"Folder"}else{$Type}}}`
}| Export-Csv "C:\Setup\ResultsC.csv" -NoTypeInformation
The closest I tried was this solution but it doesn't give me enough information or go deep enough into the folders.Export sub-folder name as path and create a csv for each parent sub-folder in a different location
I am brand new to PowerShell and have gone through tutorials to learn the basics. I'm now at the point where it's a step beyond my knowledge and could use some guidance.
Scenario: I have a Projects folder with about 250 individual project folders using the Project ID as the name of the folder. Since Microsoft File Explorer does not update the modified date on the parent folder to the most recent date of the child files/folders, I am trying to run a script that will export a Get-childitem on each folder. I have the code for doing one folder at a time (see below), but I would like to have this loop and export a csv for each project folder and name the csv as the project ID. Project Folders named with IDs in E:\Projects
Alternative Scenario: I am doing all of this to find the most recent modified date within each of these project folders so I can archive those before 2022 and keep the others in this location. If there is a script that would give me an output of the most recent lastwritetime for all files in the project ID folders and list them. This would be very beneficial as well.
Get-ChildItem -Path "E:\Projects\1033-001" -Recurse |`
foreach {
$Item = $_
$Type = $_.Extension
$Path = $_.FullName
$ParentS = ($_.Fullname).split("\")
$Parent = $ParentS[@($ParentS.Length - 2)]
$Folder = $_.PSIsContainer
$Age = $_.LastWriteTime
$Path | Select-Object `
@{n="filePath";e={$Path}},`
@{n="Name";e={$Item}},`
@{n="Last Modified";e={$Age}},`
@{n="Folder Name";e={if($Parent){$Parent}else{$Parent}}},`
@{n="Extension";e={if($Folder){"Folder"}else{$Type}}}`
}| Export-Csv "C:\Setup\ResultsC.csv" -NoTypeInformation
The closest I tried was this solution but it doesn't give me enough information or go deep enough into the folders.Export sub-folder name as path and create a csv for each parent sub-folder in a different location
Share Improve this question asked Mar 28 at 17:26 Christopher PyeChristopher Pye 31 bronze badge 1- I think there is a left bracket missing right after the select-object. – Walter Mitty Commented Mar 30 at 10:56
2 Answers
Reset to default 0Below code will output all items with the latest modified time inside each project folder.
It produces a CSV output file where you can find the differences between the last modified time of the project folder and that of the latest modified object inside.
$sourcePath = 'E:\Projects'
$outputPath = 'C:\Setup\ResultsC.csv'
# loop over the projects folders and get the object with the latest modified time (if any) inside
Get-ChildItem -Path $sourcePath -Directory | ForEach-Object {
$latestItem = $_ | Get-ChildItem -Recurse | Sort-Object LastWriteTime | Select-Object -Last 1
if ($latestItem) {
[PsCustomObject]@{
'ProjectFolder' = $_.FullName
'Folder Last Modified' = $_.LastWriteTime
'Latest Item' = $latestItem.FullName
'Latest Item Modified' = $latestItem.LastWriteTime
'Latest Item ObjectType' = if ($latestItem.PSIsContainer) {'Directory'} else {'File'}
}
}
} | Export-Csv -Path $outputPath -NoTypeInformation
These are the items that jump out at me
Your initial query "Get-ChildItem" is only targeting a subfolder of your entire 'Projects' directory.
I would assume this is just limiting the scope for faster testing of the output, but if not, this is a reason for "not enough information"A lot of your variable assignment inside the loop is redundant.
We can just directly cite the 'current item' variable inside the loop for its properties, when deciding what to return.You are taking $Path, and then selecting custom properties and setting their expression as completely different variables.
While this does function, it is very unorthodox.
The more conventional method would be to directly create a new object, and then define keys/values on it, directly using the "$_" automatic variable
Here is a cleaner version of what you had:
$Items = Get-ChildItem -Path "E:\Projects" -Recurse | ForEach-Object {
[PSCustomObject]@{
"filePath" = $_.FullName
"Name" = $_.Name
"Last Modified" = $_.LastWriteTime
"Folder Name" = $foo.FullName.Remove($($foo.FullName.LastIndexOf('\'))) # trim the final backslash through End of Line
"Extension" = if ($_.PSIsContainer) {"Directory"} else {$_.Extension}
}
}
$Items | Export-Csv -NoTypeInformation -Path "C:\Setup\ResultsC.csv"
For 'archiving', as an example - this will select all 'folders', with a modify date earlier than 2 years, and move them into a separate folder.
$Items | Where-Object {$_.Extension -like 'Directory' -and $_.LastWriteTime -lt $((Get-Date).AddYears(-2))} | ForEach-Object {
Move-Item -Path $_.filepath -Destination "E:\MyArchive" -Verbose -WhatIf
}
Finally, to address the concern of "A folder does not have its Modified Time updated when a child is modified" -
An alternate path you can take is finding the most recently updated file inside a folder, and overwriting the parent folder's "LastWriteTime" using that date.
An example can be found here: https://superuser/a/1650065/2522669