The Wonders of Date Math using Windows PowerShell

The Wonders of Date Math using Windows PowerShell

  • Comments 12

Larry Hayden posted a query about dates at:
http://techtasks.com/bookmarks/powershell/2006/09/interview-with-a-scripter-jeffrey-snover/

He has a script which gets all the Application Events that happened TODAY:

————————————————————
$today = [DateTime]::Today
$Events = Get-Eventlog -New 1024 Application | Where {$Today -le $_.TimeWritten}
$Events |Group EntryType,Source |Format-Table Count,Name -Auto
————————————————————

What Larry really wants is the Application Events that happend in the last 24 hours.  We'll Larry - you're in luck because PowerShell leverages the awesome .NET frameworks which support Date Math.  Check this out:

PS> [DateTime]::Now  |Get-Member -MemberType Method

   TypeName: System.DateTime
Name                 MemberType Definition
----                 ---------- ----------
Add                  Method     System.DateTime Add(TimeSpan value)
AddDays              Method     System.DateTime AddDays(Double value)
AddHours             Method     System.DateTime AddHours(Double value)
AddMilliseconds      Method     System.DateTime AddMilliseconds(Double v...
AddMinutes           Method     System.DateTime AddMinutes(Double value)
AddMonths            Method     System.DateTime AddMonths(Int32 months)
AddSeconds           Method     System.DateTime AddSeconds(Double value)
AddTicks             Method     System.DateTime AddTicks(Int64 value)
AddYears             Method     System.DateTime AddYears(Int32 value)
CompareTo            Method     System.Int32 CompareTo(Object value), Sy...
Equals               Method     System.Boolean Equals(Object value), Sys...
GetDateTimeFormats   Method     System.String[] GetDateTimeFormats(), Sy...
GetHashCode          Method     System.Int32 GetHashCode()
GetType              Method     System.Type GetType()
GetTypeCode          Method     System.TypeCode GetTypeCode()
...
IsDaylightSavingTime Method     System.Boolean IsDaylightSavingTime()
Subtract             Method     System.TimeSpan Subtract(DateTime value)...
ToBinary             Method     System.Int64 ToBinary()
ToFileTime           Method     System.Int64 ToFileTime()
ToFileTimeUtc        Method     System.Int64 ToFileTimeUtc()
ToLocalTime          Method     System.DateTime ToLocalTime()
ToLongDateString     Method     System.String ToLongDateString()
ToLongTimeString     Method     System.String ToLongTimeString()
ToOADate             Method     System.Double ToOADate()
ToShortDateString    Method     System.String ToShortDateString()
ToShortTimeString    Method     System.String ToShortTimeString()
ToString             Method     System.String ToString(), System.String ...
ToUniversalTime      Method     System.DateTime ToUniversalTime()

So lets see this in action:

PS> [DateTime]::Now
Saturday, September 16, 2006 9:29:29 PM

PS> [DateTime]::Now.AddDays(1)
Sunday, September 17, 2006 9:29:29 PM

PS> [DateTime]::Now.AddDays(7)
Saturday, September 23, 2006 9:29:30 PM

PS> [DateTime]::Now.AddDays(-1)
Friday, September 15, 2006 9:29:30 PM

PS> [DateTime]::Now.AddDays(-7)
Saturday, September 09, 2006 9:29:31 PM

Yes that's right - you can provide negative numbers to AddDays() and it will do the old Way-Back Machine trick.

So all you have to do to get the Application Events for the last 24 hours is:

————————————————————
$24HoursAgo = [DateTime]::Now.AddHours(-24)
$Events = Get-Eventlog -New 1024 Application | Where {$24HoursAgo -le $_.TimeWritten}
$Events |Group EntryType,Source |Format-Table Count,Name -Auto
————————————————————

Date math VERY simple to learn once you know that it is possible and it is very useful so take a couple of minutes and try it out - it's an investment that will pay rich dividends over the next few years.

Here is how you find out which processes have been started in the last hour:
PS> $1HourAgo = [DateTime]::Now.AddHours(-1)
PS> Get-Process |where {$_.StartTime -ge $1HourAgo}

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
     52       2     1244       9520    51     0.13   4240 notepad
    216       8    32296      31008   173     4.39   2420 powershell
    117       4     3124       5564    54     0.06   5276 SearchFilterHost
    287       5     4044       6972    58     0.17   2380 SearchProtocol...

Here is how you can find out what type of files you have been working on most in the last month:

PS> dir \ -Recurse | where {$1MonthAgo -le $_.LastWriteTime} |
>>  Group Extension | sort -Descending Count |Select -First 10 |
>>  Format-Table Count,Name -AutoSize

Count Name
----- ----
  297 .cs
  249 .zip
  128 .ps1
   96 .txt
   90 .log
   51 .xml
   30 .dll
   21 .msg
   20 .dbf
   15 .url

By the way - check out the readability of the scripts required to accomplish this.  Imagine you wrote this script and the day after you installed it on all your production servers, you got hit by a beer truck.  What are the odds that the person replacing you would be able to understand and maintain this script?  I think they are pretty good.

So avoid beer trucks that drive at high speeds on the sidewalk but write your scripts like you might not be quick enough one day.  :-)  (And apologizes in advance to anyone that has recently lost a loved one to a stray beer-truck.)

Cheers!

Jeffrey Snover [MSFT]
Windows PowerShell/Aspen Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

PSMDTAG:DOTNET: DateTime

PSMDTAG:FAQ: How do I events that occured in the last 24 hours?

 

Leave a Comment
  • Please add 8 and 4 and type the answer here:
  • Post
  • Thank you so much!

    The script appears to do exactly what I need it to.  I appreciate your time.
  • Thanks!

    after finding on Google, The script is useful!

  • Don't use $_.CreationTime, it doesn't seem to work in the comparision.  After looking at this I changed my script to look $_.LastWriteTime.  Thanks

  • A co-worker of mine ran into an alert flood scenario and needed to resolve a large number of alerts. 

  • I've been looking everywhere for a way to do this. Thanks a bunch!!

  • I am new to powershell and I would like to set a variable $begintime  04:00 and increase it by 5 minutes at a time. can this be done?

    thank you

    robert

  • Get-Date but AddDays

    Should I really be annoyed as I am by this inconsistent approach to hyphen usage? Probably not, but for a ground up shell design it sucks!

  • Get-Date is a Powershell commandlet, and AddDays is a .NET method. Which means the two are completely different and not part of the same command system. All Powershell commandlets have hyphens.

    Is that right, everyone?

  • I need a script that will determine if it is the last day of the month. Or better yet the last backup window of the month. Example:

    on the very last day of every month I need a full to run. I cannot use a schedule for this as I have a third party tool actually doing the backup. The third party tool has a script on the end of it that calls our backup of that flat file. Our backup window would be between 6pm-6am. So I need a script that will A)Determine if today is the last day of the month or the 1st prior to 6 am and if so move to another section that will point it to the appropiate answer file for the full backup.

  • OMG, that's just too easy.  Thanks!

  • Hi,

        I need a powershell script to delete files in a folder that are 15 months old.Do u have any idea to get the date 15 months ago?.

  • So I'm trying to filter an ad query based on computers that are older than 90 days. Here's what I have (which isn't working)

    Get-ADComputer -Filter {enabled -eq $true; LastLogonDate -lt ([DateTime]::Now.AddDays(-90))} -properties *

    Any ideas? The error is that it doesn't like the operator.

Page 1 of 1 (12 items)