Как пинговать заданный IP и подавать звуковой сигнал при недоступности
Как-то возникла потребность отслеживать доступность в сети нескольких важных устройств и отвлекать оператора от кроссвордов негромким, но навязчивым писком. Дело происходило в изолированной сети, где нежелательно устанавливать сторонний софт.
Закрыть этот вопрос помог почти забытый скриптовый язык hta. Получилось довольно изящно: в 150 строчках уместились и код, и нехитрый пользовательский интерфейс, и кастомный звуковой сигнал. Скрипт делает ровно одну вещь: пингует адреса по списку и пищит через колонки, когда связь пропала. Бип!
Скачать: Мониторинг связи.hta
Скрипт запускается как приложение, двойным кликом. Список адресов для проверки задаётся внутри, для этого файл нужно открыть с помощью блокнота.

Детали
Скрипт работает одинаково хорошо на всей линейке Windows от XP до 11-й, ничего дополнительно устанавливать не нужно.
В системе должно быть разрешено исполнение ActiveX для локальных страниц (по умолчанию разрешено). Это галочки в окне настроек internet Explorer, в разделе, связанном с безопасностью и политиками. Да, hta крутится на движке IE, который Microsoft сохранили даже в эпоху Edge.

Код
Записывать в кодировке ansi:
<html>
<head>
<title>Мониторинг связи</title>
<HTA:APPLICATION APPLICATIONNAME="PingMonitor" SINGLEINSTANCE="yes" />
</head>
<body>
<h1>Проверка связи</h1>
<label><input type="checkbox" id="alarm" checked> Сигнал при потере связи</label>
<br><br>
<div id="grid"></div>
<div id="alarm_wrap"></div>
<script language="JScript">
// Версия 12.01.2026
// Мониторим связь и пиликаем через колонки при сбоях
// Список проверяемых адресов:
var hosts = [
{ip: "192.168.1.1", name: "Циска" },
{ip: "192.168.1.2", name: "База данных" },
{ip: "PetelinSasha.ru" } // name задавать не обязательно
];
var pingInterval = 6000;
var pingTimeout = '1000';
// Звук бип - можно заменить на свой, это wav в base64-with-padding
var alarmBase64="UklGRuYBAABXQVZFZm10IBAAAAABAAEAESsAABErAAABAAgAZGF0YcIBAAB/gIaHd3eEeGmHlXhzi52IcYx5V3uCcoScoIJlhmZdh4CEmLCba0t6VVygm5WSq4xbT31bdKeYk46kf0ZefFiFsJSLlad0OnByWomkkYeZo3BAg29fkJ6MhZ6YYkyGYW2hk4mNpYlVXoNdeaONipCkf0xwfF6DooqIlJ90S35xYo2ahYiZmWlQh2ZpmZKEiJ2QYFuIYXSfjYeKooZVaoJdfKKJh5CifFF3eF6EnYSHlZ9xT4NsY5GXg4ialmZVh2Rsm5KHip+MW2GGXnakjYeNoIBVbYBffqKHh5GhdlB8dWCJnIOGlpxtUYVrZ5SVhYebk2NZiGNunZCGiZ6JW2OFYHehi4eNoX5Ucnxfgp+FhpKfdFF/cmOLl4SGl5lqVIdoaJaThYabj2Jch2Ryno6Fip+FWmqCYHyhh4aPoXtVd3lhhJuEh5OdcVKDb2SOl4WGl5VpVohobJiShIecjGFhhmJ2oIuFi5+CWW5/YX+eh4eQoHdSfHZhiJyFhpSZb1OFbmeRloSGmJFmWohlcJyPhImdiF5lhGF4noqGjKB/VXR9YIGfh4aRnXVTfnVjipqEhpWXbFWHa2qVk4OGmY9kXYc="
for (var i = 0; i < hosts.length; i++) {
var host = hosts[i];
if (!host.name) host.name = host.ip;
host.lastSeen = "-";
host.status = 1;
host.lostCount = 0;
}
var wmi=GetObject("winmgmts:root/cimv2");
function base64ToBinary(b64) {
var xml = new ActiveXObject("MSXML2.DOMDocument.6.0");
var el = xml.createElement("tmp");
el.dataType = "bin.base64";
el.text = b64;
return el.nodeTypedValue;
}
var fso=new ActiveXObject("Scripting.FileSystemObject");
var tempFile=fso.GetSpecialFolder(2) + "\\noping.wav";
var stream = new ActiveXObject("ADODB.Stream");
stream.Type = 1;
stream.Open();
stream.Write(base64ToBinary(alarmBase64));
stream.SaveToFile(tempFile, 2);
stream.Close();
function playSound() {
if (!document.getElementById("alarm").checked) return;
var wrap = document.getElementById("alarm_wrap");
var bs = document.createElement("bgsound");
bs.loop = 1;
bs.src = tempFile;
wrap.innerHTML = "";
wrap.appendChild(bs);
}
function autosize() {
var table = document.getElementById("mainTable");
window.resizeTo(table.offsetWidth + 140, document.body.scrollHeight + 80);
}
function decodeStatus(code) {
switch(code) {
case 0: return "Доступен";
case 1: return "...";
case 11002: return "Destination net unreachable";
case 11003: return "Host not found";
case 11004: return "Destination host unreachable";
case 11010: return "Request timed out";
default: return "Ошибка "+code;
}
}
function render() {
var html="<table id='mainTable' border=1 cellpadding=4 cellspacing=0>";
html+="<tr bgcolor='#cccccc'><th>Адрес</th><th>Устройство</th><th>Когда был в сети</th><th>Состояние</th><th>Потери</th></tr>";
for (var i=0;i<hosts.length;i++) {
var h=hosts[i];
var ok=(h.status==0);
var color = ok?"#00aa00":"#aa0000";
color = (h.status==1)?"#cccccc":color;
html+="<tr bgcolor='"+color+"' style='color:white'>";
html+="<td>"+h.ip+"</td>";
html+="<td>"+h.name+"</td>";
html+="<td>"+h.lastSeen+"</td>";
html+="<td>"+decodeStatus(h.status)+"</td>";
html+="<td>"+h.lostCount+"</td>";
html+="</tr>";
}
html+="</table>";
document.getElementById("grid").innerHTML=html;
}
function check() {
var i = 0, anyFail = false;
function nextHost() {
if (i >= hosts.length) {
if (anyFail) playSound();
return setTimeout(check, pingInterval);
}
var host = hosts[i++];
var res = new Enumerator(wmi.ExecQuery("SELECT * FROM Win32_PingStatus WHERE Address='" + host.ip + "' AND Timeout=" + pingTimeout));
if (!res.atEnd()) {
host.status = res.item().StatusCode;
if (host.status == 0) {
host.lastSeen = new Date().toLocaleTimeString();
} else {
anyFail = true;
host.lostCount++;
}
} else {
host.status = -1;
host.lostCount++;
anyFail = true;
}
render();
setTimeout(nextHost, 50);
}
nextHost();
}
render();
autosize();
setTimeout(check,50);
</script>
</body></html>