Unix style "tail -f" written in PowerShell

This section contains scripts that hMailServer has contributed with. hMailServer 5 is needed to use these.
Post Reply
palinka
Senior user
Senior user
Posts: 2172
Joined: 2017-09-12 17:57

Unix style "tail -f" written in PowerShell

Post by palinka » 2020-04-22 14:24

Since we're still on lockdown.... :D I was going to post this in Soren's VBS tail thread, but then I thought its better not to hijack the thread.

Powershell has a built in tail.

Code: Select all

Get-Content "C:\path\to\content.log" -Wait -Tail N
Where N is the number of lines to return.

Here are some examples for AWSTATS and hmailserver logs.

Code: Select all

$LogDir = "C:\Program Files (x86)\hMailServer\Logs" #<-- No trailing "\" please

<#	Tail AWSTATS log   #>
Get-Content "$LogDir\hmailserver_awstats.log" -Wait -Tail 1 | ConvertFrom-String -Delimiter "`t" -PropertyNames TimeStamp, Sender, Recipient, ConnectionSender, ConnectionRecipient, Protocol, QuestionMark, StatusCode, MessageSize | ForEach {
	$TimeStamp = $_.TimeStamp
	$Sender = $_.Sender
	$Recipient = $_.Recipient
	$ConnectionSender = $_.ConnectionSender
	$ConnectionRecipient = $_.ConnectionRecipient
	$Protocol = $_.Protocol
	$QuestionMark = $_.QuestionMark
	$StatusCode = $_.StatusCode
	$MessageSize = $_.MessageSize

	<#  DO SOMETHING  #>

}

<#	Tail hMailServer log   #>
<#	First find today's log   #>
Get-ChildItem $LogDir | Where {$_.Name -match "^hmailserver_"+$((Get-Date).ToString("yyyy-MM-dd"))+".log$"} | ForEach {
	$LogName = $_
	
	<#	Tail log and convert log lines to objects   #>
	Get-Content "$LogDir\$LogName" -Wait -Tail 1 | ConvertFrom-String -Delimiter "`t" -PropertyNames Protocol, ThreadID, PropOne, PropTwo, PropThree, PropFour | ForEach {

		<#	If SMTP, define properties, which are different than others  #>
		If ($_.Protocol -match "SMTP(D|C)") {
			$Protocol = $_.Protocol
			$ThreadID = $_.ThreadID
			$Session = $_.PropOne
			$DateTime = $_.PropTwo
			$IPAddress = $_.PropThree
			$Message = $_.PropFour

			<#  DO SOMETHING  #>

		}

		<#	If NOT SMTP, define properties  #>
		If ($_.Protocol -notmatch "SMTP(D|C)") {
			$Protocol = $_.Protocol
			$ThreadID = $_.ThreadID
			$DateTime = $_.PropOne
			$Message = $_.PropTwo

			<#  DO SOMETHING  #>

		}
	}
}

Setting properties from the hmailserver log is a little tricky because there are two log formats: one for smtp and one for everything else, but its not that big of a deal. I only use smtp anyway, so my actual, working one goes like this:

Code: Select all

<#	Tail log   #>
<#	First find today's log   #>
Get-ChildItem $LogDir | Where {$_.Name -match "^hmailserver_"+$((Get-Date).ToString("yyyy-MM-dd"))+".log$"} | ForEach {
	$LogName = $_
	
	<#	Tail log and convert log lines to objects   #>
	Get-Content "$LogDir\$LogName" -Wait -Tail 1 | ConvertFrom-String -Delimiter "`t" -PropertyNames Protocol, ThreadID, Session, DateTime, IPAddress, Message | ForEach {

		<#	If SMTPD proceed, discard all others   #>
		If ($_.Protocol -match "SMTPD") {

			$Protocol = $_.Protocol
			$ThreadID = $_.ThreadID
			$Session = $_.Session
			$DateTime = $_.DateTime
			$IPAddress = $_.IPAddress
			$Message = $_.Message

			<#  DO SOMETHING  #>
		
		}
	}
}
They DON'T run 24/7. I shut them off and restart them at midnight when the log rolls over.

Post Reply