运维中经常需要检查主机是否在线,服务是否运行正常。设备数目少的话可以手工去查看,但是面对几百台设备的话就力不从心了,这就需要自动话批量去检查。
网上很多是通过ping检测连通性的例子,但是有的主机为了安全禁止ping,所以只能通过端口来检测了。
下面是一段powershell脚本来实现该功能,在检测到端口不通时发送邮件通知。
其中”D:\port\iplist.txt "是主机ip地址列表 ,一行一个,参数用空格分隔
192.168.1.1 3389 备注
192.168.1.2 3389 备注
...................
#逐行读取文本中ip及端口进行连通性测试
#设置powershell ExecutionPolicy Bypass
$iplist = Get-Content D:\port\iplist.txt #主机ip地址列表
$regHost = "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"
$regPort = "\s(?<alp>\d{1,5})"
$regNote = "\s(?<alp>\D.*)"
$remoteHost = ""
$Port = ""
$note = ""
$global:mailtext = ""
#测试端口函数
function Test-Port
{
Param([string]$ComputerName,$port,$timeout = 2000)
try
{
$tcpclient = New-Object -TypeName system.Net.Sockets.TcpClient
$iar = $tcpclient.BeginConnect($ComputerName,$port,$null,$null)
$wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)
if($wait)
{
$null = $tcpclient.EndConnect($iar)
$tcpclient.Close()
$ptext = $ComputerName.ToString()+" : "+$port +" "+"已连接:"+$note+"`n"
#return $ptext
}
else
{
$tcpclient.Close()
$global:mailtext +="故障IP "+$ComputerName.ToString()+" : "+$port +" "+"备注:"+$note+"`n"
#return $global:mailtext
}
}
catch
{
$false
}
}
#开始
foreach ($i in $iplist){
if($i -match $regHost){
$remoteHost = $Matches[0];
}
if($i -match $regPort){
$Port = $Matches.alp;
}
if($i -match $regNote){
$note = $Matches.alp;
}
Test-Port -ComputerName $remoteHost -port $Port
}
#当检测到有主机端口不通时发送邮件通知
if($global:mailtext){
$smtpServer = "xxxxx" #SMTP服务器地址
$smtpUser = "xxxxx" #发送邮件的账号
$smtpPassword = "xxxxxx" #发送邮件的秘密
$titleDate = get-date -format "yyyy-MM-dd HH:mm:ss"
$titleweek = get-date -uformat "%A"
#create the mail message
$mail = New-Object System.Net.Mail.MailMessage
#set the addresses
$MailAddress="xxxxxx" #发件人地址
$MailtoAddress="xxxxxx" #收件人地址
$mail.From = New-Object System.Net.Mail.MailAddress($MailAddress)
$mail.To.Add($MailtoAddress)
#set the content
$mail.Subject = "警告:检测到网络设备不通 $titleDate $titleweek "
$mail.Priority = "High"
$mail.Body = $global:mailtext
#send the message
$smtp = New-Object System.Net.Mail.SmtpClient -argumentList $smtpServer
$smtp.Credentials = New-Object System.Net.NetworkCredential -argumentList $smtpUser,$smtpPassword
$smtp.Send($mail)
}