2

Currently, there are around 20-30 computers into which I dial on a regular basis. I am currently using HyperTerminal on Windows XP SP3 to do this. Once my computer connects to the other computer, I get a string printout of some information which I manually eyeball and type into Excel.

While it works well for manual connections, it's a tedious process that I feel should be automated. I'm doing it once a week, now, because it's so laborious (usually 30-40 minutes per), but ideally I'd like to have it run as a scheduled task every day. However, HyperTerminal doesn't seem to offer any scripting capabilities. Furthermore, I tried using the session logging feature and it doesn't seem to work reliably that well.

Is there some way, perhaps using a batch or VBS or PowerShell script, that I could sequentially dial a series of computers, and then automatically log the terminal output to a text file, timestamped?

The added caveat is I also need to be able to handle exceptions, e.g. if the computer is busy. HyperTerminal has a "Redial on Busy" feature, and sometimes I use that or dial the rest of the computers and then come back to that one. I need to build that into my script, also.

Considering that war dialing is possible, although it doesn't log the output, only the absence or presence of a carrier tone, I feel like this is achievable. How might I go about implementing this?

I need a Batch or VBS solution, if possible. I'm not sure how good PowerShell support is on Windows XP, and for various reasons, I'd prefer not to install any additional tools (e.g. Python, etc.) onto the machine.

Clarification: I have a friend who at one point made a script that could dial out using Hayes commands onto the line. That's the easy part; the hard part is being able to detect the printout from the remote computer and log that to a text file.

The paid version of HyperTerminal offers facilities to script things along these lines, but I would like to do this for free by using a custom script, with the ability to handle busy numbers as well.

Thanks!

PowerShell

Here's what I get when running the PowerShell script: enter image description here

Here is the script I tried:

# Create your instance of the SerialPort Class
$serialPort = new-Object System.IO.Ports.SerialPort
# Set various COM-port settings
$serialPort.PortName = "COM3"
$serialPort.BaudRate = 1200
$serialPort.WriteTimeout = 500
$serialPort.ReadTimeout = 23000
$serialPort.DtrEnable = "true"
# or in one command
# $serialPort= new-Object System.IO.Ports.SerialPort COM#,Baudrate,None,8,one
# Open the connection
$serialPort.Open()
# write to it
$serialPort.WriteLine( "at+csq" + "`r" )
$serialPort.WriteLine( "atdt1NPANXXXXXX" + "`r" )
# wait
start-sleep -m 50
# read line
$line = $serialPort.ReadLine()
Write-Host $line
# write to it
$serialPort.Close()

Closest Solution So Far:

Closest I've been able to get is using AHK, which is quite finicky, but works enough of the time to be useful. My plan is to hook it up a batch script and pass in each number and iterate through until I've successfully gotten a printout from each computer.

