Pingen met VBScript

Hoewel Microsoft weinig meer doet aan de ontwikkeling van HTA (HTML Application) en VBScript, hebben ze wel degelijk nog nut. Als je een splashscreen wil maken voor een script of applicatie zit je niet te wachten op Powershell, want tegen de tijd dat PowerShell geladen is is je splashscreen niet meer nodig. En daar komt de HTA om de hoek kijken, eventueel uitgebreid met de functionaliteit om te pingen met VBScript.

 

Een HTML Application of HTA is geschreven in HTML en hoewel de HTA niet direct in je browser wordt geopend maar met mshta.exe, maakt deze wel gebruik van de engine van Internet Explorer. Als je de HTA vervolgens ook nog interactief wil maken ben je aangewezen op JavaScript en VBScript, want Powershell werkt niet in de context van Internet Explorer. De tijd die het kost om de HTA te laden is minimaal en daardoor ideaal voor het maken van een splashscreen tijdens het opstarten van een ander proces.

Voor een eigen splashscreen wilden we graag de internet verbinding controleren inclusief de latency. Vanuit een command prompt doe je dit met het Ping commando, maar vanuit onze HTA  maken we daarvoor dus gebruik van VBScript. Er zijn hiervoor verschillende methoden, namelijk:

Run Method

Met .Run kan je een commando vanuit een VBScript draaien. Eerst creëer je een instance van de Windows Scripting Host Shell. Vervolgens gebruik je .Run waarbij je drie parameters kunt meegeven. De eerste is het daadwerkelijke commando, de tweede is de windowstyle (0=verborgen, 1=actief) en de derde is of het script moet wachten tot het commando is afgerond (booleaan).

 

Script

Om te pingen met VBScript d.m.v. het Run commando kun je het volgende script gebruiken:

Set objShell = CreateObject("WScript.Shell")
objPing = objShell.Run("Cmd.exe ping -n 1 www.gtsonline.nl", 0, true)
WScript.Echo "objPing: " & objPing

Output

objPing: 0

Conclusie

Het mooie is dat het commando onzichtbaar wordt uitgevoerd, maar de output is beperkt. Bij 0 is de Ping succesvol uitgevoerd en bij 1 is de Ping mislukt. Helaas is er met dit commando geen mogelijkheid om meer informatie terug te krijgen zoals de latency.

 

Exec method

Het .Exec commando is vergelijkbaar met .Run, maar er zijn ook een paar wezenlijke verschillen. Ook hier creëer je een instance van de Windows Scripting Host Shell, maar je kunt slechts één parameter meegeven: het daadwerkelijke commando, in ons geval een ping.

 

Script

Set objShell = CreateObject("WScript.Shell")
Set objPing = objShell.Exec("ping -n 1 www.gtsonline.nl")
DoUntil objPing.StdOut.AtEndOfStream
   WScript.Echo objPing.StdOut.ReadLine
Loop

Output

Pinging www.gtsonline.nl [5.61.248.159] with 32 bytes of data:
Reply from 5.61.248.159: bytes=32 time=29ms TTL=60

Ping statistics for5.61.248.159:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 29ms, Maximum = 29ms, Average = 29ms

Conclusie

Zoals je ziet is de output vergelijkbaar met hoe het eruit ziet als je handmatig vanaf de command prompt een ping uitvoert. Helaas moet je aardig wat scripten om de juiste regel eruit te halen en vervolgens daar dan weer de daadwerkelijke latency. Verder zie je kort de console van de commandprompt voorbij flitsen, wat niet echt wenselijk is als je juist de gebruikerservaring wil verbeteren door middel van een splashscreen.

 

Win32_PingStatus

Het alternatief is om een Ping uit te voeren met de Win32_PingStatus class. Dit is een WMI query die de waarden van het Ping commando representeert. Het resultaat is een collectie en dus heb je een ‘For each’ statement nodig om de resultaten uit te lezen, maar dan heb je ook wat.

Script

Set colPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery ("select * from Win32_PingStatus where address = 'www.gtsonline.nl'")
For Each objPing in colPing
   WScript.Echo "Status: " & objPing.Statuscode
   If objPing.Statuscode = 0 Then
      WScript.Echo "Adres: " & objPing.ProtocolAddress
      WScript.Echo "Buffersize: " & objPing.BufferSize
      WScript.Echo "Latency (ms): " & objPing.ResponseTime
      WScript.Echo "TTL: " & objPing.ResponseTimeToLive
   Endif
Next

Output

Status: 0
Adres: 5.61.248.159
Buffersize: 32
Latency (ms): 29
TTL: 60

Conclusie

Het grote voordeel is dat je met deze laatste methode gemakkelijk meerdere waarden van het Ping commando kan uitlezen. Naast de hier gegenereerde output zijn er nog meer waardes beschikbaar, zoals bijvoorbeeld het IPv6 adres. Hoewel deze laatste optie om te pingen vanuit VBScript wat ingewikkelder is, zijn de resultaten veel beter bruikbaar in de rest van het script.