-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAutomate.ps1
166 lines (156 loc) · 7.06 KB
/
Automate.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
function Test-SshSession {
[cmdletbinding()]
param($loop_level = 0)
write-debug "$($MyInvocation.MyCommand)[$($loop_level)]"
if ($loop_level -gt 1) {
throw "$($MyInvocation.MyCommand)[$($loop_level)]: Something is wrong here. We are already at loop level $($loop_level)."
}
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: Testing for session variable."
if (!(Test-Path variable:\session)) {
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: No SSH session found. Creating a new one. Loop level: $($loop_level)"
New-SshSession # This will trigger the request for a server ip, as it's a mandatory parameter on the new-sshsession function.
Test-SshSession -loop_level ($loop_level + 1)
} else {
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: Session variable exists."
}
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: Testing if session is closed."
if (!($session.isconnected)) {
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: SSH session is not connected"
return $false
# throw "Not connected to the device. Run Connect-SSHSession to connect and create a new shell."
} else {
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: session is open"
return $true
}
}
function Test-SshShell {
[cmdletbinding()]
param()
write-debug "$($MyInvocation.MyCommand)"
if (Test-SshSession) {
try {
[void]$shell.read()
$shell.WriteLine('')
write-verbose "$($MyInvocation.MyCommand): Sleeping for 1 seconds to give time for the shell to respond"
start-sleep -Seconds 1
$response = $shell.read()
$response -match ">|config"
write-verbose "$($MyInvocation.MyCommand): We have shell? $($response -match ">|config")."
} catch {
write-verbose "$($MyInvocation.MyCommand): We don't have yet a shell"
return $false
}
} else {
write-verbose "$($MyInvocation.MyCommand): The SSH session is not connected."
write-verbose "$($MyInvocation.MyCommand): Run connect-sshsession to connect."
return $false
}
}
function Test-SshConfigMode {
[cmdletbinding()]
param($shell = $global:shell,$loop_level = 0)
write-debug "$($MyInvocation.MyCommand)[$($loop_level)]"
if ($loop_level -gt 1) {
throw "$($MyInvocation.MyCommand)[$($loop_level)]: Something is worng here. We are already at loop level $($loop_level)."
}
if (Test-SshShell) {
[void]$shell.read()
$shell.writeline("")
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: Sleeping for 500 milliseconds to give the shell time to respond"
Start-Sleep -Milliseconds 500
$read = $shell.read()
return ($read -match 'config\(')
} else {
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: We are not even connected to any session."
#As we are testing config mode, we assume that the user wants to be connected to a session and we aren't connected. So we will take error correction action and connect to the session.
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: calling Connect-SSHSession"
Connect-SSHSession
# return $false
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: Now that we hopfully are connected to a session, we still need to find out if we have config mode or not."
Test-SshConfigMode -loop_level ($loop_level + 1)
}
}
function New-SshSession {
param(
[parameter(Mandatory)]$server,
[parameter(Mandatory)]$plaintext_password
)
write-debug "$($MyInvocation.MyCommand)"
remove-item env:\swlegacy -ErrorAction:SilentlyContinue
if ($server) {
$global:session = [Renci.SshNet.SshClient]::new($server,"admin",$plaintext_password)
$global:session.ConnectionInfo.Timeout = [timespan]::FromSeconds(5)
$global:session.ConnectionInfo.RetryAttempts = 5
}
# $session
}
function Connect-SSHSession {
[cmdletbinding()]
param(
$session = $session,
$lagecy = $env:swlegacy,
$loop_level = 0
)
write-debug "$($MyInvocation.MyCommand)[$($loop_level)]"
if ($loop_level -gt 1) {
throw "$($MyInvocation.MyCommand)[$($loop_level)]: Something is worng here. We are already at loop level $($loop_level)."
}
if (Test-SshSession) {
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)] We were still connected to the session. reconnecting..."
$session.disconnect()
}
try {
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: attempting to connect to $($session.ConnectionInfo.Host)"
$session.connect()
} catch {
Throw "Unable to connect to device."
}
$connectd = Test-SshSession
Write-Verbose "$($MyInvocation.MyCommand)[$($loop_level)]: $connected"
if ($connectd) {
$global:shell = $session.CreateShellStream("dumb", 0, 0, 0, 0, 3000)
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: Sleeping for 2 seconds to give time for the shell to respond"
start-sleep -Seconds 2
if ($global:shell.read() -notmatch "admin@.*>") {
$global:shell.Writeline($plaintext_password)
$global:shell.WriteLine("no cli pager session")
$global:shell.WriteLine("cli output-format plain-text")
$env:swlegacy = $true
} else {
$global:shell.WriteLine("no cli pager session")
$global:shell.WriteLine("cli format out plain-text")
$env:swlegacy = $false
}
if ($global:shell) {
write-output "$($MyInvocation.MyCommand)[$($loop_level)]: We have shell access"
}
} else {
Write-Verbose "$($MyInvocation.MyCommand)[$($loop_level)]: We are still not connected. Attempting again."
Connect-SSHSession -loop_level ($loop_level + 1)
}
}
function Enter-SshConfigmode {
[cmdletbinding()]
param($shell = $global:shell, $loop_level = 0)
write-debug "$($MyInvocation.MyCommand)[$($loop_level)]"
if ($loop_level -gt 1) {
throw "$($MyInvocation.MyCommand)[$($loop_level)]: Something is worng here. We are already at loop level $($loop_level)."
}
if (!(Test-SshConfigMode)) {
$shell.writeline("configure")
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: Sleeping for 1 second to give the shell time to respond"
start-sleep -Seconds 1
$output = $shell.read()
if ($output -match "Do you wish") {
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: preempted. Kicking out other admin"
$shell.writeline("yes")
}
}
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: confirming we are indead in config mode. Loop level: $($loop_level)"
if (!(Test-SshConfigMode)) {
write-verbose "$($MyInvocation.MyCommand)[$($loop_level)]: Nope, not yet in config mode. Attempting again."
Enter-SshConfigmode -loop_level ($loop_level + 1)
} else {
$true
}
}