Justin Owens
asked on
How do I use PowerShell to 1) telnet to a list of digis to 2) login and run a single command?
First, I have never written a single PowerShell script in my life, so if this is not the best language to use, please let me know. I need to run a small script that will connect to about 200 Digi devices to run a reboot command. The command is "boota=r". It is a command which reboots the Digi. I want to have a script that will parse through a file to extrapolate a list of IP addresses to which it should connect to perform this command.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
That bit I'm not entirely sure about.
DrUltima,
please provide a piece of code!
This comment is more or like a question on how "far" you are already ... maybe some changes to the scripts you are currently working on will do the trick ;) ...
Best regards,
Raisor
please provide a piece of code!
This comment is more or like a question on how "far" you are already ... maybe some changes to the scripts you are currently working on will do the trick ;) ...
Best regards,
Raisor
ASKER
Raisor, I appreciate the suggestion, but I have no code to submit. I am willing to do this in PowerShell or VBS, but the reality is I am not a programmer. I have been tasked by my boss to come up with an easy way to reboot the digis that doesn't require manually connecting to each of them by a human. The only way to reboot them remotely is to open a telnet session to the device, login, and and then pass the reboot command. I have no idea how to accomplish this programatically.
ASKER
OK, I found a PowerShell Script on the internet that I could base some logic off of. The code below WORKS when it can connect to the destination IP.
When the destination does not respond or a connect fails, I get this error, and then the script closes completely:
Could not connect to remote computer: Exception calling ".ctor" with "2" argument(s): "A connection attempt failed beca
use the connected party did not properly respond after a period of time, or established connection failed because conne
cted host has failed to respond 1.1.1.1:23"
At H:\Reboot-Digis.ps1:46 char:17
+ trap { throw <<<< "Could not connect to remote computer: $_"; exit }
What I want it to do is just move on to the next IP on the list. If it gives a "cannot connect to xx.xx.xx.xx, moving on" type of message, that is lovely, but I don't need that. I just need it to finish.
Also, I had to hard code the text file which contained the IP list. I want that to be an input variable, but I just don't know how to do that. Either as a command line parameter or as a requested input, it doesn't matter to me.
I also had to force it to run as though it is not being run from the shell, in otherwords, right now, to run this script, I open PowerShell and type .\reboot-digis.ps1. I would LOVE it if I could just click an icon or type a single line from a regular command prompt.
Any pointers appreciated.
When the destination does not respond or a connect fails, I get this error, and then the script closes completely:
Could not connect to remote computer: Exception calling ".ctor" with "2" argument(s): "A connection attempt failed beca
use the connected party did not properly respond after a period of time, or established connection failed because conne
cted host has failed to respond 1.1.1.1:23"
At H:\Reboot-Digis.ps1:46 char:17
+ trap { throw <<<< "Could not connect to remote computer: $_"; exit }
What I want it to do is just move on to the next IP on the list. If it gives a "cannot connect to xx.xx.xx.xx, moving on" type of message, that is lovely, but I don't need that. I just need it to finish.
Also, I had to hard code the text file which contained the IP list. I want that to be an input variable, but I just don't know how to do that. Either as a command line parameter or as a requested input, it doesn't matter to me.
I also had to force it to run as though it is not being run from the shell, in otherwords, right now, to run this script, I open PowerShell and type .\reboot-digis.ps1. I would LOVE it if I could just click an icon or type a single line from a regular command prompt.
Any pointers appreciated.
# ==============================================================================================
#
# Microsoft PowerShell Source File -- Created with SAPIEN Technologies PrimalScript 4.1
#
# NAME: ME
#
# AUTHOR: COMPANY NAME HERE
# DATE : 3/25/2009
#
# COMMENT: Code originally found at http://www.leeholmes.com/blog/ScriptingNetworkTCPConnectionsInPowerShell.aspx
#
# ==============================================================================================
## Connect-Computer.ps1
## Interact with a service on a remote TCP port
param(
##[string] $remoteHost = "xxx.xxx.xxx.xxx",
[int] $port = 23,
[string] $inputObject,
[int] $commandDelay = 100
)
[string] $output = ""
$currentInput = $inputObject
if(-not $currentInput)
{
$SCRIPT:currentInput = @($input)
}
##I want it to always run batched, not wait for input, so I commented out the check and forced $scriptedMode
##$scriptedMode = [bool] $currentInput
$scriptedMode = 1
##Here we have to replace username, password, and command with what we want to happen once the telnet session is opened.
##$currentInput = ("username","password","command")
$currentInput = ("USER","PASSWORD","boot a=r")
function Main
{
## Open the socket, and connect to the computer on the specified port
if(-not $scriptedMode)
{
write-host "Connecting to $remoteHost on port $port"
}
trap { throw "Could not connect to remote computer: $_"; exit }
$socket = new-object System.Net.Sockets.TcpClient($remoteHost, $port)
if(-not $scriptedMode)
{
write-host "Connected. Press ^D followed by [ENTER] to exit.`n"
}
$stream = $socket.GetStream()
$writer = new-object System.IO.StreamWriter($stream)
## Create a buffer to receive the response
$buffer = new-object System.Byte[] 1024
$encoding = new-object System.Text.AsciiEncoding
while($true)
{
## Receive the output that has buffered so far
$SCRIPT:output += GetOutput
## If we're in scripted mode, send the commands,
## receive the output, and exit.
if($scriptedMode)
{
foreach($line in $currentInput)
{
$writer.WriteLine($line)
$writer.Flush()
Start-Sleep -m $commandDelay
}
$SCRIPT:output += GetOutput
break
}
## If we're in interactive mode, write the buffered
## output, and respond to input.
else
{
if($output)
{
foreach($line in $output.Split("`n"))
{
write-host $line
}
$SCRIPT:output = ""
}
## Read the user's command, quitting if they hit ^D
$command = read-host
if($command -eq ([char] 4)) { break; }
## Otherwise, Write their command to the remote host
$writer.WriteLine($command)
$writer.Flush()
}
}
## Close the streams
$writer.Close()
$stream.Close()
## If we're in scripted mode, return the output
if($scriptedMode)
{
$output
}
}
## Read output from a remote host
function GetOutput
{
$outputBuffer = ""
$foundMore = $false
## Read all the data available from the stream, writing it to the
## output buffer when done.
do
{
## Allow data to buffer for a bit
start-sleep -m 1000
## Read what data is available
$foundmore = $false
while($stream.DataAvailable)
{
$read = $stream.Read($buffer, 0, 1024)
$outputBuffer += ($encoding.GetString($buffer, 0, $read))
$foundmore = $true
}
} while($foundmore)
$outputBuffer
}
##I eventually want to make $Digis = Get-Content $rebootList and have $rebootList defined as an input variable.
$Digis = Get-Content h:\test.csv
foreach ($remoteHost in $Digis) {. Main}
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Open in new window