Share via


sorting files and getting the latest filename and lastwrite time

Question

Tuesday, July 4, 2017 8:07 AM

hi,

this is probabbly my second powershell script I am very new to scripting.

I have written a simple script to find the latest file in a folder, but its taking a long time to just get the last file like a more than a minute.

Am I doing any wrong?

please suggest me the llightest and fastest way to do it.

Please find below the script.

I am in urgent need as have to deploy it in production ASAP.

$lastMessage = dir -Path D:\BizTalk\Log\Incoming\customer\HAV*.xml | where-Object {$_.LastWriteTime -gt (get-date).AddMinutes(-20)} | Sort-Object LastWriteTime -descending | Select -first 1 

All replies (34)

Wednesday, July 5, 2017 8:25 AM ✅Answered

You need to learn to work with what you can get.

$filename = cmd /c "dir D:\Biztalk\Log\Incoming\Costumer\HAV*.xml /od  /b"| select  -last 1
Get-Item -Path D:\Biztalk\Log\Incoming\Costumer\ -Include $filename

\(ツ)_/


Wednesday, July 5, 2017 8:35 AM ✅Answered

or like this:

$filename = Get-Item -Path (Join-Path -Path 'D:\Biztalk\Log\Incoming\Costumer' -ChildPath ( cmd /c "dir D:\Biztalk\Log\Incoming\Costumer\HAV*.xml /od  /b" | Select-Object -Last 1))
$filename.LastWriteTime
$filename.FullName

But you REALLY should take some time to learn the basics of Powershell. Really.

Grüße - Best regards

PS:> (79,108,97,102|%{[char]$_})-join''


Wednesday, July 5, 2017 11:20 AM ✅Answered

this would work instead need to use 

$filename = cmd /c "dir D:\Biztalk\Log\Incoming\Costumer\HAV*.xml /o-d  /b"| select  -first 1
Get-Item -Path D:\Biztalk\Log\Incoming\Costumer\$filename

and also takes less time. 

thanks


Tuesday, July 4, 2017 8:11 AM

All depends on the number of files in the folder. 

\(ツ)_/


Tuesday, July 4, 2017 8:12 AM

when ran the same sorting with batch file it just took some seconds.


Tuesday, July 4, 2017 8:31 AM

The batch sort sorts text. PowerShell sorts objects.

How do you know it is the sort that is taking time?

\(ツ)_/


Tuesday, July 4, 2017 8:52 AM

there is a batch file which gives the last message and its timestamp  in the folder> it took around 15 seconds

in powershell when I ran above script to get the latest file > it took around 1 minute 40 seconds


Tuesday, July 4, 2017 9:45 AM

what happens when you drop the "where-object" part ... actually you don't need that

$lastMessage = Get-ChildItem -Path D:\BizTalk\Log\Incoming\customer\HAV*.xml |
    Sort-Object LastWriteTime | 
        Select-Object -Last 1 

Grüße - Best regards

PS:> (79,108,97,102|%{[char]$_})-join''


Tuesday, July 4, 2017 9:59 AM

as there are lots of messages in the folder I thought of narrowing it down for the sort so thAT IT WILL TAKE LESS TIME


Tuesday, July 4, 2017 10:07 AM

Really often those kind of assumptions are just wrong. And as long as it does not cost any money why don't you try it at least once?

Grüße - Best regards

PS:> (79,108,97,102|%{[char]$_})-join''


Tuesday, July 4, 2017 10:09 AM

As a point of reference look at these two results.

PS D:\scripts> measure-command {dir c:\windows -rec -ea 0| Out-Null}


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 23
Milliseconds      : 495
Ticks             : 234954771
TotalDays         : 0.000271938392361111
TotalHours        : 0.00652652141666667
TotalMinutes      : 0.391591285
TotalSeconds      : 23.4954771
TotalMilliseconds : 23495.4771



PS D:\scripts> measure-command {cmd /c "dir/s c:\windows >null:"}


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 6
Milliseconds      : 806
Ticks             : 68067902
TotalDays         : 7.87822939814815E-05
TotalHours        : 0.00189077505555556
TotalMinutes      : 0.113446503333333
TotalSeconds      : 6.8067902
TotalMilliseconds : 6806.7902



PS D:\scripts>

PowerShell takes three times as long because it is creating objects.  batch commands only generate strings and are optimized to the OS.

\(ツ)_/


Tuesday, July 4, 2017 10:12 AM

Thank you very much BOfH for your suggestion.

I tried the same sugggested by you it took again long time of 2 minutes13 seconds


Tuesday, July 4, 2017 10:16 AM

thank you jrv

Is there any way around to make it run fast?


Tuesday, July 4, 2017 10:17 AM

So now you know that's the time Powershell takes for this task.  ;-)

Grüße - Best regards

PS:> (79,108,97,102|%{[char]$_})-join''


Tuesday, July 4, 2017 11:08 AM

Is there any work around to make it faster?


Tuesday, July 4, 2017 11:08 AM

Does the runtime really matters?

Grüße - Best regards

PS:> (79,108,97,102|%{[char]$_})-join''


