• Welcome to Overclockers Forums! Join us to reply in threads, receive reduced ads, and to customize your site experience!

PROGRAMMING

Overclockers is supported by our readers. When you click a link to make a purchase, we may earn a commission. Learn More.

churchill50

New Member
Joined
Nov 5, 2014
hi guys
please am new here and i do please need your help to write a batch file script to ping ip addresses on a server and then return notification of the ip addresses that are nonpingable..i really need this urgently guys please me out..thanks
 
First of all, :welcome: to the forums!

Does it have to be a batch script? I've seen this done many times with powershell.

Very basic version: (credit: Stackoverflow

Code:
$servers = "JOHNJ1", "JOHNJ2"
foreach ($server in $servers) {
    $status = (get-service -Name lanmanserver -ComputerName $server).Status
    if ($status -eq "Running") {
        "Its Up!"
    } else {
        "Its Down!"
    }
}

Something with a bit more flair: (Credit: Spiceworks
Description
Ever wanted a simple HTML report showing you the UP/DOWN status of your servers? And for a little extra flavor how long that server has been up for? Some basic disk information?

1. Download the script to your favorite location and name it Uptime.ps1
2. Open a Powershell prompt and type: Get-Help pathtoscript\Uptime.ps1 -Full
3. Edit PARAM section so that variables match your environment.
4. Edit $Key variable with random numbers, this is your encryption key.
5. Run it manually once, if you are using alternative credentials script will prompt you for password and save those credentials to a file.

To run as a scheduled task:
1. Create the scheduled task and set your trigger (hourly?)
2. For action the Executable should be Powershell.exe
3. For Arguments use: -ExecutionPolicy Bypass -File pathtoscript\Uptime.ps1

Inspired by this thread:
http://community.spiceworks.com/topic/264653-server-uptime-display

Read more about this script on my Blog:
http://thesurlyadmin.com/2012/10/11/simple-server-status/

And you can read more about the latest version here:
http://thesurlyadmin.com/2013/05/07/new-version-simple-server-status/

Code:
<# 
.SYNOPSIS
	Simple HTML report generator for UP/DOWN status of servers.
.DESCRIPTION
	Create a simple UP/DOWN report, with length of uptime report in a simple HTML
	report.  Also includes a "lowest" disk alert, showing you whichever disk has the
    lowest amount of disk space and how much that is (bar graph).  There is also
    a detailed disk report you can click on to view.
    
    Will accept an secondary credential and use that to gather information.  The
    username and password are stored in an encrypted file in the path you designate.
    
    Since this script is intended to be run from a scheduled task, it is important
    to modify the PARAM section to suit your needs.  
    
    How to Run:
    Make sure to run the script once on the server you intend to run the scheduled
    task.  The script will prompt for the specified credential password on the first
    run (or any time you change the credential username).  After that first run it
    will run without prompting.
	
	*** IMPORTANT ***
    Required:  Modify the $Key variable (line 74) to get unique encryption on your
    credentials.
.PARAMETER Name
	Will accept a comma seperated array of server names and if not specified default
	to load the server names from a text file.  Make sure to edit the Param section
	to fit your environment.  Will also accept object input from Get-ADComputer.
.PARAMETER AlertThreshold
	A number representing the % that free space has to go below to trigger an alert
	(changing the display to red).
.PARAMETER Path
	The output path and file name for the HTML report.  Make sure to edit the Param 
	section to fit your environment.
.PARAMETER Credential
    Specify the alternative credential
.PARAMETER PathToCred
    Path where the script will store the encrypted password file.
.EXAMPLE
	.\Uptime.ps1
	Produces the report based on the servers in C:\utils\servers.txt and will save the
	report at c:\utils\uptime.html
.EXAMPLE
	.\Uptime.ps1 -Servers server1,server2,server3 -path \\webserver\share\uptimereport.html
	Will create the uptime report for servers 1,2 and 3 and save the report at
	\\webserver\share\uptimereport.html
.EXAMPLE
	.\Uptime.ps1 -Servers server1,server2,server3 -AlertThreshold 25
	Will create the uptime report for servers 1,2 and 3 and if the lowest disk free percentage
	is below 25% it will show up in red.
.LINK
	http://community.spiceworks.com/scripts/show/1641-simple-server-uptime-report
.NOTES
	Author:        Martin Pugh 
	Twitter:       @TheSurlyAdm1n
	Spiceworks:    Martin9700
	Blog:          www.thesurlyadmin.com
	
	Changelog
        1.7        Added the ability to use alternative credentials.  Added quite a bit of error
                   handling and verbose output (if wanted).  Added the ability for the script to
                   accept pipeline input from Get-ADComputer as well as other pipeline items.
		1.6        Added remaining disk information in a more detailed report below the primary
	               status table.  Click on the "Show Disk Detail Report" link to display the detailed 
                   report.
		1.5        Added the "Lowest Disk Status" column.  The script will now look at all disk
	               volumes and report on the one with the lowest free disk space.  It will so the free
	               space as a percentage of the total.  By default if that percentage drops below 10%
	               it will "alert" and show that percentage in red.  This setting is configurable
	               using the -AlertThreshold parameter.
		1.0        Initial release
#>
[CmdletBinding()]
Param (
    [Parameter(ValueFromPipeline=$true,
        ValueFromPipelinebyPropertyName=$true)]
    [Alias("Servers")]
	[string[]]$Name = (Get-Content "c:\utils\servers.txt"),
	[int]$AlertThreshold = 10,
	[string]$Path = "c:\utils\uptime.html",
    [string]$Credential = "surly\administrator",
    [string]$PathToCred = "c:\utils"
)

Begin {
    Function Get-Credentials {
	    Param (
		    [String]$AuthUser = $env:USERNAME
	    )
        $Key = [byte]29,36,18,74,72,75,85,52,73,44,0,21,98,76,99,28
    
	    #Build the path to the credential file
        $CredFile = $AuthUser.Replace("\","~")
	    $File = $PathToCred + "\Credentials-$CredFile.crd"
    	#And find out if it's there, if not create it
	    If (-not (Test-Path $File))
    	{	(Get-Credential $AuthUser).Password | ConvertFrom-SecureString -Key $Key | Set-Content $File
	    }
    	#Load the credential file 
	    $Password = Get-Content $File | ConvertTo-SecureString -Key $Key
        $AuthUser = (Split-Path $File -Leaf).Substring(12).Replace("~","\")
        $AuthUser = $AuthUser.Substring(0,$AuthUser.Length - 4)
    	$Credential = New-Object System.Management.Automation.PsCredential($AuthUser,$Password)
	    Return $Credential
    }

    Write-Verbose "$(Get-Date): Script begins!"

    #Define static HTML
    $HeaderHTML = @"
<html>
<head>
<style type='text/css'>
body { background-color:#DCDCDC;
}
table { border:1px solid gray;
  font:normal 12px verdana, arial, helvetica, sans-serif;
  border-collapse: collapse;
  padding-left:30px;
  padding-right:30px;
}
th { color:black;
  text-align:left;
  border: 1px solid black;
  font:normal 16px verdana, arial, helvetica, sans-serif;
  font-weight:bold;
  background-color: #6495ED;
  padding-left:6px;
  padding-right:6px;
}
td.up { background-color:#32CD32;
  border: 1px solid black;
}
td.down { background-color:#B22222;
  border: 1px solid black;
}
td { border: 1px solid black;
  padding-left:6px;
  padding-right:6px;
}
div.red { background-color:#B22222;
  float:left;
  text-align:right;
}
div.green { background-color:#32CD32;
  float:left; 
}
div.free { background-color:#7FFF00;
  float:left;
  text-align:right;
}
a.detail { cursor:pointer;
  color:#1E90FF;
  text-decoration:underline;
}
</style>
</head>
<body>
<script type='text/javascript'>
<!--
window.onload=function(){
	document.getElementById("ShowHideLink").innerHTML="<h6>Show Disk Detail Report</h6>"
	document.getElementById("diskdetail").style.visibility="hidden"
}
function ShowHide() {
	if (document.getElementById("diskdetail").style.visibility=="visible")
	{
		document.getElementById("diskdetail").style.visibility="hidden"
		document.getElementById("ShowHideLink").innerHTML="<h6>Show Disk Detail Report</h6>"
	}
	else
	{
		document.getElementById("diskdetail").style.visibility="visible"
		document.getElementById("ShowHideLink").innerHTML="<h6>Hide Disk Detail Report</h6>"
	}
 }
//-->
</script>
<h1>Server Uptime Status Report</h1>
<p>
<table class="Main">
<tr><th style="width:175px;">Server Name</th><th style="width:125px;">Status</th><th style="width:475px;">Lowest Disk Status</th></tr>

"@

    $DiskDetailHeaderHTML = @"
</table>
<a id="ShowHideLink" class="detail" onClick="ShowHide()"></a>
<br>
<br>
<div id="diskdetail">
<h1>Disk Detail Report</h1><p>

"@

    $FooterHTML = @"
</div>
</body>
</html>
"@

    $AllComputers = @()
}

Process {
    #Gather all computer names before processing
    ForEach ($Computer in $Name)
    {   $AllComputers += $Computer
    }
}

End {
    #Sort the servers by name, then start getting information
    Write-Verbose "Sort server names and gather Credential information"
    $Name = $Name | Sort
    $DiskData = @()

    If ($Credential)
    {   $Cred = Get-Credentials $Credential
    }

    ForEach ($Computer in $AllComputers)
    {	Write-Verbose "Testing $Computer..."
        $ErrorReport = $null
	    If (Test-Connection $Computer -Quiet)
    	{	#Set parameters for splat, determine if checking local
            $CredParameter = @{
                ComputerName = $Computer
                ErrorAction = "Stop"
            }
            If ($Computer.ToUpper() -notlike "*$($env:COMPUTERNAME.ToUpper())*" -and $Cred)
            {   $CredParameter.Add("Credential",$Cred)
            }
        
            #Get uptime information
            Try {
        		$WMI = Get-WmiObject Win32_OperatingSystem @CredParameter
	        	If ($WMI)
		        {	$Uptime = New-TimeSpan -Start $($WMI.ConvertToDateTime($WMI.LastBootUpTime)) -End (Get-Date)
    			    $UpText = "<td class=""up"">$($Uptime.Days)d, $($Uptime.Hours)h, $($Uptime.Minutes)m</td>"
        		}
	        	Else
		        {	$UpText = "<td class=""up"">Up</td>"
    		    }
	    	    #Get disk information and pretty up the data
    	    	$Disks = Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" @CredParameter | Select `
	    	    	@{LABEL="Server";EXPRESSION={$Computer}},
		    	    @{LABEL="DriveLetter";EXPRESSION={$_.DeviceID}},
    			    @{LABEL="Size";EXPRESSION={[int]("{0:N0}" -f ($_.Size/1gb))}},
        			@{LABEL="FreeSize";EXPRESSION={[int]("{0:N0}" -f ($_.FreeSpace/1gb))}},
    	    		@{LABEL="perUsed";EXPRESSION={[int]("{0:N0}" -f ((($_.Size - $_.FreeSpace)/$_.Size)*100))}},
    		    	@{LABEL="perFree";EXPRESSION={[int]("{0:N0}" -f (100-(($_.Size - $_.FreeSpace)/$_.Size)*100))}},
    			    VolumeName
        		$DiskData += $Disks
            }
            Catch {
                Write-Verbose "Error encountered gathering information for $Computer"
                $ErrorReport = $Error[0]
                $Error.Clear | Out-Null
            }
    		
    	    #Create the simple Status table
            If ($ErrorReport)
            {   $UpText = "<td class=""down"">WMI Error</td>"
                $DiskHTML = "<div class=""red"">$($Error[0])</div>"
            }
    		ElseIf ($Disks)
        	{	$LowDisk = $Disks | Sort FreeSize | Select -First 1
    	    	If ($LowDisk.perFree -le $AlertThreshold)
    		   	{	$FreeClass = "red"
    		    }
        		Else
    	    	{	$FreeClass = "free"
    		   	}
    		    $DiskHTML = "<div class=""green"" style=""width:$($LowDisk.perUsed)%"">$($LowDisk.DriveLetter) $($LowDisk.Size)gb ($($LowDisk.perUsed)% used)</div><div class=""$FreeClass"" style=""width:$($LowDisk.perFree)%"">$($LowDisk.FreeSize)gb free ($($LowDisk.perFree)%)</div>`n"
    		}
    		Else
    		{	$DiskHTML = ""
    		}
    		$DetailHTML += "<tr><td>$Computer</td>$UpText<td>$DiskHTML</td></tr>`n"
    	}
    	Else
    	{	$DetailHTML += "<tr><td>$Computer</td><td class=""down"">DOWN</td><td class=""down""></td></tr>`n"
    	}
    }

    #Disk Details Report
    Write-Verbose "WMI data gathered, making the report"
    $Servers = $DiskData | Select Server -Unique
    ForEach ($Server in $Servers)
    {	$Server = $Server.Server
    	$DiskDetailHTML += "<h3>$Server</h3>"
    	$DiskDetailHTML += "<table>"
    	$DiskDetailHTML += "<tr><th>Drive Letter</th><th>Volume Name</th><th>Total Disk Space</th><th>Used</th><th>Free</th><th style=""width:350px;"">Usage</th></tr>`n"
    	$Disks = $DiskData | Where { $_.Server -eq $Server } | Sort DriveLetter
    	ForEach ($Disk in $Disks)
    	{	$DiskDetailHTML += "<tr><td>$($Disk.DriveLetter)</td><td>$($Disk.VolumeName)</td><td>$($Disk.Size)gb</td><td>$($Disk.Size - $Disk.FreeSize)gb</td><td>$($Disk.FreeSize)gb</td>"
    		If ($Disk.perFree -le $AlertThreshold)
    		{	$FreeClass = "red"
    		}
    		Else
    		{	$FreeClass = "free"
    		}
    		$DiskDetailHTML += "<td><div class=""green"" style=""width:$($Disk.perUsed)%""> </div><div class=""$FreeClass"" style=""width:$($Disk.perFree)%"">$($Disk.perFree)%</div></td></tr>`n"
    	}
    	$DiskDetailHTML += "</table><br>`n"
    }

    #Combine all the HTML fragments and save to a file
    $HTML = $HeaderHTML + $DetailHTML + $DiskDetailHeaderHTML + $DiskDetailHTML + $FooterHTML
    $HTML | Out-File $Path

    Write-Verbose "$(Get-Date): Script completed!"
}

Also found this on technet

Code:
# reset the lists of hosts prior to looping 
$OutageHosts = $Null 
# specify the time you want email notifications resent for hosts that are down 
$EmailTimeOut = 30 
# specify the time you want to cycle through your host lists. 
$SleepTimeOut = 45 
# specify the maximum hosts that can be down before the script is aborted 
$MaxOutageCount = 10 
# specify who gets notified 
$notificationto = "[email protected]" 
# specify where the notifications come from 
$notificationfrom = "[email protected]" 
# specify the SMTP server 
$smtpserver = "relay.domain.com" 
 
# start looping here 
Do{ 
$available = $Null 
$notavailable = $Null 
Write-Host (Get-Date) 
 
# Read the File with the Hosts every cycle, this way to can add/remove hosts 
# from the list without touching the script/scheduled task,  
# also hash/comment (#) out any hosts that are going for maintenance or are down. 
get-content \\server\share\hosts.txt | Where-Object {!($_ -match "#")} |  
ForEach-Object { 
if(Test-Connection -ComputerName $_ -Count 1 -ea silentlycontinue) 
    { 
     # if the Host is available then just write it to the screen 
     write-host "Available host ---> "$_ -BackgroundColor Green -ForegroundColor White 
     [Array]$available += $_ 
    } 
else 
    { 
     # If the host is unavailable, give a warning to screen 
     write-host "Unavailable host ------------> "$_ -BackgroundColor Magenta -ForegroundColor White 
     if(!(Test-Connection -ComputerName $_ -Count 4 -ea silentlycontinue)) 
       { 
        # If the host is still unavailable for 4 full pings, write error and send email 
        write-host "Unavailable host ------------> "$_ -BackgroundColor Red -ForegroundColor White 
        [Array]$notavailable += $_ 
 
        if ($OutageHosts -ne $Null) 
            { 
                if (!$OutageHosts.ContainsKey($_)) 
                { 
                 # First time down add to the list and send email 
                 Write-Host "$_ Is not in the OutageHosts list, first time down" 
                 $OutageHosts.Add($_,(get-date)) 
                 $Now = Get-date 
                 $Body = "$_ has not responded for 5 pings at $Now" 
                 Send-MailMessage -Body "$body" -to $notificationto -from $notificationfrom ` 
                  -Subject "Host $_ is down" -SmtpServer $smtpserver 
                } 
                else 
                { 
                    # If the host is in the list do nothing for 1 hour and then remove from the list. 
                    Write-Host "$_ Is in the OutageHosts list" 
                    if (((Get-Date) - $OutageHosts.Item($_)).TotalMinutes -gt $EmailTimeOut) 
                    {$OutageHosts.Remove($_)} 
                } 
            } 
        else 
            { 
                # First time down create the list and send email 
                Write-Host "Adding $_ to OutageHosts." 
                $OutageHosts = @{$_=(get-date)} 
                $Body = "$_ has not responded for 5 pings at $Now"  
                Send-MailMessage -Body "$body" -to $notificationto -from $notificationfrom ` 
                 -Subject "Host $_ is down" -SmtpServer $smtpserver 
            }  
       } 
    } 
} 
# Report to screen the details 
Write-Host "Available count:"$available.count 
Write-Host "Not available count:"$notavailable.count 
Write-Host "Not available hosts:" 
$OutageHosts 
Write-Host "" 
Write-Host "Sleeping $SleepTimeOut seconds" 
sleep $SleepTimeOut 
if ($OutageHosts.Count -gt $MaxOutageCount) 
{ 
    # If there are more than a certain number of host down in an hour abort the script. 
    $Exit = $True 
    $body = $OutageHosts | Out-String 
    Send-MailMessage -Body "$body" -to $notificationto -from $notificationfrom ` 
     -Subject "More than $MaxOutageCount Hosts down, monitoring aborted" -SmtpServer $smtpServer 
} 
} 
while ($Exit -ne $True)
 
Last edited:
Agreed with Janus, Powershell is the way of the future! Batch scripting is just... ancient... and.. ugly.


But yeah, that last link provided is a step in the right direction for you. (Keep in mind it's not complete code, just a snippet).

Basically you just need to ping a server (ping -n 1 ip.address) and then check for the return code of that ping command with the variable %ErrorLevel%. If it's 0, that means it was successful and your ping came back. If it is anything else, it failed.

Also, if you're just checking to see if it responds to a ping, that's fine, but if you're trying to determine whether or not a server is actually up and accessible, this isn't a 100% effective way to do it.
 
Back