0

I am trying to parse a file for only the most recent entries. Each entry in the log file starts with date in the format "m/d/yyyy h:mm:ss PM".

I write a script that accomplishes what I wanted but unfortunately this script runs on Powershell 5 but not Powershell 2

$regex = '\b([1-2][0-9]|[0-9])\/([1-3][0-9]|[0-9])\/(20[0-9][0-9]) ((1[0-2]|0?[1-9]):([0-5][0-9]):([0-5][0-9]) ([AaPp][Mm]))'

$lines = gci C:\temp\Gateway.log | select-string -pattern $regex |select linenumber, matches
$log=@()
foreach($line in $lines)
{
    [datetime]$logdate = ($line.matches).value
    $ln = $line.linenumber

    if ($logdate -gt '2017-06-29 12:00:00')
    {
        $log += $ln
    }
}

$log

When i try to run this script on the server with powershell 2, i get the following error.

Cannot convert null to type "System.DateTime".

I am having trouble converting the value found by the select-string into datetime. tried convert to string with tostring and also with out-string

  $dt = $line.matches
    $val = $dt|select Value
    $val1 = $val|Out-String
    $val2 = $val.tostring()
    [datetime]$val1
    [datetime]$val2

How can I get the value as datetime so I can do datemath on in it powershell 2?

5
  • Regardless of PowerShell version, simply casting the string to DateTime is poor form because it assumes the locale actually accepts date/time values of that specific format. Use something like [DateTime]::ParseExact($val1, "M/d/yyyy H:mm:ss tt", [CultureInfo]::InvariantCulture) instead. (I forget if there's a more PowerShellian way of doing that.) Commented Jul 4, 2017 at 21:56
  • Note also that your regex is overly complicated: there's really no need for you to care if someone tries to pass off 14/68/3016 1:62:63 PM as a valid date/time, just let the parser sort out that's invalid. Things like [0-9]+ are fine for simple delineation work. If the date/time happens to have a fixed size or a non-space delimiter it's even simpler. Commented Jul 4, 2017 at 22:03
  • @JeroenMostert the upper case H denotes a 24 hour format, change to lower case h Commented Jul 4, 2017 at 22:31
  • I think my issue is not so much the date conversion, but the convert to string. when i try to do $val.tostring() is returns null. the type of val is PSCustomObject. Commented Jul 5, 2017 at 13:46
  • @JeroenMostert yeah, i'm a novice at regex so this was first example I found that worked for me. But I will take your note in consideration, simpler the better. thx Commented Jul 5, 2017 at 13:56

1 Answer 1

1

To my experience the am/pm conversion doesn't work (also not with [CultureInfo]::InvariantCulture) if your current locale settings don't apply with it.

You need to specify a cultureinfo object which supports am/pm

$enUS = 'en-US' -as [Globalization.CultureInfo]
$val1 = (get-date).ToString("M/d/yyyy H:mm:ss tt", $enUS)
$val1
[DateTime]::ParseExact($val1, "M/d/yyyy H:mm:ss tt", $enUS)
Sign up to request clarification or add additional context in comments.

2 Comments

I have to cast my matches date as an array because tostring() was not converting anything. $enUS = 'en-US' -as [Globalization.CultureInfo] $dt = $line.matches $val = @($dt|%{$_.Value}) $val = $val[0].ToString() [DateTime]::ParseExact($val, "M/d/yyyy H:mm:ss tt", $enUS)
Take care with the upper case H, according to these tables you need the lower case h for 12hour am/pm format.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.