Read in a date and time from a string

Tagged: , ,

This topic contains 7 replies, has 5 voices, and was last updated by Profile photo of Karl Forster Karl Forster 1 year, 11 months ago.

  • Author
    Posts
  • #26392
    Profile photo of Karl Forster
    Karl Forster
    Participant

    I have a log file that I need to put some alerting onto and would like to use Powershell.

    The log file has multiple line in all in this format.
    (ART)End Processing Autoroutines (12/06/15 15:50:47)

    I have so far used the below to get the last line in the file.
    get-content C:\Karl\ATM-E-DocsEmailproatm.log -tail 1

    I would like to read in the date and time part of the string to compare the difference with the current date and time. Then perform some actions.

    I am having trouble separating the date from the string to assign to a variable.

    Any help would be appreciated.

    Thanks in advance.
    Karl

  • #26393
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    If you know that your date/time will always be in that US format (mm/dd/yy hh:mm:ss), then you can use a combination of regex and casting:

  • #26394
    Profile photo of tommymaynard
    tommymaynard
    Member
    $x = '(ART)End Processing Autoroutines (12/06/15 15:50:47)'
    New-TimeSpan -Start (Get-Date) -End ($x.Split('(',3)[-1]).TrimEnd(')')
    

    I have no idea of your skill level, so it's possible this might hurt your brain. In case it does, then let's walk though how I came up with this.

    1. I assigned $x the string you're collecting from your log file.

    PS C:\> $x = '(ART)End Processing Autoroutines (12/06/15 15:50:47)'

    2. I wanted to start splitting up the string, and did so at the left parens. I indicated to the .Split() method to make three substrings, so I could get the date and time on a line by itself. For fun, try changing 3, to 1 and 2 to see the difference.

    PS C:\> $x.Split('(',3)
    
    ART)End Processing Autoroutines
    12/06/15 15:50:47)

    3. Next, I grabbed the last element, or index, so it would only give me the last substring.

    PS C:\> $x.Split('(',3)[-1]
    12/06/15 15:50:47)

    4. When I just had the date and time, I used the .TrimEnd() method to remove the ending right paren.

    PS C:\> ($x.Split('(',3)[-1]).TrimEnd(')')
    12/06/15 15:50:47

    5. In the end, I stuffed all this together as the value for the New-TimeSpan's -End parameter and it returned the comparison.

    Edit: Or just use Dave's suggestion. By the way, all those double quotes are supposed to be single. I'm not sure why that happened.

  • #26397
    Profile photo of Karl Forster
    Karl Forster
    Participant

    Thanks guys, that make perfect sense now. I was trying to use trim to do it but knew there would be a different method.

    Just learning the basics of powershell at the moment by watching the VMA powershell jumpstart.

  • #26481
    Profile photo of Karl Forster
    Karl Forster
    Participant

    Hi Guys

    I was wondering if you could take a look at my code and let me know if I could have improved it? As I am just starting out, getting the syntax correct was my main hurdle here.

    Any feedback would be appreciated.

     
    #Read last line from the Log file
    $Logfile ="C:\karl\ATM-E-DocsReceiptsproatm.log"
    $Server ="Proclaim-ATM2"
    $ATMName ="Edocs Reciepts ATM"
    $to = "Karl@helphire.co.uk"
    $from = "ATMMonitor@helphire.co.uk"
    $subject = "Critical Message from node: $server"
    $x = get-content $Logfile -tail 1
    
    
    
    #If last line contains specific words exit the script
    if ($x -match "FORCED SHUTDOWN" )
    {
    Write-host "Forced shutdown in Last Line"
    Exit
    }
    else
    {
      #Cuts out the date field from the string
    $logDateTime = ($x.split("(",3)[-1]).trimend(")")
      #Comapres the current time to the Log date Time
    $TimeDiff = New-TimeSpan -end $logDateTime
    
    #If Time difference is greater than 5 Minutes Send email.
    if ($TimeDiff.minutes -lt -5)
    {
    $email_body ="The $ATMName on server $Server has not written to its log file since $logDateTime and requires investigation  
       The log file can be found here: $logfile 
       This will trigger a Proclaim_emailalert." 
       send-mailmessage -to $to -from $from -subject $Subject -smtpserver "mail.internal.local" -body $email_body -bodyashtml;
    }
    }
    
    
    
  • #26487
    Profile photo of Martin Nielsen
    Martin Nielsen
    Participant

    I'd like to advocate the use of named regex groups to make sense of text files and logs. They make everything look so pretty.

    Edit: Okay I tried pasting an example, but the website simply does not allow .NET style regex naming groups. It eats the triangle brackets.

    http://pastebin.com/K3eP1vKu

  • #26498
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    Some Powershell functionality you should look into is here strings and splatting. Also, keep in mind you don't need to use "Exit" because your if code block doesn't do anything else if you meet the if criteria. Using Write-Host is also a bad practice. You can either just return a string or use [cmdletbinding()] and then you can use Write-Verbose to display information for trouble shooting using the -Verbose switch. Take a look at the below:

    $Logfile ="C:\karl\ATM-E-DocsReceiptsproatm.log"
    $Server ="Proclaim-ATM2"
    $ATMName ="Edocs Reciepts ATM"
    
    #check out Powershell splatting.  We define all parameters in
    #a hash table and then can pass those to Send-MailMessage
    $splat = @{to = "Karl@helphire.co.uk";
               from = "ATMMonitor@helphire.co.uk"
               subject = "Critical Message from node: $server";
               smtpserver = "mail.internal.local"
               attachments=$Logfile
               bodyashtml =$true
               }
    
    
    $content = get-content $Logfile -tail 1
    #Cuts out the date field from the string
    $logDateTime = ($content.split("(",3)[-1]).trimend(")")
    
    #Check out Powershell here strings.  Allows you to format
    #something like HTML and pass it later.  Comes in handy
    #with SQL queries as well.
    $hereString =@" 
    
        
            An email message from our sponsor
        
        
            
                The $ATMName on server $Server has not written to its log file since $logDateTime and requires investigation
                The log file is attached for review.
                This will trigger a Proclaim_emailalert."
            
        
    
    "@
    
    #Dynamically add body parameter since body is ready
    $splat.Add("body", $hereString)
    
    #If last line contains specific words exit the script
    if ( $content -match "FORCED SHUTDOWN" ) {
        "Forced shutdown in Last Line"
    }
    else {
        #Compares the current time to the Log date Time
        #If Time difference is greater than 5 Minutes Send email.
        if ((New-TimeSpan -end $logDateTime).minutes -lt -5) {
           Send-MailMessage @splat
        }
    }
    
  • #26510
    Profile photo of Karl Forster
    Karl Forster
    Participant

    Great info rob & Martin. Can see the value in both of the alternatives.

    Thanks for taking your time to help me out.

You must be logged in to reply to this topic.