You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过PowerShell从SSRS 2017已发布报表生成Excel文件?

SSRS 2017 报表导出Excel:PowerShell 401未授权问题解决及替代方案

问题背景

我需要运行PowerShell脚本自动从SSRS 2017已发布报表生成Excel文件,当前使用的脚本如下:

$reportServerURI = "http://NOCSQL05:80/ReportServer/"
$reportPath = "/Folder/Project"
$format = "EXCELOPENXML"
$parameters = @()

# Update these variables with the correct credentials
$username = "ValidUsr"
$password = "ValidPwd"

$RS = New-WebServiceProxy -Class 'ReportingService2010' -NameSpace 'Microsoft.SqlServer.ReportingServices2017' -Uri $reportServerURI

if($RS -ne $null) {
    $RS.Credentials = New-Object System.Net.NetworkCredential($username, $password)
    $Report = $RS.LoadReport($reportPath, $null)
    if($Report -ne $null) {
        $RS.SetExecutionParameters($parameters, "nl-nl") > $null
        $RenderOutput = $RS.Render($format, $null, [ref] $null, [ref] $null, [ref] $null, [ref] $null, [ref] $null)
        if($RenderOutput -ne $null) {
            $Stream = New-Object System.IO.FileStream("C:\Users\TM0658\Documents\report.xlsx", [System.IO.FileMode]::Create)
            $Stream.Write($RenderOutput, 0, $RenderOutput.Length)
            $Stream.Close()
        }
    }
}

执行脚本时出现401未授权错误,详情如下:

New-WebServiceProxy : The request failed with HTTP status 401: Unauthorized.
At C:\Users\TM0658\Documents\SSRS_Export.ps1:11 char:7
+ $RS = New-WebServiceProxy -Class 'ReportingService2010' -NameSpace 'M ...
+       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (http://nocsql05/ReportServer/:Uri) [New-WebServiceProxy], WebException
    + FullyQualifiedErrorId : WebException,Microsoft.PowerShell.Commands.NewWebServiceProxy

已确认服务器URL有效、用户权限足够,但问题仍存在,希望解决该问题,也接受PowerShell之外的替代方案。


PowerShell脚本修复方案

1. 提前传入凭据(核心修复)

原脚本先创建代理再设置凭据,但New-WebServiceProxy创建时就会发起请求,导致凭据未及时生效。修改为创建代理时直接传入凭据:

$reportServerURI = "http://NOCSQL05:80/ReportServer/"
$reportPath = "/Folder/Project/ReportName" # 补充具体报表名称
$format = "EXCELOPENXML"
$parameters = @()

$username = "ValidUsr"
$password = "ValidPwd"
$domain = "YourDomain" # 域账号需添加域名,本地账号可留空

# 创建凭据对象
$credential = New-Object System.Net.NetworkCredential($username, $password, $domain)

# 创建代理时直接传入凭据
$RS = New-WebServiceProxy -Class 'ReportingService2010' -Namespace 'Microsoft.SqlServer.ReportingServices2017' -Uri $reportServerURI -Credential $credential

if($RS -ne $null) {
    $Report = $RS.LoadReport($reportPath, $null)
    if($Report -ne $null) {
        $RS.SetExecutionParameters($parameters, "nl-nl") > $null
        $RenderOutput = $RS.Render($format, $null, [ref] $null, [ref] $null, [ref] $null, [ref] $null, [ref] $null)
        if($RenderOutput -ne $null) {
            $Stream = New-Object System.IO.FileStream("C:\Users\TM0658\Documents\report.xlsx", [System.IO.FileMode]::Create)
            $Stream.Write($RenderOutput, 0, $RenderOutput.Length)
            $Stream.Close()
        }
    }
}

2. 适配NTLM认证(若SSRS使用该方式)

如果SSRS启用NTLM认证,需强制代理使用NTLM避免Kerberos双跳问题:

# 在创建代理前添加以下配置
$proxyParams = @{
    Class = 'ReportingService2010'
    Namespace = 'Microsoft.SqlServer.ReportingServices2017'
    Uri = $reportServerURI
    UseDefaultCredential = $false
}
$RS = New-WebServiceProxy @proxyParams
$RS.PreAuthenticate = $true
$RS.Credentials = $credential

3. 验证报表路径

确保$reportPath是SSRS中的完整路径,需包含具体报表名称,例如/Folder/Project/SalesReport,而非仅文件夹路径。


替代方案

1. 使用SSRS REST API(SSRS 2017+推荐)

SSRS 2017及以上版本支持REST API,比旧Web Service更稳定,示例代码:

$reportServerURI = "http://NOCSQL05:80/ReportServer"
$reportPath = "/Folder/Project/ReportName"
$outputPath = "C:\Users\TM0658\Documents\report.xlsx"
$username = "ValidUsr"
$password = "ValidPwd"
$domain = "YourDomain"

$credential = New-Object System.Management.Automation.PSCredential("$domain\$username", (ConvertTo-SecureString $password -AsPlainText -Force))

# 构建REST API导出请求URL
$apiUrl = "$reportServerURI/api/v2.0/reports('$reportPath')/Export?format=EXCELOPENXML"

# 发起请求并保存Excel文件
Invoke-RestMethod -Uri $apiUrl -Credential $credential -OutFile $outputPath

2. 使用rs.exe命令行工具

创建VB脚本文件ExportReport.vbs:

Public Sub Main()
    Dim rs As New ReportingService2010
    rs.Credentials = New System.Net.NetworkCredential("ValidUsr", "ValidPwd", "YourDomain")
    rs.Url = "http://NOCSQL05:80/ReportServer/ReportService2010.asmx"

    Dim reportPath As String = "/Folder/Project/ReportName"
    Dim format As String = "EXCELOPENXML"
    Dim parameters As ParameterValue() = Nothing

    Dim warnings As Warning() = Nothing
    Dim streamIDs As String() = Nothing
    Dim mimeType As String = ""
    Dim encoding As String = ""
    Dim fileNameExtension As String = ""
    Dim bytes As Byte() = rs.Render(format, Nothing, parameters, Nothing, Nothing, Nothing, warnings, streamIDs)

    Dim fs As New System.IO.FileStream("C:\Users\TM0658\Documents\report.xlsx", System.IO.FileMode.Create)
    fs.Write(bytes, 0, bytes.Length)
    fs.Close()
End Sub

通过rs.exe执行脚本:

rs.exe -i ExportReport.vbs -s http://NOCSQL05:80/ReportServer/

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 12:10:32