InterLinked
  • 2,406
  • 6
  • 29
  • 64
  • 1
    This is certainly technically possible. If you use Win XP, I presume you're likely using 32-bit so can use DOS programs. I've done things like this with {Commo} (which you cannot register anymore due to it being a single-person creator who died), and Terminate. There were other competing solutions in the day, mostly DOS programs and not Windows programs. You might also try the free AutoHotkey.com. While these all involve downloading a product, what you're asking for is likely to require significant enough programming that you would be downloading code anyway, so no major loss really. – TOOGAM Nov 10 '19 at 17:53
  • @TOOGAM XP is NT, not DOS-based, are you sure it can run DOS programs? Do you know where I can find either the Commo or Terminate programs? If I can run a DOS program, that works for me. AHK might not be optimal, since when I need to add a number to it it won't be as straightforward to do – InterLinked Nov 10 '19 at 18:43
  • Absolutely, Windows XP 32-bit has some amount of DOS compatibility. [Recommended Google Search|https://www.google.com/search?q=dumb+terminal+software+serial+port+dos+commo+terminate&oq=dumb+terminal+software+serial+port+dos+commo+terminate]. I wouldn't fear AHK, as I've used it to interact with a remote system (via Telnet) and the language is flexible enough that I doubt adding a phone number would be painful. – TOOGAM Nov 11 '19 at 02:14
  • @TOOGAM How is that DOS at all? I'm confused. That looks more like telnet/SSH applications, e.g. access to remote systems. – InterLinked Nov 11 '19 at 12:07
  • {Commo} and Terminate were communications programs released for DOS. Such programs typically worked well in a 32-bit Windows XP environment. Your latest comment used the word "that" twice, both times being too vague for me to respond. If you want a more detailed answer, you'll need to be more specific. Ultimately, I don't have a pre-canned answer that will be super easy to implement. Some further effort will be needed to develop a solution. Although I didn't provide a full solve (which is why I didn't make an "answer" here), I hope my info might have been helpful. – TOOGAM Nov 12 '19 at 14:27
  • @TOOGAM I'm trying AHK, but it's seriously giving me a headache. Every time I run my script, something different happens, there is absolutely *no consistency* at all – InterLinked Nov 13 '19 at 15:10
  • @TOOGAM I've been able to come up with a solution that is somewhat stable. It's hit or miss, sometimes it works 90% of the time, others it fails 90% of the time. However, I could conceivably come up with a batch script that calls the AHK script passing in each number and iterating through the list, and if it doesn't find a saved text file, will retry such numbers accordingly. I was able to have AHK save to a text file and save a screenshot as a backup. Perhaps consider posting as answer. – InterLinked Nov 14 '19 at 03:17
  • Once I used code like found in my newly-created answer, I then found AHK to be reliable enough that it wasn't the cause of my problems. (A remote system closing a connection before giving me a logon prompt might be a remaining issue, but that wasn't AHK's fault.) I can't debug your AHK with no details other than "absolutely *no consistency* at all". You might wish to consider adding more details, perhaps to a new question. (After all, if your question is more about AHK than controlling a modem, then a new question should be made, since specific questions are preferred over evolving ones.) – TOOGAM Nov 14 '19 at 22:15
  • @TOOGAM It's no matter, it's reliable enough that it works sufficiently for my purposes. Even with it's large failure rate, it works enough of the time to save me some serious time. I'll just have to make sure the batch file that calls it will keep looping until it has a record for every single number – InterLinked Nov 14 '19 at 23:49
  • @TOOGAM See https://superuser.com/questions/1502199/how-to-improve-consistency-reliability-of-ahk-scripts – InterLinked Nov 15 '19 at 01:14

4 Answers4

3

A tool that could help with your problem is the AT Command Tester Desktop App, a commercial product ($9.95) with 7-day free trial.

This product can execute a script of AT commands under its "Script Mode" tab, where it can save and load the script from the local computer.

It also has a command line mode where it can be called by:

atc –port portname –script filename

The tool can also collect and save modem logs. I have not tried it, as I don't have a modem or know any number to call, but if the logs are saved as text files it should be a simple matter to write a little text-search script for errors/success.

enter image description here


If you would prefer writing your own, a simple PowerShell script may do it, using the System.IO.Ports.SerialPort class.

Here is an example (untested and very theoretical) :

# Create your instance of the SerialPort Class
$serialPort = new-Object System.IO.Ports.SerialPort
# Set various COM-port settings
$serialPort.PortName = "COM1"
$serialPort.BaudRate = 19200
$serialPort.WriteTimeout = 500
$serialPort.ReadTimeout = 3000
$serialPort.DtrEnable = "true"
# or in one command
# $serialPort= new-Object System.IO.Ports.SerialPort COM#,Baudrate,None,8,one
# Open the connection
$serialPort.Open()
# write to it
$serialPort.WriteLine( "at+csq" + "`r" )
# wait
start-sleep -m 50
# read line
$line = $serialPort.ReadLine()
Write-Host $line
# write to it
$serialPort.Close()

Note that the end of line character as used by the modem needs attention.

Here is my session on an XP VM where I installed .Net Framework 2.0 and KB968930. It almost worked, except that there is nothing connected to COM1, so it hanged on the ReadLine() call until ended by a timeout.

Please note that there was a copy-paste error in my script, now corrected. The line that didn't work was:

$line = $port.ReadLine()

It should have been:

$line = $serialPort.ReadLine()

enter image description here

