-
Notifications
You must be signed in to change notification settings - Fork 0
/
renameIAP.ps1
281 lines (229 loc) · 7.64 KB
/
renameIAP.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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
Import-Module PowerArubaIAP
Import-Module Posh-SSH
$global:SSHSession = $null
$global:SSHStream = $null
$global:credentials = $null
$global:numberdigits = $null
function get-aps() {
$apsCmd = Get-ArubaIAPShowCmd "show aps"
$apsStr = $apsCmd."Command output"
# split the output into lines
$apsStrArr = $apsStr -split "`n"
$apList = @()
# loop through lines
foreach ($ap in $apsStrArr) {
# regex match for ap name and ip
$info = $ap | Select-String -Pattern '(.+?)\s*((?:[0-9]{1,3}\.){3}[0-9]{1,3}).*([A-Z0-9]{10})'
# if no match, skip
if (!$info.Matches.Groups) { continue }
# get the name and ip
$apName = $info.Matches.Groups[1].Value
$apIp = $info.Matches.Groups[2].Value
$apSn = $info.Matches.Groups[3].Value
# write ap ip and name to list
$apList += [PSCustomObject]@{
Name = $apName
Ip = $apIp
Sn = $apSn
}
}
return $apList | Sort-Object -Property Sn
}
function send-commands {
Param(
[Parameter(mandatory = $true)]$command,
[Parameter(mandatory = $false)]$silent = $false
)
# loop through 3 times and try to execute the command, if it fails, try again
$tries = 3
for ($i = 0; $i -lt $tries - 1; $i++) {
try {
if (!$silent) {
Write-Host "sending command $command ($($i + 1)/$tries)"
}
$global:SSHStream.read() | out-null
Invoke-SSHStreamShellCommand -Command $command -ShellStream $global:SSHStream
$result_stream = $global:SSHStream.read()
return $result_stream
}
catch {
# if this is the last try, throw error
if ($i -eq $tries - 1) {
throw "Could not execute ssh command ""$command"" on ap"
}
continue
}
}
}
function get-ap-name {
Param(
[Parameter(mandatory = $true)]$prefix,
[Parameter(mandatory = $true)]$number
)
$apnumberStr = $number.ToString()
# add leading zeros if numberdigits is set
if ($numberdigits -gt 1) {
$apnumberStr = $number.ToString("0" * $numberdigits)
}
$apName = $prefix + $apnumberStr
return $apName
}
function write-ap-info {
Param(
[Parameter(mandatory = $true)]$ap,
[Parameter(mandatory = $true)]$newApName
)
Write-Host ""
Write-Host ("-" * 40)
Write-Host "new name: $newApName" -ForegroundColor Green
Write-Host ""
Write-Host "old name: $($ap.Name)" -ForegroundColor Red
Write-Host "IP: $($ap.Ip), SN: $($ap.Sn)" -ForegroundColor Red
Write-Host ("-" * 40)
Write-Host ""
}
function main() {
# read settings from settings.json
try {
$settings = Get-Content -Raw -Path settings.json | ConvertFrom-Json
$numberdigits = $settings.numberdigits
$nameprefix = $settings.nameprefix
$apnumber = $settings.firstnumber
# throw error if numberdigits is not set or not a number between 1 and 4
if (!$numberdigits -or $numberdigits -lt 1 -or $numberdigits -gt 4) {
throw "settings.numberdigits must be set to a number between 1 and 4"
}
# throw error if nameprefix is not set or not a string or an empty string
if (!$nameprefix -or $nameprefix -eq "" -or $nameprefix -isnot [string]) {
throw "settings.nameprefix must be set to a string"
}
# throw error if firstnumber is not set or not a number between 1 and 9999
if (!$apnumber -or $apnumber -lt 1 -or $apnumber -gt 9999) {
throw "settings.firstnumber must be set to a number between 1 and 9999"
}
}
catch {
Write-Host "Could not read settings.json, aborting"
Write-Host $_.Exception.Message
return
}
$secpassword = ConvertTo-SecureString $settings.password -AsPlainText -Force
$credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $settings.username, $secpassword
Connect-ArubaIAP $settings.ip -Username $settings.username -Credentials $credentials -SkipCertificateCheck | out-null
# get aps
$aps = get-aps
# print aps to console
$aps | Format-Table -AutoSize
# throw error if no aps found
if ($aps.Count -eq 0) {
throw "No APs found"
}
Write-Host "Found $($aps.Count) active APs" -ForegroundColor Green
$skiptoapnumber = 1
# ask the user if he wants to skip some already renamed aps
Write-Host "Skip some already renamed APs? (y/n) [n]" -ForegroundColor Yellow
$skip = Read-Host
# if he wants to skip some aps, ask him for the first ap number to rename
if ($skip -eq "y") {
Write-Host ""
Write-Host "First AP number to rename?" -ForegroundColor Yellow
$skiptoapnumber = Read-Host
try {
$skiptoapnumber = [int]$skiptoapnumber
}
catch {
throw "Invalid number (not an integer)"
}
if ($skiptoapnumber -lt 1 -or $skiptoapnumber -gt $aps.Count) {
throw "Invalid number (out of range)"
}
Write-Host ""
Write-Host "Skipping to AP number $skiptoapnumber of $($aps.Count)" -ForegroundColor Green
}
else {
$skiptoapnumber = $apnumber
Write-Host ""
}
$firstapname = get-ap-name -prefix $nameprefix -number $skiptoapnumber
Write-Host "First AP name will be ${firstapname}" -ForegroundColor Green
# ask the user if he wants to continue
Write-Host "Continue? (y/n)" -ForegroundColor Yellow
$continue = Read-Host
if ($continue -ne "y") {
Write-Host "Aborting" -ForegroundColor Red
return
}
foreach ($ap in $aps) {
if ($apnumber -lt $skiptoapnumber) {
$apnumber++
continue
}
$apName = get-ap-name -prefix $nameprefix -number $apnumber
write-ap-info $ap $apName
# try to establish ssh connection to ap
# if it fails for 3 tries, skip the ap
$tries = 3
for ($i = 0; $i -lt $tries - 1; $i++) {
try {
Write-Host "establishing ssh connection... ($($i + 1)/$tries)"
$global:SSHSession = New-SSHSession -ComputerName $ap.Ip -port 22 -Credential $credentials -AcceptKey
$global:SSHStream = New-SSHShellStream -SSHSession $global:SSHSession
$global:SSHStream.read() | out-null
break
}
catch {
# if this is the last try, write error and skip
if ($i -eq $tries - 1) {
Write-Host "Could not connect to AP, skipping"
}
continue
}
}
# try to execute a dummy show command to see if the ssh connection is ready
# if not, wait a second and try again
# if it fails for 8 tries, throw error
try {
$tries = 8
for ($i = 0; $i -lt $tries - 1; $i++) {
$result = send-commands "show time-range" -silent $true
if ($null -eq $result -or $result -eq "") {
Write-Host "ssh connection not yet ready, waiting... ($($i + 1)/$tries)"
# if this is the last try, throw error
if ($i -eq $tries - 1) {
throw "Could not connect to AP"
}
Start-Sleep -Seconds 1
}
else {
break
}
}
}
catch {
Write-Host "Could not execute ssh commands on ap, skipping"
continue
}
# let the ap leds blink to indicate which ap is being renamed
send-commands "ap-leds blink" | out-null
Write-Host "AP LEDs set to blink"
# rename the ap
Set-ArubaIAPHostname -hostname $apName -iap_ip_addr $ap.Ip | out-null
Write-Host "AP renamed to $apName"
# wait for user to continue
Write-Host "Press enter to continue" -ForegroundColor Yellow
Read-Host | out-null
# set ap leds back to normal mode
send-commands "ap-leds normal" | out-null
Write-Host "AP LEDs set to normal"
Start-Sleep -Seconds 1
# close ssh session to ap
Remove-SSHSession -SSHSession $global:SSHSession | out-null
# increment ap number
$apnumber++
}
# disconnect from controller
Disconnect-ArubaIAP -Confirm:$false
Write-Host ""
Write-Host "Done" -ForegroundColor Green
}
main