Powershell get date from log file - powershell

I would like to get date from the log file text.
Text in log file.
Error code. 200105. Simple text and so on -------------> it should get date as 2020 Jan 05
Error code. 2000207. Simple text and so on -------------> it should get date as 2020 Feb 07
I try this but it doesnt work.
Get-Date "200105" -format "y-m-d" but it doesnt work.
I also try "200105" | Date but still same issue
This does work [datetime]::ParseExact("120105", "y.m.d", $null) but how do I get just the date but ignore all of the other text

If you want a shorter version you can do that by piping the output as follows
$date = [datetime]::ParseExact($text2, "y.M.d", $null)
$date | Get-Date -Format dd-MMMM-yyyy
Or
$date.ToString("yyyy MMMM dd")

Your second example 2000207 is invalid because of the extra 0 in there.
I would use the TryParseExact method here to see if what you have got is actually a parsable datetime string.
$logLine = 'Error code. 200105. Simple text and so on'
if ($logLine -match '^Error code\s*\.?\s*(\d{6})') {
$date = Get-Date # any valid DateTime object will do
if ([datetime]::TryParseExact($Matches[1], 'yyMMdd', [cultureinfo]::InvariantCulture, 0, [ref]$date)) {
# do something with the date found. For demo, just output in the console
"Found a date: $date"
}
}
You are probably reading the log file line-by-line, something like:
Get-Content -Path 'TheLogFile' | ForEach-Object {
if ($_ -match '^Error code\s*\.?\s*(\d{6})') {
$date = Get-Date # any valid DateTime object will do
if ([datetime]::TryParseExact($Matches[1], 'yyMMdd', [cultureinfo]::InvariantCulture, 0, [ref]$date)) {
# do something with the date found. For demo, just output in the console
"Found a date: $date"
}
}
}

According to the documentation, Get-Date converts a string to a date if it recognises the date format from the locale settings.
For instance, in UK it recognises Get-Date "2020/03/21" but not Get-Date "20200321"
The format string is only used for formatting the current date.
This works: the number of characters in the format string represents the size of the input (it matches the number of digits in the day and year - it is more complicated for months) and M represents months (m represents minutes).
PS /home/alistair> [datetime]::ParseExact("200321","yyMMdd",$null)
Saturday, 21 March 2020 00:00:00

Related

Powershell - Find the latest Friday

