You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PowerShell通过Invoke-WebRequest/COM对象下载日志文件遇阻

解决PowerShell自动下载KACE日志文件的问题

我来帮你一步步搞定这个自动下载日志的问题,先从你遇到的Invoke-WebRequest问题说起,再聊IE COM对象的解决方案。

一、修复Invoke-WebRequest下载失败的问题

你目前的问题核心是请求下载链接时被重定向回登录页,虽然补了Referer头,但可能还有几个关键点没注意到:

1. 确保请求的是正确的下载URL

你提到日志下载链接是https://some.thing.com/common/download_logs.php,但你之前执行的命令是POST到settings_support.php——这不对,应该直接请求下载链接本身。

2. 完善请求头与会话传递

除了Referer,还要确保会话$ms是登录后的有效会话,同时检查是否需要将CSRF Token作为表单参数提交(有些网站会要求POST请求时携带CSRF Token,而不仅仅是放在Cookie里)。

试试这个修正后的命令:

# 构造完整请求头
$headers = @{
    "User-Agent"      = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063"
    "Referer"         = "https://some.thing.com/adminui/settings_support.php"
    "Accept-Encoding" = "gzip, deflate"
    "Accept"          = "text/html, application/xhtml+xml, image/jxr, */*"
    "Accept-Language" = "en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3"
}

# 直接请求下载链接,用WebSession传递登录状态,指定OutFile保存文件
Invoke-WebRequest -Uri "https://some.thing.com/common/download_logs.php" `
                  -WebSession $ms `
                  -Headers $headers `
                  -OutFile "C:\your\save\path\kbox_logs.tgz"

3. 排查CSRF Token的传递方式

如果上面的命令还是失败,抓包对比浏览器请求:

  • 看浏览器请求download_logs.php时用的是GET还是POST方法
  • 如果是POST,检查表单里是否有KACE_CSRF_TOKEN字段,有的话需要在请求里加上:
    $formParams = @{
        "KACE_CSRF_TOKEN" = "aad3f8c254d2f25bd24e35c51d654541822080da825d6353937a7fe294216089689cc68480299b657f4fb1e9be77ac711a658a96e2df50ffc5e242b94bd9baf4"
    }
    Invoke-WebRequest -Uri "https://some.thing.com/common/download_logs.php" `
                      -WebSession $ms `
                      -Headers $headers `
                      -Method POST `
                      -Body $formParams `
                      -OutFile "kbox_logs.tgz"
    

二、解决IE COM对象的两个问题

1. 修复无法点击下载链接的问题

你的代码里点击链接的语法有误,过滤元素后需要确保拿到正确的DOM对象再调用click()。修正后的代码片段:

# 导航到支持页面后,查找下载链接
$ie.navigate("http://some.thing.com/adminui/settings_support.php")
while ($ie.busy -eq $true) { Start-Sleep 1 }

# 正确获取并点击链接
$downloadLink = $ie.document.getElementsByTagName("a") | Where-Object { $_.innerText -eq 'Retrieve appliance activity logs' }
if ($downloadLink) {
    $downloadLink.click()
} else {
    Write-Host "找不到下载链接,请检查innerText是否匹配"
}

2. 后台自动保存下载文件

用快捷键S确实不够优雅,你可以通过修改IE的注册表设置,让它自动保存指定类型的文件,再监控下载文件夹获取文件:

步骤1:修改IE自动下载设置

# 修改IE安全区域设置,允许自动保存.tgz文件(0=允许,1=提示,3=禁止)
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" -Name "1803" -Value 0

步骤2:监控下载文件夹并处理文件

$shell = New-Object -ComObject Shell.Application
$downloadFolder = $shell.Namespace(0x0010) # 系统默认下载文件夹路径
$targetPath = "C:\your\target\path\kbox_logs.tgz"

# 等待下载完成
while (-not ($downloadFolder.Items() | Where-Object { $_.Name -eq 'kbox_logs.tgz' })) {
    Start-Sleep 1
}

# 移动文件到指定位置
Move-Item -Path (Join-Path $downloadFolder.Self.Path 'kbox_logs.tgz') -Destination $targetPath -Force

总结

优先推荐Invoke-WebRequest的方案,不需要GUI,效率更高;如果必须用IE COM对象,按上面的方法修复点击逻辑和自动保存问题。

内容的提问来源于stack exchange,提问作者Rrrrr5r

火山引擎 最新活动