Поскольку использование связки VBScript + Планировщик Windows + Командная строка не смогли работать так как было нужно в моем случае, пришлось подключить "тяжелую артиллерию" в виде C#.NET. Получилась программа на стандартных функциях второй версии платформы - Telnet-клиент в который "вшит" скрипт операций для исполнения.
Поскольку всё делалось быстренько, то не предусмотрена возможность загрузки текстового файла-скрипта. Пока по крайней мере. Программа запускается и работает от любого пользователя и будучи настроенной через Планировщик Windows под любого пользователя, способна запускаться даже при заблокированном ПК.
В тексте все понятно и просто. Прикладываю класс и программу пример.
Сам класс:
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Net.Sockets;
- using System.Threading;
- namespace MinimalisticTelnet
- {
- enum Verbs {
- WILL = 251,
- WONT = 252,
- DO = 253,
- DONT = 254,
- IAC = 255
- }
- enum Options
- {
- SGA = 3
- }
- class TelnetConnection
- {
- TcpClient tcpSocket;
- int TimeOutMs = 2000; //стандартный таймаут
- public TelnetConnection(string Hostname, int Port)
- {
- tcpSocket = new TcpClient(Hostname, Port);
- }
- public string Login(string Username,string Password,int LoginTimeOutMs)
- {
- int oldTimeOutMs = TimeOutMs;
- TimeOutMs = LoginTimeOutMs; //таймаут для логина (он длиннее)
- string s = Read();
- if (!s.TrimEnd().EndsWith(":"))
- throw new Exception("Failed to connect : no login prompt");
- WriteLine(Username);
- s += Read();
- if (!s.TrimEnd().EndsWith(":"))
- throw new Exception("Failed to connect : no password prompt");
- WriteLine(Password);
- s += Read();
- TimeOutMs = oldTimeOutMs; //сбрасываем на стандартный таймаут
- return s;
- }
- public void WriteLine(string cmd)
- {
- Write(cmd + "\n");
- }
- public void Write(string cmd)
- {
- if (!tcpSocket.Connected) return;
- byte[] buf = System.Text.ASCIIEncoding.ASCII.GetBytes(cmd.Replace("\0xFF","\0xFF\0xFF"));
- tcpSocket.GetStream().Write(buf, 0, buf.Length);
- }
- public string Read()
- {
- if (!tcpSocket.Connected) return null;
- StringBuilder sb=new StringBuilder();
- do
- {
- ParseTelnet(sb);
- Thread.Sleep(TimeOutMs);
- } while (tcpSocket.Available > 0);
- return sb.ToString().Replace(" [K", "");//убираем символ от (наверное) роутера
- }
- public bool IsConnected
- {
- get { return tcpSocket.Connected; }
- }
- void ParseTelnet(StringBuilder sb)
- {
- while (tcpSocket.Available > 0)
- {
- int input = tcpSocket.GetStream().ReadByte();
- switch (input)
- {
- case -1 :
- break;
- case (int)Verbs.IAC:
- // interpret as command
- int inputverb = tcpSocket.GetStream().ReadByte();
- if (inputverb == -1) break;
- switch (inputverb)
- {
- case (int)Verbs.IAC:
- //literal IAC = 255 escaped, so append char 255 to string
- sb.Append(inputverb);
- break;
- case (int)Verbs.DO:
- case (int)Verbs.DONT:
- case (int)Verbs.WILL:
- case (int)Verbs.WONT:
- // reply to all commands with "WONT", unless it is SGA (suppres go ahead)
- int inputoption = tcpSocket.GetStream().ReadByte();
- if (inputoption == -1) break;
- tcpSocket.GetStream().WriteByte((byte)Verbs.IAC);
- if (inputoption == (int)Options.SGA )
- tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WILL:(byte)Verbs.DO);
- else
- tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WONT : (byte)Verbs.DONT);
- tcpSocket.GetStream().WriteByte((byte)inputoption);
- break;
- default:
- break;
- }
- break;
- default:
- sb.Append( (char)input );
- break;
- }
- }
- }
- }
- }
И пример программы:
- using System;
- using System.Threading;
- namespace MinimalisticTelnet
- {
- class Program
- {
- static void Main(string[] args)
- {
- TelnetConnection tc = new TelnetConnection("СЮДА АДРЕС", 23);
- string s = tc.Login("ЛОГИН", "ПАРОЛЬ",4000);
- Console.Write(s);
- string prompt = s.TrimEnd();
- prompt = s.Substring(prompt.Length -1,1);
- if (prompt != "$" && prompt != ">" )
- throw new Exception("Connection failed");
- prompt = "";
- tc.WriteLine("system reboot"); //system reboot
- // tc.WriteLine("interface PPTP0 no connect"); //
- Thread.Sleep(2000);//даем время сброситься интерфейсу (судя по всему это нужно)
- // tc.WriteLine("interface PPTP0 connect");
- tc.WriteLine("exit");
- Console.WriteLine("SESSION DISCONNECTED");
- }
- }
- }