Поскольку использование связки 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(" ", "");//убираем символ от (наверное) роутера
  •         }
  •         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;
  •                 }
  •             }
  •         }
  •     }
  • }

 И пример программы:

  1. using System;
  2. using System.Threading;
  3. namespace MinimalisticTelnet
  4. {
  5.     class Program
  6.     {
  7.         static void Main(string[] args)
  8.         {
  9.             TelnetConnection tc = new TelnetConnection("СЮДА АДРЕС", 23);
  10.             string s = tc.Login("ЛОГИН", "ПАРОЛЬ",4000);
  11.             Console.Write(s);
  12.             string prompt = s.TrimEnd();
  13.             prompt = s.Substring(prompt.Length -1,1);
  14.             if (prompt != "$" && prompt != ">" )
  15.                 throw new Exception("Connection failed");
  16.             prompt = "";
  17.             tc.WriteLine("system reboot"); //system reboot
  18.  //           tc.WriteLine("interface PPTP0 no connect"); //
  19.             Thread.Sleep(2000);//даем время сброситься интерфейсу (судя по всему это нужно)
  20. //            tc.WriteLine("interface PPTP0 connect");
  21.             tc.WriteLine("exit");
  22.             Console.WriteLine("SESSION DISCONNECTED");
  23.         }
  24.     }
  25. }