0

因此,我编写了一个 powershell 脚本,该脚本通过特定网站进行爬网,并将该网站上托管的所有软件下载到我的本地计算机上。有问题的网站是nirsoft.net,我将在下面包含完整的脚本。无论如何,所以我有这个脚本可以下载网站上托管的所有应用程序文件,当我注意到一些奇怪的事情时:虽然大多数文件下载成功完成,但有几个文件没有成功下载,导致文件损坏4KB:

在此处输入图像描述

对于那些熟悉 Nirsoft 软件的人来说,这些工具非常强大,但也经常因为密码破解工具而被误认为是危险的,所以我猜测为什么会发生这种情况,因为 powershell 的如果我猜测为为什么会发生这种情况,我猜是因为 powershell 的“Invoke-webrequest cmdlet”使用 Internet Explorer 的引擎作为其核心功能,Internet Explorer 将文件标记为危险并拒绝下载它们,从而导致 powershell下载文件失败。我通过尝试使用 Internet Explorer 手动下载每个损坏的文件来确认这一点,这将它们全部标记为恶意文件。然而,这就是事情变得奇怪的地方。为了绕过这个限制,我尝试了各种其他方法在我的脚本中下载文件,比如使用纯 dotnet 对象( (New-object System.Net.WebClient).DownloadFile("url","file") )甚至一些第三方命令行工具(Windows 的 wget,cygwin 中的 wget 等),但无论我尝试什么,我使用的任何一种替代方法都无法下载未损坏的文件。所以我想知道是否有办法解决这个问题,我想知道为什么第三方工具也会受到影响。是否有某种规则要求任何脚本工具必须使用 Internet Explorer 的引擎才能连接到 Internet 或其他东西?提前致谢。哦,在我发布脚本之前的最后一件事。以下是我在通过 powershell 下载时遇到困难的文件之一的 URL, 在此处输入链接描述

不用多说,这是脚本。再次感谢:

$VerbosePreference = "Continue"
$DebugPreference = "Continue"
$present = $true
$subdomain = $null
$prods = (Invoke-WebRequest "https://www.nirsoft.net/utils/index.html").links
Foreach ($thing in $prods)
{
    If ($thing.Innertext -match "([A-Za-z]|\s)+v\d{1,3}\.\d{1,3}(.)*")
    {
        If ($thing.href.Contains("/"))
        {
            
        }
        $page = Invoke-WebRequest "https://www.nirsoft.net/utils/$($thing.href)"
        If ($thing.href -like "*dot_net_tools*")
        {
            $prodname = $thing.innerText.Trim().Split(" ")
        }
        Else
        {
            $prodname = $thing.href.Trim().Split(".")
        }
        $newlinks = $page.links | Where-Object {$_.Innertext -like "*Download*" -and ($_.href.endswith("zip") -or $_.href.endswith("exe"))}
       # $page.ParsedHtml.title
        #$newlinks.href
        Foreach ($item in $newlinks)
        {
            $split = $item.href.Split("/")
            If ($item.href -like "*toolsdownload*")
            {
                Try
                {
                    Write-host "https://www.nirsoft.net$($item.href)"
                    Invoke-WebRequest "https://www.nirsoft.net$($item.href)" -OutFile "$env:DOWNLOAD\test\$($split[-1])" -ErrorAction Stop
                }
                Catch
                {
                    Write-Host $thing.href -ForegroundColor Red
                }
            }
            elseif ($item.href.StartsWith("http") -and $item.href.Contains(":"))
            {
                Try
                {
                    Write-host "$($item.href)"
                    Invoke-WebRequest $item.href -OutFile "$env:DOWNLOAD\test\$($split[-1])" -ErrorAction Stop
                }
                Catch
                {
                    Write-Host "$($item.href)" -ForegroundColor Red
                }
            }
            Elseif ($thing.href -like "*/dot_net_tools*")
            {
                Try
                {
                    Invoke-WebRequest "https://www.nirsoft.net/dot_net_tools/$($item.href)" -OutFile "$env:DOWNLOAD\test\$($split[-1])" -ErrorAction Stop
                }
                Catch
                {
                    Write-Host $thing.href -ForegroundColor Red
                }
            }
            Else
            {
                Try
                {
                    Write-Host "https://www.nirsoft.net/utils/$($item.href)"
                    Invoke-WebRequest "https://www.nirsoft.net/utils/$($item.href)" -OutFile "$env:DOWNLOAD\test\$($item.href)" -ErrorAction Stop
                }
                Catch
                {
                     Write-Host $thing.href -ForegroundColor Red
                }
            }
            If ($item.href.Contains("/"))
            {
                If (!(Test-Path "$env:DOWNLOAD\test\$($split[-1])"))
                {
                    $present = $false
                }
            }
            Else
            {
                If (!(Test-Path "$env:DOWNLOAD\test\$($item.href)"))
                {
                    $present = $false
                }
            }
        }
    }
}

