";
286 |
287 | return pageSource.Contains(unavailableString);
288 | }
289 |
290 | private static JObject LoadJson(string pageSource)
291 | {
292 | var dataRegex = new Regex(@"ytplayer\.config\s*=\s*(\{.+?\});", RegexOptions.Multiline);
293 |
294 | string extractedJson = dataRegex.Match(pageSource).Result("$1");
295 |
296 | return JObject.Parse(extractedJson);
297 | }
298 |
299 | private static void ThrowYoutubeParseException(Exception innerException, string videoUrl)
300 | {
301 | throw new YoutubeParseException("Could not parse the Youtube page for URL " + videoUrl + "\n" +
302 | "This may be due to a change of the Youtube page structure.\n" +
303 | "Please report this bug at www.github.com/flagbug/YoutubeExtractor/issues",
304 | innerException);
305 | }
306 |
307 | private class ExtractionInfo
308 | {
309 | public bool RequiresDecryption { get; set; }
310 |
311 | public Uri Uri { get; set; }
312 | }
313 | }
314 | }
--------------------------------------------------------------------------------
/src/YoutubeExtractorCore.Example/Properties/PublishProfiles/publish-module.psm1:
--------------------------------------------------------------------------------
1 | # WARNING: DO NOT MODIFY this file. Visual Studio will override it.
2 | param()
3 |
4 | $script:AspNetPublishHandlers = @{}
5 |
6 | <#
7 | These settings can be overridden with environment variables.
8 | The name of the environment variable should use "Publish" as a
9 | prefix and the names below. For example:
10 |
11 | $env:PublishMSDeployUseChecksum = $true
12 | #>
13 | $global:AspNetPublishSettings = New-Object -TypeName PSCustomObject @{
14 | MsdeployDefaultProperties = @{
15 | 'MSDeployUseChecksum'=$false
16 | 'SkipExtraFilesOnServer'=$true
17 | 'retryAttempts' = 20
18 | 'EnableMSDeployBackup' = $false
19 | 'DeleteExistingFiles' = $false
20 | 'AllowUntrustedCertificate'= $false
21 | 'MSDeployPackageContentFoldername'='website\'
22 | 'EnvironmentName' = 'Production'
23 | 'AuthType'='Basic'
24 | 'MSDeployPublishMethod'='WMSVC'
25 | }
26 | }
27 |
28 | function InternalOverrideSettingsFromEnv{
29 | [cmdletbinding()]
30 | param(
31 | [Parameter(Position=0)]
32 | [object[]]$settings = ($global:AspNetPublishSettings,$global:AspNetPublishSettings.MsdeployDefaultProperties),
33 |
34 | [Parameter(Position=1)]
35 | [string]$prefix = 'Publish'
36 | )
37 | process{
38 | foreach($settingsObj in $settings){
39 | if($settingsObj -eq $null){
40 | continue
41 | }
42 |
43 | $settingNames = $null
44 | if($settingsObj -is [hashtable]){
45 | $settingNames = $settingsObj.Keys
46 | }
47 | else{
48 | $settingNames = ($settingsObj | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name)
49 |
50 | }
51 |
52 | foreach($name in @($settingNames)){
53 | $fullname = ('{0}{1}' -f $prefix,$name)
54 | if(Test-Path "env:$fullname"){
55 | $settingsObj.$name = ((get-childitem "env:$fullname").Value)
56 | }
57 | }
58 | }
59 | }
60 | }
61 |
62 | InternalOverrideSettingsFromEnv -prefix 'Publish' -settings $global:AspNetPublishSettings,$global:AspNetPublishSettings.MsdeployDefaultProperties
63 |
64 | function Register-AspnetPublishHandler{
65 | [cmdletbinding()]
66 | param(
67 | [Parameter(Mandatory=$true,Position=0)]
68 | $name,
69 | [Parameter(Mandatory=$true,Position=1)]
70 | [ScriptBlock]$handler,
71 | [switch]$force
72 | )
73 | process{
74 | if(!($script:AspNetPublishHandlers[$name]) -or $force ){
75 | 'Adding handler for [{0}]' -f $name | Write-Verbose
76 | $script:AspNetPublishHandlers[$name] = $handler
77 | }
78 | elseif(!($force)){
79 | 'Ignoring call to Register-AspnetPublishHandler for [name={0}], because a handler with that name exists and -force was not passed.' -f $name | Write-Verbose
80 | }
81 | }
82 | }
83 |
84 | function Get-AspnetPublishHandler{
85 | [cmdletbinding()]
86 | param(
87 | [Parameter(Mandatory=$true,Position=0)]
88 | $name
89 | )
90 | process{
91 | $foundHandler = $script:AspNetPublishHandlers[$name]
92 |
93 | if(!$foundHandler){
94 | throw ('AspnetPublishHandler with name "{0}" was not found' -f $name)
95 | }
96 |
97 | $foundHandler
98 | }
99 | }
100 |
101 | function GetInternal-ExcludeFilesArg{
102 | [cmdletbinding()]
103 | param(
104 | $publishProperties
105 | )
106 | process{
107 | $excludeFiles = $publishProperties['ExcludeFiles']
108 | foreach($exclude in $excludeFiles){
109 | if($exclude){
110 | [string]$objName = $exclude['objectname']
111 |
112 | if([string]::IsNullOrEmpty($objName)){
113 | $objName = 'filePath'
114 | }
115 |
116 | $excludePath = $exclude['absolutepath']
117 |
118 | # output the result to the return list
119 | ('-skip:objectName={0},absolutePath=''{1}''' -f $objName, $excludePath)
120 | }
121 | }
122 | }
123 | }
124 |
125 | function GetInternal-ReplacementsMSDeployArgs{
126 | [cmdletbinding()]
127 | param(
128 | $publishProperties
129 | )
130 | process{
131 | foreach($replace in ($publishProperties['Replacements'])){
132 | if($replace){
133 | $typeValue = $replace['type']
134 | if(!$typeValue){ $typeValue = 'TextFile' }
135 |
136 | $file = $replace['file']
137 | $match = $replace['match']
138 | $newValue = $replace['newValue']
139 |
140 | if($file -and $match -and $newValue){
141 | $setParam = ('-setParam:type={0},scope={1},match={2},value={3}' -f $typeValue,$file, $match,$newValue)
142 | 'Adding setparam [{0}]' -f $setParam | Write-Verbose
143 |
144 | # return it
145 | $setParam
146 | }
147 | else{
148 | 'Skipping replacement because its missing a required value.[file="{0}",match="{1}",newValue="{2}"]' -f $file,$match,$newValue | Write-Verbose
149 | }
150 | }
151 | }
152 | }
153 | }
154 |
155 | <#
156 | .SYNOPSIS
157 | Returns an array of msdeploy arguments that are used across different providers.
158 | For example this will handle useChecksum, AppOffline etc.
159 | This will also add default properties if they are missing.
160 | #>
161 | function GetInternal-SharedMSDeployParametersFrom{
162 | [cmdletbinding()]
163 | param(
164 | [Parameter(Mandatory=$true,Position=0)]
165 | [HashTable]$publishProperties,
166 | [Parameter(Mandatory=$true,Position=1)]
167 | [System.IO.FileInfo]$packOutput
168 | )
169 | process{
170 | $sharedArgs = New-Object psobject -Property @{
171 | ExtraArgs = @()
172 | DestFragment = ''
173 | EFMigrationData = @{}
174 | }
175 |
176 | # add default properties if they are missing
177 | foreach($propName in $global:AspNetPublishSettings.MsdeployDefaultProperties.Keys){
178 | if($publishProperties["$propName"] -eq $null){
179 | $defValue = $global:AspNetPublishSettings.MsdeployDefaultProperties["$propName"]
180 | 'Adding default property to publishProperties ["{0}"="{1}"]' -f $propName,$defValue | Write-Verbose
181 | $publishProperties["$propName"] = $defValue
182 | }
183 | }
184 |
185 | if($publishProperties['MSDeployUseChecksum'] -eq $true){
186 | $sharedArgs.ExtraArgs += '-usechecksum'
187 | }
188 |
189 | if($publishProperties['EnableMSDeployAppOffline'] -eq $true){
190 | $sharedArgs.ExtraArgs += '-enablerule:AppOffline'
191 | }
192 |
193 | if($publishProperties['WebPublishMethod'] -eq 'MSDeploy'){
194 | if($publishProperties['SkipExtraFilesOnServer'] -eq $true){
195 | $sharedArgs.ExtraArgs += '-enableRule:DoNotDeleteRule'
196 | }
197 | }
198 |
199 | if($publishProperties['WebPublishMethod'] -eq 'FileSystem'){
200 | if($publishProperties['DeleteExistingFiles'] -eq $false){
201 | $sharedArgs.ExtraArgs += '-enableRule:DoNotDeleteRule'
202 | }
203 | }
204 |
205 | if($publishProperties['retryAttempts']){
206 | $sharedArgs.ExtraArgs += ('-retryAttempts:{0}' -f ([int]$publishProperties['retryAttempts']))
207 | }
208 |
209 | if($publishProperties['EncryptWebConfig'] -eq $true){
210 | $sharedArgs.ExtraArgs += '-EnableRule:EncryptWebConfig'
211 | }
212 |
213 | if($publishProperties['EnableMSDeployBackup'] -eq $false){
214 | $sharedArgs.ExtraArgs += '-disablerule:BackupRule'
215 | }
216 |
217 | if($publishProperties['AllowUntrustedCertificate'] -eq $true){
218 | $sharedArgs.ExtraArgs += '-allowUntrusted'
219 | }
220 |
221 | # add excludes
222 | $sharedArgs.ExtraArgs += (GetInternal-ExcludeFilesArg -publishProperties $publishProperties)
223 | # add replacements
224 | $sharedArgs.ExtraArgs += (GetInternal-ReplacementsMSDeployArgs -publishProperties $publishProperties)
225 |
226 | # add EF Migration
227 | if (($publishProperties['EfMigrations'] -ne $null) -and $publishProperties['EfMigrations'].Count -gt 0){
228 | if (!(Test-Path -Path $publishProperties['ProjectPath'])) {
229 | throw 'ProjectPath property needs to be defined in the pubxml for EF migration.'
230 | }
231 | try {
232 | # generate T-SQL files
233 | $EFSqlFiles = GenerateInternal-EFMigrationScripts -projectPath $publishProperties['ProjectPath'] -packOutput $packOutput -EFMigrations $publishProperties['EfMigrations']
234 | $sharedArgs.EFMigrationData.Add('EFSqlFiles',$EFSqlFiles)
235 | }
236 | catch {
237 | throw ('An error occurred while generating EF migrations. {0} {1}' -f $_.Exception,(Get-PSCallStack))
238 | }
239 | }
240 | # add connection string update
241 | if (($publishProperties['DestinationConnectionStrings'] -ne $null) -and $publishProperties['DestinationConnectionStrings'].Count -gt 0) {
242 | try {
243 | # create/update appsettings.[environment].json
244 | GenerateInternal-AppSettingsFile -packOutput $packOutput -environmentName $publishProperties['EnvironmentName'] -connectionStrings $publishProperties['DestinationConnectionStrings']
245 | }
246 | catch {
247 | throw ('An error occurred while generating the publish appsettings file. {0} {1}' -f $_.Exception,(Get-PSCallStack))
248 | }
249 | }
250 |
251 | if(-not [string]::IsNullOrWhiteSpace($publishProperties['ProjectGuid'])) {
252 | AddInternal-ProjectGuidToWebConfig -publishProperties $publishProperties -packOutput $packOutput
253 | }
254 |
255 | # return the args
256 | $sharedArgs
257 | }
258 | }
259 |
260 | <#
261 | .SYNOPSIS
262 | This will publish the folder based on the properties in $publishProperties
263 |
264 | .PARAMETER publishProperties
265 | This is a hashtable containing the publish properties. See the examples here for more info on how to use this parameter.
266 |
267 | .PARAMETER packOutput
268 | The folder path to the output of the dnu publish command. This folder contains the files
269 | that will be published.
270 |
271 | .PARAMETER pubProfilePath
272 | Path to a publish profile (.pubxml file) to import publish properties from. If the same property exists in
273 | publishProperties and the publish profile then publishProperties will win.
274 |
275 | .EXAMPLE
276 | Publish-AspNet -packOutput $packOutput -publishProperties @{
277 | 'WebPublishMethod'='MSDeploy'
278 | 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';`
279 | 'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="$env:PublishPwd"}
280 |
281 | .EXAMPLE
282 | Publish-AspNet -packOutput $packOutput -publishProperties @{
283 | 'WebPublishMethod'='FileSystem'
284 | 'publishUrl'="$publishDest"
285 | }
286 |
287 | .EXAMPLE
288 | Publish-AspNet -packOutput $packOutput -publishProperties @{
289 | 'WebPublishMethod'='MSDeploy'
290 | 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';`
291 | 'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="$env:PublishPwd"
292 | 'ExcludeFiles'=@(
293 | @{'absolutepath'='test.txt'},
294 | @{'absolutepath'='references.js'}
295 | )}
296 |
297 | .EXAMPLE
298 | Publish-AspNet -packOutput $packOutput -publishProperties @{
299 | 'WebPublishMethod'='FileSystem'
300 | 'publishUrl'="$publishDest"
301 | 'ExcludeFiles'=@(
302 | @{'absolutepath'='test.txt'},
303 | @{'absolutepath'='_references.js'})
304 | 'Replacements' = @(
305 | @{'file'='test.txt$';'match'='REPLACEME';'newValue'='updatedValue'})
306 | }
307 |
308 | Publish-AspNet -packOutput $packOutput -publishProperties @{
309 | 'WebPublishMethod'='FileSystem'
310 | 'publishUrl'="$publishDest"
311 | 'ExcludeFiles'=@(
312 | @{'absolutepath'='test.txt'},
313 | @{'absolutepath'='c:\\full\\path\\ok\\as\\well\\_references.js'})
314 | 'Replacements' = @(
315 | @{'file'='test.txt$';'match'='REPLACEME';'newValue'='updatedValue'})
316 | }
317 |
318 | .EXAMPLE
319 | Publish-AspNet -packOutput $packOutput -publishProperties @{
320 | 'WebPublishMethod'='FileSystem'
321 | 'publishUrl'="$publishDest"
322 | 'EnableMSDeployAppOffline'='true'
323 | 'AppOfflineTemplate'='offline-template.html'
324 | 'MSDeployUseChecksum'='true'
325 | }
326 | #>
327 | function Publish-AspNet{
328 | param(
329 | [Parameter(Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
330 | [hashtable]$publishProperties = @{},
331 |
332 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
333 | [System.IO.FileInfo]$packOutput,
334 |
335 | [Parameter(Position=2,ValueFromPipelineByPropertyName=$true)]
336 | [System.IO.FileInfo]$pubProfilePath
337 | )
338 | process{
339 | if($publishProperties['WebPublishMethodOverride']){
340 | 'Overriding publish method from $publishProperties[''WebPublishMethodOverride''] to [{0}]' -f ($publishProperties['WebPublishMethodOverride']) | Write-Verbose
341 | $publishProperties['WebPublishMethod'] = $publishProperties['WebPublishMethodOverride']
342 | }
343 |
344 | if(-not [string]::IsNullOrWhiteSpace($pubProfilePath)){
345 | $profileProperties = Get-PropertiesFromPublishProfile -filepath $pubProfilePath
346 | foreach($key in $profileProperties.Keys){
347 | if(-not ($publishProperties.ContainsKey($key))){
348 | 'Adding properties from publish profile [''{0}''=''{1}'']' -f $key,$profileProperties[$key] | Write-Verbose
349 | $publishProperties.Add($key,$profileProperties[$key])
350 | }
351 | }
352 | }
353 |
354 | if(!([System.IO.Path]::IsPathRooted($packOutput))){
355 | $packOutput = [System.IO.Path]::GetFullPath((Join-Path $pwd $packOutput))
356 | }
357 |
358 | $pubMethod = $publishProperties['WebPublishMethod']
359 | 'Publishing with publish method [{0}]' -f $pubMethod | Write-Output
360 |
361 | # get the handler based on WebPublishMethod, and call it.
362 | &(Get-AspnetPublishHandler -name $pubMethod) $publishProperties $packOutput
363 | }
364 | }
365 |
366 | <#
367 | .SYNOPSIS
368 |
369 | Inputs:
370 |
371 | Example of $xmlDocument: '
'
372 | Example of $providerDataArray:
373 |
374 | [System.Collections.ArrayList]$providerDataArray = @()
375 |
376 | $iisAppSourceKeyValue=@{"iisApp" = @{"path"='c:\temp\pathtofiles';"appOfflineTemplate" ='offline-template.html'}}
377 | $providerDataArray.Add($iisAppSourceKeyValue)
378 |
379 | $dbfullsqlKeyValue=@{"dbfullsql" = @{"path"="c:\Temp\PathToSqlFile"}}
380 | $providerDataArray.Add($dbfullsqlKeyValue)
381 |
382 | $dbfullsqlKeyValue=@{"dbfullsql" = @{"path"="c:\Temp\PathToSqlFile2"}}
383 | $providerDataArray.Add($dbfullsqlKeyValue)
384 |
385 | Manifest File content:
386 |
387 |
388 |
389 |
390 |
391 |
392 | #>
393 | function AddInternal-ProviderDataToManifest {
394 | [cmdletbinding()]
395 | param(
396 | [Parameter(Mandatory=$true, Position=0)]
397 | [XML]$xmlDocument,
398 | [Parameter(Position=1)]
399 | [System.Collections.ArrayList]$providerDataArray
400 | )
401 | process {
402 | $siteNode = $xmlDocument.SelectSingleNode("/sitemanifest")
403 | if ($siteNode -eq $null) {
404 | throw 'sitemanifest element is missing in the xml object'
405 | }
406 | foreach ($providerData in $providerDataArray) {
407 | foreach ($providerName in $providerData.Keys) {
408 | $providerValue = $providerData[$providerName]
409 | $xmlNode = $xmlDocument.CreateElement($providerName)
410 | foreach ($providerValueKey in $providerValue.Keys) {
411 | $xmlNode.SetAttribute($providerValueKey, $providerValue[$providerValueKey]) | Out-Null
412 | }
413 | $siteNode.AppendChild($xmlNode) | Out-Null
414 | }
415 | }
416 | }
417 | }
418 |
419 | function AddInternal-ProjectGuidToWebConfig {
420 | [cmdletbinding()]
421 | param(
422 | [Parameter(Position=0)]
423 | [HashTable]$publishProperties,
424 | [Parameter(Position=1)]
425 | [System.IO.FileInfo]$packOutput
426 | )
427 | process {
428 | try {
429 | [Reflection.Assembly]::LoadWithPartialName("System.Xml.Linq") | Out-Null
430 | $webConfigPath = Join-Path $packOutput 'web.config'
431 | $projectGuidCommentValue = 'ProjectGuid: {0}' -f $publishProperties['ProjectGuid']
432 | $xDoc = [System.Xml.Linq.XDocument]::Load($webConfigPath)
433 | $allNodes = $xDoc.DescendantNodes()
434 | $projectGuidComment = $allNodes | Where-Object { $_.NodeType -eq [System.Xml.XmlNodeType]::Comment -and $_.Value -eq $projectGuidCommentValue } | Select -First 1
435 | if($projectGuidComment -ne $null) {
436 | if($publishProperties['IgnoreProjectGuid'] -eq $true) {
437 | $projectGuidComment.Remove() | Out-Null
438 | $xDoc.Save($webConfigPath) | Out-Null
439 | }
440 | }
441 | else {
442 | if(-not ($publishProperties['IgnoreProjectGuid'] -eq $true)) {
443 | $projectGuidComment = New-Object -TypeName System.Xml.Linq.XComment -ArgumentList $projectGuidCommentValue
444 | $xDoc.LastNode.AddAfterSelf($projectGuidComment) | Out-Null
445 | $xDoc.Save($webConfigPath) | Out-Null
446 | }
447 | }
448 | }
449 | catch {
450 | }
451 | }
452 | }
453 |
454 | <#
455 | .SYNOPSIS
456 |
457 | Example of $EFMigrations:
458 | $EFMigrations = @{'CarContext'='Car Context ConnectionString';'MovieContext'='Movie Context Connection String'}
459 |
460 | #>
461 |
462 | function GenerateInternal-EFMigrationScripts {
463 | [cmdletbinding()]
464 | param(
465 | [Parameter(Mandatory=$true,Position=0)]
466 | [System.IO.FileInfo]$projectPath,
467 | [Parameter(Mandatory=$true,Position=1)]
468 | [System.IO.FileInfo]$packOutput,
469 | [Parameter(Position=2)]
470 | [HashTable]$EFMigrations
471 | )
472 | process {
473 | $files = @{}
474 | $dotnetExePath = GetInternal-DotNetExePath
475 | foreach ($dbContextName in $EFMigrations.Keys) {
476 | try
477 | {
478 | $tempDir = GetInternal-PublishTempPath -packOutput $packOutput
479 | $efScriptFile = Join-Path $tempDir ('{0}.sql' -f $dbContextName)
480 | $arg = ('ef migrations script --idempotent --output {0} --context {1}' -f
481 | $efScriptFile,
482 | $dbContextName)
483 |
484 | Execute-Command $dotnetExePath $arg $projectPath | Out-Null
485 | if (Test-Path -Path $efScriptFile) {
486 | if (!($files.ContainsKey($dbContextName))) {
487 | $files.Add($dbContextName, $efScriptFile) | Out-Null
488 | }
489 | }
490 | }
491 | catch
492 | {
493 | throw 'error occured when executing dotnet.exe to generate EF T-SQL file'
494 | }
495 | }
496 | # return files object
497 | $files
498 | }
499 | }
500 |
501 | <#
502 | .SYNOPSIS
503 |
504 | Example of $connectionStrings:
505 | $connectionStrings = @{'DefaultConnection'='Default ConnectionString';'CarConnection'='Car Connection String'}
506 |
507 | #>
508 | function GenerateInternal-AppSettingsFile {
509 | [cmdletbinding()]
510 | param(
511 | [Parameter(Mandatory = $true,Position=0)]
512 | [System.IO.FileInfo]$packOutput,
513 | [Parameter(Mandatory = $true,Position=1)]
514 | [string]$environmentName,
515 | [Parameter(Position=2)]
516 | [HashTable]$connectionStrings
517 | )
518 | process {
519 | $configProdJsonFile = 'appsettings.{0}.json' -f $environmentName
520 | $configProdJsonFilePath = Join-Path -Path $packOutput -ChildPath $configProdJsonFile
521 |
522 | if ([string]::IsNullOrEmpty($configProdJsonFilePath)) {
523 | throw ('The path of {0} is empty' -f $configProdJsonFilePath)
524 | }
525 |
526 | if(!(Test-Path -Path $configProdJsonFilePath)) {
527 | # create new file
528 | '{}' | out-file -encoding utf8 -filePath $configProdJsonFilePath -Force
529 | }
530 |
531 | $jsonObj = ConvertFrom-Json -InputObject (Get-Content -Path $configProdJsonFilePath -Raw)
532 | # update when there exists one or more connection strings
533 | if ($connectionStrings -ne $null) {
534 | foreach ($name in $connectionStrings.Keys) {
535 | #check for hierarchy style
536 | if ($jsonObj.ConnectionStrings.$name) {
537 | $jsonObj.ConnectionStrings.$name = $connectionStrings[$name]
538 | continue
539 | }
540 | #check for horizontal style
541 | $horizontalName = 'ConnectionStrings.{0}:' -f $name
542 | if ($jsonObj.$horizontalName) {
543 | $jsonObj.$horizontalName = $connectionStrings[$name]
544 | continue
545 | }
546 | # create new one
547 | if (!($jsonObj.ConnectionStrings)) {
548 | $contentForDefaultConnection = '{}'
549 | $jsonObj | Add-Member -name 'ConnectionStrings' -value (ConvertFrom-Json -InputObject $contentForDefaultConnection) -MemberType NoteProperty | Out-Null
550 | }
551 | if (!($jsonObj.ConnectionStrings.$name)) {
552 | $jsonObj.ConnectionStrings | Add-Member -name $name -value $connectionStrings[$name] -MemberType NoteProperty | Out-Null
553 | }
554 | }
555 | }
556 |
557 | $jsonObj | ConvertTo-Json | out-file -encoding utf8 -filePath $configProdJsonFilePath -Force
558 |
559 | #return the path of config.[environment].json
560 | $configProdJsonFilePath
561 | }
562 | }
563 |
564 | <#
565 | .SYNOPSIS
566 |
567 | Inputs:
568 | Example of $providerDataArray:
569 |
570 | [System.Collections.ArrayList]$providerDataArray = @()
571 |
572 | $iisAppSourceKeyValue=@{"iisApp" = @{"path"='c:\temp\pathtofiles';"appOfflineTemplate" ='offline-template.html'}}
573 | $providerDataArray.Add($iisAppSourceKeyValue)
574 |
575 | $dbfullsqlKeyValue=@{"dbfullsql" = @{"path"="c:\Temp\PathToSqlFile"}}
576 | $providerDataArray.Add($dbfullsqlKeyValue)
577 |
578 | $dbfullsqlKeyValue=@{"dbfullsql" = @{"path"="c:\Temp\PathToSqlFile2"}}
579 | $providerDataArray.Add($dbfullsqlKeyValue)
580 |
581 | Manifest File content:
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 | #>
590 |
591 | function GenerateInternal-ManifestFile {
592 | [cmdletbinding()]
593 | param(
594 | [Parameter(Mandatory=$true,Position=0)]
595 | [System.IO.FileInfo]$packOutput,
596 | [Parameter(Mandatory=$true,Position=1)]
597 | $publishProperties,
598 | [Parameter(Mandatory=$true,Position=2)]
599 | [System.Collections.ArrayList]$providerDataArray,
600 | [Parameter(Mandatory=$true,Position=3)]
601 | [ValidateNotNull()]
602 | $manifestFileName
603 | )
604 | process{
605 | $xmlDocument = [xml]'
'
606 | AddInternal-ProviderDataToManifest -xmlDocument $xmlDocument -providerDataArray $providerDataArray | Out-Null
607 | $publishTempDir = GetInternal-PublishTempPath -packOutput $packOutput
608 | $XMLFile = Join-Path $publishTempDir $manifestFileName
609 | $xmlDocument.OuterXml | out-file -encoding utf8 -filePath $XMLFile -Force
610 |
611 | # return
612 | [System.IO.FileInfo]$XMLFile
613 | }
614 | }
615 |
616 | function GetInternal-PublishTempPath {
617 | [cmdletbinding()]
618 | param(
619 | [Parameter(Mandatory=$true, Position=0)]
620 | [System.IO.FileInfo]$packOutput
621 | )
622 | process {
623 | $tempDir = [io.path]::GetTempPath()
624 | $packOutputFolderName = Split-Path $packOutput -Leaf
625 | $publishTempDir = [io.path]::combine($tempDir,'PublishTemp','obj',$packOutputFolderName)
626 | if (!(Test-Path -Path $publishTempDir)) {
627 | New-Item -Path $publishTempDir -type directory | Out-Null
628 | }
629 | # return
630 | [System.IO.FileInfo]$publishTempDir
631 | }
632 | }
633 |
634 | function Publish-AspNetMSDeploy{
635 | param(
636 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
637 | $publishProperties,
638 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
639 | $packOutput
640 | )
641 | process{
642 | if($publishProperties){
643 | $publishPwd = $publishProperties['Password']
644 |
645 | $sharedArgs = GetInternal-SharedMSDeployParametersFrom -publishProperties $publishProperties -packOutput $packOutput
646 | $iisAppPath = $publishProperties['DeployIisAppPath']
647 |
648 | # create source manifest
649 |
650 | # e.g
651 | #
652 | #
653 | #
654 | #
655 | #
656 | #
657 |
658 | [System.Collections.ArrayList]$providerDataArray = @()
659 | $iisAppValues = @{"path"=$packOutput};
660 | $iisAppSourceKeyValue=@{"iisApp" = $iisAppValues}
661 | $providerDataArray.Add($iisAppSourceKeyValue) | Out-Null
662 |
663 | if ($sharedArgs.EFMigrationData -ne $null -and $sharedArgs.EFMigrationData.Contains('EFSqlFiles')) {
664 | foreach ($sqlFile in $sharedArgs.EFMigrationData['EFSqlFiles'].Values) {
665 | $dbFullSqlSourceKeyValue=@{"dbFullSql" = @{"path"=$sqlFile}}
666 | $providerDataArray.Add($dbFullSqlSourceKeyValue) | Out-Null
667 | }
668 | }
669 |
670 | [System.IO.FileInfo]$sourceXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml'
671 |
672 | $providerDataArray.Clear() | Out-Null
673 | # create destination manifest
674 |
675 | # e.g
676 | #
677 | #
678 | #
679 | #
680 | #
681 |
682 | $iisAppValues = @{"path"=$iisAppPath};
683 | if(-not [string]::IsNullOrWhiteSpace($publishProperties['AppOfflineTemplate'])){
684 | $iisAppValues.Add("appOfflineTemplate", $publishProperties['AppOfflineTemplate']) | Out-Null
685 | }
686 |
687 | $iisAppDestinationKeyValue=@{"iisApp" = $iisAppValues}
688 | $providerDataArray.Add($iisAppDestinationKeyValue) | Out-Null
689 |
690 | if ($publishProperties['EfMigrations'] -ne $null -and $publishProperties['EfMigrations'].Count -gt 0) {
691 | foreach ($connectionString in $publishProperties['EfMigrations'].Values) {
692 | $dbFullSqlDestinationKeyValue=@{"dbFullSql" = @{"path"=$connectionString}}
693 | $providerDataArray.Add($dbFullSqlDestinationKeyValue) | Out-Null
694 | }
695 | }
696 |
697 |
698 | [System.IO.FileInfo]$destXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'DestinationManifest.xml'
699 |
700 | <#
701 | "C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe"
702 | -source:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\SourceManifest.xml'
703 | -dest:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\DestManifest.xml',ComputerName='https://contoso.scm.azurewebsites.net/msdeploy.axd',UserName='$contoso',Password='
',IncludeAcls='False',AuthType='Basic'
704 | -verb:sync
705 | -enableRule:DoNotDeleteRule
706 | -retryAttempts=2"
707 | #>
708 |
709 | if(-not [string]::IsNullOrWhiteSpace($publishProperties['MSDeployPublishMethod'])){
710 | $serviceMethod = $publishProperties['MSDeployPublishMethod']
711 | }
712 |
713 | $msdeployComputerName= InternalNormalize-MSDeployUrl -serviceUrl $publishProperties['MSDeployServiceURL'] -siteName $iisAppPath -serviceMethod $publishProperties['MSDeployPublishMethod']
714 | if($publishProperties['UseMSDeployServiceURLAsIs'] -eq $true){
715 | $msdeployComputerName = $publishProperties['MSDeployServiceURL']
716 | }
717 |
718 | $publishArgs = @()
719 | #use manifest to publish
720 | $publishArgs += ('-source:manifest=''{0}''' -f $sourceXMLFile.FullName)
721 | $publishArgs += ('-dest:manifest=''{0}'',ComputerName=''{1}'',UserName=''{2}'',Password=''{3}'',IncludeAcls=''False'',AuthType=''{4}''{5}' -f
722 | $destXMLFile.FullName,
723 | $msdeployComputerName,
724 | $publishProperties['UserName'],
725 | $publishPwd,
726 | $publishProperties['AuthType'],
727 | $sharedArgs.DestFragment)
728 | $publishArgs += '-verb:sync'
729 | $publishArgs += $sharedArgs.ExtraArgs
730 |
731 | $command = '"{0}" {1}' -f (Get-MSDeploy),($publishArgs -join ' ')
732 |
733 | if (! [String]::IsNullOrEmpty($publishPwd)) {
734 | $command.Replace($publishPwd,'{PASSWORD-REMOVED-FROM-LOG}') | Print-CommandString
735 | }
736 | Execute-Command -exePath (Get-MSDeploy) -arguments ($publishArgs -join ' ')
737 | }
738 | else{
739 | throw 'publishProperties is empty, cannot publish'
740 | }
741 | }
742 | }
743 |
744 | function Escape-TextForRegularExpressions{
745 | [cmdletbinding()]
746 | param(
747 | [Parameter(Position=0,Mandatory=$true)]
748 | [string]$text
749 | )
750 | process{
751 | [regex]::Escape($text)
752 | }
753 | }
754 |
755 | function Publish-AspNetMSDeployPackage{
756 | param(
757 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
758 | $publishProperties,
759 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
760 | $packOutput
761 | )
762 | process{
763 | if($publishProperties){
764 | $packageDestinationFilepath = $publishProperties['DesktopBuildPackageLocation']
765 |
766 | if(!$packageDestinationFilepath){
767 | throw ('The package destination property (DesktopBuildPackageLocation) was not found in the publish properties')
768 | }
769 |
770 | if(!([System.IO.Path]::IsPathRooted($packageDestinationFilepath))){
771 | $packageDestinationFilepath = [System.IO.Path]::GetFullPath((Join-Path $pwd $packageDestinationFilepath))
772 | }
773 |
774 | # if the dir doesn't exist create it
775 | $pkgDir = ((new-object -typename System.IO.FileInfo($packageDestinationFilepath)).Directory)
776 | if(!(Test-Path -Path $pkgDir)) {
777 | New-Item $pkgDir -type Directory | Out-Null
778 | }
779 |
780 | <#
781 | "C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe"
782 | -source:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\SourceManifest.xml'
783 | -dest:package=c:\temp\path\contosoweb.zip
784 | -verb:sync
785 | -enableRule:DoNotDeleteRule
786 | -retryAttempts=2
787 | #>
788 |
789 | $sharedArgs = GetInternal-SharedMSDeployParametersFrom -publishProperties $publishProperties -packOutput $packOutput
790 |
791 | # create source manifest
792 |
793 | # e.g
794 | #
795 | #
796 | #
797 | #
798 |
799 | [System.Collections.ArrayList]$providerDataArray = @()
800 | $iisAppSourceKeyValue=@{"iisApp" = @{"path"=$packOutput}}
801 | $providerDataArray.Add($iisAppSourceKeyValue) | Out-Null
802 |
803 | [System.IO.FileInfo]$sourceXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml'
804 |
805 | $publishArgs = @()
806 | $publishArgs += ('-source:manifest=''{0}''' -f $sourceXMLFile.FullName)
807 | $publishArgs += ('-dest:package=''{0}''' -f $packageDestinationFilepath)
808 | $publishArgs += '-verb:sync'
809 | $packageContentFolder = $publishProperties['MSDeployPackageContentFoldername']
810 | if(!$packageContentFolder){ $packageContentFolder = 'website' }
811 | $publishArgs += ('-replace:match=''{0}'',replace=''{1}''' -f (Escape-TextForRegularExpressions $packOutput), $packageContentFolder )
812 | $publishArgs += $sharedArgs.ExtraArgs
813 |
814 | $command = '"{0}" {1}' -f (Get-MSDeploy),($publishArgs -join ' ')
815 | $command | Print-CommandString
816 | Execute-Command -exePath (Get-MSDeploy) -arguments ($publishArgs -join ' ')
817 | }
818 | else{
819 | throw 'publishProperties is empty, cannot publish'
820 | }
821 | }
822 | }
823 |
824 | function Publish-AspNetFileSystem{
825 | param(
826 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
827 | $publishProperties,
828 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
829 | $packOutput
830 | )
831 | process{
832 | $pubOut = $publishProperties['publishUrl']
833 |
834 | if([string]::IsNullOrWhiteSpace($pubOut)){
835 | throw ('publishUrl is a required property for FileSystem publish but it was empty.')
836 | }
837 |
838 | # if it's a relative path then update it to a full path
839 | if(!([System.IO.Path]::IsPathRooted($pubOut))){
840 | $pubOut = [System.IO.Path]::GetFullPath((Join-Path $pwd $pubOut))
841 | $publishProperties['publishUrl'] = "$pubOut"
842 | }
843 |
844 | 'Publishing files to {0}' -f $pubOut | Write-Output
845 |
846 | # we use msdeploy.exe because it supports incremental publish/skips/replacements/etc
847 | # msdeploy.exe -verb:sync -source:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\SourceManifest.xml' -dest:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\DestManifest.xml'
848 |
849 | $sharedArgs = GetInternal-SharedMSDeployParametersFrom -publishProperties $publishProperties -packOutput $packOutput
850 |
851 | # create source manifest
852 |
853 | # e.g
854 | #
855 | #
856 | #
857 | #
858 |
859 | [System.Collections.ArrayList]$providerDataArray = @()
860 | $contentPathValues = @{"path"=$packOutput};
861 | $contentPathSourceKeyValue=@{"contentPath" = $contentPathValues}
862 | $providerDataArray.Add($contentPathSourceKeyValue) | Out-Null
863 |
864 | [System.IO.FileInfo]$sourceXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml'
865 |
866 | $providerDataArray.Clear() | Out-Null
867 | # create destination manifest
868 |
869 | # e.g
870 | #
871 | #
872 | #
873 | $contentPathValues = @{"path"=$publishProperties['publishUrl']};
874 | if(-not [string]::IsNullOrWhiteSpace($publishProperties['AppOfflineTemplate'])){
875 | $contentPathValues.Add("appOfflineTemplate", $publishProperties['AppOfflineTemplate']) | Out-Null
876 | }
877 | $contentPathDestinationKeyValue=@{"contentPath" = $contentPathValues}
878 | $providerDataArray.Add($contentPathDestinationKeyValue) | Out-Null
879 |
880 | [System.IO.FileInfo]$destXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'DestinationManifest.xml'
881 |
882 | $publishArgs = @()
883 | $publishArgs += ('-source:manifest=''{0}''' -f $sourceXMLFile.FullName)
884 | $publishArgs += ('-dest:manifest=''{0}''{1}' -f $destXMLFile.FullName, $sharedArgs.DestFragment)
885 | $publishArgs += '-verb:sync'
886 | $publishArgs += $sharedArgs.ExtraArgs
887 |
888 | $command = '"{0}" {1}' -f (Get-MSDeploy),($publishArgs -join ' ')
889 | $command | Print-CommandString
890 | Execute-Command -exePath (Get-MSDeploy) -arguments ($publishArgs -join ' ')
891 |
892 | # copy sql script to script folder
893 | if (($sharedArgs.EFMigrationData['EFSqlFiles'] -ne $null) -and ($sharedArgs.EFMigrationData['EFSqlFiles'].Count -gt 0)) {
894 | $scriptsDir = Join-Path $pubOut 'efscripts'
895 |
896 | if (!(Test-Path -Path $scriptsDir)) {
897 | New-Item -Path $scriptsDir -type directory | Out-Null
898 | }
899 |
900 | foreach ($sqlFile in $sharedArgs.EFMigrationData['EFSqlFiles'].Values) {
901 | Copy-Item $sqlFile -Destination $scriptsDir -Force -Recurse | Out-Null
902 | }
903 | }
904 | }
905 | }
906 |
907 | <#
908 | .SYNOPSIS
909 | This can be used to read a publish profile to extract the property values into a hashtable.
910 |
911 | .PARAMETER filepath
912 | Path to the publish profile to get the properties from. Currenlty this only supports reading
913 | .pubxml files.
914 |
915 | .EXAMPLE
916 | Get-PropertiesFromPublishProfile -filepath c:\projects\publish\devpublish.pubxml
917 | #>
918 | function Get-PropertiesFromPublishProfile{
919 | [cmdletbinding()]
920 | param(
921 | [Parameter(Position=0,Mandatory=$true)]
922 | [ValidateNotNull()]
923 | [ValidateScript({Test-Path $_})]
924 | [System.IO.FileInfo]$filepath
925 | )
926 | begin{
927 | Add-Type -AssemblyName System.Core
928 | Add-Type -AssemblyName Microsoft.Build
929 | }
930 | process{
931 | 'Reading publish properties from profile [{0}]' -f $filepath | Write-Verbose
932 | # use MSBuild to get the project and read properties
933 | $projectCollection = (New-Object Microsoft.Build.Evaluation.ProjectCollection)
934 | if(!([System.IO.Path]::IsPathRooted($filepath))){
935 | $filepath = [System.IO.Path]::GetFullPath((Join-Path $pwd $filepath))
936 | }
937 | $project = ([Microsoft.Build.Construction.ProjectRootElement]::Open([string]$filepath.Fullname, $projectCollection))
938 |
939 | $properties = @{}
940 | foreach($property in $project.Properties){
941 | $properties[$property.Name]=$property.Value
942 | }
943 |
944 | $properties
945 | }
946 | }
947 |
948 | function Print-CommandString{
949 | [cmdletbinding()]
950 | param(
951 | [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]
952 | $command
953 | )
954 | process{
955 | 'Executing command [{0}]' -f $command | Write-Output
956 | }
957 | }
958 |
959 | function Execute-CommandString{
960 | [cmdletbinding()]
961 | param(
962 | [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]
963 | [string[]]$command,
964 |
965 | [switch]
966 | $useInvokeExpression,
967 |
968 | [switch]
969 | $ignoreErrors
970 | )
971 | process{
972 | foreach($cmdToExec in $command){
973 | 'Executing command [{0}]' -f $cmdToExec | Write-Verbose
974 | if($useInvokeExpression){
975 | try {
976 | Invoke-Expression -Command $cmdToExec
977 | }
978 | catch {
979 | if(-not $ignoreErrors){
980 | $msg = ('The command [{0}] exited with exception [{1}]' -f $cmdToExec, $_.ToString())
981 | throw $msg
982 | }
983 | }
984 | }
985 | else {
986 | cmd.exe /D /C $cmdToExec
987 |
988 | if(-not $ignoreErrors -and ($LASTEXITCODE -ne 0)){
989 | $msg = ('The command [{0}] exited with code [{1}]' -f $cmdToExec, $LASTEXITCODE)
990 | throw $msg
991 | }
992 | }
993 | }
994 | }
995 | }
996 |
997 | function Execute-Command {
998 | [cmdletbinding()]
999 | param(
1000 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
1001 | [String]$exePath,
1002 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
1003 | [String]$arguments,
1004 | [Parameter(Position=2)]
1005 | [System.IO.FileInfo]$workingDirectory
1006 | )
1007 | process{
1008 | $psi = New-Object -TypeName System.Diagnostics.ProcessStartInfo
1009 | $psi.CreateNoWindow = $true
1010 | $psi.UseShellExecute = $false
1011 | $psi.RedirectStandardOutput = $true
1012 | $psi.RedirectStandardError=$true
1013 | $psi.FileName = $exePath
1014 | $psi.Arguments = $arguments
1015 | if($workingDirectory -and (Test-Path -Path $workingDirectory)) {
1016 | $psi.WorkingDirectory = $workingDirectory
1017 | }
1018 |
1019 | $process = New-Object -TypeName System.Diagnostics.Process
1020 | $process.StartInfo = $psi
1021 | $process.EnableRaisingEvents=$true
1022 |
1023 | # Register the event handler for error
1024 | $stdErrEvent = Register-ObjectEvent -InputObject $process -EventName 'ErrorDataReceived' -Action {
1025 | if (! [String]::IsNullOrEmpty($EventArgs.Data)) {
1026 | $EventArgs.Data | Write-Error
1027 | }
1028 | }
1029 |
1030 | # Starting process.
1031 | $process.Start() | Out-Null
1032 | $process.BeginErrorReadLine() | Out-Null
1033 | $output = $process.StandardOutput.ReadToEnd()
1034 | $process.WaitForExit() | Out-Null
1035 | $output | Write-Output
1036 |
1037 | # UnRegister the event handler for error
1038 | Unregister-Event -SourceIdentifier $stdErrEvent.Name | Out-Null
1039 | }
1040 | }
1041 |
1042 |
1043 | function GetInternal-DotNetExePath {
1044 | process {
1045 | $dotnetinstallpath = $env:dotnetinstallpath
1046 | if (!$dotnetinstallpath) {
1047 | $DotNetRegItem = Get-ItemProperty -Path 'hklm:\software\dotnet\setup\'
1048 | if ($env:DOTNET_HOME) {
1049 | $dotnetinstallpath = Join-Path $env:DOTNET_HOME -ChildPath 'dotnet.exe'
1050 | }
1051 | elseif ($DotNetRegItem -and $DotNetRegItem.InstallDir){
1052 | $dotnetinstallpath = Join-Path $DotNetRegItem.InstallDir -ChildPath 'dotnet.exe'
1053 | }
1054 | }
1055 | if (!(Test-Path $dotnetinstallpath)) {
1056 | throw 'Unable to find dotnet.exe, please install it and try again'
1057 | }
1058 | # return
1059 | [System.IO.FileInfo]$dotnetinstallpath
1060 | }
1061 | }
1062 |
1063 | function Get-MSDeploy{
1064 | [cmdletbinding()]
1065 | param()
1066 | process{
1067 | $installPath = $env:msdeployinstallpath
1068 |
1069 | if(!$installPath){
1070 | $keysToCheck = @('hklm:\SOFTWARE\Microsoft\IIS Extensions\MSDeploy\3','hklm:\SOFTWARE\Microsoft\IIS Extensions\MSDeploy\2','hklm:\SOFTWARE\Microsoft\IIS Extensions\MSDeploy\1')
1071 |
1072 | foreach($keyToCheck in $keysToCheck){
1073 | if(Test-Path $keyToCheck){
1074 | $installPath = (Get-itemproperty $keyToCheck -Name InstallPath -ErrorAction SilentlyContinue | select -ExpandProperty InstallPath -ErrorAction SilentlyContinue)
1075 | }
1076 |
1077 | if($installPath){
1078 | break;
1079 | }
1080 | }
1081 | }
1082 |
1083 | if(!$installPath){
1084 | throw "Unable to find msdeploy.exe, please install it and try again"
1085 | }
1086 |
1087 | [string]$msdInstallLoc = (join-path $installPath 'msdeploy.exe')
1088 |
1089 | "Found msdeploy.exe at [{0}]" -f $msdInstallLoc | Write-Verbose
1090 |
1091 | $msdInstallLoc
1092 | }
1093 | }
1094 |
1095 | function InternalNormalize-MSDeployUrl{
1096 | [cmdletbinding()]
1097 | param(
1098 | [Parameter(Position=0,Mandatory=$true)]
1099 | [string]$serviceUrl,
1100 |
1101 | [string] $siteName,
1102 |
1103 | [ValidateSet('WMSVC','RemoteAgent','InProc')]
1104 | [string]$serviceMethod = 'WMSVC'
1105 | )
1106 | process{
1107 | $tempUrl = $serviceUrl
1108 | $resultUrl = $serviceUrl
1109 |
1110 | $httpsStr = 'https://'
1111 | $httpStr = 'http://'
1112 | $msdeployAxd = 'msdeploy.axd'
1113 |
1114 | if(-not [string]::IsNullOrWhiteSpace($serviceUrl)){
1115 | if([string]::Compare($serviceMethod,'WMSVC',[StringComparison]::OrdinalIgnoreCase) -eq 0){
1116 | # if no http or https then add one
1117 | if(-not ($serviceUrl.StartsWith($httpStr,[StringComparison]::OrdinalIgnoreCase) -or
1118 | $serviceUrl.StartsWith($httpsStr,[StringComparison]::OrdinalIgnoreCase)) ){
1119 |
1120 | $serviceUrl = [string]::Concat($httpsStr,$serviceUrl.TrimStart())
1121 | }
1122 | [System.Uri]$serviceUri = New-Object -TypeName 'System.Uri' $serviceUrl
1123 | [System.UriBuilder]$serviceUriBuilder = New-Object -TypeName 'System.UriBuilder' $serviceUrl
1124 |
1125 | # if it's https and the port was not passed in override it to 8172
1126 | if( ([string]::Compare('https',$serviceUriBuilder.Scheme,[StringComparison]::OrdinalIgnoreCase) -eq 0) -and
1127 | -not $serviceUrl.Contains((':{0}' -f $serviceUriBuilder.Port)) ) {
1128 | $serviceUriBuilder.Port = 8172
1129 | }
1130 |
1131 | # if no path then add one
1132 | if([string]::Compare('/',$serviceUriBuilder.Path,[StringComparison]::OrdinalIgnoreCase) -eq 0){
1133 | $serviceUriBuilder.Path = $msdeployAxd
1134 | }
1135 |
1136 | if ([string]::IsNullOrEmpty($serviceUriBuilder.Query) -and -not([string]::IsNullOrEmpty($siteName)))
1137 | {
1138 | $serviceUriBuilder.Query = "site=" + $siteName;
1139 | }
1140 |
1141 | $resultUrl = $serviceUriBuilder.Uri.AbsoluteUri
1142 | }
1143 | elseif([string]::Compare($serviceMethod,'RemoteAgent',[StringComparison]::OrdinalIgnoreCase) -eq 0){
1144 | [System.UriBuilder]$serviceUriBuilder = New-Object -TypeName 'System.UriBuilder' $serviceUrl
1145 | # http://{computername}/MSDEPLOYAGENTSERVICE
1146 | # remote agent must use http
1147 | $serviceUriBuilder.Scheme = 'http'
1148 | $serviceUriBuilder.Path = '/MSDEPLOYAGENTSERVICE'
1149 |
1150 | $resultUrl = $serviceUriBuilder.Uri.AbsoluteUri
1151 | }
1152 | else{
1153 | # see if it's for localhost
1154 | [System.Uri]$serviceUri = New-Object -TypeName 'System.Uri' $serviceUrl
1155 | $resultUrl = $serviceUri.AbsoluteUri
1156 | }
1157 | }
1158 |
1159 | # return the result to the caller
1160 | $resultUrl
1161 | }
1162 | }
1163 |
1164 | function InternalRegister-AspNetKnownPublishHandlers{
1165 | [cmdletbinding()]
1166 | param()
1167 | process{
1168 | 'Registering MSDeploy handler' | Write-Verbose
1169 | Register-AspnetPublishHandler -name 'MSDeploy' -force -handler {
1170 | [cmdletbinding()]
1171 | param(
1172 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
1173 | $publishProperties,
1174 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
1175 | $packOutput
1176 | )
1177 |
1178 | Publish-AspNetMSDeploy -publishProperties $publishProperties -packOutput $packOutput
1179 | }
1180 |
1181 | 'Registering MSDeploy package handler' | Write-Verbose
1182 | Register-AspnetPublishHandler -name 'Package' -force -handler {
1183 | [cmdletbinding()]
1184 | param(
1185 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
1186 | $publishProperties,
1187 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
1188 | $packOutput
1189 | )
1190 |
1191 | Publish-AspNetMSDeployPackage -publishProperties $publishProperties -packOutput $packOutput
1192 | }
1193 |
1194 | 'Registering FileSystem handler' | Write-Verbose
1195 | Register-AspnetPublishHandler -name 'FileSystem' -force -handler {
1196 | [cmdletbinding()]
1197 | param(
1198 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
1199 | $publishProperties,
1200 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
1201 | $packOutput
1202 | )
1203 |
1204 | Publish-AspNetFileSystem -publishProperties $publishProperties -packOutput $packOutput
1205 | }
1206 | }
1207 | }
1208 |
1209 | <#
1210 | .SYNOPSIS
1211 | Used for testing purposes only.
1212 | #>
1213 | function InternalReset-AspNetPublishHandlers{
1214 | [cmdletbinding()]
1215 | param()
1216 | process{
1217 | $script:AspNetPublishHandlers = @{}
1218 | InternalRegister-AspNetKnownPublishHandlers
1219 | }
1220 | }
1221 |
1222 | Export-ModuleMember -function Get-*,Publish-*,Register-*,Enable-*
1223 | if($env:IsDeveloperMachine){
1224 | # you can set the env var to expose all functions to importer. easy for development.
1225 | # this is required for executing pester test cases, it's set by build.ps1
1226 | Export-ModuleMember -function *
1227 | }
1228 |
1229 | # register the handlers so that Publish-AspNet can be called
1230 | InternalRegister-AspNetKnownPublishHandlers
1231 |
1232 |
--------------------------------------------------------------------------------