harrymc
  • 455,459
  • 31
  • 526
  • 924
  • Interesting, thanks for sharing. Unfortunately, if it's not free, it won't be of much help – InterLinked Nov 09 '19 at 19:22
  • $9.95 is pretty modest for the time it will save you, not so? – harrymc Nov 09 '19 at 20:10
  • But if it can be done for free, then why pay? Plus, a script would allow me to completely customize and control it, particularly since I need to iterate over a list of phone numbers and call them all – InterLinked Nov 09 '19 at 20:19
  • Added a second part, for having PowerShell fun. – harrymc Nov 09 '19 at 20:51
  • The PowerShell part is interesting. What is the part that gets the printout from the remote end - $port.ReadLine() ? – InterLinked Nov 09 '19 at 21:10
  • ReadLine() it is. I found this: [Installing Powershell 2.0 on Windows XP](https://www.faqforge.com/windows/installing-powershell-2-0-on-windows-xp/). Installing a later version is apparently impossible ([link](https://www.powershellmagazine.com/2012/09/05/powershell-3-0-is-available-for-downlevel-systems/)). However, `System.IO.Ports.SerialPort` exists already in Powershell 2.0 ([link](https://docs.microsoft.com/en-us/dotnet/api/system.io.ports.serialport?view=netframework-2.0)). – harrymc Nov 09 '19 at 21:20
  • Finally found one - here it is for posterity: https://www.microsoft.com/en-us/download/details.aspx?id=16818 – InterLinked Nov 09 '19 at 21:25
  • I ran the script; I edited my answer with the outcome – InterLinked Nov 09 '19 at 21:29
  • I found [another possibility](https://www.microsoft.com/en-us/download/details.aspx?id=20430) but perhaps yours is better. Your error may be a legitimate PowerShell error. If the line `$serialPort = new-Object System.IO.Ports.SerialPort` passes then all is possible, but PowerShell needs some study to use, some of it by trial and error. Use the PowerShell shell for testing commands. – harrymc Nov 09 '19 at 21:46
  • I customized the script to my needs and it still gives the same error. Playing around but nothing I've tried seems to work. – InterLinked Nov 09 '19 at 21:51
  • Perhaps starting the PowerShell command-line as Admin might help. If not, perhaps the $9.95 is worth it for saving you some time? – harrymc Nov 10 '19 at 07:48
  • starting as Admin? It's already an admin account, and since there's no UAC in XP, I'm pretty sure it's already running in an elevated context (update: just confirmed, it's already running from an Administrator command prompt) – InterLinked Nov 10 '19 at 16:01
  • XP, yes, forgot that. I did the same on an XP VM, and I think that the problem was a copy-paste error in my script. With it corrected, the ReadLine() call correctly hang on reading from nowhere. Does it do more on your computer? – harrymc Nov 11 '19 at 10:26
  • Well, it doesn't fail anymore with an error, the script just runs but doesn't seem to do anything. I had it call a phone on my desk and it didn't ring, so something seems to be missing – InterLinked Nov 11 '19 at 12:06
  • Also, I changed my port to COM3, since that's what the modem is actually on, and the baud rate to 1200, since the max baud rate on the remote computers is 1200 bps anyways, so all the settings should work. – InterLinked Nov 11 '19 at 12:09
  • I don't have your environment for doing further testing. One last try: Try a simple command followed by Readline while booting in Safe mode. Otherwise, it may mean that .Net 2.0 and Powershell 2.0 are just not up to it. Does the AT Command Tester manage to do the work? – harrymc Nov 11 '19 at 18:10
2

The most basic method of controlling a modem is by sending commands through a serial port. Nearly all dial-up modems support Hayes AT commands, such as ATD or ATH (usually in hardware for serial modems, sometimes emulated by the driver for USB/PCI modems).

Examples:

  • Linux/OpenBSD/FreeBSD: All programs and libraries eventually use the /dev/ttyS* special files to access serial ports. (Note: On Linux, USB-serial adapters are named ttyUSB or ttyACM.)
    In most cases your program can just open the path as if it were a regular file, then write/flush a command and read the response.

  • Windows: All programs eventually use the \\.\COM1: special files to access serial ports. The first four can be opened simply as COM1: (the shortcut is a MS-DOS relic).

  • PowerShell: There is a DevBlog on this topic.

  • Python: Use pySerial.

The other method, on Windows, might be to use the Telephony API. However, I can't find whether it supports data (terminal) calls, or only voice calls.

u1686_grawity
  • 426,297
  • 64
  • 894
  • 966
  • Yes, I've used the AT commands on occasion. But is there a way to script that? How would I issue the commands to the modem from a script? – InterLinked Nov 06 '19 at 12:19
  • 1
    Depends on programming language but practically all of them have _some_ interface to serial devices, whether it's through a special module or whether it's through opening `/dev/ttyS0` on Linux or `\\.\COM1:` on Windows. – u1686_grawity Nov 06 '19 at 13:38
  • So what would be the best way to go about this? It seems like VBScript is the only way based on my research, e.g. https://control.com/thread/1026236729#1026236890 – InterLinked Nov 06 '19 at 13:47
  • It seems like establishing a connection is easy, but I'm stuck on how I would wait for the output from the remote computer and capture it to a timestamped text file. – InterLinked Nov 06 '19 at 13:48
  • 1
    Well, I don't know about a good example for making calls, but I do have an old script that used AT commands over a serial port to receive data from a connected device (cellphone, but it's the same idea): https://github.com/grawity/code/blob/master/misc/sony-ericsson-screenshot – and yes, this worked on Windows. – u1686_grawity Nov 06 '19 at 14:10
1

As a sidenote: here are just two utilities I use to control my modems. I send and receive lots of SMS, the tools are made for this. They support multiple modems, and AT commands are used to initialize modems. Whereas all functions are somehow laid out to work with SMS, it can be highly customized with init scripts and more. I haven't tested a complete cycle like dial in another modem and receive somehow data, but maybe it is worthwhile to have a look into them:

http://smstools3.kekekasvi.com/index.php https://wammu.eu/smsd/

pebwindkraft
  • 131
  • 6
  • This link doesn't load for me... are you sure it works? – InterLinked Nov 11 '19 at 22:03
  • just tried both links, and they seem to work ... – pebwindkraft Nov 12 '19 at 19:30
  • The first one still doesn't work but the second does; this looks interesting; I will definitely check it out – InterLinked Nov 12 '19 at 20:52
  • I installed Gammu and even though I selected Create start menu and desktop shortcuts, I can't find the program anywhere. The only thing in the start menu folder is an Uninstall option, and it doesn't appear anywhere else. Reinstalling it doesn't change anything. I installed Wammu, and when I try that it fails to run; the logs show "Provider DLL failed to initialize correctly" a few times – InterLinked Nov 12 '19 at 21:27
1

AutoHotkey.com can be helpful.

I believe that a key trick to making it work reliably will be to use the right approach. Simply dumping keystrokes into Microsoft Windows so that Windows give it to the foreground application will not be the most stable method. Here is a bit of code that I used to interact with PuTTY. It worked well enough that I could start the script, which would launch PuTTY, and yet the program could then interact with the correct instance of PuTTY even if PuTTY was in the background.

(You will likely want to significantly adapt this example code.)

sPuTTYloc:="C:\Users\\me\PuTTY\PuTTY.exe"
sSiteName:="NameOfSite"
Run, "%sPuTTYloc%" -load "%sSiteName%",,UseErrorLevel,sPuTTYPID

    if %sPuTTYPID%
    {
        WinWait, ahk_pid %sPuTTYPID%
        sleep ,5000
        IfWinExist,ahk_pid %sPuTTYPID%
        {
            ControlSend,,{Enter},ahk_pid %sPuTTYPID%
; other stuff
        else
        {
MsgBox "PuTTY Window closed, spot #1"
            return ; Apparently the PuTTY window closed
        }
        Sleep 1500
        IfWinExist,ahk_pid %sPuTTYPID%
        {
            ; do other stuff
        }
        else
        {
MsgBox "PuTTY Window closed, spot #2"
            return ; Apparently the PuTTY window closed
        }
        Sleep 1500
        return
    }
return

There isn't necessarily a compelling reason why I still have things broken things up into pieces, calling "IfWinExist" multiple times. When I was creating and initially debugging the script, I found it useful for debugging (or at least feeling like I had a better idea of what was going on) if the remote end terminated the connection (which would cause my PuTTY window to close).

The main thing is that by using ControlSend to give the keystrokes to the program using the PID which was created by my Run command, if something bad happened, the script didn't continue to try to send keystrokes to Windows and end up having the keystrokes go into the wrong program.

TOOGAM
  • 15,243
  • 4
  • 41
  • 58
  • At this time (after having just posted this answer), I don't feel like this answer (or at least, this version of this answer) is a complete solution for you. However, being a very complete solution may involve also interacting with Excel, and is just too difficult for me to provide to you while I remain blind on some details. These details may be useful enough to give you a foundation upon which to achieve your goals. – TOOGAM Nov 14 '19 at 22:13
  • Excel integration is not necessary. If I can get text files with the printouts that I only need to copy and paste into Excel, and maybe rely on screenshots as a backup, and then enter the timestamp of the file, that will only take me a few minutes, as opposed to close to an hour. By the way, I've already completed my AHK solution that works for one number. AHK is super finicky though, so I'll write a batch parent script now that will call AHK for each number, as well as loop through at the end to make sure it successfully dialed all numbers – InterLinked Nov 14 '19 at 23:38