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-Stringdoes not directly return the text of matching lines, it returnsMicrosoft.PowerShell.Commands.MatchInfoobjects whose.Lineproperty contains the line text, alongside metadata.- In PowerShell (Core) 7 , you can use the
-Rawswitch to directly request the text. - In Windows PowerShell, you must access the
.Lineproperty value explicitly, either via(...).Lineor 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-splitoperator provides.
- The fields before
You can interpret strings such as
15:31:14as 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]
