locked
sorting files and getting the latest filename and lastwrite time RRS feed

  • Question

  • 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 

    Tuesday, July 4, 2017 8:07 AM

Answers

  • 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


    \_(ツ)_/

    • Marked as answer by har Wednesday, July 5, 2017 10:46 AM
    Wednesday, July 5, 2017 8:25 AM
  • 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''


    • Edited by BOfH-666 Wednesday, July 5, 2017 8:37 AM
    • Marked as answer by har Wednesday, July 5, 2017 10:46 AM
    Wednesday, July 5, 2017 8:35 AM
  • 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


    • Marked as answer by har Wednesday, July 5, 2017 11:21 AM
    • Edited by har Wednesday, July 5, 2017 11:23 AM
    Wednesday, July 5, 2017 11:20 AM

All replies

  • All depends on the number of files in the folder. 


    \_(ツ)_/

    Tuesday, July 4, 2017 8:11 AM
  • when ran the same sorting with batch file it just took some seconds.
    Tuesday, July 4, 2017 8:12 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:31 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 8:52 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:45 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 9:59 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:07 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.


    \_(ツ)_/


    • Edited by jrv Tuesday, July 4, 2017 10:10 AM
    Tuesday, July 4, 2017 10:09 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:12 AM
  • thank you jrv

    Is there any way around to make it run fast?

    Tuesday, July 4, 2017 10:16 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 10:17 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:08 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:17 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: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.


    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:37 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 11:52 AM
  • 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 12:49 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''


    • Edited by BOfH-666 Tuesday, July 4, 2017 1:07 PM
    Tuesday, July 4, 2017 1:04 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:07 PM
  • You can also do this in PowerShell:

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


    \_(ツ)_/


    • Edited by jrv Tuesday, July 4, 2017 1:33 PM
    Tuesday, July 4, 2017 1:33 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:39 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 1:53 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:15 PM
  • You forgot the "dir"!  Take the example James posted!!

    Grüße - Best regards

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

    Tuesday, July 4, 2017 2:52 PM
  • 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


    • Edited by har Wednesday, July 5, 2017 7:07 AM
    Wednesday, July 5, 2017 7: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:05 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.

    • Edited by har Wednesday, July 5, 2017 8:10 AM
    Wednesday, July 5, 2017 8:09 AM
  • 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


    \_(ツ)_/

    • Marked as answer by har Wednesday, July 5, 2017 10:46 AM
    Wednesday, July 5, 2017 8:25 AM
  • 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''


    • Edited by BOfH-666 Wednesday, July 5, 2017 8:37 AM
    • Marked as answer by har Wednesday, July 5, 2017 10:46 AM
    Wednesday, July 5, 2017 8:35 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 9:11 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''


    • Edited by BOfH-666 Wednesday, July 5, 2017 10:20 AM
    Wednesday, July 5, 2017 10:19 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.

    Wednesday, July 5, 2017 10:46 AM
  • 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


    • Marked as answer by har Wednesday, July 5, 2017 11:21 AM
    • Edited by har Wednesday, July 5, 2017 11:23 AM
    Wednesday, July 5, 2017 11:20 AM