Tuesday, July 4, 2017 11:17 AM

Is there any work around to make it faster?

If you index the folders and use Microsoft Search the time can be cut to under 2 ms. 

\(ツ)_/


Tuesday, July 4, 2017 11:24 AM

folder is already indexed.

actually I want to get the last hav file in folder after every 10 minutes and send that via mail.

Instead of doing that manually I thought of automating it using powershell.


Tuesday, July 4, 2017 11:37 AM

folder is already indexed.

actually I want to get the last hav file in folder after every 10 minutes and send that via mail.

Instead of doing that manually I thought of automating it using powershell.

The use Microsoft Search to find the newest file.   When you search with File Explorer you are using Microsoft Search.  Look for examples of how to do it from PowerShell.

\(ツ)_/


Tuesday, July 4, 2017 11:52 AM

Hmmm ... if you like to let it run every 10 minutes as a scheduled task - does the runtime really matters then?? I mean really .... ?

You would make a lot of effort for no added value ... 

Grüße - Best regards

PS:> (79,108,97,102|%{[char]$_})-join''


Tuesday, July 4, 2017 12:49 PM

In all powershell examples it says the way I have written.

and when I tried to run it , took this much of time.

I thought powershell is really powerfull and lightest way to do it. but it doesnt seems to be.

its taking a lot time to just get the latest file in the folder :-(


Tuesday, July 4, 2017 1:04 PM

I thought powershell is really powerfull ....

Yes it is ....

.... and lightest way to do it.

No .... or ... it depends ...  ;-)

Edit: If you already have a faster way you can keep using it. You could even combine cmd commands and Powershell if you really like. Even if it's not a good style - if it does the job ... !?

Grüße - Best regards

PS:> (79,108,97,102|%{[char]$_})-join''


Tuesday, July 4, 2017 1:07 PM

The following might be somewhat faster:

Get-ChildItem -Path D:\BizTalk\Log\Incoming\customer\* -Include HAV*.xml |
    Sort lastwritetime |
    Select -Last 1

\(ツ)_/


Tuesday, July 4, 2017 1:33 PM

You can also do this in PowerShell:

$filename = cmd /c "dir hav*.xml /OD /B" | select -last 1

\(ツ)_/


Tuesday, July 4, 2017 1:39 PM

thank you Grushe for your help

what do you mean by combining cmd and powershell?

how can I search for newest file using cmd in Powershell?


Tuesday, July 4, 2017 1:53 PM

"Grüße" is German and means "Best regards"!  :-D  ... it's not my Name.  ;-)

What command did you use in cmd to get the latest file? 

You simply start a cmd from Powershell and take the output (ideally the complete path of your "latest file") and procedd with it however you like.

Grüße - Best regards

PS:> (79,108,97,102|%{[char]$_})-join''


Tuesday, July 4, 2017 2:15 PM

I tried to run 

measure-command {cmd /c "D:\Biztalk\Log\Incoming\Costumer\HAV*.xml"| select -Last 1} 

and it says can not find the  path specified


Tuesday, July 4, 2017 2:52 PM

You forgot the "dir"!  Take the example James posted!!

Grüße - Best regards

PS:> (79,108,97,102|%{[char]$_})-join''


Wednesday, July 5, 2017 7:05 AM

Thank you very much James and BOFh ,

I want filename and its timestamp also.

After doing little search on net I wrote this 

cmd /c "dir D:\Biztalk\Log\Incoming\Costumer\HAV*.xml /o-d  /n"| select -First 1

but got this:-(

volume in drive "" is Data


Wednesday, July 5, 2017 8:05 AM

I posted this above.   It is the only way to do this without issues.

** md /c "dir D:\Biztalk\Log\Incoming\Costumer\HAV*.xml /od  /b"| select -last 1**

\(ツ)_/


Wednesday, July 5, 2017 8:09 AM

But I want filename and its lastwritetime also.

cmd /c "dir D:\Biztalk\Log\Incoming\Costumer\HAV*.xml /od  /b"| select -last 1

Its giving me just a file name.


Wednesday, July 5, 2017 9:11 AM

Thank you very much for your help and time BOfH and Jrv,

I was trying to use something like this 

$lastHAV=cmd /c "dir D:\Biztalk\Log\Incoming\Costumer\HAV*.xml /od  /b"| select  -last 1

$lastHAV.LastWriteTime

$lastHAV.name

but in the first line was not getting success

but thank you very much for your guidance.

I really need to learn the Powershell command and scripting.

I know I am not really good at scripting and programming, thats what disappoints me :-(

I took some basic tutorial on Powershell, but thats not helping me it seems.

 


Wednesday, July 5, 2017 10:19 AM

What  I don't understand: Why the hell don't you take our examples exactly as they are and run it in your environment? Why is your code again and again and again different to ours? 

And please - if you post code you should format it as code.

Grüße - Best regards

PS:> (79,108,97,102|%{[char]$_})-join''


Wednesday, July 5, 2017 10:46 AM

I mean to say before you post your code I was trying the above code then I saw your much cleaner code and tried that, It ran successfully .

Thank you very much once again for your help and support.