Kada koristite PowerShell možete na više načina proveriti da li je neki računar dostupan. PowerShell V2 nudi novi komandlet Test-Connection, a ako još uvek koristite V1 na raspolaganju vam je dobra stara ping komanda, WMI klasa Win32_PingStatus ili .Net klasa System.Net.NetworkInformation.Ping. Pozabavimo se malo .Net rešenjem. Prvo kreiramo novi objekt:
$Ping = New-Object System.Net.NetworkInformation.Ping
Objekt $Ping ima Send metod. Evo kako možemo videti validne načine za kreiranje instance:
$Ping | Get-Member Send | Format-List *
TypeName : System.Net.NetworkInformation.Ping
Name : Send
MemberType : Method
Definition : System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress), System.Net.NetworkInformation.Ping
Reply Send(String hostNameOrAddress, Int32 timeout), System.Net.NetworkInformation.PingReply Send(IPAddres
s address), System.Net.NetworkInformation.PingReply Send(IPAddress address, Int32 timeout), System.Net.Net
workInformation.PingReply Send(String hostNameOrAddress, Int32 timeout, Byte[] buffer), System.Net.Network
Information.PingReply Send(IPAddress address, Int32 timeout, Byte[] buffer), System.Net.NetworkInformation
.PingReply Send(String hostNameOrAddress, Int32 timeout, Byte[] buffer, PingOptions options), System.Net.N
etworkInformation.PingReply Send(IPAddress address, Int32 timeout, Byte[] buffer, PingOptions options)
Koristićemo, recimo, Send(String hostNameOrAddress, Int32 timeout) konstruktor.
$Ping.Send($hostNameOrAddress,$timeout) vraća PingReply objekt (System.Net.NetworkInformation.PingReply). Ako pogledamo njegove metode i osobine, uočićemo da nedostaje podatak o imenu računara čiju dostupnost proveravamo:
$Ping.Send('localhost',1000) | Get-Member
TypeName: System.Net.NetworkInformation.PingReply
Name MemberType Definition
---- ---------- ----------
Equals Method System.Boolean Equals(Object obj)
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
get_Address Method System.Net.IPAddress get_Address()
get_Buffer Method System.Byte[] get_Buffer()
get_Options Method System.Net.NetworkInformation.PingOptions get_Options()
get_RoundtripTime Method System.Int64 get_RoundtripTime()
get_Status Method System.Net.NetworkInformation.IPStatus get_Status()
ToString Method System.String ToString()
Address Property System.Net.IPAddress Address {get;}
Buffer Property System.Byte[] Buffer {get;}
Options Property System.Net.NetworkInformation.PingOptions Options {get;}
RoundtripTime Property System.Int64 RoundtripTime {get;}
Status Property System.Net.NetworkInformation.IPStatus Status {get;}
Ako bi želeli da proverimo veći broj računara, podatak o imenu pingovanog računara u finalnom objektu nam je neophodan. Možemo dodati ComputerName NoteProperty koristeći Add-Member komandlet. PassThru parameter je nužan, pošto, po default-u, Add-Member ne generiše nikakav izlaz. Neka je $Computers niz koji sadrži imena računara. Do imena računara i kreiranja niza možemo doći upitom u Active Directory, učitavanjem tekstualne datoteke/CSV datoteke ili direktnim navođenjem članova:
$Computers = 'localhost','10.10.0.4'
# prvo inicijalizujemo niz koji će postati naš finalni objekt
$Replies = @()
# obrađujemo svaki računar koji se nalazi u nizu $Computers
$Computers | ForEach-Object {
# prikazujemo poruku o računaru čija se dostupnost trenutno proverava
Write-Host "Proveravamo računar: $_" -foregroundcolor Yellow
# objektu $Ping.Send($_,1000) koji nastaje pingovanjem računara $_
# dodajemo ComputerName osobinu čija je vrednost ime računara $_
$Replies += Add-Member -InputObject $($Ping.Send($_,1000)) -MemberType NoteProperty -Name ComputerName -Value $_ -passthru
}
Proverimo osobine novokreiranog izlaznog objekta $Replies:
$Replies | Get-Member -type *Property
TypeName: System.Net.NetworkInformation.PingReply
Name MemberType Definition
---- ---------- ----------
ComputerName NoteProperty System.Management.Automation.PSObject ComputerName=localhost
Address Property System.Net.IPAddress Address {get;}
Buffer Property System.Byte[] Buffer {get;}
Options Property System.Net.NetworkInformation.PingOptions Options {get;}
RoundtripTime Property System.Int64 RoundtripTime {get;}
Status Property System.Net.NetworkInformation.IPStatus Status {get;}
PingReply objekt je proširen ComputerName NoteProperty-jem kako smo i želeli.
Sve je ovo divno i krasno dok proveravamo dostupnost računara na osnovu IP adresa i validnih imena, ali kada naletimo na ime računara koje Send metod ne može da razreši, dolazi do greške. Zato nam je potreban Trap blok kako bi "uhvatili" grešku, upisali informaciju o grešci u log datoteku i nastavili sa izvršenjem. Spakujmo sada sve ovo u funkciju Test-OnlineStatus.
function Test-OnlineStatus {
param (
[string[]]$ComputerName = $env:computername, # ComputerName parameter je niz; default vrednost je lokalni računar
[string]$LogFile = 'c:\OnlineStatus.log'
)
BEGIN {
$Ping = New-Object System.Net.NetworkInformation.Ping
# inicijalizujemo niz koji će postati naš finalni objekt
$Replies = @()
# $LogFile će sadržavati informaciju o imenima računara koja nisu mogla biti razrešena
# ako $LogFile već postoji, obriši je
if (Test-Path $LogFile) {Remove-Item $LogFile}
}
PROCESS {
# da bi prihvatili i vrednosti preko pipeline-a, dodajemo nizu $ComputerName i ime računara koji stiže putem pipeline-a
if ($_) {$ComputerName += $_}
$ComputerName | ForEach-Object {
# ovo je potrebno pošto se scope menja u okviru trap bloka
$computer = $_
trap {
Write-Host "Ime računara $computer nije moglo biti razrešeno." -foregroundcolor Red
"Ime računara $computer nije moglo biti razrešeno." | Out-File $LogFile -append
continue
}
. {
Write-Host "Proveravamo računar: $_" -foregroundcolor Yellow
$Replies += Add-Member -InputObject $($Ping.Send($_,1000)) -MemberType NoteProperty -Name ComputerName -Value $_ -passthru
}
}
# praznimo niz $ComputerName kako bi prihvatio sledeću vrednost preko pipeline-a
$ComputerName = $null
}
END {
Write-Output $Replies
}
}
Test-OnlineStatus funkcija ima dva parametra - ComputerName (niz imena računara) i LogFile (putanja do log datotekeu koju se upisuju informacije o imenima računara koja nisu mogla biti razrešena). Funkcija prihvata ulazne vrednosti i preko pipeline-a i kao vrednosti parametara. Čak se mogu istovremeno koristiti. Za kraj evo par primera kako se funkcija koristi:
PS C:\> $computers | Test-OnlineStatus | Select ComputerName,Status,Address | Export-Csv c:\OnlineStatus.csv -noTypeInformation
PS C:\> Test-OnlineStatus $computers -LogFile c:\izvestaj.log | Format-Table ComputerName,Status,Address -AutoSize
PS C:\> $computers | Test-OnlineStatus Server01,Server02 | Format-Table ComputerName,Status
PS C:\> 'Server01','Server02' | Test-OnlineStatus $computers | Format-Table ComputerName,Status