2010-11-16 61 views
3

我一直在玩這個沒有運氣的日子。基本上我試圖建立一個簡單的庫來使用Powershell來呈現SSRS報告。我正在使用Powershell試圖稍後緩解開發(而不是爲每個項目編寫C#應用程序)。大多數情況下,這將用於安排報告的各種事情。使用Powershell中的SOAP使用參數呈現SSRS報告

我有報告渲染主要是在Powershell中工作。我無法弄清楚的一件事是如何在調用渲染方法之前向報告提供參數。我發現很多與C#和VB(我在其他SSRS項目中使用過)有關的代碼,但是我無法將其轉換爲Powershell。

由於我是Powershell的新手,我不熟悉正確的方法。下面是我一直使用的代碼:這對那些不需要參數,顯然報告工作正常

$ReportExecutionURI = "http://glitas10//ReportServer//ReportExecution2005.asmx?wsdl" 
$ReportPath = "/Financial/ExpenseReportStub" 
$format = "PDF" 

$deviceInfo = "<DeviceInfo><NoHeader>True</NoHeader></DeviceInfo>" 
$extension = "" 
$mimeType = "" 
$encoding = "" 
$warnings = $null 
$streamIDs = $null 

$Reports = New-WebServiceProxy -Uri $ReportExecutionURI -UseDefaultCredential 

# Load the report 
$Report = $Reports.GetType().GetMethod("LoadReport").Invoke($Reports, @($ReportPath, $null)) 

# Render the report 
$RenderOutput = $Reports.Render($format, $deviceInfo, [ref] $extension, [ref] $mimeType, [ref] $encoding, [ref] $warnings, [ref] $streamIDs) 

有關我需要做什麼來實例化正確的對象和傳遞參數的任何想法?

+0

爲什麼不能直接在$ Reports上調用LoadReport?當你執行這個'$ Reports |時,你會看到什麼? GET-Member'? LoadReport不顯示嗎?如果是這樣,它有什麼簽名?此外,看看這篇文章是否有所幫助 - http://social.msdn.microsoft.com/Forums/en-US/sqlreportingservices/thread/c14011bf-6d06-492e-befa-f82902a1d187/ – 2010-11-16 17:22:22

+0

我試過了,但似乎沒有就像我提供的論據一樣。出於某種原因使用調用工作。但是,該部分起作用,並且不應該干擾提供參數。 – Matthew 2010-11-16 17:30:26

+0

添加到我以前的評論,它出現使用$ Reports.LoadReport不會接受空的歷史ID,這就是爲什麼我發現的代碼是使用調用。 – Matthew 2010-11-16 17:50:14

回答

9

下面是我最終使用的解決方案的一些信息,以防其他人需要這樣做。它工作得很好。

工作的第一種方法是構建一個由Powershell腳本使用的DLL。這工作得很好,但它會導致兩個問題。首先,你的腳本來裝載一個DLL。其次,這個DLL綁定到特定的SSRS服務器。爲了訪問另一臺服務器,你必須使用多個DLL。

最後,我回到使用Web代理。這裏的關鍵是使用名稱空間,以便您可以實例化一個ParameterValue對象。這裏的代碼:

# 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. 
$reportServerURI = "http://<SERVER>/ReportServer/ReportExecution2005.asmx?WSDL" 
$RS = New-WebServiceProxy -Class 'RS' -NameSpace 'RS' -Uri $reportServerURI -UseDefaultCredential 
$RS.Url = $reportServerURI 

# Set up some variables to hold referenced results from Render 
$deviceInfo = "<DeviceInfo><NoHeader>True</NoHeader></DeviceInfo>" 
$extension = "" 
$mimeType = "" 
$encoding = "" 
$warnings = $null 
$streamIDs = $null 

# 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 = "/PathTo/Report" 
$Report = $RS.GetType().GetMethod("LoadReport").Invoke($RS, @($reportPath, $null)) 

# Report parameters are handled by creating an array of ParameterValue objects. 
$parameters = @() 

$parameters += New-Object RS.ParameterValue 
$parameters[0].Name = "Parameter 1" 
$parameters[0].Value = "Value" 

$parameters += New-Object RS.ParameterValue 
$parameters[1].Name = "Parameter 2" 
$parameters[1].Value = "Value" 

# 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 

# 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('PDF', 
    $deviceInfo, 
    [ref] $extension, 
    [ref] $mimeType, 
    [ref] $encoding, 
    [ref] $warnings, 
    [ref] $streamIDs 
) 

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

它似乎很容易,它是。此方法運行得非常好,並且是我現在用於呈現和發送計劃報告的方法,因爲它比內置的SSRS計劃提供了更多的靈活性。另外,它相對較快。我用來發送報告的一個腳本可以呈現並每分鐘發送大約20-30個報告。

+0

任何解決方案與完整的源代碼渲染,生成文件和郵件嗎? – Kiquenet 2012-06-27 12:43:57

+0

不錯,我試過的方式是$ webclient。下載文件($ url,$ file),然後通過電子郵件發送。 – Shawn 2013-01-22 00:14:59

+0

在更新版本的powershell中,常量'[NullString] :: Value'被添加來避免$''在作爲字符串傳遞給方法時被強制爲空字符串的問題。傳遞這個常量而不是'$ null',你可以避免使用反射。如果'[NullString]'不可用作加速器,'[System.Management.Automation.Internal.AutomationNull] :: Value'是等價的(但稍微不靈活)。 – x0n 2014-10-21 20:50:55

0

有同樣的問題,而且要發送生成的MHT文件作爲電子郵件正文: 下面發現工作 老CDO.Message是我發現的唯一的事情,允許發送一個MHTML文件作爲電子郵件身體。 下面是VB程序的(工作)翻譯 舊但簡單;-)!

################## Send MHTML email ############################## 
# use antiquated CDO to send mhtml as email body 

$smtpServer = "my-mail-server" 
$smtpSubject = "MHT file sent as body of email" 
$smtpTo = "[email protected]" 
$smtpFrom = "[email protected]" 
$MHTMLfile = "my-MHT-File.mht 
# e.g. from an SSRS.Render 


$AdoDbStream = New-Object -ComObject ADODB.Stream 
$AdoDbStream.Charset = "ascii" 
$AdoDbStream.Open() 
$AdoDbStream.LoadFromFile($MHTMLfile) 
$CdoMessage = New-Object -ComObject CDO.Message 
$CdoMessage.DataSource.OpenObject($AdoDbStream,"_Stream") 

$SendUsingPort = 2 
$smtpPort = 25 

$cfg = "http://schemas.microsoft.com/cdo/configuration/" 
$CdoMessage.Configuration.Fields.Item($cfg + "sendusing") = $SendUsingPort 
$CdoMessage.Configuration.Fields.Item($cfg + "smtpserver") = $SmtpServer 
$CdoMessage.Configuration.Fields.Item($cfg + "smtpserverport") = $smtpPort 

$CdoMessage.To  = $smtpTo 
$CdoMessage.From = $smtpFrom 
$CdoMessage.Subject = $smtpSubject 

$CdoMessage.MimeFormatted = $true 
$CdoMessage.Configuration.Fields.Update() 

WRITE-HOST "Sending email" 
$CdoMessage.Send()