如何编写PowerShell脚本来自动执行这组命令?
答案 0 :(得分:3)
好的,这不是最优雅的解决方案,它确实依赖于 不寒而栗 VBscript,但在这里它... ...
创建一个VBScript以实际加快telnet会话,这是一个例子
set oShell = CreateObject("WScript.Shell")
oShell.run("Telnet")
WScript.Sleep 1000
oShell.SendKeys("Open 127.0.0.1 23")
WScript.Sleep 1000
oShell.SendKeys("{Enter}")
WScript.Sleep 1000
oShell.SendKeys("n")
WScript.Sleep 1000
oShell.SendKeys("{Enter}")
WScript.Sleep 1000
oShell.SendKeys"MyName"
WScript.Sleep 1000
oShell.SendKeys("{Enter}")
WScript.Sleep 1000
oShell.SendKeys("MyPassword")
WScript.Sleep 1000
oShell.SendKeys("{Enter}")
WScript.Sleep 1000
oShell.SendKeys("MyCommand")
WScript.Sleep 1000
oShell.SendKeys("{Enter}")
WScript.Sleep 1000
然后使用Powershell调用该脚本并将其传递给您想要执行的命令,在下面的示例中,这些命令存储在名为CommandList.txt的文件中
function Connect-MyTelnet{
Param(
[string] $IPAddress,
[string] $Port,
[string] $UserName,
[string] $Password,
[string] $cmdlistPath
)
## - Setting default values:
if($port -eq $null){ $Port = "23"; };
if($cmdlistPath -eq $null) { $CmdlistPath = 'c:\temp\cmdlist.txt'; };
## create vbscript file: MyTelnetSession.vbs
## - For Microsoft Telnet:
$MyVBScript = @"
set oShell = CreateObject("WScript.Shell")`r`n
oShell.run("Telnet")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("Open $IPAddress $Port")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("{Enter}")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("n")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("{Enter}")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("$UserName")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("{Enter}")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("$Password")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("{Enter}")`r`n
WScript.Sleep 1000`r`n
"@;
## - Get file with telnet commands:
[array] $Cmdlist = Get-Content $cmdlistPath;
## loop through and build each telnet command line:
foreach($cmd in $cmdlist)
{
## - Build VBscript lines:
$MyVBScript += 'oShell.SendKeys("'+$cmd+'")'+"`r`n";
$MyVBScript += "WScript.Sleep 1000`r`n";
$MyVBScript += 'oShell.SendKeys("{Enter}")'+"`r`n";
$MyVBScript += 'WScript.Sleep 1000'+"`r`n";
}
## - Close Telnet Session:
$MyVBScript += 'oShell.SendKeys(" QUIT")'+"`r`n";
$MyVBScript += "WScript.Sleep 1000`r`n";
$MyVBScript += 'oShell.SendKeys("{Enter}")'+"`r`n";
$MyVBScript += 'WScript.Sleep 1000'+"`r`n";
## - Save and execute generated VBscript:
$MYVBScript | Out-File -FilePath c:\temp\MyTelnet.vbs -Encoding ASCII;
& c:\temp\MyTelnet.vbs
}; Set-Alias ct Connect-MyTelnet;
那应该做你要问的......
注意:不是我的解决方案,从this blog post找到,我已经使用了一两次。
答案 1 :(得分:2)
我不会对这里的套接字做任何事情,因为你需要实现至少部分telnet规范。如果我记得那个规格有点搞笑。但是这里列出了一些.NET telnet实现:C# Telnet Library你可以直接从powershell改编或使用,就像Goyuix在他的答案中使用套接字代码一样。
答案 2 :(得分:1)
不要尝试自动化telnet可执行文件,只需创建套接字并发出命令,读取它们,然后根据它做出决定。以下是连接到本地Web服务器的简化示例:
function test() {
$msg = [System.Text.Encoding]::ASCII.GetBytes("GET / HTTP/1.0`r`nHost: localhost`r`n`r`n")
$c = New-Object System.Net.Sockets.TcpClient("localhost", 80)
$str = $c.GetStream()
$str.Write($msg, 0, $msg.Length)
$buf = New-Object System.Byte[] 4096
$count = $str.Read($buf, 0, 4096)
[System.Text.Encoding]::ASCII.GetString($buf, 0, $count)
$str.Close()
$c.Close()
}
显然,您需要从端口80更改它,并传递用户名/密码而不是Web请求标头...但这应该足以让您入门。
答案 3 :(得分:0)
我创建了一个powershell脚本来从单个主机telnet多个商店,并且可以选择捕获或不捕获tracert和ping命令
telnet多个主机并捕获tracert和ping命令的命令
#Mutlple Telneting guide
#Created by : Mohit
#How to use ?
#Step 1 : Add mutiple IPs in DestinationIP.csv
#Step 2 : Run Batch file TelnetMultipleHost.bat
####################################################################################################################
$DestinationIP= Get-Content .\DestinationIP.csv
$ipV4 = (Test-Connection -ComputerName (hostname) -Count 1).IPV4Address.IPAddressToString
####################################################################################################################
write-host "-------------------Welcome to Multiple Telnet Host Panel-------------------------"
write-host ""
write-host ""
write-host "IMPORTANT: Make sure you are running this tool from source IP which in this case is " $ipV4
write-host ""
$Ports = Read-Host -Prompt "Enter Destination Port No.(# for multple ports just seperate ports with ,)"
write-host ""
write-host "Port No. you entered:" $Ports
write-host ""
write-host "Select Option"
write-host ""
write-host "Type 1 for telnet Host WITH trace logs"
write-host "Type 2 for telnet Host WITHOUT trace logs"
write-host ""
$option =Read-Host -Prompt "Type here"
write-host ""
Start-Transcript -Path .\TraceLogs_$ipV4.txt
switch($option)
{
#Type 1 for telnet Host WITH trace logs
1{
foreach ($Destination in $DestinationIP)
{
foreach ($Port in $Ports) {
# Create a Net.Sockets.TcpClient object to use for # checking for open TCP ports.
$Socket = New-Object Net.Sockets.TcpClient
# Suppress error messages
$ErrorActionPreference = 'SilentlyContinue'
# Try to connect
$Socket.Connect($Destination, $Port)
# Make error messages visible again
$ErrorActionPreference = 'Continue'
# Determine if we are connected.
if ($Socket.Connected) {
"${Destination}: Port $Port is open"
$Socket.Close()
}
else {
"${Destination}: Port $Port is closed or filtered"
if (test-connection $Destination -count 1 -quiet) {
write-host $Destination "Ping succeeded." -foreground green
} else {
write-host $Destination "Ping failed." -foreground red
}
Test-NetConnection $Destination -TraceRoute
}
# Apparently resetting the variable between iterations is necessary.
$Socket = $null
}
}
}
# Type 2 for telnet Host WITHOUT trace logs
2{
foreach ($Destination in $DestinationIP) {
foreach ($Port in $Ports) {
# Create a Net.Sockets.TcpClient object to use for
# checking for open TCP ports.
$Socket = New-Object Net.Sockets.TcpClient
# Suppress error messages
$ErrorActionPreference = 'SilentlyContinue'
# Try to connect
$Socket.Connect($Destination, $Port)
# Make error messages visible again
$ErrorActionPreference = 'Continue'
# Determine if we are connected.
if ($Socket.Connected) {
"${Destination}: Port $Port is open"
$Socket.Close()
}
else {
"${Destination}: Port $Port is closed or filtered"
}
# Apparently resetting the variable between iterations is necessary.
$Socket = $null
}
}
}
}
Stop-Transcript
请注意:TelnetMultipleHost.bat此批处理用于运行powershell命令
确保我们在同一目录中有bat,ps1文件
批处理文件的代码:
@echo off Powershell.exe -executionpolicy remotesigned -File。\ TelnetMultipleHost.ps1 暂停
答案 4 :(得分:0)
我建议您使用TeraTerm这个免费软件。 您可以远程登录到您的计算机,然后运行TTL脚本。 它非常强大且可靠。我每天都在工作中使用它。 如果您有兴趣,可以进行更多搜索。 TTL脚本示例:
i = 100
do while i>0
sendln 'un 1357'
wait '>'
sendln '.w 4 42800024 0000000a'
wait '>'
sendln '.w 4 42800014 00000004'
wait 'in service'
sendln 'info'
wait'>'
sendln 'start'
wait '20'#13#10'>' '0'#13#10'>'
if result!=2 then
break
endif
i = i - 1
loop
答案 5 :(得分:0)
这是PowerShell中非常基本的Telnet客户端。它实质上只是.net Framework的TcpClient,带有一些额外的代码来拒绝任何IAC命令(即,与服务器协商其功能时,它对所有请求都说“我不/不愿意这样做”),以确保基本的NVT实施都可以使用。)
代码在此处维护:https://gist.github.com/JohnLBevan/e28fbb6c0dfdd45a21e03c104999c212
Function New-TelnetClient {
[CmdletBinding()]
Param (
[Parameter()]
[string]$ComputerName = '127.0.0.1'
,
[Parameter()]
[int]$PortNo = 23
,
[Parameter()]
[System.Text.Encoding]$Encoding = [System.Text.Encoding]::ASCII
,
[Parameter()]
[int]$BufferSize = 1024
)
[System.Net.Sockets.TcpClient]$telnet = New-Object 'System.Net.Sockets.TcpClient'
try {
$telnet.PSTypeNames.Add('ClearChannel.Net.Sockets.TelnetClient')
$telnet | Add-Member -MemberType 'NoteProperty' -Name 'Encoding' -Value ($Encoding)
$telnet | Add-Member -MemberType 'NoteProperty' -Name 'EndOfCommand' -Value ([System.Environment]::NewLine)
$telnet | Add-Member -MemberType 'NoteProperty' -Name 'BufferSize' -Value ($BufferSize)
$telnet.Connect($ComputerName, $PortNo)
$telnet | Add-Member -MemberType 'NoteProperty' -Name 'Writer' -Value (New-Object -TypeName 'System.IO.StreamWriter' -ArgumentList ($telnet.GetStream()))
$telnet.Writer.AutoFlush = $true
$telnet | Add-Member -MemberType 'ScriptMethod' -Name 'SendCommand' -Value ({
Param([string]$CommandText)
#$this.Writer.WriteLine($CommandText + $this.EndOfCommand) #writeline should stick the line endings in place anyway, but just to be sure, added this
$this.Writer.WriteLine($CommandText)
(New-Object -TypeName 'PSObject' -Property @{Direction='Input'; Value=$CommandText; When=((Get-Date).ToUniversalTime())})
})
$telnet | Add-Member -MemberType 'ScriptMethod' -Name 'HandleIac' -Value ({
if ($this.Available) {
[int]$byte = $this.GetStream().ReadByte()
[byte]$defaultResponse = 254 # for most IAC requests, we'll respond with don't
switch ($byte) {
-1 { # end of stream (shouldn't happen, but handled in case)
Write-Warning 'Unexpected end of stream whilst processing IAC'
return
}
255 { # Escaped IAC character
Write-Debug 'IAC Escaped'
return $byte
}
253 { #if we get a DO, change default response to WON'T instead of DON'T
$defaultResponse = 252
# do not break; continue to next case statement
}
{(251, 252, 253, 254) -contains $_} { # Will, Won't, Do, Don't
$byte = $this.GetStream().ReadByte() # this is the option we need to respond to; currently we just deny all options to get a raw NVT
switch ($byte) {
-1 {
Write-Warning 'Unexpected end of stream whilst processing IAC'
}
# if we want to handle specific IAC codes we can add support here
default {
$this.GetStream().WriteByte(255) # IAC
$this.GetStream().WriteByte($defaultResponse) # Don't/Won't
$this.GetStream().WriteByte($byte) # whatever you told me
}
}
return
}
default {
Write-Warning "$byte is not a control character, but was received after an IAC character"
}
}
}
})
$telnet | Add-Member -MemberType 'ScriptMethod' -Name 'GetBytes' -Value ({
Start-Sleep -Milliseconds 500 #added to get correct output; otherwise we seem to fly past the handshake :/
while ($this.Available -gt 0) {
[int]$byte = $this.GetStream().ReadByte() #held as int to allow -1 status code for end of stream
switch ($byte) {
-1 { # end of stream
return
}
255 { #IAC control character received
Write-Verbose 'IAC Command Received'
$this.HandleIac()
break
}
{($_ -ge 0) -and ($_ -lt 255)} { # normal data (not sure if it's worth returning the 0s... haven't seen anything to suggest that they're special though, as -1 is the eof.
[byte]$byte
Write-Debug "found $byte"
break
}
default {
throw "Received value $_ when expecting a byte (0-255)"
}
}
}
})
$telnet | Add-Member -MemberType 'ScriptMethod' -Name 'GetOutput' -Value ({
[byte[]]$bytes = $this.GetBytes()
if (($null -ne $bytes) -and ($bytes.Length -gt 0)) {
Write-Verbose "raw output is $(($bytes | %{"$_"}) -join ', ')"
$this.Encoding.GetString($bytes)
} else {
write-verbose 'no output this time'
}
})
$telnet | Add-Member -MemberType 'ScriptMethod' -Name 'ReceiveThenSendCommands' -Value ({
Param([string[]]$Commands)
foreach ($commandText in $commands) {
$this.GetOutput()
$this.SendCommand($commandText)
}
$this.GetOutput()
})
if ($telnet.Connected) {
$telnet
} else {
throw 'Failed to connect'
}
} catch {
Remove-TelnetClient -TelnetClient $telnet
}
}
Function Remove-TelnetClient {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)]
[AllowNull()]
[PSObject]$TelnetClient
)
if ($null -ne $TelnetClient) {
if ($TelnetClient.Connected) {
$TelnetClient.GetStream().Close()
$TelnetClient.Close()
}
if($TelnetClient.Dispose) {
$TelnetClient.Dispose()
}
}
}
以下是在普通脚本会话中如何使用它的示例:
# Example Usage
$telnet = New-TelnetClient -ComputerName 'TelnetServerNameFqdnOrIp'
try {
$telnet.ReceiveThenSendCommands(@(
'myTelnetUsername'
'myPlaintextTelnetPassword'
'DIR' #or whatever command I want to run
)) | Format-List # show the output in a readable format, including when it contains new line characters
} finally {
Remove-TelnetClient $telnet
}
但是,如果您想以交互方式运行它,只需在要将命令推送到服务器时调用SendCommand,然后调用GetOutput即可查看结果。例如您可以一次将每一行打到下面。
$telnet = New-TelnetClient -ComputerName 'TelnetServerNameFqdnOrIp'
$telnet.GetOutput() # will probably display a welcome message & logon prompt
$telnet.SendCommand('myUsername') # send your username
$telnet.GetOutput() # will probably echo back your username then prompt for a password
$telnet.SendCommand('myPassword') # send your password
$telnet.GetOutput() # unlikely to output anything for a valid password; will give an error for an invalid one
$telnet.SendCommand('DIR') # send whatever commands you want to run
$telnet.GetOutput() # get the output of those commands
Remove-TelnetClient $telnet # once you're done, cleanly closes down the client