さらに、オートパイロットらしく、入力の応答を com.txt で指定する仕様に更新

PowerShell は使えますな…Visual Stadio Express のお陰で、Windows でも
いろいろプログラム組んでますけど、インタプリタで高機能なのは楽ちん♪
コマンドラインでぱぱぱっと書けるのが性に合ってるのです(笑)


com.txt の記入例)"user@ukikusa"というのはプロンプト文字列の一部
date
user@ukikusa
telnet localhost
login:
user
Password:
password
user@ukikusa
ls -ld *
user@ukikusa
logout
user@ukikusa


スクリプトソース)


## telnet-robot.ps1
##
## telnet プロトコルでサーバに接続してコマンドを実行する。
##
## 引数: remoteHost ホスト名
## port 接続ポート
## cmdfile リモートホストで実行するコマンドリスト
## logfile 実行ログを保存するファイル名
## user ユーザ名
## passwd パスワード
param(
[string] $remoteHost = "ukikusa",
[int] $port = 23,
[string] $cmdfile = "c:\users\kotora\com.txt",
[string] $logfile = "c:\users\kotora\Temp.txt",
[string] $user = "user",
[string] $passwd = "password"
)

# Start Logging
###############################################################################
Start-Transcript -Path "$logfile"

# Main Loop
###############################################################################
try {
## ホストに TCP で接続
write-host "Connecting to $remoteHost on port $port`r`n"
$socket = new-object System.Net.Sockets.TcpClient($remoteHost, $port)
if($socket -eq $null) {
throw ("Could Not Connect")
}
write-host "Connected $remoteHost on port $port`r`n"

$stream = $socket.GetStream()
$writer = new-object System.IO.StreamWriter($stream)

$buffer = new-object System.Byte[] 1024
$nego = new-object System.Byte[] 1024
$encoding = new-object System.Text.UTF8Encoding

# Telnet Negotiation
$IAC = 255 # interpret as command:
$DONT = 254 # you are not to use option
$DO = 253 # please, you use option
$WONT = 252 # I won't use option
$WILL = 251 # I will use option
$SB = 250 # interpret as subnegotiation
$GA = 249 # you may reverse the line
$EL = 248 # erase the current line
$EC = 247 # erase the current character
$AYT = 246 # are you there
$AO = 245 # abort output--but let prog finish
$IP = 244 # interrupt process--permanently
$BREAK= 243 # break
$DM = 242 # data mark--for connect. cleaning
$NOP = 241 # nop
$SE = 240 # end of record (transparent mode)
$EOR = 239 # end of record (transparent mode)
$ABORT= 238 # Abort process
$SUSP = 237 # Suspend process
$xEOF = 236 # End of file: EOF is already used...

$TELOPT_BINARY = 0
$TELOPT_ECHO = 1
$TELOPT_SGA = 3
$TELOPT_NAWS = 4
$TELOPT_STATUS = 5
$TELOPT_NAOCRD = 10
$TELOPT_NAOFFD = 13
$TELOPT_TTYPE = 24
$TELOPT_TSPEED = 32
$TELOPT_XDISPLOC = 35
$TELOPT_NEW_ENVIRON = 39

$TELQUAL_IS = 0
$TELQUAL_SEND = 1
$TELQUAL_INFO = 2
$TELQUAL_REPLY = 2
$TELQUAL_NAME = 3

$CR = "`r`n"
$debug = 0
$retry = 1000
$input_wait = 1000

# Exsec comand list read
###########################################################################
$commands = Get-Content $cmdfile;

##
## Telnet Negitiation

# STAGE1:サーバにサブコマンドの受付を要求
###########################################################################
$rep = 0
for($r=0; $r -lt $retry; $r++) {
start-sleep -m 500
if ($stream.DataAvailable) {
$read = $stream.Read($buffer, 0, 1024)
if($buffer[0] -eq $IAC) {
if($debug -eq 1) {
write-host Recieve1: $CR
for($i=0; $i -lt $read; $i++) {
write-host $buffer[$i]
}
write-host Reply1: $CR
}
for($c=0; $buffer[$c] -ne 0; $c+=3) {
if($buffer[$c+1] -eq $DO) {
if($buffer[$c+2] -eq $TELOPT_TSPEED) {
$nego = $IAC,$WONT,$TELOPT_TSPEED
$stream.Write($nego, 0, $nego.Length)
} else {
$nego = $IAC,$WILL,$buffer[$c+2]
$stream.Write($nego, 0, $nego.Length)
}
$stream.Flush()
if($debug -eq 1) {
write-host $nego $CR
}
}
}
}
$r = $retry
$rep = 1
}
}
if($rep -eq 0) {
throw ("No response negoation`r`n")
}
# STAGE2:サブコマンドでこちらの端末設定を適当に送信
###########################################################################
$rep = 0
for($r=0; $r -lt $retry; $r++) {
start-sleep -m 500
if($stream.DataAvailable) {
$read = $stream.Read($buffer, 0, 1024)
if($buffer[0] -eq $IAC) {
if($debug -eq 1) {
write-host Recieve2: $CR
for($i=0; $i -lt $read; $i++) {
write-host $buffer[$i]
}
write-host Reply2: $CR
}
for($c=0; $buffer[$c] -ne 0; $c+=6) {
if($buffer[$c+1] -eq $SB) {
switch($buffer[$c+2]) {
$TELOPT_XDISPLOC {
# XDisplay じゃないので適当に設定
$nego = $IAC,$SB,$TELOPT_XDISPLOC,0,0,0,0,$IAC,$SE
$stream.Write($nego, 0, $nego.Length)
}
$TELOPT_NEW_ENVIRON {
$nego = $IAC,$SB,$TELOPT_NEW_ENVIRON,$TELQUAL_IS,$IAC,$SE
$stream.Write($nego, 0, $nego.Length)
}
$TELOPT_TTYPE {
# ターミナルタイプを vt100 に設定
$nego = $IAC,$SB,$TELOPT_TTYPE,00,118,116,49,48,48,$IAC,$SE
$stream.Write($nego, 0, $nego.Length)
}
}
}
$stream.Flush()
if($debug -eq 1) {
write-host $nego $CR
}
}
}
$r = $retry
$rep = 1
}
}
if($rep -eq 0) {
throw ("No response negoation`r`n")
}
# STAGE3:他の問い合わせに、全部問い合わせなくていいと回答
###########################################################################
$rep = 0
for($r=0; $r -lt $retry; $r++) {
start-sleep -m 500
if($stream.DataAvailable) {
$read = $stream.Read($buffer, 0, 1024)
if($buffer[0] -eq $IAC) {
if($debug -eq 1) {
write-host Recieve3: $CR
for($i=0; $i -lt $read; $i++) {
write-host $buffer[$i]
}
write-host Reply3: $CR
}
for($c=0; $buffer[$c] -ne 0; $c+=3) {
if($buffer[$c+1] -eq $DO) {
$nego = $IAC,$WONT,$buffer[$c+2]
$stream.Write($nego, 0, $nego.Length)
$stream.Flush()
if($debug -eq 1) {
write-host $nego $CR
}
}
}
}
$r = $retry
$rep = 1
}
}
if($rep -eq 0) {
throw ("No response negoation`r`n")
}
# ログインプロンプトにユーザとパスワードを送信
###########################################################################
$rep = 0
for($r=0; $r -lt $retry; $r++) {
start-sleep -m 500
if ($stream.DataAvailable) {
while($stream.DataAvailable) {
$read = $stream.Read($buffer, 0, 1024)
write-host -n ($encoding.GetString($buffer, 0, $read))
}
start-sleep -m $input_wait
$writer.WriteLine($user)
$writer.Flush()
$r = $retry
$rep = 1
}
}
if($rep -eq 0) {
throw ("No response negoation`r`n")
}
$rep = 0
for($r=0; $r -lt $retry; $r++) {
start-sleep -m 500
if ($stream.DataAvailable) {
while($stream.DataAvailable) {
$read = $stream.Read($buffer, 0, 1024)
write-host -n ($encoding.GetString($buffer, 0, $read))
}
start-sleep -m $input_wait
$writer.WriteLine($passwd)
$writer.Flush()
$r = $retry
$rep = 1
}
}
if($rep -eq 0) {
throw ("No response negoation`r`n")
}
# プロンプトを受信
###########################################################################
$rep = 0
for($r=0; $r -lt $retry; $r++) {
start-sleep -m 500
if ($stream.DataAvailable) {
while($stream.DataAvailable) {
$read = $stream.Read($buffer, 0, 1024)
write-host -n ($encoding.GetString($buffer, 0, $read))
}
$r = $retry
$rep = 1
}
}
if($rep -eq 0) {
throw ("No response login`r`n")
}
# ここから実行したい管理コマンドを送信
###########################################################################
for($i=0; $i -le $commands.Count; $i++) {
$rep = 0
$line = ""
start-sleep -m $input_wait
$writer.WriteLine($commands[$i])
$writer.Flush()
$i++
for($r=0; $r -lt $retry; $r++) {
start-sleep -m $input_wait
if ($stream.DataAvailable) {
while($stream.DataAvailable) {
$read = $stream.Read($buffer, 0, 1024)
$line = ($encoding.GetString($buffer, 0, $read))
write-host -n $line
# 実行完了文字列をチェック
if($line -match $commands[$i]) {
$r = $retry
$rep = 1
}
}
}
}
if($rep -eq 0) {
throw ("No response Command`r`n")
}
}
# ログアウト
###########################################################################
start-sleep -m $input_wait
$writer.WriteLine("exit")
$writer.Flush()
# ホストからの応答を受けて処理終了
###########################################################################
$rep = 0
for($r=0; $r -lt $retry; $r++) {
start-sleep -m 500
if ($stream.DataAvailable) {
while($stream.DataAvailable) {
$read = $stream.Read($buffer, 0, 1024)
write-host -n ($encoding.GetString($buffer, 0, $read))
}
start-sleep -m $input_wait
$writer.WriteLine("bye!") # 送信はなんでもOK!
$writer.Flush()
$r = $retry
$rep = 1
}
}
if($rep -eq 0) {
throw ("No response exit`r`n")
}
}

# ERROR Routine(catch throw)
###############################################################################
catch {
write-host $error[0]
$dateTime = get-date
$errorOccurence = "Error occurred connecting to $remoteHost on $port at $dateTime"
write-host $errorOccurence
}

# Finalize
###############################################################################
finally {
write-host `r`n
write-host exit program.`r`n
$writer.Close()
$stream.Close()

stop-transcript
}