Reputation: 423
I have a large list of hostnames I need to ping to see if they are up or down. I'm not really that great at scripting but I managed to figure this much out:
$names = Get-content "hnames.txt"
foreach ($name in $names){
if (Test-Connection -ComputerName $name -Count 1 -ErrorAction SilentlyContinue){
Write-Host "$name is up" -ForegroundColor Green
}
else{
Write-Host "$name is down" -ForegroundColor Red
}
}
This gets me what I need but i now need to write out these results to a csv file and i have no idea how to do that.
Please Help!
Upvotes: 8
Views: 156009
Reputation: 23
So I modified @js2010 answer to check a list of ports and the ICMP ping, set the status if either the ports or the ICMP ping came back. Also set it to run by just executing instead of passing a file on execution.
function get-pport {
# Define the file path containing the URLs
$urlFile = "hnames.txt"
$outputFile = "port_scan_results.csv"
# Define the list of ports
$ports = @(22, 443, 80)
# Read URLs from the file
$urls = Get-Content $urlFile
$results = @()
$urls | ForEach-Object {
$url = $_
$openPorts = @()
# Perform ICMP ping
try {
$ping = New-Object System.Net.NetworkInformation.Ping
$pingResult = $ping.Send($url)
if ($pingResult.Status -eq 'Success') {
$status = "up"
} else {
$status = "down"
}
} catch {
Write-Host "Error: ICMP ping failed for $url - $_"
$status = "down"
}
# Check for open ports
foreach ($port in $ports) {
$client = New-Object System.Net.Sockets.TcpClient
$ar = $client.BeginConnect($url, $port, $null, $null)
$wait = $ar.AsyncWaitHandle.WaitOne(200, $false)
if ($wait -and !$ar.IsCompleted) {
$client.Close()
}
else {
if ($client.Connected) {
$openPorts += $port
}
$client.Close()
}
}
if ($openPorts -and $status -eq "down") {
$status = "up"
}
$result = New-Object -TypeName PSObject -Property @{
HostName = $url
Port = $openPorts -join ','
Status = $status
}
$results += $result
}
# Export results to CSV
$results | Export-Csv -Path $outputFile -NoTypeInformation
}
# Run the function
get-pport
Upvotes: 0
Reputation: 27433
I would do it this way. Using a list of computers and -asjob works very well. The Responsetime property (confusingly the header is "Time(ms)") will be non-null if the host is up.
$names = Get-content hnames.txt
test-connection $names -asjob -count 1 | receive-job -wait -auto
Source Destination IPV4Address IPV6Address Bytes Time(ms)
------ ----------- ----------- ----------- ----- --------
COMP001 yahoo.com 74.6.231.21 32 39
COMP001 microsoft.com 40.113.200.201 32
Lately I do it this way. It requires threadjobs installed in powershell 5.1. Or just use get-port. I stick it in a mymod\mymod.psm1 module file somewhere in $env:psmodulepath. I can check a classroom in under 10 seconds.
function get-pport { # multi-threaded
param($list)
$list |
% { $_ | start-threadjob { get-port $input } -throttlelimit 20 } |
receive-job -wait -auto
}
function Get-Port {
Param (
[parameter(ValueFromPipeline)]
[string[]]$Hostname='yahoo.com'
)
begin {
$ports = 22,5988,3389,5985
$ping = New-Object System.Net.Networkinformation.ping
$Timeout = 200 # ms
}
process {
$hostname | foreach {
$openPorts = @()
foreach ($port in $ports) {
$client = New-Object System.Net.Sockets.TcpClient
$beginConnect = $client.BeginConnect($_,$port,$null,$null)
Start-Sleep -Milli $TimeOut
if($client.Connected) { $openPorts += $port }
$client.Close()
}
$result = $Ping.Send($_, $timeout)
if (! $result) { write-error "hostname $_ not found" }
$pingstatus = ($result.status -eq 'Success')
New-Object -typename PSObject -Property @{
HostName = $_
Port = $openPorts
Ping = $pingstatus
} | select hostname,port,ping
} # end foreach
} # end process
}
Example:
$avid = cat afile.txt
pport $avid
HostName Port Ping
-------- ---- ----
A006 {3389, 5985} True
A011 {3389, 5985} True
A015 {3389} True
Upvotes: 1
Reputation: 173
$Output= @()
$names = Get-Content ".\input\Servers.txt"
foreach ($name in $names){
if (Test-Connection -Delay 15 -ComputerName $name -Count 1 -ErrorAction SilentlyContinue -quiet){
$Output+= "$name,up"
Write-Host "$Name,up" -ForegroundColor Green
}
else{
$Output+= "$name,down"
Write-Host "$Name,down" -ForegroundColor Red
}
}
$Output | Out-file ".\output\result.csv"
This is a tad cleaner, and includes the original foreground options but, BTW, the 'delay' switch seems to be ignored -PB
Upvotes: 0
Reputation: 41
I am a complete newbie to Powershell, so I took this on as a learning task, as I needed a quick and simple way to check a list of PC's for up/down status. These tweaks were needed to get it to output cleanly to the screen and to a txt file
$Output= @()
$names = Get-content "hnames.txt"
foreach ($name in $names){
if (Test-Connection -ComputerName $name -Count 1 -ErrorAction SilentlyContinue){
$Output+= "$name,up"
Write-Host "$Name,up"
}
else{
$Output+= "$name,down"
Write-Host "$Name,down"
}
}
$Output | Out-file "C:\support\result.csv"
Upvotes: 4
Reputation: 486
You can use the following code instead (I simply altered the write-host calls to CSV formatting) and execute it with "PowerShell.exe script.ps > output.csv" Note that you must execute it from the folder that contains hnames.txt, or simply change the "hnames.txt" to a full path.
$names = Get-content "hnames.txt"
foreach ($name in $names){
if (Test-Connection -ComputerName $name -Count 1 -ErrorAction SilentlyContinue){
Write-Host "$name,up"
}
else{
Write-Host "$name,down"
}
}
P.S. You can also use the Out-File Cmdlet to create the CSV file
Upvotes: 16