我正在嘗試在 Win7 上使用 powershell 自動從 Microsoft 下載 MSE 定義檔案。我正在尋找可以執行此操作的 poweshell 腳本。
我無法使用 Windows 更新服務或 BITS 服務,因為這兩者都被禁用以防止作業系統自動下載破壞計算機的更新。MSE 使用更新服務來獲取新定義。
我有一個腳本(如下)適用于使用https托管的常規檔案。例如https://www.7-zip.org/a/7z1604.exe
當我使用 Microsoft 下載 URL ( https://go.microsoft.com/fwlink/?linkid=87341 ) 時,腳本失敗并出現以下錯誤:
使用“2”引數呼叫“DownloadFile”的例外:“底層連接已關閉:發送時發生意外錯誤。” 在 C:\temp\run.ps1:9 char:40
出于某種原因,Microsoft 不使用常規的 https 或 ftp 檔案鏈接。我不知道他們使用什么樣的鏈接,但他們不適用于下面的腳本。這也不是 https 證書問題。來自 https 源的檔案可以正常作業:
$url = "https://go.microsoft.com/fwlink/?linkid=87341"
$path = "C:\temp\update.exe"
# param([string]$url, [string]$path)
if(!(Split-Path -parent $path) -or !(Test-Path -pathType Container (Split-Path -parent $path))) {
$targetFile = Join-Path $pwd (Split-Path -leaf $path)
}
(New-Object Net.WebClient).DownloadFile($url, $path)
$path
我從這個鏈接得到了上面的腳本: Downloading files with powershell 2.0 on windows 7
我錯過了一些明顯的東西。任何建議表示贊賞。
謝謝。
uj5u.com熱心網友回復:
此功能適用于 PS v5.1 和 PS v7.2.x,Invoke-WebRequest用于下載格式https://go.microsoft.com/fwlink/?linkid=idNumber的 Microsoft 鏈接,首先檢查檔案名是否可以從中檢索Content-Disposition(如 Matthew Hodgkins博客中所述),如果失敗,然后嘗試BaseResponse通過確定檔案的型別并從適當的位置提取 URI 來從中提取檔案名。
如果代碼無法確定檔案名,它會嘗試使用檔案名保存檔案Dowloaded.File,但這未經測驗且不應被信任。可能會拋出錯誤。
注意:雖然這對代碼中的 3 個示例鏈接有效,但此代碼的性質是人們應該期望它對某些鏈接有效,而對其他鏈接無效。如果有人發現失敗的鏈接并將其放在評論中,我也許能夠弄清楚如何提取正確的檔案名并修改函式以正確處理它。
function Invoke-WebRequestDownload {
[OutputType([string])]
param (
[Parameter(Mandatory = $true, Position = 0)]
[string]$Uri,
[Parameter(Mandatory = $false, Position = 1)]
[string]$OutFile = "$PSScriptRoot\Downloaded.File"
)
$FileDownload = Invoke-WebRequest -Uri $Uri
$FilePath = [System.IO.Path]::GetDirectoryName($OutFile)
if(-not $FilePath) {$FilePath = $PSScriptRoot}
$FileName = $null
if([bool]$FileDownload.Headers['Content-Disposition']) {
$FileName = [System.Net.Mime.ContentDisposition]::new($FileDownload.Headers["Content-Disposition"]).FileName
} else {
switch ($FileDownload.BaseResponse) {
{$_ -is [System.Net.HttpWebResponse]} {
$FileName = $FileDownload.BaseResponse.ResponseUri.Segments[-1]
}
{$_ -is [System.Net.Http.HttpResponseMessage]} {
$FileName = $FileDownload.BaseResponse.RequestMessage.RequestUri.Segments[-1]
}
Default {
$FileName = [System.IO.Path]::GetFileName($OutFile)
}
}
}
if(-not $FileName) {$FileName = 'Downloaded.File'}
$FileNamePath = Join-Path -Path $FilePath -ChildPath $FileName
$File = [System.IO.FileStream]::new($FileNamePath, [System.IO.FileMode]::Create)
$File.Write($FileDownload.Content, 0, $FileDownload.RawContentLength)
$File.Close()
Return $FileNamePath
}
$OutFilePath = Invoke-WebRequestDownload -Uri 'https://go.microsoft.com/fwlink/?linkid=87341'
#$OutFilePath = Invoke-WebRequestDownload -Uri 'http://go.microsoft.com/fwlink/?LinkId=393217'
#$OutFilePath = Invoke-WebRequestDownload -Uri 'https://go.microsoft.com/fwlink/?linkid=2109047&Channel=Stable&language=en&consent=1'
$OutFilePath
uj5u.com熱心網友回復:
這段代碼似乎可以解決問題:
$download = Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?linkid=87341"
$FileName = $download.BaseResponse.ResponseUri.Segments[-1]
$file = [System.IO.FileStream]::new("$PSScriptRoot\$FileName", [System.IO.FileMode]::Create)
$file.Write($download.Content, 0, $download.RawContentLength)
$file.Close()
從 Matthew Hodgkins博客和 killtime 的鏈接我們得到:
$download = Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?linkid=87341"
Content-Disposition但是Hodgkins 的代碼嘗試使用$download. 通過查看,$download我最終發現這$download.BaseResponse.ResponseUri給了我們一個 Uri。搜索從 Uri 獲取檔案名最終導致我Lee_Dailey使用Segments[-1],給我們:
$FileName = $download.BaseResponse.ResponseUri.Segments[-1]
至于檔案目的地,在我的情況下,我希望它與腳本位于同一個檔案夾,因此$PSScriptRoot用于對 Hodgkins 的示例進行小改動。
$file = [System.IO.FileStream]::new("$PSScriptRoot\$FileName", [System.IO.FileMode]::Create)
$file.Write($download.Content, 0, $download.RawContentLength)
$file.Close()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/505068.html
