jcarreiro
jcarreiro

Reputation: 39

PowerShell find most recent file

I'm new to powershell and scripting in general. Doing lots of reading and testing and this is my first post.
Here is what I am trying to do. I have a folder that contains sub-folders for each report that runs daily. A new sub-folder is created each day.
The file names in the sub-folders are the same with only the date changing. I want to get a specific file from yesterday's folder.
Here is what I have so far:

Get-ChildItem -filter “MBVOutputQueriesReport_C12_Custom.html” -recurse -path D:\BHM\Receive\ | where(get-date).AddDays(-1)  

Both parts (before and after pipe) work. But when I combine them it fails. What am I doing wrong?

Upvotes: 0

Views: 3184

Answers (5)

loneshark99
loneshark99

Reputation: 714

Can do something like this.

$time = (get-date).AddDays(-1).Day
Get-ChildItem -Filter "MBVOutputQueriesReport_C12_Custom.html" -Recurse -Path  D:\BHM\Receive\ | Where-Object { $_.LastWriteTime.Day -eq $time }

Upvotes: 0

TessellatingHeckler
TessellatingHeckler

Reputation: 28993

What am I doing wrong?

0,1,2,3,4,5 | Where { $_ -gt 3 }

this will compare the incoming number from the pipeline ($_) with 3 and allow things that are greater than 3 to get past it - whenever the $_ -gt 3 test evaluates to $True.

0,1,2,3,4,5 | where { $_ }

this has nothing to compare against - in this case, it casts the value to boolean - 'truthy' or 'falsey' and will allow everything 'truthy' to get through. 0 is dropped, the rest are allowed.

Get-ChildItem | where Name -eq 'test.txt'

without the {} is a syntax where it expects Name is a property of the thing coming through the pipeline (in this case file names) and compares those against 'test.txt' and only allows file objects with that name to go through.

Get-ChildItem | where Length

In this case, the property it's looking for is Length (the file size) and there is no comparison given, so it's back to doing the "casting to true/false" thing from earlier. This will only show files with some content (non-0 length), and will drop 0 size files, for example.

ok, that brings me to your code:

 Get-ChildItem | where(get-date).AddDays(-1)

With no {} and only one thing given to Where, it's expecting the parameter to be a property name, and is casting the value of that property to true/false to decide what to do. This is saying "filter where *the things in the pipeline have a property named ("09/08/2016 14:12:06" (yesterday's date with current time)) and the value of that property is 'truthy'". No files have a property called (yesterday's date), so that question reads $null for every file, and Where drops everything from the pipeline.

You can do as Jimbo answers, and filter comparing the file's write time against yesterday's date. But if you know the files and folders are named in date order, you can save -recursing through the entire folder tree and looking at everything, because you know what yesterday's file will be called.

Although you didn't say, you could do approaches either like

$yesterday = (Get-Date).AddDays(-1).ToString('MM-dd-yyyy')
Get-ChildItem "d:\receive\bhm\$yesterday\MBVOutputQueriesReport_C12_Custom.html"

# (or whatever date pattern gets you directly to that file)

or

Get-ChildItem | sort -Property CreationTime -Descending | Select -Skip 1 -First 1

to get the 'last but one' thing, ordered by reverse created date.

Upvotes: 1

JosefZ
JosefZ

Reputation: 30113

Read output from get-date | Get-Member -MemberType Property and then apply Where-Object docs:

Get-ChildItem -filter “MBVOutputQueriesReport_C12_Custom.html” -recurse -path D:\BHM\Receive\ | `
    Where-Object {$_.LastWriteTime.Date -eq (get-date).AddDays(-1).Date}

Upvotes: 0

TheMadTechnician
TheMadTechnician

Reputation: 36297

You could pipe the results to the Sort command, and pipe that to Select to just get the first result.

Get-ChildItem -filter “MBVOutputQueriesReport_C12_Custom.html” -recurse -path D:\BHM\Receive\ | Sort LastWriteTime -Descending | Select -First 1

Upvotes: 0

Jimbo
Jimbo

Reputation: 2537

Try:

where {$_.lastwritetime.Day -eq ((get-date).AddDays(-1)).Day}

Upvotes: 0

Related Questions