├── .editorconfig
├── .vs
├── ProjectSettings.json
└── slnx.sqlite
├── Example-Reports
├── .gitignore
├── Example-Reports.rptproj
├── SharedSanity.rsd
├── SomeDatasource.rds
├── example-db.sql
└── sanity-analysis.rdl
├── LICENSE.txt
├── README.md
├── ssrs-powershell-deploy.sln
└── ssrs-powershell-deploy
├── SSRS
├── Get-SSRSCredential.ps1
├── Get-SSRSProjectConfiguration.ps1
├── New-SSRSDataSet.ps1
├── New-SSRSDataSource.ps1
├── New-SSRSFolder.ps1
├── New-SSRSReport.ps1
├── New-SSRSWebServiceProxy.ps1
├── New-XmlNamespaceManager.ps1
├── Normalize-SSRSFolder.ps1
├── Publish-SSRSProject.ps1
├── Publish-SSRSSolution.ps1
├── SSRS.psd1
└── SSRS.psm1
├── Usage
├── Usage-FromCredentialFiles.ps1
└── Usage-PlainText.ps1
└── ssrs-powershell-deploy.pssproj
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Per-solution / project / file code formatting settings, automatically configure your preferred editor.
2 | # http://EditorConfig.org
3 | # Visual Studio plugin that reads this file:
4 | # - https://visualstudiogallery.msdn.microsoft.com/c8bccfe2-650c-4b42-bc5c-845e21f96328
5 |
6 | root = true
7 |
8 | [*]
9 | indent_style = tab
10 | insert_final_newline = true
11 |
--------------------------------------------------------------------------------
/.vs/ProjectSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "CurrentProjectSetting": null
3 | }
--------------------------------------------------------------------------------
/.vs/slnx.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timabell/ssrs-powershell-deploy/e50fec64951dad7a2c57a32966191754d5c42a56/.vs/slnx.sqlite
--------------------------------------------------------------------------------
/Example-Reports/.gitignore:
--------------------------------------------------------------------------------
1 | *.data
2 |
--------------------------------------------------------------------------------
/Example-Reports/Example-Reports.rptproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | $base64$PFNvdXJjZUNvbnRyb2xJbmZvIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOmRkbDI9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDAzL2VuZ2luZS8yIiB4bWxuczpkZGwyXzI9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDAzL2VuZ2luZS8yLzIiIHhtbG5zOmRkbDEwMF8xMDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDA4L2VuZ2luZS8xMDAvMTAwIiB4bWxuczpkZGwyMDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDEwL2VuZ2luZS8yMDAiIHhtbG5zOmRkbDIwMF8yMDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDEwL2VuZ2luZS8yMDAvMjAwIiB4bWxuczpkZGwzMDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDExL2VuZ2luZS8zMDAiIHhtbG5zOmRkbDMwMF8zMDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDExL2VuZ2luZS8zMDAvMzAwIiB4bWxuczpkZGw0MDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDEyL2VuZ2luZS80MDAiIHhtbG5zOmRkbDQwMF80MDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDEyL2VuZ2luZS80MDAvNDAwIiB4bWxuczpkd2Q9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vRGF0YVdhcmVob3VzZS9EZXNpZ25lci8xLjAiPg0KICA8RW5hYmxlZD5mYWxzZTwvRW5hYmxlZD4NCiAgPFByb2plY3ROYW1lPjwvUHJvamVjdE5hbWU+DQogIDxBdXhQYXRoPjwvQXV4UGF0aD4NCiAgPExvY2FsUGF0aD48L0xvY2FsUGF0aD4NCiAgPFByb3ZpZGVyPjwvUHJvdmlkZXI+DQo8L1NvdXJjZUNvbnRyb2xJbmZvPg==
4 |
5 |
6 | SomeDatasource.rds
7 | SomeDatasource.rds
8 |
9 |
10 |
11 |
12 | SharedSanity.rsd
13 | SharedSanity.rsd
14 |
15 |
16 |
17 |
18 | sanity-analysis.rdl
19 | sanity-analysis.rdl
20 |
21 |
22 |
23 |
24 | Debug
25 | Win32
26 |
27 | bin\Debug
28 | SSRS2008R2
29 | http://localhost/Reports
30 | ssrs-powershell-deploy/Example-Reports
31 | ssrs-powershell-deploy/Data Sources
32 | ssrs-powershell-deploy/Datasets
33 | ssrs-powershell-deploy/Report Parts
34 |
35 |
36 |
37 | DebugLocal
38 | Win32
39 |
40 | bin\DebugLocal
41 | SSRS2008R2
42 | http://localhost/Reports
43 | ssrs-powershell-deploy/Example-Reports
44 | ssrs-powershell-deploy/Data Sources
45 | ssrs-powershell-deploy/Datasets
46 | ssrs-powershell-deploy/Report Parts
47 |
48 |
49 |
50 | Release
51 | Win32
52 |
53 | bin\Release
54 | SSRS2008R2
55 | http://localhost/Reports
56 | ssrs-powershell-deploy/Example-Reports
57 | ssrs-powershell-deploy/Data Sources
58 | ssrs-powershell-deploy/Datasets
59 | ssrs-powershell-deploy/Report Parts
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/Example-Reports/SharedSanity.rsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SomeDatasource
6 | SELECT COUNT(*) AS madnessCount
7 | FROM reasonsToDislikeSsrs
8 |
9 |
10 |
11 | madnessCount
12 | System.Int32
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Example-Reports/SomeDatasource.rds:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SQL
5 | Data Source=.;Initial Catalog=ssrs_deploy_example
6 | true
7 |
8 | 988a3b3b-d1a8-4923-9dd6-a62ab07c3210
9 |
--------------------------------------------------------------------------------
/Example-Reports/example-db.sql:
--------------------------------------------------------------------------------
1 | create database ssrs_deploy_example;
2 | go
3 | use ssrs_deploy_example;
4 | go
5 | create table reasonsToDislikeSsrs (id int primary key identity(1,1), reason nvarchar(500));
6 | go
7 |
8 | set nocount on;
9 |
10 | insert into reasonsToDislikeSsrs (reason) values ('for the sake of your sanity');
11 | go 100 -- repeat the above sql 100 times
12 |
--------------------------------------------------------------------------------
/Example-Reports/sanity-analysis.rdl:
--------------------------------------------------------------------------------
1 |
2 |
3 | 0
4 |
5 |
6 | SomeDatasource
7 | None
8 | 7260e8d2-ad04-494b-b302-80b2135d0178
9 |
10 |
11 |
12 |
13 |
14 | SomeDatasource
15 | SELECT id, reason
16 | FROM reasonsToDislikeSsrs
17 |
18 |
19 |
20 | id
21 | System.Int32
22 |
23 |
24 | reason
25 | System.String
26 |
27 |
28 |
29 |
30 |
31 | SharedSanity
32 |
33 |
34 |
35 | madnessCount
36 | System.Int32
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | true
47 | true
48 |
49 |
50 |
51 |
52 | Sanity analysis
53 |
54 |
55 |
56 |
57 |
58 |
59 | textbox1
60 | 0.21in
61 | 1.36458in
62 |
68 |
69 |
70 |
71 |
72 |
73 | 1in
74 |
75 |
76 | 4in
77 |
78 |
79 |
80 |
81 | 0.21in
82 |
83 |
84 |
85 |
86 | true
87 | true
88 |
89 |
90 |
91 |
92 | id
93 |
94 |
95 |
96 |
99 |
100 |
101 | textbox2
102 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | true
115 | true
116 |
117 |
118 |
119 |
120 | reason
121 |
122 |
123 |
124 |
125 |
126 |
127 | textbox3
128 |
134 |
135 |
136 |
137 |
138 |
139 |
140 | 0.21in
141 |
142 |
143 |
144 |
145 | true
146 | true
147 |
148 |
149 |
150 |
151 | =Fields!id.Value
152 |
153 |
154 |
155 |
156 |
157 |
158 | id
159 |
165 |
166 |
167 |
168 |
169 |
170 |
171 | true
172 | true
173 |
174 |
175 |
176 |
177 | =Fields!reason.Value
178 |
179 |
180 |
181 |
182 |
183 |
184 | reason
185 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 | After
208 | true
209 | true
210 |
211 |
212 |
213 | Detail
214 |
215 |
216 |
217 |
218 | Detail_Collection
219 | Output
220 | true
221 |
222 |
223 |
224 | EmbeddedDataSet
225 | 0.98486in
226 | 0.42in
227 | 5in
228 | 1
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 | true
239 | true
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 | Textbox7
252 |
256 |
257 | 2pt
258 | 2pt
259 | 2pt
260 | 2pt
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 | 1in
272 |
273 |
274 |
275 |
276 | 0.25in
277 |
278 |
279 |
280 |
281 | true
282 | true
283 |
284 |
285 |
286 |
287 | =Sum(Fields!madnessCount.Value)
288 |
289 |
290 |
291 |
292 |
293 |
294 | madnessCount
295 |
299 |
300 | 2pt
301 | 2pt
302 | 2pt
303 | 2pt
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 | 0.25in
322 |
323 |
324 | true
325 | true
326 |
327 |
328 |
329 |
330 | madness Count
331 |
332 |
333 |
334 |
335 |
336 |
337 | Textbox5
338 |
342 |
343 | 2pt
344 | 2pt
345 | 2pt
346 | 2pt
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 | 1in
364 |
365 |
366 | true
367 | true
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 | Textbox4
380 |
384 |
385 | 2pt
386 | 2pt
387 | 2pt
388 | 2pt
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 | SanityCounter
397 | 0.41542in
398 | 0.5in
399 | 2in
400 | 2
401 |
404 |
405 |
406 |
407 |
408 | 2.1925in
409 |
410 |
411 | 5in
412 |
413 | 1in
414 | 1in
415 | 1in
416 | 1in
417 |
418 |
419 |
420 |
421 | en-US
422 | true
423 | Inch
424 | 6ccbd4ec-b724-44f5-93e0-2ab05ee7364e
425 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SSRS Powershell Deploy
2 |
3 | * https://github.com/timabell/ssrs-powershell-deploy
4 |
5 | PowerShell module to publish SQL Server Reporting Services project(s)
6 | (`.rptproj`) to a Reporting Server
7 |
8 | ## Chat
9 |
10 | [](https://gitter.im/ssrs-powershell-deploy/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
11 |
12 | ## Wiki
13 |
14 | There's a [project wiki on
15 | github](https://github.com/timabell/ssrs-powershell-deploy/wiki), go ahead and
16 | expand it
17 |
18 | ## This fork
19 |
20 | This repository was forked from:
21 |
22 | * https://gist.github.com/Jonesie/9005796
23 | * which was forked from https://gist.github.com/ChrisMissal/5979564
24 | * which was forked from https://gist.github.com/jstangroome/3043878
25 |
26 | I've turned it into a proper github repo to allow discussion, pull requests
27 | etc.
28 |
29 | ## Installation
30 |
31 | ### PowerShell Gallery
32 |
33 | Install the [SSRS module](https://www.powershellgallery.com/packages/SSRS/)
34 | from [PowerShell Gallery](https://www.powershellgallery.com/):
35 |
36 | Make sure you have PowerShell Gallery installed (instructions on their
37 | homepage). It's already available in Windows 10.
38 |
39 | In an elevated powershell console run:
40 |
41 | Install-Module -Name SSRS
42 |
43 | Say `y` to installing from untrusted. Then close the elevated console and you
44 | will now have the `Publish-SSRSProject`/`Solution` commands available in all
45 | your powershell sessions.
46 |
47 | If you can't use the gallery for some reason then you can do a manual install
48 | from a download:
49 |
50 | ### Manual install
51 |
52 | 1. Download the .zip from
53 | https://github.com/timabell/ssrs-powershell-deploy/releases/latest
54 | 2. Right-click the zip file in windows explorer, click "properties", and then
55 | click "Unblock".
56 | 3. Create folder `Documents\WindowsPowerShell\Modules\`
57 | 4. Open up the zip file, copy the SSRS folder, paste it into
58 | `Documents\WindowsPowerShell\Modules\`. (Or somewhere on your
59 | `$env:PSModulePath`)
60 |
61 | ## Usage
62 |
63 | Publish-SSRSProject.ps1 -path YourReportsProject.rptproj -configuration Release -verbose
64 |
65 | You can either specifiy a build configuration to read from the project file, or
66 | you can specify all the information required to publish in the rest of the
67 | parameters.
68 |
69 | Publish-SSRSProject [-Path] [[-Configuration]
70 | ] [[-ServerUrl] ] [[-Folder] ]
71 | [[-DataSourceFolder] ] [[-DataSetFolder] ]
72 | [[-OutputPath] ] [[-OverwriteDataSources] ]
73 | [[-OverwriteDatasets] ] [[-Credential] ]
74 | []
75 |
76 | ## Example reports
77 |
78 | To open the Example-Reports project in Visual Studio you'll need [Sql Server
79 | Data Tools (SSDT)](https://msdn.microsoft.com/en-us/library/mt204009.aspx)
80 |
81 | ## General SSRS gotchas
82 |
83 | Disappearing dataset panel -
84 | http://stackoverflow.com/questions/7960824/i-lost-datasets-pane-in-visual-studio/28883272#28883272
85 |
86 | VS report projects cache both datasets and data. Remove all the `.data` files and the
87 | `bin/` folder(s) to be sure your changes will work when published.
88 | http://stackoverflow.com/questions/3424928/in-ssrs-is-there-a-way-to-disable-the-rdl-data-file-creation
89 |
90 | More SSRS love http://timwise.blogspot.co.uk/2015/08/100-reasons-i-hate-ssrs.html <3 <3
91 |
92 | ## Development
93 |
94 | Developed with [PowerShell Tools for Visual Studio 2015](https://visualstudiogallery.msdn.microsoft.com/c9eb3ba8-0c59-4944-9a62-6eee37294597)
95 |
96 | To test the module locally directly from the source tree you can import by specifiying the path to the psd1 file.
97 |
98 | PS C:\repo\ReportDefinitions> Import-Module C:\repo\tim\ssrs-powershell-deploy\ssrs-powershell-deploy\SSRS\SSRS.psd1
99 | PS C:\repo\ReportDefinitions> Publish-SSRSProject
100 |
101 | See the exported commands with
102 |
103 | PS C:\repo\ReportDefinitions> Get-Command -Module SSRS
104 |
105 | CommandType Name Version Source
106 | ----------- ---- ------- ------
107 | Function Publish-SSRSProject 1.2.0 SSRS
108 | Function Publish-SSRSSolution 1.2.0 SSRS
109 |
110 | Unload again with
111 |
112 | PS C:\repo\ReportDefinitions> Remove-Module SSRS
113 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25123.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{F5034706-568F-408A-B7B3-4D38C6DB8A32}") = "ssrs-powershell-deploy", "ssrs-powershell-deploy\ssrs-powershell-deploy.pssproj", "{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{761E3B09-5200-403C-A893-AE2292154B5F}"
9 | ProjectSection(SolutionItems) = preProject
10 | .editorconfig = .editorconfig
11 | Example-Reports\example-db.sql = Example-Reports\example-db.sql
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Project("{F14B399A-7131-4C87-9E4B-1186C45EF12D}") = "Example-Reports", "Example-Reports\Example-Reports.rptproj", "{80BB4912-31C6-4D99-B273-E4B0F54E81AB}"
16 | EndProject
17 | Global
18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 | Debug|Any CPU = Debug|Any CPU
20 | DebugLocal|Any CPU = DebugLocal|Any CPU
21 | Release|Any CPU = Release|Any CPU
22 | EndGlobalSection
23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
24 | {6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.DebugLocal|Any CPU.ActiveCfg = Debug|Any CPU
27 | {6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.DebugLocal|Any CPU.Build.0 = Debug|Any CPU
28 | {6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|Any CPU.Build.0 = Release|Any CPU
30 | {80BB4912-31C6-4D99-B273-E4B0F54E81AB}.Debug|Any CPU.ActiveCfg = Debug
31 | {80BB4912-31C6-4D99-B273-E4B0F54E81AB}.Debug|Any CPU.Build.0 = Debug
32 | {80BB4912-31C6-4D99-B273-E4B0F54E81AB}.Debug|Any CPU.Deploy.0 = Debug
33 | {80BB4912-31C6-4D99-B273-E4B0F54E81AB}.DebugLocal|Any CPU.ActiveCfg = DebugLocal
34 | {80BB4912-31C6-4D99-B273-E4B0F54E81AB}.DebugLocal|Any CPU.Build.0 = DebugLocal
35 | {80BB4912-31C6-4D99-B273-E4B0F54E81AB}.Release|Any CPU.ActiveCfg = Release
36 | {80BB4912-31C6-4D99-B273-E4B0F54E81AB}.Release|Any CPU.Build.0 = Release
37 | {80BB4912-31C6-4D99-B273-E4B0F54E81AB}.Release|Any CPU.Deploy.0 = Release
38 | EndGlobalSection
39 | GlobalSection(SolutionProperties) = preSolution
40 | HideSolutionNode = FALSE
41 | EndGlobalSection
42 | EndGlobal
43 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/Get-SSRSCredential.ps1:
--------------------------------------------------------------------------------
1 | Function Get-SSRSCredential
2 | {
3 | [CmdletBinding(SupportsShouldProcess=$true)]
4 | param
5 | (
6 | [string] $username,
7 | [string] $password
8 | )
9 |
10 | $script:ErrorActionPreference = 'Stop'
11 |
12 | $pass = ConvertTo-SecureString -AsPlainText -Force -String $password
13 | $user = $username
14 |
15 | $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$pass
16 | return $cred
17 | }
18 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/Get-SSRSProjectConfiguration.ps1:
--------------------------------------------------------------------------------
1 | function Get-SSRSProjectConfiguration{
2 | #requires -version 2.0
3 | [CmdletBinding()]
4 | param (
5 | [parameter(Mandatory=$true)]
6 | [ValidatePattern('\.rptproj$')]
7 | [ValidateScript({ Test-Path -PathType Leaf -Path $_ })]
8 | [string]
9 | $Path,
10 |
11 | [parameter(Mandatory=$true)]
12 | [string]
13 | $Configuration
14 |
15 | )
16 |
17 | $script:ErrorActionPreference = 'Stop'
18 | Set-StrictMode -Version Latest
19 |
20 | Write-Verbose "Reading '$Configuration' config from '$Path'"
21 |
22 | [xml]$Project = Get-Content -Path $Path
23 |
24 | $propertyGroupCount = $Project.Project.PropertyGroup.Count
25 |
26 | for($i = 0; $i -lt $propertyGroupCount; $i++)
27 | {
28 | if($Project.Project.PropertyGroup[$i].FullPath -eq $Configuration)
29 | {
30 | $Config = $Project.Project.PropertyGroup[$i]
31 | break
32 | }
33 | }
34 |
35 | #$Config = $Project.SelectNodes('Project/PropertyGroup') |
36 | # Where-Object { $_.FullPath -eq $Configuration } |
37 | # Select-Object -First 1
38 | if (-not $Config) {
39 | throw "Could not find configuration '$Configuration'."
40 | }
41 |
42 |
43 | $OverwriteDataSources = $false
44 | if ($Config.SelectSingleNode('OverwriteDataSources')) {
45 | $OverwriteDataSources = [Convert]::ToBoolean($Config.OverwriteDataSources)
46 | }
47 |
48 | $OverwriteDatasets = $false
49 | if ($Config.SelectSingleNode('OverwriteDatasets')) {
50 | $OverwriteDatasets = [Convert]::ToBoolean($Config.OverwriteDatasets)
51 | }
52 |
53 |
54 | return New-Object -TypeName PSObject -Property @{
55 | ServerUrl = $Config.TargetServerUrl
56 | Folder = Normalize-SSRSFolder -Folder $Config.TargetReportFolder
57 | DataSourceFolder = Normalize-SSRSFolder -Folder $Config.TargetDataSourceFolder
58 | DataSetFolder = Normalize-SSRSFolder -Folder $Config.TargetDataSetFolder
59 | OutputPath = $Config.OutputPath
60 | OverwriteDataSources = $OverwriteDataSources
61 | OverwriteDatasets = $OverwriteDatasets
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/New-SSRSDataSet.ps1:
--------------------------------------------------------------------------------
1 | function New-SSRSDataSet (
2 | $Proxy,
3 | [string]$RsdPath,
4 | [string]$Folder,
5 | [bool]$Overwrite=$false,
6 | $DataSourcePaths
7 | )
8 | {
9 |
10 | $script:ErrorActionPreference = 'Stop'
11 | Write-Verbose "Processing DataSet '$RsdPath'..."
12 |
13 | $Folder = Normalize-SSRSFolder -Folder $Folder
14 |
15 | $Name = [System.IO.Path]::GetFileNameWithoutExtension($RsdPath)
16 | $RawDefinition = Get-Content -Encoding Byte -Path $RsdPath
17 | [xml]$Rsd = Get-Content -Path $RsdPath
18 | $properties = $null
19 | $warnings = $null
20 |
21 | #Nevermind it always uses filename
22 | # if([string]::IsNullOrEmpty($Rsd.SharedDataSet.DataSet.Name ))
23 | # {
24 | # $Rsd.SharedDataSet.DataSet.Name=$Name
25 | # }
26 |
27 | $FakeResult = New-Object -TypeName PSObject -Property @{
28 | Name = $Rsd.SharedDataSet.DataSet.Name
29 | Path = $Folder + '/' + $Name
30 | }
31 |
32 | $exists = $Proxy.GetItemType($FakeResult.Path) -ne 'Unknown'
33 | $write = $false
34 | if ($exists) {
35 | if ($Overwrite) {
36 | Write-Verbose " - overwriting"
37 | $write = $true
38 | } else {
39 | Write-Verbose " - skipped, already exists"
40 | }
41 | } else {
42 | Write-Verbose " - creating new"
43 | $write = $true
44 | }
45 |
46 | if ($write) {
47 |
48 | # https://msdn.microsoft.com/en-us/library/reportservice2010.reportingservice2010.createcatalogitem.aspx
49 | $Results = $Proxy.CreateCatalogItem("DataSet", $Name, $Folder, $Overwrite, $RawDefinition, $properties, [ref]$warnings)
50 |
51 | $DataSourcePath = $DataSourcePaths[$Rsd.SharedDataSet.DataSet.Query.DataSourceReference]
52 | if ($DataSourcePath) {
53 | $Reference = New-Object -TypeName SSRS.ReportingService2010.ItemReference
54 | $Reference.Reference = $DataSourcePath
55 | $Reference.Name = 'DataSetDataSource' #$Rsd.SharedDataSet.DataSet.Name
56 |
57 | $Proxy.SetItemReferences($Folder + '/' + $Name, @($Reference))
58 |
59 | }
60 | }
61 | else{
62 | $Results=$FakeResult;
63 | }
64 | return $Results
65 | }
66 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/New-SSRSDataSource.ps1:
--------------------------------------------------------------------------------
1 |
2 | function New-SSRSDataSource (
3 | $Proxy,
4 | [string]$RdsPath,
5 | [string]$Folder,
6 | [bool]$Overwrite
7 | )
8 | {
9 | $script:ErrorActionPreference = 'Stop'
10 |
11 | Write-Verbose "Processing DataSource '$RdsPath'..."
12 |
13 | $Folder = Normalize-SSRSFolder -Folder $Folder
14 |
15 | [xml]$Rds = Get-Content -Path $RdsPath
16 | $ConnProps = $Rds.RptDataSource.ConnectionProperties
17 |
18 | $Definition = New-Object -TypeName SSRS.ReportingService2010.DataSourceDefinition
19 | $Definition.ConnectString = $ConnProps.ConnectString
20 | $Definition.Extension = $ConnProps.Extension
21 |
22 |
23 | #Does the IntegratedSecurity property exist
24 | $integratedproperty = $ConnProps | Get-Member -MemberType Property | where {$_.name -like 'IntegratedSecurity'}
25 |
26 | if($integratedproperty -ne $null)
27 | {
28 | if ([Convert]::ToBoolean($ConnProps.IntegratedSecurity)) {
29 | $Definition.CredentialRetrieval = 'Integrated'
30 | }
31 | }
32 | else{
33 | write-verbose "IntegratedSecurity Missing"
34 | }
35 |
36 | $DataSource = New-Object -TypeName PSObject -Property @{
37 | Name = $Rds.RptDataSource.Name
38 | Path = $Folder + '/' + $Rds.RptDataSource.Name
39 | }
40 |
41 | $exists = $Proxy.GetItemType($DataSource.Path) -ne 'Unknown'
42 | $write = $false
43 | if ($exists) {
44 | if ($Overwrite) {
45 | Write-Verbose " - overwriting"
46 | $write = $true
47 | } else {
48 | Write-Verbose " - skipped, already exists"
49 | }
50 | } else {
51 | Write-Verbose " - creating new"
52 | $write = $true
53 | }
54 |
55 | if ($write) {
56 | # assign result to avoid polluting return value. http://stackoverflow.com/a/23225503/10245
57 | # Oh what an ugly language powerhell is. :-/
58 | $foo = $Proxy.CreateDataSource($DataSource.Name, $Folder, $Overwrite, $Definition, $null)
59 | }
60 |
61 | return $DataSource
62 | }
63 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/New-SSRSFolder.ps1:
--------------------------------------------------------------------------------
1 | function New-SSRSFolder (
2 | $Proxy,
3 | [string]
4 | $Name,
5 | [switch]
6 | $Recursing
7 | )
8 | {
9 | $script:ErrorActionPreference = 'Stop'
10 |
11 | if (!$recursing) {
12 | Write-Verbose "Creating SSRS folder '$Name'"
13 | }
14 |
15 | $Name = Normalize-SSRSFolder -Folder $Name
16 |
17 | if ($Proxy.GetItemType($Name) -ne 'Folder') {
18 | $Parts = $Name -split '/'
19 | $Leaf = $Parts[-1]
20 | $Parent = $Parts[0..($Parts.Length-2)] -join '/'
21 |
22 | if ($Parent) {
23 | New-SSRSFolder -Proxy $Proxy -Name $Parent -Recursing
24 | } else {
25 | $Parent = '/'
26 | }
27 |
28 | # create folder, suppressing console output from proxy
29 | $Proxy.CreateFolder($Leaf, $Parent, $null) > $null
30 | } else {
31 | if (!$recursing) {
32 | Write-Verbose " - skipped, already exists"
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/New-SSRSReport.ps1:
--------------------------------------------------------------------------------
1 | function New-SSRSReport (
2 | $Proxy,
3 | [string]$RdlPath,
4 | $RdlName
5 | )
6 | {
7 | $script:ErrorActionPreference = 'Stop'
8 |
9 | [xml]$Definition = Get-Content -Path $RdlPath
10 | $NsMgr = New-XmlNamespaceManager $Definition d
11 |
12 | $RawDefinition = Get-Content -Encoding Byte -Path $RdlPath
13 |
14 | $Name = $RdlName -replace '\.rdl$',''
15 |
16 | $DescProp = New-Object -TypeName SSRS.ReportingService2010.Property
17 | $DescProp.Name = 'Description'
18 | $DescProp.Value = ''
19 | $HiddenProp = New-Object -TypeName SSRS.ReportingService2010.Property
20 | $HiddenProp.Name = 'Hidden'
21 | $HiddenProp.Value = 'false'
22 | $Properties = @($DescProp, $HiddenProp)
23 |
24 | $Xpath = 'd:Report/d:Description'
25 | $DescriptionNode = $Definition.SelectSingleNode($Xpath, $NsMgr)
26 |
27 | if($DescriptionNode)
28 | {
29 | $DescProp.Value = $DescriptionNode.Value
30 | }
31 |
32 | if($Name.StartsWith('_'))
33 | {
34 | $HiddenProp.Value = 'true'
35 | }
36 |
37 | Write-Verbose "Creating report $Name"
38 | $warnings = $null
39 | $Results = $Proxy.CreateCatalogItem("Report", $Name, $Folder, $true, $RawDefinition, $Properties, [ref]$warnings)
40 |
41 | $Xpath = 'd:Report/d:DataSources/d:DataSource/d:DataSourceReference/..'
42 | $DataSources = $Definition.SelectNodes($Xpath, $NsMgr) |
43 | ForEach-Object {
44 | $DataSourcePath = $DataSourcePaths[$_.DataSourceReference]
45 | if (-not $DataSourcePath) {
46 | throw "Invalid data source reference '$($_.DataSourceReference)' in $RdlPath"
47 | }
48 | $Reference = New-Object -TypeName SSRS.ReportingService2010.DataSourceReference
49 | $Reference.Reference = $DataSourcePath
50 | $DataSource = New-Object -TypeName SSRS.ReportingService2010.DataSource
51 | $DataSource.Item = $Reference
52 | $DataSource.Name = $_.Name
53 | $DataSource
54 | }
55 | if ($DataSources) {
56 | $Proxy.SetItemDataSources($Folder + '/' + $Name, $DataSources)
57 | }
58 |
59 | $Xpath = 'd:Report/d:DataSets/d:DataSet/d:SharedDataSet/d:SharedDataSetReference/../..'
60 | $References = $Definition.SelectNodes($Xpath, $NsMgr) |
61 | ForEach-Object {
62 | $DataSetPath = $DataSetPaths[$_.SharedDataSet.SharedDataSetReference]
63 | if ($DataSetPath) {
64 | $Reference = New-Object -TypeName SSRS.ReportingService2010.ItemReference
65 | $Reference.Reference = $DataSetPath
66 | $Reference.Name = $_.Name
67 | $Reference
68 | }
69 | }
70 | if ($References) {
71 | $Proxy.SetItemReferences($Folder + '/' + $Name, $References)
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/New-SSRSWebServiceProxy.ps1:
--------------------------------------------------------------------------------
1 | Function New-SSRSWebServiceProxy
2 | {
3 | #requires -version 2.0
4 | [CmdletBinding()]
5 | param (
6 | [parameter(Mandatory=$true)]
7 | [ValidatePattern('^https?://')]
8 | [string]
9 | $Uri,
10 |
11 | [System.Management.Automation.PSCredential]
12 | $Credential
13 | )
14 |
15 | $script:ErrorActionPreference = 'Stop'
16 | Set-StrictMode -Version Latest
17 |
18 | if (-not $Uri.EndsWith('.asmx')) {
19 | if (-not $Uri.EndsWith('/')) {
20 | $Uri += '/'
21 | }
22 | $Uri += 'ReportService2010.asmx'
23 | }
24 |
25 | $Assembly = [AppDomain]::CurrentDomain.GetAssemblies() |
26 | Where-Object {
27 | $_.GetType('SSRS.ReportingService2010.ReportingService2010')
28 | }
29 | if (($Assembly | Measure-Object).Count -gt 1) {
30 | throw 'AppDomain contains multiple definitions of the same type. Restart PowerShell host.'
31 | }
32 |
33 | if (-not $Assembly) {
34 |
35 | if ($Credential) {
36 | $CredParams = @{ Credential = $Credential }
37 | } else {
38 | $CredParams = @{ UseDefaultCredential = $true }
39 | }
40 | $Proxy = New-WebServiceProxy -Uri $Uri -Namespace SSRS.ReportingService2010 @CredParams
41 |
42 | } else {
43 |
44 | $Proxy = New-Object -TypeName SSRS.ReportingService2010.ReportingService2010
45 | if ($Credential) {
46 | $Proxy.Credentials = $Credential.GetNetworkCredential()
47 | } else {
48 | $Proxy.UseDefaultCredentials = $true
49 | }
50 |
51 | }
52 |
53 | $Proxy.Url = $Uri
54 | return $Proxy
55 | }
56 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/New-XmlNamespaceManager.ps1:
--------------------------------------------------------------------------------
1 | function New-XmlNamespaceManager ($XmlDocument, $DefaultNamespacePrefix) {
2 |
3 | $script:ErrorActionPreference = 'Stop'
4 |
5 | $NsMgr = New-Object -TypeName System.Xml.XmlNamespaceManager -ArgumentList $XmlDocument.NameTable
6 | $DefaultNamespace = $XmlDocument.DocumentElement.GetAttribute('xmlns')
7 | if ($DefaultNamespace -and $DefaultNamespacePrefix) {
8 | $NsMgr.AddNamespace($DefaultNamespacePrefix, $DefaultNamespace)
9 | }
10 | return ,$NsMgr # unary comma wraps $NsMgr so it isn't unrolled
11 | }
12 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/Normalize-SSRSFolder.ps1:
--------------------------------------------------------------------------------
1 | function Normalize-SSRSFolder (
2 | [string]$Folder
3 | )
4 | {
5 | $script:ErrorActionPreference = 'Stop'
6 | if (-not $Folder.StartsWith('/')) {
7 | $Folder = '/' + $Folder
8 | }
9 |
10 | if($Folder.EndsWith('/')) {
11 | $Folder = $Folder.Substring(0, $Folder.Length -1)
12 | }
13 |
14 | return $Folder
15 | }
16 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/Publish-SSRSProject.ps1:
--------------------------------------------------------------------------------
1 | function Publish-SSRSProject{
2 | #requires -version 2.0
3 | # https://github.com/timabell/ssrs-powershell-deploy
4 | [CmdletBinding()]
5 | param (
6 | [parameter(Mandatory=$true)]
7 | [ValidatePattern('\.rptproj$')]
8 | [ValidateScript({ Test-Path -PathType Leaf -Path $_ })]
9 | [string]
10 | $Path,
11 |
12 | [parameter(Mandatory=$false)]
13 | [string]
14 | $Configuration,
15 |
16 | [parameter(Mandatory=$false)]
17 | [ValidatePattern('^https?://')]
18 | [string]
19 | $ServerUrl, #THESE ARE NOW OVERRRIDES IF $Configuration is specified
20 |
21 | [parameter(Mandatory=$false)]
22 | [string]
23 | $Folder, #THESE ARE NOW OVERRRIDES IF $Configuration is specified
24 |
25 | [parameter(Mandatory=$false)]
26 | [string]
27 | $DataSourceFolder, #THESE ARE NOW OVERRRIDES IF $Configuration is specified
28 |
29 | [parameter(Mandatory=$false)]
30 | [string]
31 | $DataSetFolder, #THESE ARE NOW OVERRRIDES IF $Configuration is specified
32 |
33 | [parameter(Mandatory=$false)]
34 | [string]
35 | $OutputPath, #THESE ARE NOW OVERRRIDES IF $Configuration is specified
36 |
37 | [parameter(Mandatory=$false)]
38 | [bool]
39 | $OverwriteDataSources, #THESE ARE NOW OVERRRIDES IF $Configuration is specified
40 |
41 | [parameter(Mandatory=$false)]
42 | [bool]
43 | $OverwriteDatasets, #THESE ARE NOW OVERRRIDES IF $Configuration is specified
44 |
45 |
46 | [System.Management.Automation.PSCredential]
47 | $Credential
48 | )
49 |
50 |
51 | $script:ErrorActionPreference = 'Stop'
52 | Set-StrictMode -Version Latest
53 |
54 | $Path = $Path | Convert-Path
55 | $ProjectRoot = $Path | Split-Path
56 | [xml]$Project = Get-Content -Path $Path
57 |
58 |
59 |
60 | #Argument validation
61 | if(![string]::IsNullOrEmpty($Configuration))
62 | {
63 | $Config = Get-SSRSProjectConfiguration -Path $Path -Configuration $Configuration
64 |
65 | if([string]::IsNullOrEmpty($ServerUrl))
66 | {
67 | Write-Verbose "Using Project Server URL: $($Config.ServerUrl)"
68 | $ServerUrl = $Config.ServerUrl
69 | }
70 |
71 | if([string]::IsNullOrEmpty($Folder))
72 | {
73 | Write-Verbose "Using Project Folder : $($Config.Folder)"
74 | $Folder = $Config.Folder
75 | }
76 |
77 | if([string]::IsNullOrEmpty($DataSourceFolder))
78 | {
79 | Write-Verbose "Using Project DataSourceFolder: $($Config.DataSourceFolder)"
80 | $DataSourceFolder = $Config.DataSourceFolder
81 | }
82 |
83 | if([string]::IsNullOrEmpty($DataSetFolder))
84 | {
85 | Write-Verbose "Using Project DataSetFolder: $($Config.DataSetFolder)"
86 | $DataSetFolder = $Config.DataSetFolder
87 | }
88 |
89 | if([string]::IsNullOrEmpty($OutputPath))
90 | {
91 | Write-Verbose "Using Project OutputPath: $($Config.OutputPath)"
92 | $OutputPath = $Config.OutputPath
93 | }
94 |
95 | if(!$PSBoundParameters.ContainsKey("OverwriteDataSources"))
96 | {
97 | Write-Verbose "Using Project OverwriteDataSources: $($Config.OverwriteDataSources)"
98 | $OverwriteDataSources = $Config.OverwriteDataSources
99 | }
100 |
101 | if(!$PSBoundParameters.ContainsKey("OverwriteDatasets"))
102 | {
103 | Write-Verbose "Using Project OverwriteDatasets: $($Config.OverwriteDatasets)"
104 | $OverwriteDatasets = $Config.OverwriteDatasets
105 | }
106 |
107 |
108 | }
109 |
110 | $Project.SelectNodes('Project/Reports/ProjectItem') |
111 | ForEach-Object {
112 | $CompiledRdlPath = $ProjectRoot | Join-Path -ChildPath $OutputPath | join-path -ChildPath $_.FullPath
113 | $RdlPath = $ProjectRoot | join-path -ChildPath $_.FullPath
114 |
115 | if ((test-path $CompiledRdlPath) -eq $false)
116 | {
117 | write-error ('Report "{0}" is listed in the project but wasn''t found in the bin\ folder. Rebuild your project before publishing.' -f $CompiledRdlPath)
118 | break;
119 | }
120 | $RdlLastModified = (get-item $RdlPath).LastWriteTime
121 | $CompiledRdlLastModified = (get-item $CompiledRdlPath).LastWriteTime
122 | if ($RdlLastModified -gt $CompiledRdlLastModified)
123 | {
124 | write-error ('Report "{0}" in bin\ is older than source file "{1}". Rebuild your project before publishing.' -f $CompiledRdlPath,$RdlPath)
125 | break;
126 | }
127 | }
128 |
129 |
130 | $Folder = Normalize-SSRSFolder -Folder $Folder
131 | $DataSourceFolder = Normalize-SSRSFolder -Folder $DataSourceFolder
132 |
133 | $Proxy = New-SSRSWebServiceProxy -Uri $ServerUrl -Credential $Credential
134 |
135 | $FullServerPath = $Proxy.Url
136 | Write-Verbose "Connecting to: $FullServerPath"
137 |
138 | New-SSRSFolder -Proxy $Proxy -Name $Folder
139 | New-SSRSFolder -Proxy $Proxy -Name $DataSourceFolder
140 | New-SSRSFolder -Proxy $Proxy -Name $DataSetFolder
141 |
142 | $DataSourcePaths = @{}
143 | for($i = 0; $i -lt $Project.Project.ItemGroup[0].DataSource.Count; $i++) {
144 | $RdsPath = $ProjectRoot | Join-Path -ChildPath $Project.Project.ItemGroup[0].DataSource[$i].Include
145 |
146 | $DataSource = New-SSRSDataSource -Proxy $Proxy -RdsPath $RdsPath -Folder $DataSourceFolder -Overwrite $OverwriteDataSources
147 | $DataSourcePaths.Add($DataSource.Name, $DataSource.Path)
148 | }
149 |
150 | $DataSetPaths = @{}
151 | $Project.SelectNodes('Project/DataSets/ProjectItem') |
152 | ForEach-Object {
153 | $RsdPath = $ProjectRoot | Join-Path -ChildPath $_.FullPath
154 | $DataSet = New-SSRSDataSet -Proxy $Proxy -RsdPath $RsdPath -Folder $DataSetFolder -DataSourcePaths $DataSourcePaths -Overwrite $OverwriteDatasets
155 | if(-not $DataSetPaths.Contains($DataSet.Name))
156 | {
157 | $DataSetPaths.Add($DataSet.Name, $DataSet.Path)
158 | }
159 | }
160 |
161 | for($i = 0; $i -lt $Project.Project.ItemGroup[1].Report.Count; $i++) {
162 |
163 | $extension = $Project.Project.ItemGroup[1].Report[$i].Include.Substring($Project.Project.ItemGroup[1].Report[$i].Include.length - 3 , 3)
164 |
165 | if(ImageExtensionValid -ext $extension){
166 |
167 | $PathImage = $ProjectRoot | Join-Path -ChildPath $Project.Project.ItemGroup[1].Report[$i].Include
168 | $RawDefinition = Get-Content -Encoding Byte -Path $PathImage
169 |
170 | $DescProp = New-Object -TypeName SSRS.ReportingService2010.Property
171 | $DescProp.Name = 'Description'
172 | $DescProp.Value = ''
173 | $HiddenProp = New-Object -TypeName SSRS.ReportingService2010.Property
174 | $HiddenProp.Name = 'Hidden'
175 | $HiddenProp.Value = 'false'
176 | $MimeProp = New-Object -TypeName SSRS.ReportingService2010.Property
177 | $MimeProp.Name = 'MimeType'
178 | $MimeProp.Value = 'image/' + $extension
179 |
180 | $Properties = @($DescProp, $HiddenProp, $MimeProp)
181 |
182 | $Name = $Project.Project.ItemGroup[1].Report[$i].Include
183 | Write-Verbose "Creating resource $Name"
184 | $warnings = $null
185 | $Results = $Proxy.CreateCatalogItem("Resource", $Project.Project.ItemGroup[1].Report[$i].Include, $Folder, $true, $RawDefinition, $Properties, [ref]$warnings)
186 | }
187 | }
188 |
189 | for($i = 0; $i -lt $Project.Project.ItemGroup[1].Report.Count; $i++) {
190 | if($Project.Project.ItemGroup[1].Report[$i].Include.EndsWith('.rdl')){
191 | $CompiledRdlPath = $ProjectRoot | Join-Path -ChildPath $OutputPath | join-path -ChildPath $Project.Project.ItemGroup[1].Report[$i].Include
192 | New-SSRSReport -Proxy $Proxy -RdlPath $CompiledRdlPath -RdlName $Project.Project.ItemGroup[1].Report[$i].Include
193 | }
194 | }
195 |
196 | Write-host "Completed."
197 | }
198 |
199 | function ImageExtensionValid($ext){
200 | $valid = 0;
201 |
202 | Switch($ext)
203 | {
204 | 'png' { $valid = 1; }
205 | 'bmp' { $valid = 1; }
206 | 'gif' { $valid = 1; }
207 | 'jpg' { $valid = 1; }
208 | }
209 |
210 | return $valid;
211 | }
212 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/Publish-SSRSSolution.ps1:
--------------------------------------------------------------------------------
1 | function Publish-SSRSSolution{
2 | #requires -version 2.0
3 | [CmdletBinding()]
4 | # Path is the full path to the solution file, including the file name.
5 | # i.e. D:\dev\Reports\Reports.sln
6 | param (
7 | [parameter(Mandatory=$true)]
8 | [ValidateScript({ Test-Path -Path $_ -PathType Leaf })]
9 | [string]
10 | $Solution,
11 |
12 | [parameter(
13 | ParameterSetName='Configuration',
14 | Mandatory=$true)]
15 | [string]
16 | $Configuration,
17 |
18 | [System.Management.Automation.PSCredential]
19 | $credentials
20 | )
21 |
22 | $ErrorActionPreference = 'Stop'
23 | Set-StrictMode -Version Latest
24 |
25 | # Get credentials, interactive
26 | #$credentials = Get-Credential
27 | # non-interactive
28 | #$secpasswd = ConvertTo-SecureString "PlainTextPassword" -AsPlainText -Force
29 | #$mycreds = New-Object System.Management.Automation.PSCredential ("username", $secpasswd)
30 |
31 | $Solution = ($Solution | Resolve-Path).ProviderPath
32 |
33 | $SolutionRoot = $Solution | Split-Path
34 |
35 | # Guid is for the Reports project type.
36 | $SolutionProjectPattern = @"
37 | (?x)
38 | ^ Project \( " \{ F14B399A-7131-4C87-9E4B-1186C45EF12D \} " \)
39 | \s* = \s*
40 | " (? [^"]* ) " , \s+
41 | " (? [^"]* ) " , \s+
42 | "@
43 |
44 | Get-Content -Path $Solution |
45 | ForEach-Object {
46 | if ($_ -match $SolutionProjectPattern) {
47 | $ProjectPath = $SolutionRoot | Join-Path -ChildPath $Matches['path']
48 | $ProjectPath = ($ProjectPath | Resolve-Path).ProviderPath
49 | #"$ProjectPath" = full path to the project file
50 |
51 | & Publish-SSRSProject -path $ProjectPath -configuration $configuration -verbose -credential $credentials
52 | }
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/SSRS.psd1:
--------------------------------------------------------------------------------
1 | @{
2 | RootModule = "SSRS"
3 | ModuleVersion = '1.3.0'
4 | GUID = '58a90a5a-fba6-464c-8906-65d78d08d398'
5 | Author = 'Tim Abell and others'
6 | Description = 'https://github.com/timabell/ssrs-powershell-deploy - PowerShell module to deploy SQL Server Reporting Services project(s) (`.rptproj`) to a Reporting Server'
7 | HelpInfoURI = 'https://github.com/timabell/ssrs-powershell-deploy'
8 | FunctionsToExport = @("Publish-SSRSProject", "Publish-SSRSSolution")
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/SSRS/SSRS.psm1:
--------------------------------------------------------------------------------
1 |
2 | #Dot source all ps1 files
3 | #These are the small function used by others
4 | . $PSScriptRoot\Get-SSRSCredential.ps1
5 | . $PSScriptRoot\Normalize-SSRSFolder.ps1
6 | . $PSScriptRoot\New-XmlNamespaceManager.ps1
7 |
8 | . $PSScriptRoot\New-SSRSFolder.ps1
9 | . $PSScriptRoot\New-SSRSDataSource.ps1
10 | . $PSScriptRoot\New-SSRSDataSet.ps1
11 | . $PSScriptRoot\New-SSRSReport.ps1
12 |
13 |
14 | #Larger methods that might use some of the ones above
15 | . $PSScriptRoot\New-SSRSWebServiceProxy.ps1
16 | . $PSScriptRoot\Get-SSRSProjectConfiguration.ps1
17 | . $PSScriptRoot\Publish-SSRSProject.ps1
18 | . $PSScriptRoot\Publish-SSRSSolution.ps1
19 |
20 | Export-ModuleMember Get-SSRSCredential, Normalize-SSRSFolder, New-XmlNamespaceManager, New-SSRSFolder, New-SSRSDataSource, New-SSRSDataSet, New-SSRSReport, New-SSRSWebServiceProxy, Get-SSRSProjectConfiguration, Publish-SSRSProject, Publish-SSRSSolution
21 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/Usage/Usage-FromCredentialFiles.ps1:
--------------------------------------------------------------------------------
1 | if (-not (Test-Path("cred2.txt"))) {
2 | Write-Host "=========================================================" -foregroundcolor cyan
3 | Write-Host "» To publish the Debug configuration to localhost, type"
4 | Write-Host "» your credentials. It will be stored as a SecureString"
5 | Write-Host "» on disk, but not checked into source control."
6 | Write-Host "» Username: " -foregroundcolor cyan; Read-Host | Out-File cred1.txt
7 | Write-Host "» Password: " -foregroundcolor cyan; Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File cred2.txt
8 | }
9 |
10 | $pass = cat cred2.txt | ConvertTo-SecureString
11 | $user = cat cred1.txt
12 | $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$pass
13 |
14 | Write-Host "Publish started..." -foregroundcolor yellow
15 |
16 | Import-Module .\Module\SSRS.psm1
17 |
18 | Publish-SSRSProject -Path 'pathtoproject\ProjectFile.rptproj' -Configuration 'Debug' -Credential $cred
19 |
20 | Write-Host "Publish finished!" -foregroundcolor green
21 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/Usage/Usage-PlainText.ps1:
--------------------------------------------------------------------------------
1 |
2 | $pass = "password"
3 | $user = "username"
4 |
5 | Import-Module .\Module\SSRS.psm1
6 |
7 | Write-Host "Publish started..." -foregroundcolor yellow
8 | $cred=Get-SSRSCredential -username $user -password $pass
9 | Publish-SSRSProject -Verbose -Path 'pathtoproject\ProjectFile.rptproj' -Configuration 'Release' -Credential $cred
10 |
11 | Write-Host "Publish finished!" -foregroundcolor green
12 |
--------------------------------------------------------------------------------
/ssrs-powershell-deploy/ssrs-powershell-deploy.pssproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | 2.0
6 | 6CAFC0C6-A428-4d30-A9F9-700E829FEA51
7 | Exe
8 | MyApplication
9 | MyApplication
10 | ssrs-powershell-deploy
11 | -path 'Example-Reports\Example-Reports.rptproj' -configuration Release -verbose -debug
12 | Multiple contributors
13 |
14 |
15 | https://github.com/timabell/ssrs-powershell-deploy
16 |
17 | PowerShell module to deploy SQL Server Reporting Services project(s) (`.rptproj`) to a Reporting Server
18 | 93d8a973-f14f-41b3-9faa-6eefd4cd8b43
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | DEBUG;TRACE
26 | prompt
27 | 4
28 |
29 |
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------