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?
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)
Related
I'm trying to get a value from a CSV file.
If today's date = DateInCSVFile give the "key" value.
Keys.csv
Guest,Key
1-Jun,OIOMY-ZFILZ
2-Jun,LSSJC-PDEUL
3-Jun,MQNVJ-TETLV
4-Jun,HCJIJ-ECVPY
5-Jun,SPACR-AJSLU
6-Jun,MEURS-UQTVX
Code:
$today = Get-Date -format dd-MMM
$keys = import-csv c:\office\keys.csv -Header #(1..2)
$data = $keys | ? { $_.1 -match $today}
Write-Host $data.2
I tried the foreach and if commands. Nothing worked.
I can think of a couple of options. If you want something quick and dirty, try:
$stuff = Import-Csv -Path .\stuff.csv
foreach ($thing in $stuff) {
if ( $thing.Guest -eq $(Get-date -Format 'd-MMM') ) {
Write-Output $thing.Key
}
}
I import the CSV file's contents to a variable. I iterate over each line. If the day in Guest matches the current day, I output the key
The only problem with your code is your date format, dd-MMM, as LotPings observes:
It creates 0-left-padded numbers for single-digit days such as 6, whereas the dates in the CSV have no such padding.
Thus, changing Get-Date -format dd-MMM to Get-Date -format d-MMM (just d instead of dd) should fix your problem.
However, given that you're reading the entire file into memory anyway, you can optimize the command to (PSv4+):
$today = Get-Date -Format d-MMM
(Import-Csv c:\office\keys.csv).Where({ $_.Guest -eq $today }).Key
Also note that the purpose of -match is to perform regular-expression-based matching, not (case-insensitive) string equality; use -eq for the latter.
I want to convert datetime to Epoch format in csv file using PowerShell. In the csv file I have only time data, and I want to use current date and time specified in csv to convert it to Epoch format .
in.csv
"192.168.1.2","01-any1TEST ","Ping","Down at least 3 min","17:25:14",":Windows 2012 Server"
"192.168.1.2","02-any2TEST ","Ping","Down at least 4 min","17:25:40",":Unix Server"
"192.168.1.2","03-any3TEST ","Ping","Down at least 3 min","17:26:21",":windows host "
My findings
This should be doable using a combination of the below two. The main issue I am facing is that I am unable to combine the current date with the time in csv file.
Import-Csv ".\out.csv" |
ForEach-Object {
$_.Date = [datetime]::Parse($_.Date).ToString('MM/dd/yyyy HH:mm')
}
Get-Date -Date "12/31/2015 23:59:59" -UFormat %s
When using Get-Date, you have the option to override values manually or using another datetime
For example:
Import-Csv ".\out.csv" |
ForEach-Object {
$tempDate = [datetime]::Parse($_.Date).ToString('MM/dd/yyyy HH:mm')
Get-Date -Hour $tempDate.Hour -Minute $tempDate.Minute -UFormat %s
}
I'd do it like this:
Import-Csv ".\out.csv" |
ForEach-Object {
$_.Date = Get-Date -Date $_.Date -UFormat %s
}
If you want to be a bit more explicit about what it's doing, you can convert the time to a timespan, which can be added to a date. Then you can pipe it to Get-Date to format it:
Import-Csv ".\out.csv" |
ForEach-Object {
$_.Date = [DateTime]::Today + [Timespan]::Parse($_.Date) | Get-Date -UFormat %s
}
[DateTime]::Today is today's date at midnight (time 00:00:00).
Ok, try the code below. It will write a warning message to the console when it finds a date that it can't parse. It won't fix the problem, but it will tell you where the problem is.
Import-Csv ".\out.csv" |
ForEach-Object {
$t = [timespan]::Zero
if ([Timespan]::TryParse($_.Date,[ref]$t)) {
$_.Date = [DateTime]::Today + $t | Get-Date -UFormat %s
}
else {
Write-Warning "Unable to parse timespan '$($_.Date)' for record $($_)"
}
}
This is working perfectly for me in 2.0 and not on 4.0 version . If possible please let me know why is is not working on powershell 4.0 .
$EventTime = $($s.EventTime)
$value = get-date -format d
$Imported = Import-Csv 'C:\PathToFIle\out.csv'
$Output = foreach ($i in $Imported) {
foreach ($c in $EventTime) {
$time=$i.eventtime
$fulltime =$value+' '+$time
$i.EventTime = Get-Date -Date $fulltime -UFormat %s
}
$i
}
$Output
$Output | Export-Csv 'C:\PathToFIle\TestComputers.csv' -NoTypeInformation
0001;Third Week;Every Monday 12am-2am
002;Third Week;Every Tuesday 8pm-10pm
003;Third Week;Every Monday 12am-2am
#Get the number of lines in a CSV file
$Lines = (Import-Csv "C:\MM1.csv").count
#Import the CSV file
$a = #(Import-CSV "C:\MM1.csv")
$month = Get-Date -Format MMMM
#loop around the end of the file
for ($i=0; $i -le $lines; $i++) {
$Servername = $a[$i].ServerName
$week = $a[$i].Week
$dayweekString = [String]$a[$i].DayTime
# This will help in getting the Day of the WeekDay String
$dayweekString = ($dayweekString -split "\s+",(3))[(1)]
#This will find the time Ex 2am or 8pm, it can be any time
$DayNew = if ($Day -match "\d{1,2}Travelm") {$Matches[0]}
#Format for Maintenance mode which can be fed into the SCOM MM Script.
$MaintenanceTime = get-date "$DayNew $month.$($_.$dayweekString).$year"
write-host $Servername, $MaintenanceTime
#Store all my data while in a for each loop
New-Object -TypeName PSObject -Property #{
ServerNameNew = $Servername
TimeStamp = $MaintenanceTime
} | Select-Object ServerNameNew,TimeStamp
} | Export-Csv -Path "C:\MM3.csv" -Append
# Error as extra Pipe
I am not able to pipe the output while in a loop with a header. Says Extra pipe and writes a extra line of TimeStamp Variable to the line.
You are trying to pipe the result of the for statement to another command. That's not supported. If you want to do that, you need to use a subexpression around the statement:
$( for(){} ) | ...
(The reason is that pipelines need an expression as their first element. And for is not an expression, it's a statement.)
However, in your case I'd replace the for with a simple pipeline iterating over the array, like this:
Import-CSV "C:\MM1.csv" | ForEach-Object {
$Servername = $_.ServerName
$week = $_.Week
$dayweekString = [String]$_.DayTime
...
}
Generally there is very rarely a reason to use explicit looping constructs in PowerShell. It leads to code that's awkward at best (because it resembles converted C# or VBScript code) and horrible at worst. Just don't do it.
I have a log that I want to parse and, among other things, convert the date/time from the current local format to UTC and convert it back to text.
I have the logic to do everything except the conversion part.
$_.Line -replace '(\d{4}\-\d{2}\-\d{2}\s\d{2}:\d{2}:\d{2})',(conversion_here)
You can use the [DateTime] object for this:
([DateTime]'2015-07-03 10:58:00').Date.ToUniversalTime()
For your replacement scenario, you could use:
$pattern = '(\d{4}\-\d{2}\-\d{2}\s\d{2}:\d{2}:\d{2})'
if ($line -match $pattern) {
$utcStr = ([DateTime]$matches[1]).ToUniversalTime().ToString('yyyy-MM-dd HH:mm:ss')
$line -replace $pattern, $utcStr
}
Use the Replace() method of the regex class with a callback function:
$fmt = 'yyyy-MM-dd HH:mm:ss'
$callback = {
(Get-Date $args[0].Groups[1].Value).ToUniversalTime().ToString($fmt)
}
$re = [regex]'(\d{4}\-\d{2}\-\d{2}\s\d{2}:\d{2}:\d{2})'
...
$re.Replace($_.Line, $callback)
...
I'm able to remove the attribute using the codes below. However, I don't know how to reformat a date string to the ISO format. From date="20140424T140222Z" to date="2014-04-24T14:02:22Z"
function update {
$unzippedLocation = Get-ChildItem $destination -Recurse
# from date="20140424T140222Z" to date="2014-04-24T14:02:22Z"
Message "Remove and reformat attributes"
$regex='date="(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z"'
ForEach($unzippedFile in $unzippedLocation) {
(Get-Content $unzippedFile) |
ForEach-Object { $_ -replace ' crc=""', '' } |
ForEach-Object { $_ -replace $regex, 'date="$1-$2-$3T$4:$5:$6Z"' } |
Set-Content $unzippedFile
Write-Host "crc attribute has been removed from $($unzippedFile.Name)"
Write-Host "date attribute has been reformated from $($unzippedFile.Name)"
}
}
I don't fully understand where you need to that the replacement of the date, but one approach is to use regular expression to update the date. Here is a sample for one string, you can incorporate it where you need to:
#Defines regex with a separate group for each component
$regex='date="(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z"'
#Sample input
$input = 'date="20140424T140222Z"'
#Update the string
$result = $input -replace $regex, 'date="$1-$2-$3T$4:$5:$6Z"'
Write-Host $result
#Result is
#date="2014-04-24T14:02:22Z"
You can use the .net method TryParseExact.
This method will try to parse any string in a valid DateTime value and then you format back to ISO format. Using this method you test if your values are valid.
Example:
$dateString = "20140424T140222Z"
$format = "yyyyMMddTHHmmssZ"
[ref]$parsedDate = get-date
$parsed = [DateTime]::TryParseExact($dateString, $format,[System.Globalization.CultureInfo]::InvariantCulture,[System.Globalization.DateTimeStyles]::None,$parseddate)
if($parsed)
{
write "$dateString is valid"
}
$parseddate.Value.ToString("yyyy-MM-ddTHH:mm:ssZ")