Как загрузить защищенный файл с помощью PowerShell?

Я пытаюсь загрузить файл с помощью PowerShell 3.0 с моего сервера сборки TeamCity. Я настроил TeamCity для использования проверки подлинности NTLM, но не могу загрузить файл напрямую и перенаправить для входа в систему.

Я пытаюсь использовать следующий код PowerShell для загрузки файла.

$artifacts = "http://teamcity/repository/download/bt1/.lastSuccessful/%7Bbuild.number%7D.zip"
Invoke-WebRequest -Uri $artifacts -UseDefaultCredentials

Мой ответ на запрос - перенаправление на страницу входа.


person Aaron Weiker    schedule 09.01.2013    source источник


Ответы (2)


Вот код для окончательного решения.


$artifacts = "http://teamcity/repository/download/bt1/.lastSuccessful/%7Bbuild.number%7D.zip"
$login = "http://teamcity/ntlmLogin.html"
$dest = "Artifacts.zip"

$TeamCitySession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
Invoke-WebRequest -Uri $login -WebSession $TeamCitySession -UseDefaultCredentials -UseBasicParsing
Invoke-WebRequest -Uri $artifacts -WebSession $TeamCitySession -UseBasicParsing -OutFile $dest

Чтобы понять, что происходит, мне нужно было использовать Fiddler, чтобы отследить, как выглядит успешный запрос, а также отследить, что происходит в PowerShell. Для этого мне пришлось заставить мой запрос PowerShell использовать его. Ниже показано, как я включил трассировку Fiddler из PowerShell.

Invoke-WebRequest -Uri $artifacts -UseDefaultCredentials -Proxy http://localhost:8888/

Добавив к команде аргумент -Proxy, он указал команде использовать Fiddler в качестве прокси-сервера.

Отсюда я увидел, что TeamCity перенаправляет меня на страницу входа. Поскольку у меня включена аутентификация NTLM, есть специальная страница, на которую вы переходите, чтобы войти в систему. Итак, что я хотел сделать отсюда, так это посетить эту страницу входа, а затем загрузить файл с использованием файлов cookie, которые я получаю, поскольку TeamCity использует файл cookie для отслеживания статуса аутентификации.

Также оказывается, что командлеты Invoke-WebRequest также позволяют подключать их с помощью веб-сеанса. Это можно сделать двумя способами: с помощью параметра -WebSession или параметра -SessionVariable. После некоторых проб и ошибок выясняется, что если вы используете параметр -SessionVariable, он будет перезаписывать переменную сеанса после каждого запроса, так что на самом деле он не будет делиться состоянием. Ясно, что это не то поведение, которое я ищу. Вместо этого мне пришлось использовать параметр -WebSession, после чего я мог объединить вход в систему и загрузку файла. Как только я это сделал, все начало работать.

person Aaron Weiker    schedule 09.01.2013
comment
Если я правильно понял, вы можете исправить опечатку в первой строке Invoke-WebRequest на -Uri $login. :) - person Frode F.; 09.01.2013
comment
Спасибо @Греймер. Это снова была одна из тех проблем с копированием/вставкой. - person Aaron Weiker; 09.01.2013

Причина, по которой использование -SessionVariable отключало (изменяло) состояние, заключается в том, что -SessionVariable предназначен для вывода результатов этого конкретного веб-сеанса Invoke-WebReqeust в качестве переменной, которая будет использоваться в дальнейшем.

Если мы посмотрим на Get-Help для этого конкретного параметра:

PS C:\windows\system32> get-help Invoke-WebRequest -Parameter SessionVariable

-SessionVariable <String>
    Creates a web request session and saves it in the value of the specified variable. Enter a variable name without the dollar sign ($) symbol.

When you specify a session variable, Invoke-WebRequest creates a web request session object and assigns it to a variable with the specified name in your
Windows PowerShell session. You can use the variable in your session as soon as the command completes.

Unlike a remote session, the web request session is not a persistent connection. It is an object that contains information about the connection and the
request, including cookies, credentials, the maximum redirection value, and the user agent string. You can use it to share state and data among web
requests.

To use the web request session in subsequent web requests, specify the session variable in the value of the WebSession parameter. Windows PowerShell uses
the data in the web request session object when establishing the new connection. To override a value in the web request session, use a cmdlet parameter,
such as UserAgent or Credential. Parameter values take precedence over values in the web request session.

You cannot use the SessionVariable and WebSession parameters in the same command.

Required?                    false
Position?                    named
Default value
Accept pipeline input?       false
Accept wildcard characters?  false

Это можно рассматривать как случай несколько запутанного имени переменной. Спасибо, что разместили здесь готовый код!

person FoxDeploy    schedule 17.12.2014