PowerShell Invoke-WebRequest как настроить выбор варианта запроса в одном сценарии
Предыстория. Есть удаленные устройства, которые в случае необходимости нужно резервировать. Если делать это вручную, пройдя авторизацию, дождавшись полной загрузки GUI - может потребоваться минут 5 - 10. Написал запрос CURL на авторизацию - работает. Дальше не стал возиться с командной строкой, ибо там изворачиваться нужно, нет функционала нужного. Переписал на PowerShell.
Шаг 1. Запрос авторизации
$ip = Read-Host "Введите ip-адрес"
$xmlauth = "<request method=""login"" request_id=""1"" username=""name"" password=""pass""/>"
$access = Invoke-WebRequest -Uri ("http://"+$ip+":4000/xap2") `
-Method Post `
-ContentType "text/xml" `
-Body $xmlauth
$sessionid = ([xml]$access.Content).response.session_id
Write-Host $access #пример вывода после успешной авторизации
<response username="name" session_id="123456789" request_id="1" access_lvl="2">
<status status="0" status_text="OK"/>
</response>
Write-Host $sessionid #этот id подставляется во все последующие запросы
123456789
Шаг 2. Запрос на изменение параметров
$xml3in = @"
<request method="set" request_id="2" session_id="$sessionid" return_events="false">
<data>
<ports>
<asi_input enable="false" _id="0"/>
<asi_input enable="true" _id="2"/>
<_all _id="8">
<plprep main_globid="2"/>
</_all>
</ports>
</data>
</request>
"@
$request3in = Invoke-WebRequest -Uri ("http://"+$ip+":4000/xap2") `
-Method Post `
-ContentType "text/xml" `
-Body $xml3in
$status = ([xml]$request3in.Content).response.status.status_text
Write-Host $request3in #Пример вывода после успешного выполнения
<response request_id="2">
<status status="0" status_text="OK"/>
</response>
Write-Host $status #Пример вывода текста статуса, можно и по номеру сделать.
OK
if ( $status -like 'ok' ) {
Write-Host "УСТРОЙСТВО ПЕРЕКЛЮЧЕНО КУДА НАДО ($status)" -foregroundcolor Green
}
else {
Write-Host "ЧТО-ТО ПОШЛО НЕ ТАК ($status)" -foregroundcolor Red
}
Шаг 3. Запрос на изменение параметров (возврат в исходное состояние) Отличие только в теле запроса.
$xml1in = @"
<request method="set" request_id="3" session_id="$sessionid" return_events="false">
<data>
<ports>
<asi_input enable="true" _id="0"/>
<asi_input enable="false" _id="2"/>
<_all _id="8">
<plprep main_globid="0"/>
</_all>
</ports>
</data>
</request>
"@
Вопрос. Как реализовать выбор варианта действия в одном сценарии? Можно ли это сделать через функцию и подставлять только нужные параметры, при выборе варианта?
Обновление 28.10.24 Добавил меню. Теперь функцию нужно внедрить в варианты выбора меню.
function askchoice {
Clear-Host
Write-Host "░░░░ МЕНЮ РЕЗЕРВИРОВАНИЯ ░░░░" -backgroundcolor DarkBlue
Write-Host "░ ░" -backgroundcolor DarkBlue
Write-Host "░ 1. ВВЕДИТЕ IP-АДРЕС ░" -backgroundcolor DarkBlue
Write-Host "░ 2. ПЕРЕВЕСТИ НА 3in ░" -backgroundcolor DarkBlue
Write-Host "░ 3. ВЕРНУТЬ НА 1in ░" -backgroundcolor DarkBlue
Write-Host "░ Q. ВЫХОД ░" -backgroundcolor DarkBlue
Write-Host "░ ░" -backgroundcolor DarkBlue
Write-Host "░░░░░░░░░░░░░░░░░░░░░░░░░░░░░" -backgroundcolor DarkBlue
Write-Host "ТЕКУЩИЙ IP-АДРЕС СТАНЦИИ: $ip" -ForegroundColor Green
}
Do {
askchoice
$choice = Read-Host "ВЫБЕРИТЕ НОМЕР [1-3] ЛИБО Q ДЛЯ ВЫХОДА"
switch ($choice)
{
1 {
$ban = @("10.10.10.10", "10.10.10.11", "10.10.10.12", "10.10.10.13")
do {
$Global:ip = Read-Host "ВВЕДИТЕ IP-АДРЕС"
if ($ban -contains $ip) {
Write-Host "ДОСТУП ЗАПРЕЩЕН" -ForegroundColor Red
}
}
While ($ban -contains $ip)
}
2 {
Write-Host "ВЫПОЛНЯЕТСЯ ПРОЦЕСС РЕЗЕРВИРОВАНИЯ" -ForegroundColor Cyan
#строка кода
ping $ip; pause
}
3 {
Write-Host "ВЫПОЛНЯЕТСЯ ПРОЦЕСС ВОЗВРАТА НА ШТАТНУЮ СХЕМУ" -ForegroundColor Cyan
#строка кода
tracert $ip; pause
}
q {
exit
}
default {
Write-Host "НЕТ НОМЕРА В СПИСКЕ, ПОВТОРИТЕ ВЫБОР" -ForegroundColor Yellow; pause
}
}
}
while ($choice -ne "q")
Ответы (2 шт):
Да, можно, как раз при помощи функции с параметрами:
function Set-Options {
[CmdletBinding()]
Param(
[Switch] $SetDefault
)
Begin {
$ip = Read-Host "Введите ip-адрес"
$xmlauth = "<request method=""login"" request_id=""1"" username=""name"" password=""pass""/>"
$access = Invoke-WebRequest -Uri ("http://" + $ip + ":4000/xap2") `
-Method Post `
-ContentType "text/xml" `
-Body $xmlauth
$sessionid = ([xml]$access.Content).response.session_id
Write-Host $access #пример вывода после успешной авторизации
<response username="name" session_id="123456789" request_id="1" access_lvl="2">
<status status="0" status_text="OK"/>
</response>
Write-Host $sessionid #этот id подставляется во все последующие запросы
123456789
}
process {
$xmlin = @"
<request method="set" request_id="2" session_id="$sessionid" return_events="false">
<data>
<ports>
<asi_input enable="false" _id="0"/>
<asi_input enable="true" _id="2"/>
<_all _id="8">
<plprep main_globid="2"/>
</_all>
</ports>
</data>
</request>
"@
if ($SetDefault) {
$xmlin = @"
<request method="set" request_id="3" session_id="$sessionid" return_events="false">
<data>
<ports>
<asi_input enable="true" _id="0"/>
<asi_input enable="false" _id="2"/>
<_all _id="8">
<plprep main_globid="0"/>
</_all>
</ports>
</data>
</request>
"@
}
$request3in = Invoke-WebRequest -Uri ("http://" + $ip + ":4000/xap2") `
-Method Post `
-ContentType "text/xml" `
-Body $xmlin
$status = ([xml]$request3in.Content).response.status.status_text
Write-Host $request3in #Пример вывода после успешного выполнения
<response request_id="2">
<status status="0" status_text="OK"/>
</response>
Write-Host $status #Пример вывода текста статуса, можно и по номеру сделать.
OK
if ( $status -like 'ok' ) {
Write-Host "УСТРОЙСТВО ПЕРЕКЛЮЧЕНО КУДА НАДО ($status)" -foregroundcolor Green
}
else {
Write-Host "ЧТО-ТО ПОШЛО НЕ ТАК ($status)" -foregroundcolor Red
}
}
end{}
}
применять соответственно
set-options чтобы изменить настройки
set-options -SetDefault чтобы вернуть настройки
подробнее про функции можно почитать в документации Microsoft
На текущий момент, вот такая рабочая конструкция получилась.
#Тело запросов Body
$auth = [xml]"<request method=""login"" request_id=""1"" username=""name"" password=""pass""/>"
$backup = [xml]@"
<request method="set" request_id="2" session_id="" return_events="false">
<data>
<ports>
<asi_input enable="false" _id="0"/>
<asi_input enable="true" _id="2"/>
<_all _id="8">
<plprep main_globid="2"/>
</_all>
</ports>
</data>
</request>
"@
$primary = [xml]@"
<request method="set" request_id="3" session_id="" return_events="false">
<data>
<ports>
<asi_input enable="true" _id="0"/>
<asi_input enable="false" _id="2"/>
<_all _id="8">
<plprep main_globid="0"/>
</_all>
</ports>
</data>
</request>
"@
$check = [xml]@"
<request method="get" request_id="4" session_id="">
<data>
<ports>
<_all _id="8">
<plprep _select="main_globid"/>
</_all>
</ports>
</data>
</request>
"@
#POST запросы по URL + Body
function Select-Replacer
{
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$url,
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[xml]$body
)
$ErrorActionPreference = "STOP"
try
{
$response = Invoke-WebRequest -Uri $url -Method Post -ContentType "text/xml" -Body $body
Write-Host ("КОД ОТВЕТА - "+$response.StatusCode) -Foregroundcolor Green
Write-Host ("СОЕДИНЕНИЕ - "+$response.StatusDescription) -Foregroundcolor Green
$sessionid = ([xml] $response.Content).response.session_id
#Write-Host ("session_id в функции - "+$sessionid)
$status = ([xml]$response.Content).response.status.status_text
#Write-Host ("статус выполнения в функции - "+$status)
$asiout = ([xml]$response.Content).response.data.ports.asi_output.plprep.main_globid
#Write-Host ("id источника в функции - "+$asiout)
}
catch
{
#$e = $Error[0].Exception
$e = $_.Exception
Write-Host ("ОШИБКА - "+$e.Message) -Foregroundcolor Red
$ecode = [int]$e.Response.StatusCode
if ($ecode -eq 404)
{
Write-Host ("КОД ОТВЕТА - "+$e.Response.StatusCode.value__) -Foregroundcolor Red
Write-Host ("НЕТ СОЕДИНЕНИЯ - "+$e.Response.StatusDescription) -Foregroundcolor Red
}
else
{
Write-Host ("КОД ОТВЕТА - "+$e.Response.StatusCode.value__) -ForegroundColor Yellow
Write-Host ("ЧТО-ТО ПОШЛО НЕ ТАК - "+$e.Response.StatusDescription) -ForegroundColor Yellow
}
}
$ErrorActionPreference = "CONTINUE"
Return @{"сессия"=$sessionid; "статус"=$status; "источник"=$asiout;}
}
#Меню с очисткой консоли
function Ask-Choice
{
Clear-Host
Write-Host "░░░░ МЕНЮ РЕЗЕРВИРОВАНИЯ ░░░░" -Backgroundcolor DarkBlue
Write-Host "░ ░" -Backgroundcolor DarkBlue
Write-Host "░ 1. ВВЕСТИ IP-АДРЕС ░" -Backgroundcolor DarkBlue
Write-Host "░ 2. ПРОЙТИ РЕГИСТРАЦИЮ ░" -Backgroundcolor DarkBlue
Write-Host "░ 3. ПЕРЕВЕСТИ НА 3in ░" -Backgroundcolor DarkBlue
Write-Host "░ 4. ВЕРНУТЬ НА 1in ░" -Backgroundcolor DarkBlue
Write-Host "░ 5. ПРОВЕРИТЬ СХЕМУ ░" -Backgroundcolor DarkBlue
Write-Host "░ Q. ВЫХОД ░" -Backgroundcolor DarkBlue
Write-Host "░ ░" -Backgroundcolor DarkBlue
Write-Host "░░░░░░░░░░░░░░░░░░░░░░░░░░░░░" -Backgroundcolor DarkBlue
}
#Выбор варианта и вызов функции
Do
{
Ask-Choice
Write-Host "ТЕКУЩИЙ IP-АДРЕС СТАНЦИИ: $ip" -ForegroundColor Magenta
$choice = Read-Host "ВЫБЕРИТЕ НОМЕР [1-5] ЛИБО Q ДЛЯ ВЫХОДА"
switch ($choice)
{
1
{
$ban = @("10.10.10.10", "10.10.10.11", "10.10.10.13", "10.10.10.14", "10.10.10.15")
do
{
$ip = Read-Host "ВВЕДИТЕ IP-АДРЕС"
$ipregex = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
$url = "http://{0}:8049/xap2" -f $ip
#$url = ("http://"+$ip+":8049/xap2")
if ($ban -contains $ip)
{
Write-Host "ПРЕДУПРЕЖДЕНИЕ: ДОСТУП ЗАПРЕЩЕН" -ForegroundColor Red
}
elseif ($ip -notmatch $ipregex)
{
Write-Host "ПРЕДУПРЕЖДЕНИЕ: НЕКОРРЕКТНЫЙ IP ИЛИ ПУСТОЕ ЗНАЧЕНИЕ" -ForegroundColor Yellow
}
}
While (($ban -contains $ip) -or ($ip -notmatch $ipregex))
}
2
{
Write-Host "ВЫПОЛНЯЕТСЯ ПРОЦЕСС РЕГИСТРАЦИИ" -ForegroundColor Cyan
$result = Select-Replacer $url $auth
$XMLbody = $backup, $primary, $check
Foreach ($item in (Select-XML -Xml $XMLbody -XPath "//request"))
{
$item.node.session_id = "$($result.сессия)"
}
#$XMLbody.request | ForEach-Object {
#Write-Output ("текущее значение session_id в xml: "+$_.session_id)
#}
Write-Host ("Номер session_id - "+$($result.сессия))
Write-Host ("Статус выполнения - "+$($result.статус))
if ($($result.статус) -like 'ok')
{
Write-Host "УСПЕШНО" -ForegroundColor Green; pause
}
else
{
Write-Host "ОШИБКА" -Foregroundcolor Red -Backgroundcolor White; pause
}
Clear-Variable -name result.статус
}
3
{
Write-Host "ВЫПОЛНЯЕТСЯ ПРОЦЕСС РЕЗЕРВИРОВАНИЯ" -foregroundColor Cyan
$result = Select-Replacer $url $backup
Write-Host ("Статус выполнения - "+$($result.статус))
if ($($result.статус) -like 'ok')
{
Write-Host "УСПЕШНО" -ForegroundColor Green; pause
}
elseif ($($result.статус) -like "Unknown session ID")
{
Write-Host "НЕОБХОДИМО ЗАРЕГИСТРИРОВАТЬСЯ" -Foregroundcolor Red -Backgroundcolor White; pause
}
else
{
Write-Host "ОШИБКА" -Foregroundcolor Red -Backgroundcolor White; pause
}
Clear-Variable -name result.статус
}
4
{
Write-Host "ВЫПОЛНЯЕТСЯ ПРОЦЕСС ВОЗВРАТА НА ШТАТНУЮ СХЕМУ" -foregroundColor Cyan
$result = Select-Replacer $url $primary
Write-Host ("Статус выполнения - "+$($result.статус))
if ($($result.статус) -like 'ok')
{
Write-Host "УСПЕШНО" -ForegroundColor Green; pause
}
elseif ($($result.статус) -like "Unknown session ID")
{
Write-Host "НЕОБХОДИМО ЗАРЕГИСТРИРОВАТЬСЯ" -Foregroundcolor Red -Backgroundcolor White; pause
}
else
{
Write-Host "ОШИБКА" -Foregroundcolor Red -Backgroundcolor White; pause
}
Clear-Variable -name result.статус
}
5
{
Write-Host "ВЫПОЛНЯЕТСЯ ПРОВЕРКА СХЕМЫ" -ForegroundColor Cyan
$result = Select-Replacer $url $check
Write-Host ("Статус выполнения - "+$($result.статус))
Write-Host ("Это id источника - "+$($result.источник))
if (($($result.статус) -like 'ok') -and ($($result.источник) -eq '0'))
{
Write-Host "ШТАТНЫЙ ИСТОЧНИК 1.in" -Foregroundcolor Yellow; pause
}
elseif (($($result.статус) -like 'ok') -and ($($result.источник) -eq '2'))
{
Write-Host "РЕЗЕРВНЫЙ ИСТОЧНИК 3.in" -Foregroundcolor Green; pause
}
elseif ($($result.статус) -like "Unknown session ID")
{
Write-Host "НЕОБХОДИМО ЗАРЕГИСТРИРОВАТЬСЯ" -Foregroundcolor Red -Backgroundcolor White; pause
}
else
{
Write-Host "ОШИБКА" -Foregroundcolor Red -Backgroundcolor White; pause
}
Clear-Variable -name result.статус
}
q
{
exit
}
default
{
Write-Host "НЕТ НОМЕРА В СПИСКЕ, ПОВТОРИТЕ ВЫБОР" -ForegroundColor Yellow; pause
}
}
}
while ($choice -ne "q")