2015-02-26 2 views
3

Я пытаюсь заставить PowerShell отправлять веб-запрос на наш сервер SSRS и фиксировать результаты. Я ударил стену, используя параметр rs:FORMAT=EXCEL в строке URL-адреса SSRS. У меня есть следующие:SSRS и PowerShell: Получить отчет как Excel

Во-первых, инициализации учетных данных:

$User = "MYDOMAIN\MyUser" 
$PWord = ConvertTo-SecureString -String "WooHooStringP$W0rd" -AsPlainText -Force 
$c = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $User, $PWord 

Теперь запросить отчет:

Invoke-WebRequest ` 
-UserAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::InternetExplorer) ` 
-Credential $c ` 
-Uri "http://myserver/ReportServer_DEV/Pages/ReportViewer.aspx?/folder+path/report+name" 

Это прекрасно работает. Я даже могу получить результаты (включая этот запрос и используя() .Content). Затем укажите формат вместо обычного рендеринга:

Invoke-WebRequest ` 
-UserAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::InternetExplorer) ` 
-Credential $c ` 
-Uri "http://myserver/ReportServer_DEV/Pages/ReportViewer.aspx?/folder+path/report+name&rs:format=HTML4.0" 

Обратите внимание на rs:Format спецификации? Работает как шарм.

Тогда для гранд-финале, дайте мне файл Excel:

Invoke-WebRequest ` 
-UserAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::InternetExplorer) ` 
-Credential $c ` 
-Uri "http://myserver/ReportServer_DEV/Pages/ReportViewer.aspx?/folder+path/report+name&rs:format=EXCEL" 

Нет может сделать, бутон:

Invoke-WebRequest : The remote server returned an error: (401) Unauthorized. 
At line:1 char:11 
+ $bytez = (Invoke-WebRequest ` 
+   ~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException 
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand 

Почему вариант rs:format=EXCEL бросить несанкционированном исключение где все остальные URL-адреса обслуживаются SSRS?

ответ

7

Я понял это! Я пошел об этом не так: SSRS предлагает доступ через веб-сервис, который PowerShell может потреблять без необходимости взломать URL-адрес и получить ответ. Я нашел сценарий, который сделал это, и изменил его в соответствии с моей целью:

function GetRSConnection($server, $instance) 
{ 
    # Create a proxy to the SSRS server and give it the namespace of 'RS' to use for 
    # instantiating objects later. This class will also be used to create a report 
    # object. 

    $User = "DOMAIN\Username" 
    $PWord = ConvertTo-SecureString -String "Pa$$w0rd" -AsPlainText -Force 
    $c = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $User, $PWord 

    $reportServerURI = "http://" + $server + "/" + $instance + "/ReportExecution2005.asmx?WSDL" 

    $RS = New-WebServiceProxy -Class 'RS' -NameSpace 'RS' -Uri $reportServerURI -Credential $c 
    $RS.Url = $reportServerURI 
    return $RS 
} 

function GetReport($RS, $reportPath) 
{ 
    # Next we need to load the report. Since Powershell cannot pass a null string 
    # (it instead just passses ""), we have to use GetMethod/Invoke to call the 
    # function that returns the report object. This will load the report in the 
    # report server object, as well as create a report object that can be used to 
    # discover information about the report. It's not used in this code, but it can 
    # be used to discover information about what parameters are needed to execute 
    # the report. 
    $reportPath = "/" + $reportPath 
    $Report = $RS.GetType().GetMethod("LoadReport").Invoke($RS, @($reportPath, $null)) 

    # initialise empty parameter holder 
    $parameters = @() 
    $RS.SetExecutionParameters($parameters, "nl-nl") > $null 
    return $report 
} 

function AddParameter($params, $name, $val) 
{ 
    $par = New-Object RS.ParameterValue 
    $par.Name = $name 
    $par.Value = $val 
    $params += $par 
    return ,$params 
} 

function GetReportInFormat($RS, $report, $params, $outputpath, $format) 
{ 
    # Set up some variables to hold referenced results from Render 
    $deviceInfo = "<DeviceInfo><NoHeader>True</NoHeader></DeviceInfo>" 
    $extension = "" 
    $mimeType = "" 
    $encoding = "" 
    $warnings = $null 
    $streamIDs = $null 

    # Report parameters are handled by creating an array of ParameterValue objects. 
    # Add the parameter array to the service. Note that this returns some 
    # information about the report that is about to be executed. 
    # $RS.SetExecutionParameters($parameters, "en-us") > $null 
    $RS.SetExecutionParameters($params, "nl-nl") > $null 

    # Render the report to a byte array. The first argument is the report format. 
    # The formats I've tested are: PDF, XML, CSV, WORD (.doc), EXCEL (.xls), 
    # IMAGE (.tif), MHTML (.mhtml). 
    $RenderOutput = $RS.Render($format, 
     $deviceInfo, 
     [ref] $extension, 
     [ref] $mimeType, 
     [ref] $encoding, 
     [ref] $warnings, 
     [ref] $streamIDs 
    ) 

    # Determine file name 
    $parts = $report.ReportPath.Split("/") 
    $filename = $parts[-1] + "." 
    switch($format) 
    { 
     "EXCEL" { $filename = $filename + "xls" } 
     "WORD" { $filename = $filename + "doc" } 
     "IMAGE" { $filename = $filename + "tif" } 
     default { $filename = $filename + $format } 
    } 

    if($outputpath.EndsWith("\\")) 
    { 
     $filename = $outputpath + $filename 
    } else 
    { 
     $filename = $outputpath + "\" + $filename 
    } 

    $filename 

    # Convert array bytes to file and write 
    $Stream = New-Object System.IO.FileStream($filename), Create, Write 
    $Stream.Write($RenderOutput, 0, $RenderOutput.Length) 
    $Stream.Close() 
} 

$RS = GetRSConnection -server "DEVBOX" -instance "ReportServer_DEV" 
$report = GetReport -RS $RS -reportPath "folder name/report name" 

$params = @() 
$params = AddParameter -params $params -name "Month" -val "201311" 

GetReportInformat -RS $RS -report $report -params $params -outputpath "i:\test" -format "EXCEL" 
Смежные вопросы