Задать вопрос
@Habarovchanin
Свободный художник

Проверка доступности URI‐адреса средствами powershell на подобие curl?

Задача.
Проверить корректность и доступность URL-адреса, больше ничего не требуется.. Команда вызывается из другого программного файла (скрипт VimL).
Используя программу "curl" это можно сделать такой командой:
curl --silent --fail --output nul --head <URL>
после чего считывается код возврата "curl" и подставляется в текстовый буфер.
Покурив Интернет и документацию, набросал команду, которая выполняет что‐то похожее:
powershell -command "%{[Net.ServicePointManager]::SecurityProtocol = 'Tls12, Tls11, Tls, Ssl3'} ; Invoke-Webrequest -UseDefaultCredentials -disablekeepalive -maximumredirection 2 -method head -UseBasicParsing -uri <URL>"

Но есть несколько сложностей:
1. Она пишет в консоль. Должна быть полностью «немой», т. е. как ключ "--silent" в программе "curl".
2. Получить от неё код возврата, типа такого или что‐то похожее, как возвращает "curl". Пробовал разные варианты.
И как ранее подсказывал MaxKozlov с exit
powershell -command "%{[Net.ServicePointManager]::SecurityProtocol = 'Tls12, Tls11, Tls, Ssl3'} ; exit Invoke-Webrequest -UseDefaultCredentials -disablekeepalive -maximumredirection 2 -method head -UseBasicParsing -uri <URL>"

И пытался считать "$LastExitCode", и прочитать переменную "$?", но результат удручающий.
Как я понял, с этим в "PowerShell" всё плохо.
Есть ли какие‐нибудь решения? Нужно просто получить результат от команды — корректный URL или нет, доступен хост или нет.
  • Вопрос задан
  • 1052 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
в .net как ни странно http 304 и 40x и 50x будут Exception которые
ErrorAction SilentlyContinue не спрячет при выполнение invoke-webrequest или invoke-restmethod И приходится

try {
    $ProgressPreference = 'Stop'
     $response  = Invoke-WebRequest -uri $url   
    $ProgressPreference = 'Continue'
  } catch [Exception]{
    # 1 NameResolutionFailure  
    # 15 ProxyNameResolutionFailure	
    # 2 ConnectFailure
    # 3 ReceiveFailure
    # 7 ProtocolError
    # 9 TrustFailure
    if ( $exception.Status -ne 7 ) {
      $statuscode =  $exception.Status

    } else { 
      $statuscode = $exception_statuscode.value__
    }
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@NortheR73
системный инженер
Она пишет в консоль. Должна быть полностью «немой», т. е. как ключ "--silent" в программе "curl".

$WebObjVariable = Invoke-WebRequest -Uri <URL> # вывод в переменную
$WebObjVariable.StatusCode
$WebObjVariable.StatusDescription

Получить от неё код возврата, типа такого или что‐то похожее, как возвращает "curl". Пробовал разные варианты.

Разве (Invoke-WebRequest -Uri <URL>).StatusCode возвращает не то, что надо?
Ответ написан
@FluffyBeaver
А для тех, кто считает, что VimL - это International Vocabulary of Legal Metrology (VIML), можете пояснить, что именно нужно скормить тому самому "другому программному файлу"?
Мне кажется, из Powershell (в отличие от curl) можно вернуть всё (хоть доступность URL с поправкой на температуру воздуха) , что угодно, лишь бы задача была понятна.
Пока получается "надо сделать как curl".
Но как только появится описание того, что возвращает (и куда возвращает) curl (именно что и куда возвращает, а не какая команда была использована), то тут сразу появятся люди, которые скажут, как это сделать в Powershell.
Ответ написан
@Habarovchanin Автор вопроса
Свободный художник
Итак, решение, приемлемое для этой конкретной задачи, было найдено!
Огромнейшее спасибо всем, кот подсказывал направление поиска решения! Отдельная благодарность сергей кузьмин (если бы я увидел его ответ раньше...)

А решение, как оказалось, достаточно простое:
powershell -nologo -noprofile "%{[Net.ServicePointManager]::SecurityProtocol = 'Tls12, Tls11, Tls, Ssl3'} ;(Invoke-WebRequest -UseBasicParsing -Uri <ULR>).StatusCode;exit [int]$Error[0].Exception.Status"


Результат считывается из значение свойства "Status" члена "Exception" в переменной $Error. Это помогает обработать ситуации типа такой
Invoke-WebRequest : Невозможно разрешить удаленное имя: 'cle.linux.org.tw'
строка:1 знак:77
+ %{[Net.ServicePointManager]::SecurityProtocol = 'Tls12, Tls11, Tls, Ssl3'} ;Invo ...
+ ~
~~~
+ CategoryInfo: InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Когда до ответа сервера ("Response") дело даже не доходило, и получали "0" код возврата, хотя ошибка была. Значить искать причину надо было где‐то раньше.
Посмотрев через $Error[0].Exception | Get-Member видим, что в "Exception" есть такое свойство как
Status           Property   System.Net.WebExceptionStatus Status {get;}
, которое и даёт ответ, было соединение или нет.

Ну, вот, как‐то так. Почти полный аналог "curl".

Если надо получить строковое описания статуса соединения, то необходимо убрать [int] перед $Error[0].Exception.Status. Ещё обратите внимание, что считывается последний код Exception текущей сессии.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы