I'm trying to use Web Deploy to publish my ASP.NET Core application to IIS. The server is Windows 10 Pro. I downloaded version 3.6 as the documentation suggests, and the installer said I had a newer version of Web Deploy already installed.
When I set up a Web Deploy profile in Visual Studio and try to publish using the Publish wizard, I get this error:
An error occurred during publish. Exception calling ".ctor" with "1" argument(s): "Invalid URI: The format of the URI could not be determined."
For reference, here are the profile files (autogenerated by Visual Studio):
Web Deploy.pubxml
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<ADUsesOwinOrOpenIdConnect>False</ADUsesOwinOrOpenIdConnect>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>http://localhost</SiteUrlToLaunchAfterPublish>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<PublishFramework>netcoreapp1.0</PublishFramework>
<UsePowerShell>True</UsePowerShell>
<EnableMSDeployAppOffline>True</EnableMSDeployAppOffline>
<MSDeployServiceURL>localhost</MSDeployServiceURL>
<DeployIisAppPath>HelloCoreWorld</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>InProc</MSDeployPublishMethod>
<EnableMSDeployBackup>False</EnableMSDeployBackup>
<UserName />
<_SavePWD>False</_SavePWD>
</PropertyGroup>
</Project>
Web Deploy.ps1
[cmdletbinding(SupportsShouldProcess=$true)]
param($publishProperties=#{}, $packOutput, $pubProfilePath)
# to learn more about this file visit https://go.microsoft.com/fwlink/?LinkId=524327
try{
if ($publishProperties['ProjectGuid'] -eq $null){
$publishProperties['ProjectGuid'] = 'e3328cb4-6ad9-49c1-8eff-52590ec622df'
}
$publishModulePath = Join-Path (Split-Path $MyInvocation.MyCommand.Path) 'publish-module.psm1'
Import-Module $publishModulePath -DisableNameChecking -Force
# call Publish-AspNet to perform the publish operation
Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -pubProfilePath $pubProfilePath
}
catch{
"An error occurred during publish.`n{0}" -f $_.Exception.Message | Write-Error
}
How should I go about debugging this?
Related
I have created Service Fabric Application and added Stateless ASP.NET Core Web API 3.1 project into it. When I run the Service Fabric Application locally using VS 2019, I am getting the below error:-
The PowerShell script failed to execute. See the Service Fabric Tools pane in the output window for details.
Bellow is the output window info
C:\Users\malle\Documents\Mahesh\Projects\RetentionPortal\API\Application1\pkg\Debug is not found.
At C:\Program Files\Microsoft SDKs\Service
Fabric\Tools\PSModule\ServiceFabricSDK\Publish-NewServiceFabricApplication.ps1:120 char:9
+ throw $errMsg
+ ~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (C:\Users\malle\...g is not found.:String) [], RuntimeException
+ FullyQualifiedErrorId : C:\Users\malle\Documents\Mahesh\Projects\RetentionPortal\API\Application1\pkg\Debug is n
ot found.
Finished executing script 'Publish-NewServiceFabricApplication'.
Time elapsed: 00:00:01.7629461
Started executing script 'Unpublish-ServiceFabricApplication'.
powershell -NonInteractive -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -Command "[void](Connect-ServiceFabricCluster); Import-Module 'C:\Program Files\Microsoft SDKs\Service Fabric\Tools\PSModule\ServiceFabricSDK\ServiceFabricSDK.psm1'; Unpublish-ServiceFabricApplication -ApplicationName 'fabric:/Application1' -ErrorAction Stop"
Removing application...
Finished executing script 'Unpublish-ServiceFabricApplication'.
Time elapsed: 00:00:01.5278716
Started executing script 'UnregisterApplicationType'.
powershell -NonInteractive -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -Command "[void](Connect-ServiceFabricCluster); Import-Module 'C:\Program Files\Microsoft SDKs\Service Fabric\Tools\PSModule\ServiceFabricSDK\ServiceFabricSDK.psm1'; if (Get-ServiceFabricApplicationType -ApplicationTypeName 'Application1Type' | Where-Object { $_.ApplicationTypeVersion -eq '1.0.0' }) { Unregister-ServiceFabricApplicationType -ApplicationTypeName 'Application1Type' -ApplicationTypeVersion '1.0.0' -ErrorAction Stop -Force }"
Finished executing script 'UnregisterApplicationType'.
Time elapsed: 00:00:01.4425472
Any help is really appreciated
General solution steps:
Reboot Computer
Log On
Start Visual Studio as Admin
Open Service Fabric Project
F5 to Debug
Try to run the same project again, same output
Run POwerShell as Admin, Connect-ServiceFabricCluster.
Start debugging (F5) in Visual Studio
Everything's fine now
For more details, you can check the issues oin github.
Publish-NewServiceFabricApplication fails to read ApplicationManifest.xml
If the above solution does not work, it is recommended to try the following steps.
Create pkg/Debug folder.
I have some files under Debug folder, so I deleted them.
Clean and Rebuild Solution.
F5 Run. It will generate files you want.
How can I check are IIS and .NET Core Hosting Bundle installed in WiX Toolset Installer?
By detecting the registry key you will found the iis and .net core bundle are instlled or not:
<util:RegistrySearch Root="HKLM"
Key="SOFTWARE\Microsoft\InetStp\Components"
Value="W3SVC"
Variable="WebServer"/>
<ExePackage Id='IIS_WebServer'
DisplayName='Installing IIS: IIS-WebServer'
PerMachine='yes'
SourceFile='.\Resources\Dism.exe'
InstallCondition='NOT WebServer'
InstallCommand='/Online /Enable-Feature /FeatureName:IIS-WebServer'>
</ExePackage>
Below is the other iis components:
Discover Installed Components
another way is you can use the Powershell to check the registry key:
$DotNETCoreUpdatesPath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Updates\.NET Core"
$DotNetCoreItems = Get-Item -ErrorAction Stop -Path $DotNETCoreUpdatesPath
$NotInstalled = $True
$DotNetCoreItems.GetSubKeyNames() | Where { $_ -Match "Microsoft .NET Core.*Windows Server Hosting" } | ForEach-Object {
$NotInstalled = $False
Write-Host "The host has installed $_"
}
If ($NotInstalled) {
Write-Host "Can not find ASP.NET Core installed on the host"
}
How to determine ASP.NET Core installation on a Windows Server by PowerShell
I have the following build step which runs a script in Azure Powershell. The script basically publishes files to the web app (see further down for details).
This works just fine with all of my web apps EXCEPT FOR ONE. I get the following error:
scriptCommand= & "C:\a\8b0700333\MyProj\Scripts\Publish.ps1"
-websiteName mywebapp -packOutput "C:\a\8b0700333\MyProj\Api"
Stopping web app...
Publishing web app...
Publishing with publish method [MSDeploy]
[error]Error: The specified credentials cannot be used with the
authentication scheme 'Basic'.
[error]Error: Default credentials
cannot be supplied for the Basic authentication scheme.
[error]Parameter name: authType
[error]Error count: 1.
The Publish.ps1 script:
param($websiteName, $packOutput)
$website = Get-AzureWebsite -Name $websiteName
# get the scm url to use with MSDeploy. By default this will be the second in the array
$msdeployurl = $website.EnabledHostNames[1]
$publishProperties = #{'WebPublishMethod'='MSDeploy';
'MSDeployServiceUrl'=$msdeployurl;
'DeployIisAppPath'=$website.Name;
'Username'=$website.PublishingUsername;
'Password'=$website.PublishingPassword
'SkipExtraFilesOnServer'='False'}
Write-Output "Stopping web app..."
Stop-AzureWebsite -Name $websiteName
Write-Output "Publishing web app..."
$publishScript = "${env:ProgramFiles(x86)}\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Web Tools\Publish\Scripts\default-publish.ps1"
. $publishScript -publishProperties $publishProperties -packOutput $packOutput
Write-Output "Starting web app..."
Start-AzureWebsite -Name $websiteName
Had the same issue, the problem was coming from the fact that apparently the script Microsoft provides doesn't support slots.
Made a fixed version here https://gist.github.com/baywet/f7ed425c48ccde4399c7
Helping myself from this post How can I get the PublishUrl via Azure PowerShell?
This error usually occurs when using MS deploy HTTP Basic Authentication without any credentials specified. So you can add following code in the PowerShell script to check if the publish username and password for the web app is get correctly.
Write-Output $website.PublishingUsername
Write-Output $website.PublishingPassword
And also, check the value of msdeployurl to see if it is the correct URL (Usually like: youwebappname.scm.azurewebsites.net) for deployment.
Write-Output $msdeployurl
We publish to our Azure Web App using MSBuild MSDeploy in VSO/VSTS Build (vNext) using the script below. This works well.
BUT, when assigning the Azure Web App to a custom domain (through the Azure Portal), the publish fails.
VSTS Build error on MSDeploy:
Publishing with publish method [MSDeploy]
Executing command ["C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -source:IisApp='C:\a\8b0700fff\MrProjectMain\Api\wwwroot' -dest:IisApp='myproject-prod-webapp',ComputerName='https://myproject-prod-webapp.azurewebsites.net/msdeploy.axd',UserName='$myproject-prod-webapp',Password='{PASSWORD-REMOVED-FROM-LOG}',IncludeAcls='False',AuthType='Basic' -verb:sync -enableLink:contentLibExtension -retryAttempts:2 -disablerule:BackupRule]
[error]Error Code: ERROR_COULD_NOT_CONNECT_TO_REMOTESVC
[error]More Information: Could not connect to the remote computer ("myproject-prod-webapp.azurewebsites.net") using the specified process ("Web Management Service") because the server did not respond. Make sure that the process ("Web Management Service") is started on the remote computer. Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_COULD_NOT_CONNECT_TO_REMOTESVC.
[error]Error: The remote server returned an error: (403) Forbidden.
[error]Error count: 1.
Azure portal custom domain setup:
Publish script:
param($websiteName, $packOutput)
$website = Get-AzureWebsite -Name $websiteName
$msdeployurl = $website.EnabledHostNames[1]
$publishProperties = #{'WebPublishMethod'='MSDeploy';
'MSDeployServiceUrl'=$msdeployurl;
'DeployIisAppPath'=$website.Name;
'Username'=$website.PublishingUsername;
'Password'=$website.PublishingPassword;
'SkipExtraFilesOnServer'='False';
'AllowUntrustedCertificate'='True'}
Write-Output "Publishing web app..."
$publishScript = "${env:ProgramFiles(x86)}\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Web Tools\Publish\Scripts\default-publish.ps1"
. $publishScript -publishProperties $publishProperties -packOutput $packOutput
The issue is here:
$msdeployurl = $website.EnabledHostNames[1]
By default, the MSDeploy SCM URL is the second in the EnabledHostNames array. So it works by default. But it may not work as soon as you made some changes to your web app. According to the logs you provided, MSDeploy is trying to connect to "https://myproject-prod-webapp.azurewebsites.net/msdeploy.axd", this is not a SCM URL. The SCM URL should like this: "https://myproject-prod-webapp.scm.azurewebsites.net/msdeploy.axd". So you need to check what is the correct scm URL array number now. You can add the code like following in the PowerShell script to see which one is the scm URL and then update the script accordingly.
Write-Output $website.EnabledHostNames[0]
Write-Output $website.EnabledHostNames[1]
Write-Output $website.EnabledHostNames[2]
...
You can also refer to this article to update your script to get the correct SCM url automatically.
We have a solution featuring a web application project destined as a web role in a Windows Azure cloud service. It also bears a cloud service project that targets the cloud service only (production slot)
SlnRoot\WebApp1\WebApp1.csproj
SlnRoot\CloudDeployment\CloudServiceName\CloudServiceName.ccproj
Publishing (deploying) from Visual Studio is very easy; simply select the Publish... option from the cloud project's context menu and hit Publish with all the pre-configured cloud service settings.
Now we are going a further step of trying to automate this process so I'm trying it out from command-line and raw MSBuild without the aid of Visual Studio.
.nuget\nuget.exe restore
msbuild .\CloudDeployment\CloudServiceName\CloudServiceName.ccproj /t:Publish /p:PublishDir=..\..\pubout\ /fl1 /v:d
But it appears the Publish target is in reality the Package option in Visual Studio, only generating the cspkg file which has to be manually uploaded to Windows Azure portal. This will not do, of course. Is there a separate target to specify to carry out the additional step (Deploy is not it; no such target) that Visual Studio carries out so easily?
Thanks for your advice. The true answer to the gap in my knowledge however - how do MSBuild and PowerShell gel together in the first place - came from my colleague who crafted a custom MSBuild proj file to get it all working together. A basic sample follows with comments
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0"
DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Declare configuration properties for this deployment -->
<!-- This custom.proj file is in a sub-directory in solution root -->
<PropertyGroup>
<SolutionDir Condition=" '$(SolutionDir)'=='' ">$(MSBuildThisFileDirectory)..\</SolutionDir>
<SolutionPath Condition=" '$(SolutionPath)'=='' ">$(MSBuildThisFileDirectory)..\CloudService.sln</SolutionPath>
<OutDir Condition=" '$(OutDir)'=='' ">$(MSBuildThisFileDirectory)\Output\Binaries\</OutDir>
<PackageOutDir>$(MSBuildThisFileDirectory)Output\Packages\</PackageOutDir>
<TargetCloudService>targetcloudservice</TargetCloudService>
<DeployConfig>BuildConfig</DeployConfig>
<PubSettingsPath>$(MSBuildThisFileDirectory)subscription.publishsettings</PubSettingsPath>
<SubscriptionName>subscription name</SubscriptionName>
<StorageAccount>targetstorageaccount</StorageAccount>
</PropertyGroup>
<!-- Target to restore all Nuget packages on a clean repo pull. -->
<Target Name="RestorePackages">
<Message Text="Restoring nuget..."/>
<Exec Command=""$(SolutionDir).nuget\NuGet.exe" restore "$(SolutionPath)"" />
</Target>
<!--
Target to package the indicated cloud project,
which will build the referenced web role project first with desired build config.
-->
<Target Name="PackageCloud" DependsOnTargets="RestorePackages">
<Message Text="Creating package for cloud deployment ..."/>
<MSBuild
Projects="$(MSBuildThisFileDirectory)..\CloudDeployment\$(TargetCloudService)\$(TargetCloudService).ccproj"
Properties="OutputPath=$(PackageOutDir)$(TargetCloudService)\;Configuration=$(DeployConfig);"
Targets="Publish"/>
</Target>
<!--
Target to deploy the package produced by the dependency target.
This is the part that launches PowerShell to execute custom ps1 script
with all the cloud service parameters (MSBuild variables above)
and cspkg package for deployment.
The custom script uses the Azure module cmdlets to make service checks and publish.
-->
<Target Name="DeployCloud" DependsOnTargets="PackageCloud">
<Message Text="Deploying package to cloud service ..."/>
<Exec WorkingDirectory="$(MSBuildThisFileDirectory)"
Command="$(windir)\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -f $(MSBuildThisFileDirectory)PublishCloudService.ps1 -packageLocation "$(PackageOutDir)$(TargetCloudService)\app.publish\$(TargetCloudService).cspkg" -cloudConfigLocation "$(PackageOutDir)$(TargetCloudService)\app.publish\ServiceConfiguration.Cloud.cscfg" -subscriptionDataFile "$(PubSettingsPath)" -selectedsubscription "$(SubscriptionName)" -servicename $(TargetCloudService) -storageAccountName $(StorageAccount)" />
</Target>
</Project>
So a one-shot deployment invocation would be something like
msbuild.exe custom.proj /t:DeployCloud
As astaykov pointed out, MSBuild on it's own doesn't know how to deploy to Azure but you can install the Azure Powershell SDK to do the deployment.
Even using the publishsettings file, there are still some additional commands you need to perform to do the deployment beyond just the publish one:
Import-AzurePublishSettingsFile - to use the settings
Set-AzureSubscription - used to set a default storage account (where you will upload the package from msbuild)
Select-AzureSubscription - used to update the subscription for your powershell context
Get-AzureStorageContainer - get the container you're going to upload the package to
New-AzureStorageContainer - useful if the container doesn't already exist
Set-AzureStorageBlobContent - Upload the package to blob storage
Get-AzureStorageBlob - Read info about the blob, likes it's Uri
Get-AzureDeployment - Get info about a deployment in a slot of your service - useful before dpleoyment, while waiting for instances to start, etc
Remove-AzureDeployment - Removes a deployment - useful if you publish to staging and VIP swap into production
New-AzureDeployment - Create a new deployment from a given package (blob), config, etc in a service
Move-AzureDeployment - VIP swap staging/production slots
Set-AzureDeployment - Can be used to change the status of a deployment
I have a post around building a sample publication script here: Automated Deployment to Azure Hosted Services
It walks through the process in greater depth to use those scripts in building a deployment script that follows the "deploy to staging and VIP swap into production" path, but a lot of the details are still relevant for a direct upgrade deployment.
I use a similar method for several projects, but go one step further and swap out the configuration projects in between an msbuild call and packaging.
On the "publish settings" vs credentials, I think it comes down to where you are going to be running these builds (and who has access to that environment) and whether you feel more comfortable with a certificate enabling access or a set of credentials, based on portability and visibility/access in your build process. A lot of the core steps will be the same, though.
After you get your CSPKG and CSCONFIG files, you need to "manually" publish your project. MSBuild does not publish the project. You can use Azure PowerShell to publish the project. The Publish-AzureService is the cmdlet you are looking for.
You can also configure one (or more) users in your Azure AD tenant (something that each Azure subscription has) and enable fully automatic deployment with PowerShell without the need of .publishsettings file and client certificates. Check my Non-interactive login with Azure PowerShell and Azure AD blog post.
UPDATE
Fairly stright forward and easy to use PowerShell Script for creating new deployment on existing Cloud Service and existing Storage Account:
Add-AzureAccount
Select-AzureSubscription "<subscription name>"
Set-AzureSubscription -SubscriptionName "<subscription name>" `
-CurrentStorageAccountName "<storage_account_name>"
New-AzureDeployment -ServiceName "<cloud_service_name>" `
-Package "D:/tmp/cloud/myservice.cspkg" `
-Configuration "D:/tmp/cloud/ServiceConfiguration.Cloud.cscfg" `
-Slot "Staging"
And an Upgrade Script:
Add-AzureAccount
Select-AzureSubscription "<subscription name>"
Set-AzureSubscription -SubscriptionName "<subscription name>" `
-CurrentStorageAccountName "<storage_account_name>"
Set-AzureDeployment -Upgrade `
-ServiceName "<cloud_service_name>" `
-Package "D:/tmp/cloud/myservice.cspkg" `
-Configuration "D:/tmp/cloud/ServiceConfiguration.Cloud.cscfg" `
-Slot "Staging"
For Slot you can either use Staging or Production. For the case you use publish settings file, just replace the Add-AzureAccount with Import-AzurePublishSettingsFile.
Note that these are verified scripts.
A good example of a script that deploys to an Azure Cloud Service from Build vNext source code: Publish-AzureCloudDeployment.ps1