PowerShell Invoke-WebRequest, как автоматически использовать оригинальное имя файла?
Как я могу использовать Invoke-WebRequest для загрузки файла, но автоматически сделать имя файла таким же, как если бы я загружался через браузер? Я не нашел способ сделать работу -OutFile
без указания имени файла вручную. Я в порядке с этим, используя несколько других строк кода.
Хорошее решение будет:
- Работайте, даже если имя файла отсутствует в URL-адресе запроса. Например, URL-адрес для загрузки средств удаленной отладки Visual Studio x64 составляет
http://go.microsoft.com/fwlink/?LinkId=393217
, но он загружает файл rtools_setup_x64.exe
.
- Не сохраняйте весь файл в памяти перед записью на диск, если только то, что Invoke-WebRequest уже делает даже с параметром -OutFile (?)
Спасибо!
Ответы
Ответ 1
В приведенном примере вам нужно будет получить перенаправленный URL-адрес, который включает в себя имя файла для загрузки. Вы можете использовать следующую функцию:
Function Get-RedirectedUrl {
Param (
[Parameter(Mandatory=$true)]
[String]$URL
)
$request = [System.Net.WebRequest]::Create($url)
$request.AllowAutoRedirect=$false
$response=$request.GetResponse()
If ($response.StatusCode -eq "Found")
{
$response.GetResponseHeader("Location")
}
}
Затем это вопрос разбора имени файла с конца ответного URL (GetFileName из System.IO.Path сделает это):
$FileName = [System.IO.Path]::GetFileName((Get-RedirectedUrl "http://go.microsoft.com/fwlink/?LinkId=393217"))
Это оставит $FileName = rtools_setup_x64.exe
, и вы сможете загрузить там файл.
Ответ 2
Благодаря Райану у меня есть полуиспользуемая функция:
Function Get-Url {
param ( [parameter(position=0)]$uri )
invoke-webrequest -uri "$uri" -outfile $(split-path -path "$uri" -leaf)
}
Графический файл и xml файл, который я смог загрузить. Когда я пытаюсь загрузить эту веб-страницу и открыть ее с помощью Edge, она будет работать время от времени.
Ответ 3
Попробуйте этот метод (может не всегда работать, потому что имя файла может отсутствовать в заголовке ответа)
- вызовите Invoke-WebRequest, чтобы получить результат. Затем вы можете проверить результат, чтобы посмотреть, что находится в заголовках.
- получить имя файла из заголовка ответа (это может быть в Headers.Location или в каком-то другом месте. Когда я выполняю свой запрос для URL, который я устранял, я обнаружил его в заголовках ["Content-Disposition"] и он выглядит как
inline; filename="zzzz.docx"
- Создайте новый файл на основе имени и запишите содержимое в этот файл
Вот код сампе:
$result = Invoke-WebRequest -Method GET -Uri $url -Headers $headers
$contentDisposition = $result.Headers.'Content-Disposition'
$fileName = $contentDisposition.Split("=")[1].Replace("'"","")
$path = Join-Path $yourfoldername $fileName
$file = [System.IO.FileStream]::new($path, [System.IO.FileMode]::Create)
$file.write($result.Content, 0, $result.RawContentLength)
$file.close()
Ответ 4
Суть моего кода - это работает.. используя PS 5.1
Я прокомментировал нормальное утверждение -Outfile, потому что это означало бы, что я знал имя файла заранее. Я соединил это, основываясь на нескольких источниках, существует множество способов парсинга заголовков Content-Disposition, поэтому используйте все, что вам подходит.
$outpath = "C:\\temp\\"
Вызов:
$result = Invoke-WebRequest -method GET -Uri $resourceUrl -Headers
$resourceHeaders -Verbose #-OutFile $($outPath+"$nodeId.pdf")
разбор
$outFilename = $outpath+$result.Headers.'Content-Disposition'.Split("=")[1].Split('\\""')[1] #shaky parsing - might require improvement in time
Написание файла (это в основном PDF для меня
[System.IO.File]::WriteAllBytes($outFilename, $result.content)
Ответ 5
powershell.exe Invoke-WebRequest -Uri serverIP/file.exe -OutFile C:\Users\file.exe