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 шт):

Автор решения: Dyakov Alexander

Да, можно, как раз при помощи функции с параметрами:

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

→ Ссылка
Автор решения: Vacheslav Great

На текущий момент, вот такая рабочая конструкция получилась.

#Тело запросов 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")
→ Ссылка