How can the following code be modified to identify the latest Friday within the past week (instead of the next one), but with formatting?
$Date = #(#(0..7) | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -ieq "Friday"})[0]
Source: https://stackoverflow.com/a/23939203/5651418
The post you linked to offers a more elegant solution, which you can adapt as follows:
# Get the most recent Friday relative to the given date,
# which may be that date itself.
$mostRecentFriday =
($date = Get-Date).AddDays((-7 - $date.DayOfWeek + [DayOfWeek]::Friday) % 7)
If you want to create a formatted string representation of the resulting [datetime] instance (all examples below yield something like '07 01 2022':
To use Unix-style format specifiers, use Get-Date's -UFormat parameter:
Get-Date $mostRecentFriday -UFormat '%d %m %Y'
To use .NET's format specifiers, use Get-Data's -Format parameter:
Get-Date $mostRecentFriday -Format 'dd MM yyyy'
Alternatively, pass the format string to the [datetime]
instance's .ToString() method:
$mostRecentFriday.ToString('dd MM yyyy')
If I understood correctly, your expected output would be 1 7 2022, I would personally use a do loop that stops as soon as the DayOfWeek Property of the DateTime instance is Friday:
$date = [datetime]::Now
do {
$date = $date.AddDays(-1)
} until($date.DayOfWeek -eq [DayOfWeek]::Friday)
$date.ToString("d M yyyy")
I noticed that some Get-Date -UFormat specifiers didn't seem to work when attempting to incorporate them into an output string.
Should anyone need to incorporate some rarely needed ones (like 'Week of Year' (%G), 'Day of Year (%j), etc) you could preset needed variables and add them to the output string:
$DayOfYear = (Get-Date -UFormat %j)
$WeekOfYear = (Get-Date -UFormat %V)
$Date = #(#(0..7) | % {$(Get-Date).AddDays(-$_)} | ? {$_.DayOfWeek -ieq "Wednesday"})[0].ToString("MM-dd-yyyy|Week $WeekOfYear|'Day' $DayOfYear")
I imagine someone could incorporate all the code into one Powershell command.
Additional Get-Date -UFormat specifiers: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-date?view=powershell-7.2#notes

Powershell keep looping until condition is true then proceed

I have written a script that so far is able to check a file "latest.json" for the "created_at" object which shows the last date that a commit has occurred for software.
$websiteJson = Invoke-WebRequest "https://website/latest.json" | ConvertFrom-Json | select created_at
$todaysDate = Get-Date -Format "yyyy-MM-dd HH:mm"
if($websitejson.created_at | where {$_.created_at -eq $todaysDate}){
Write-Output "Today's date matches"
} else {
Write-Output "has not yet been updated"
}
How part of latest.json looks like
"created_at":"2020-03-23 17:32:48"
How do I change this to keep looping until the date pull from latest.json matches then proceed to next step (would download and install software). Also, since "created at" has "17:32:48" will this cause the date check to fail since the time does not match?
. I want it to keep checking if dates match.
Thank you!
Right now, I'm not going to bother converting dates to match to make sure they're the same format, but what you need for your specific questions is just a do until loop. I might update this to check the date formats if you supply an example layout of the returned JSON.
Do{
$websiteJson = Invoke-WebRequest "https://website/latest.json" | ConvertFrom-Json | select created_at
$todaysDate = Get-Date -Format "yyyy-MM-dd HH:mm"
if($websitejson.created_at | where {$_.created_at -eq $todaysDate}){
Write-Output "Today's date matches"
} else {
Write-Output "has not yet been updated"
}
start-sleep -s 60
}until($websiteJson -eq $todaysDate)
I believe this wont work right off the bat. You'll have to get the JSON date and $todaysDate to be the same format, then you can do this and it will work.
if you want to compare the date and/or time, use datetime objects instead of datetime strings. something like this ...
if you want to test for the actual time difference between two time objects ...
((Get-Date -Date '2020-03-23 18:11:22') - [datetime]'2020-03-23 17:32:48').TotalHours
# result = 0.642777777777778
you keep mentioning date as if you don't want the time, so this method would work for comparing the date parts of two timestamps ...
# the date at the time the code was run = 2020 April 03, Friday 4:30:34 PM
$Today = (Get-Date).Date
$Created_At = '2020-04-03 15:15:15'
$Today -eq ([datetime]$Created_At).Date
result = True

Get the date modified to be formatted with AM/PM with powershell

I've currently got
Get-Item "C:\path\to\file.txt" | ForEach-Object { $_.LastWriteTime }
Which outputs like this
12/18/2018 16:54:32
But I want it to output like this
12/18/2018 4:54 PM
Is there any way I can do that?
Use the DateTime objects formatting. More info here
Get-Item "C:\path\to\file.txt" | ForEach-Object {
$_.LastWriteTime.ToString("MM/dd/yyyy hh:mm tt")
}
Much simpler to just use (Get-Date -Format 'M/d/yyyy h:mm tt')
# Convert 24hr time to 12hr with AM/PM ie, Monday 01/03/22 12:01 PM
Get-Date -Format "HH" -OutVariable time >$2
if ($time -ge 12) {
$ptime = Get-Date -Format "dddd MM/dd/yy hh:mm"
Write-Host "Right now it is $ptime PM"
} else {
$atime = Get-Date -Format "dddd MM/dd/yy hh:mm"
Write-Host "Right now it is $atime AM"
}
# clear variables
$time=$null
$atime=$null
$ptime=$null
tl;dr
Assuming that your current culture is US-English (in which case $PSCulture returns en-US), you have the following options to get the desired string format for a given [datetime] instance, such as contained in $_.LastWriteTime in your command ($PROFILE is used as a sample input file):
# Use .ToString() with the general date-time format, "g":
# -> e.g., "7/14/2022 3:44 PM"
Get-Item $PROFILE | ForEach-Object {
$_.LastWriteTime.ToString('g')
}
# Alternative, via Get-Date -Format
Get-Item $PROFILE | ForEach-Object {
Get-Date -Date $_.LastWriteTime -Format g
}
Note that the above implies that the simplest way to get the current date and time in the desired format is to use:
# Get the *current* date and time in general format.
# -> e.g. "7/14/2022 12:47 PM"
Get-Date -Format g
If you need a custom format that isn't covered by one of the standard formats, use kpogue's helpful answer.
Read on for background information, including how to ask for formats from a different culture, notably how to use the en-US culture for formatting even while a different culture is in effect.
The command in your question would not produce the display format in your sample output - instead, it would result in a more verbose, culture-specific representation as you would see for the current date with Get-Date, such as Thursday, July 7, 2022 3:44:57 PM in the US-English culture.
However, you would get such output if you were to stringify the [datetime] value via string interpolation with "$($_.LastWriteTime)", in which case PowerShell invariably applies the invariant culture, which is based on the US-English culture, but distinct from it, notably in that it guarantees culture-invariance and long-term stability - specifically, in this case it differs with respect to 12-hour vs. 24-hour clock representations, in that it uses a 24-hour clock.
kpogue's helpful answer shows you how to use custom formatting to achieve the desired output format; however, given that it seems like you're interested in the standard (general) US-English date-time format, the following solution is simpler (using $PROFILE as a sample file name):
Standard date-time format specifier g produces the desired format:
# Assumes that the current culture is en-US
Get-Item $Profile | ForEach-Object {
$_.LastWriteTime.ToString('g')
}
Sample output:
7/7/2022 3:44:57 PM
If your current culture is not en-US, you can pass the culture to use for formatting explicitly, as the second argument:
# Works irrespective of what the current culture is.
Get-Item $Profile | ForEach-Object {
$_.LastWriteTime.ToString('g', [cultureinfo] 'en-US')
}
This relies on the [datetime]::ToString() method having overloads that accept an [IFormatProvider] argument, which is an interface that the [cultureinfo] type implements, so that casting 'en-US' (the US-English culture's identifier) to [cultureinfo] results in that culture's general date-time format.

Formatting date and time in PowerShell

I want yesterday's date as "MMdd", like "0418" today's date is "0419".
I tried this:
$d = (Get-Date).AddDays(-1) | select -Property Month,Day
$e = $d.Day
$d = $d.Month
$total = "$d" + "$e"
Write-Host $total
But the output was "418".
As you can see, this is a three-letter string, but I want a four-letter one. Because I want to search files they have that format and created a day before.
The date object has a method ToString, which allows you to specify the format:
$d = (Get-Date).AddDays(-1);
$d.ToString("MMdd");
I am calling this on April the 20th, and the output is
0419
See this link for a description of the available date format strings.

PowerShell date/time conversion

I have a variable, $date, containing 24 June 2012 00:00:00.
How do I convert this to 24/06/2012?
Use the Get-Date cmdlet together with the Format parameter:
PS> $date = '24 June 2012 00:00:00'
PS> Get-Date $date -Format 'dd/MM/yyyy'
24/06/2012
I tried reading a file with dates formatted day-month-year
The answer above did not work for me, I found a different solution on how to parse my dates and check which one is newer than the current date. This is my adapted code.
$currdateobj = Get-Date
$STARTDATE = "12-05-2017" // specific non-default date format
[DateTime]$startdateobj = [DateTime]::ParseExact($STARTDATE,"dd-MM-yyyy",[System.Globalization.CultureInfo]::InvariantCulture)
if ($startdateobj -lt $currdateobj)
{
// ....
}