I have a text file that has a bunch of lines that logs my DNS. It records the time and the site that my devices request DNS.
I have the file located on c:\data
$path = 'c:\data\dns.log'
I tried to query the log by simple match for a word "xfinity"
$Query = get-content -Path $path | Select-String -SimpleMatch "xfinity"
Then I query the first time it requested and the last time it requested
$Query | select -First 1
$Query | select -Last 1
$1st = $Query | select -First 1
Then I tried to "isolate" just the time
$1st -Split ("dnsmasq")
and I got stuck below because I don't know how to select just the time. Did a lot of googling but most of the stuff just went over my head
Jan 7 15:31:14
[250]: query[A] www.xfinity.com from 172.17.0.1
How do I just get the "time" of the first line and "time" of the last line and find the elapse time between them?
Here is an example of the dns.log would look like after Select-string to simple match "xfinity"
Jan 7 15:31:14 dnsmasq[250]: query[A] www.xfinity.com from 172.17.0.1
Jan 7 15:31:14 dnsmasq[250]: forwarded www.xfinity.com to 8.8.8.8
Jan 7 15:31:14 dnsmasq[250]: query[HTTPS] www.xfinity.com from 172.17.0.1
Jan 7 15:31:18 dnsmasq[250]: query[HTTPS] dss-dl-prod.aws-origin.xfinity.com from 172.17.0.1
Jan 7 15:31:18 dnsmasq[250]: forwarded dss-dl-prod.aws-origin.xfinity.com to 8.8.8.8
Jan 7 15:31:18 dnsmasq[250]: reply dss-dl-prod.aws-origin.xfinity.com is <CNAME>
Jan 7 15:33:18 dnsmasq[250]: reply dss-dl-prod.aws-origin.xfinity.com is <CNAME>
CodePudding user response:
Generally, note that
Select-String
does not directly return the text of matching lines, it returnsMicrosoft.PowerShell.Commands.MatchInfo
objects whose.Line
property contains the line text, alongside metadata.- In PowerShell (Core) 7 , you can use the
-Raw
switch to directly request the text. - In Windows PowerShell, you must access the
.Line
property value explicitly, either via(...).Line
or by piping toSelect-Object -ExpandProperty Line
- In PowerShell (Core) 7 , you can use the
Once you extract the actual line text, you'll be dealing with strings, so you'll need to parse those strings into the fields they contain.
- The fields before
:
can unambiguously be extracted by using whitespace as the separator, which the unary form of the-split
operator provides.
- The fields before
You can interpret strings such as
15:31:14
as time spans, simply by casting them to the[timespan]
.NET type.
To put it all together:
# Get the lines of interest.
# Note: In PowerShell Core 7 , you could simplify to:
# $matchingLines = Get-Content $path | Select-String -Raw xfinity
$matchingLines = (Get-Content $path | Select-String xfinity).Line
# From the lines of interest, extract the first and last line.
$firstMatchingLine, $lastMatchingLine = $matchingLines[0], $matchingLines[-1]
# Calculate the elapsed time between
# the last and the first matching line.
[timespan] (-split $lastMatchingLine)[2] - (-split $firstMatchingLine)[2]