If ($present)
{
    Write-Host "All of the files were downloaded!!!" -ForegroundColor Green
}
Else
{
    Write-Host "Not all of the files downloaded.  Something went wrong." -ForegroundColor Red
}
4

1 回答 1

1

你有两个不同的问题。

对于任何 Defender 标志,使用这个或那个将其保存到磁盘都没有关系。您可以简单地为 Defender 中的目录添加排除项。

Guenther 指出了另一个问题,您至少需要在某些下载中提供推荐人。通过以下更改,我能够全部下载。

$VerbosePreference = "Continue"
$DebugPreference = "Continue"
$present = $true
$subdomain = $null
$path = c:\temp\downloadtest\
New-Item $path -ItemType Directory -ErrorAction SilentlyContinue | Out-Null

Add-MpPreference -ExclusionPath $path

$prods = (Invoke-WebRequest "https://www.nirsoft.net/utils/index.html").links
Foreach ($thing in $prods)
{
    If ($thing.Innertext -match "([A-Za-z]|\s)+v\d{1,3}\.\d{1,3}(.)*")
    {
        If ($thing.href.Contains("/"))
        {
        
        }
        $page = Invoke-WebRequest "https://www.nirsoft.net/utils/$($thing.href)"
        If ($thing.href -like "*dot_net_tools*")
        {
            $prodname = $thing.innerText.Trim().Split(" ")
        }
        Else
        {
            $prodname = $thing.href.Trim().Split(".")
        }
        $newlinks = $page.links | Where-Object {$_.Innertext -like "*Download*" -and ($_.href.endswith("zip") -or $_.href.endswith("exe"))}
       # $page.ParsedHtml.title
        #$newlinks.href
        Foreach ($item in $newlinks)
        {
            $split = $item.href.Split("/")
            If ($item.href -like "*toolsdownload*")
            {
                Try
                {
                    Write-host "https://www.nirsoft.net$($item.href)"
                    Invoke-WebRequest "https://www.nirsoft.net$($item.href)" -OutFile "$path\$($split[-1])" -ErrorAction Stop -Headers @{Referer="https://www.nirsoft.net$($item.href)"}
                }
                Catch
                {
                    Write-Host $thing.href -ForegroundColor Red
                }
            }
            elseif ($item.href.StartsWith("http") -and $item.href.Contains(":"))
            {
                Try
                {
                    Write-host "$($item.href)"
                    Invoke-WebRequest $item.href -OutFile "$path\$($split[-1])" -ErrorAction Stop -Headers @{Referer="$($item.href)"}
                }
                Catch
                {
                    Write-Host "$($item.href)" -ForegroundColor Red
                }
            }
            Elseif ($thing.href -like "*/dot_net_tools*")
            {
                Try
                {
                    Invoke-WebRequest "https://www.nirsoft.net/dot_net_tools/$($item.href)" -OutFile "$path\$($split[-1])" -ErrorAction Stop -Headers @{Referer="https://www.nirsoft.net/dot_net_tools/$($item.href)"}
                }
                Catch
                {
                    Write-Host $thing.href -ForegroundColor Red
                }
            }
            Else
            {
                Try
                {
                    Write-Host "https://www.nirsoft.net/utils/$($item.href)"
                    Invoke-WebRequest "https://www.nirsoft.net/utils/$($item.href)" -OutFile "$path\$($item.href)" -ErrorAction Stop -Headers @{Referer="https://www.nirsoft.net/utils/$($item.href)"}
                }
                Catch
                {
                     Write-Host $thing.href -ForegroundColor Red
                }
            }
            If ($item.href.Contains("/"))
            {
                If (!(Test-Path "$path\$($split[-1])"))
                {
                    $present = $false
                }
            }
            Else
            {
                If (!(Test-Path "$path\$($item.href)"))
                {
                    $present = $false
                }
            }
        }
    }
}

If ($present)
{
    Write-Host "All of the files were downloaded!!!" -ForegroundColor Green
}
Else
{
    Write-Host "Not all of the files downloaded.  Something went wrong." -ForegroundColor Red
}

我还建议您将下载例程转换为可以传递相对 URL 部分的函数,这样您就不必多次重复代码。

于 2020-08-08T23:25:58.653 回答