sayedihashimi / package-web

Extensions for ASP.NET web projects package creation
32 stars 18 forks source link

Remote deployment having "nested" site name fails #49

Open tbehunin opened 11 years ago

tbehunin commented 11 years ago

[The real root of this issue appears to be an MSDeploy bug, but there appears to be a work-around for PackageWeb, as outlined below.]

If remotely deploying (i.e. not localhost) via PackageWeb to an IIS site that is nested within one/more sites (i.e. "MySite\MyNestedSite"), PackageWeb will generate the following MSDeploy string:

"C:\Program Files\IIS\Microsoft Web Deploy V2\msdeploy.exe" -verb:sync -source:archiveDir="[archive dir here]" -dest:auto,includeAcls='False',ComputerName='https://MyServer:8172/MSDeploy.axd?site=MySite\MyNestedSite',Username=myusername,Password=mypassword,AuthType='BASIC' -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParamFile:"[archive dir here]\SetParameters.xml"  -skip:objectName=dirPath,absolutePath="_Deploy_" -skip:objectName=filePath,absolutePath=web\..*\.config -skip:objectName=dirPath,absolutePath=_Package -skip:objectName=filePath,absolutePath=.*\.wpp\.targets$ -allowUntrusted -enableRule:DoNotDelete

Running this will result in the following error:

Error Code: ERROR_USER_UNAUTHORIZED
More Information: Connected to the destination computer ("MyServer") using the Web Management Service, but could not uthorize. Make sure that you are using the correct user name and password, that the site you are connecting to exists, and that the credentials represent a user who has permissions to access the site.
Error: The remote server returned an error: (401) Unauthorized.
Error count: 1.

The error msg appears to be a red herring though. You will notice that the ComputerName value tacks on the site in the querystring:

https://MyServer:8172/MSDeploy.axd?site=MySite\MyNestedSite

Because the site name is still being written to the SetParameters.xml file, PackageWeb doesn't need to tack the site in the querystring. In fact, if you execute the same command above and only change the ComputerName key/value to:

ComputerName='https://MyServer:8172/MSDeploy.axd'

the deployment succeeds! So, the fix to this issue would simply be tweaking a line in the BuildMSDeployCommand() method in the Publish-Interactive.ps1 file to remove the "?site={1}", like so:

$compNameCommandFrag = ",ComputerName='{0}'" -f $compNameFixedUp

As stated earlier, the issue appears to be an MSDeploy issue, not accepting/parsing nested site names in the querystring for whatever reason. But that limitation can be alleviated if you use the SetParameters.xml file to specify the site name instead - and NOT specify the site as a querystring parameter in the ComputerName variable.

philrowan commented 10 years ago

I ran into this same issue recently. @tbehunin fix from above works fine, but then the file must be manually changed per project in the _Package directory the nuget package is creating. There is already a function in the script for determining if the target is localhost so I propose:

 # Computer name parameter
    $compNameParamValue = (FindParamByName -allParams $paramValues -name "Computer name").Value
    $compNameCommandFrag = ""
    $isCompNameLocalhost = IsComputerNameLocalhost -compName $compNameParamValue
    if($compNameParamValue.length -gt 0 -and !$isCompNameLocalhost) {
        # Since this is not for localhost we need to combine site name with this for hoster scenarios
        $siteNameParam = FindParamByName -allParams $paramValues -name $paramNameIISApp
        $compNameFixedUp = FixupMSDeployServiceUrl -msdServiceUrl $compNameParamValue
        if ($isCompNameLocalhost)
        {
        $compNameCommandFrag = ",ComputerName='{0}?site={1}'" -f $compNameFixedUp, $siteNameParam.Value
        }
        else
        {
        $compNameCommandFrag = ",ComputerName='{0}'" -f $compNameFixedUp
        }        
    }

as soon as I learn to git I'll send a pull request.

rmagruder commented 9 years ago

I think this is the issue I'm having for a site in "Default Web Site". It's referencing "Default Web Site\MySite" in the ?site parameter and blowing up with this exact error. I hope we can get this fixed.

sayedihashimi commented 9 years ago

Can you try the publishinteractive.ps1 from https://raw.githubusercontent.com/PinnacleOfIndiana/package-web/master/src/Publish-Interactive.ps1 and let me know if it works? It's in a PR which I am behind on processing. If that works for you I'll merge and release and update today.

rmagruder commented 9 years ago

I just did. Maybe I'm just putting in commands wrong, but I would like to know what the desired parameters are for a remote deploy:

For Site Name, the default from the build output is "Default Web Site/MyService"
For Computer name i type: "https://Myserver/msdeploy.axd:8173" (don't know why I can't just type "MyServer" but it never really works when I do that. I'm also assuming I should not type the ?site= at the end of this. Not sure what we should put in for "Deploy to site root". I assumed that should be false (since I want to deploy to MyService under "Default Web SIte"

The output line from this included the ?Site= with the Site Name appended to it, but of course that fails because MyService doesn't exist. So the connection to msdeploy.axd to that site fails.

I still get the misleading ERROR_DESTINATION_NOT_REACHABLE

sayedihashimi commented 9 years ago

@rmagruder where are you hosting it? The value for the site name is the name of the website in IIS. You'll need to provide the name of a site which already exists. Default Web Site is the default when you create a new IIS web server. If you are publishing to a hoster you'll need to get the publish settings from them.

If you are trying to publish an app under a website then you use the syntax "<sitename>/<appname>" from what I can tell you are trying to just publish to the site root so it would be <sitename>.

rmagruder commented 9 years ago

It is being hosted on a server on our NT Domain. It's not a hosting site. Just one of our WIndows 2008 servers on our corporate network. "Default Web Site" already exists. In the Web Deploy publish Dialog in Visual Studio, the 'site name' hints "e.g. Default Web Site/my Site" and that's the format I put it in, which is why it's probably the default in the web deploy package.

So site root = "Default Web site"? SO I should put site name = "Myservice" if that's the appname, and select root = true?

I'll try that now...just wanted to get back to you. (And the host name and need for msdeploy.axd?)

sayedihashimi commented 9 years ago

OK I have taken the changes from @teabaggs and pushed to a new branch issue49 the file is at https://github.com/sayedihashimi/package-web/blob/issue49/src/Publish-Interactive.ps1. Can you guys test it and let me know if I should merge/release it?

sayedihashimi commented 9 years ago

@rmagruder in you case it sounds like you are trying to publish the website. You stated that "Default Web Site" exists in IIS and that is your target. So site root and site name should be "Default Web Site". I think your issue is not related to what is being discussed here, but not sure.

rmagruder commented 9 years ago

"Default Web Site" exists in IIS, but I am trying to create an application inside of it called "MyService". THAT is what I want to create. However, if the ?site parameter to msdeploy.axd contains "Default Web Site/MyService" it will fail with the error described in top message. If I were to tweak the command line and run it on a VS Command prompt such that the ?site parameter was just the "Default Web Site" it would work, and would even create the Application folder inside of it, because presumably the default full site name is buried in the web deploy package somewhere.

It's like a chicken and egg problem. Msdeploy.axd won't connect to "Default Web Site/MyService" because it doesn't exist, but trying to get the magic combination of parameters in PackageWeb to CREATE the MyService folder under Default Web Site is just not happening.

I am pretty sure it's not a rights issue, because I have been able to get this all to work from a VS command prompt. But I need those transforms for the different environments. I'm sure I don't have to tell you how frustrating it is that Microsoft did not integrate publish-time transforms into their web deploy system -- since you're obviously filling a big hole here.

A hole in my understanding is this issue with msdeploy. Is the "Default Web Site/Myservice" target specified in the package that's created during build? I would have thought so, as it's requested in the Web Deploy publish dialog inside Visual Studio. My sense is I need to "CONNECT" to "Default Web Site" but have web Deploy CREATE "Default Web Site/MyService" under it. I just can see no way that ?site="Default Web Site/MyService" EVER works when MyService folder doesn't already exist in IIS.

rmagruder commented 9 years ago

.\Publish-Interactive.ps1 The '<' operator is reserved for future use. At C:\temp\MyService\Publish-Interactive.ps1:171 char:11

  • < <<<< /li>
    • CategoryInfo : ParserError: (<:OperatorToken) [], ParseException
    • FullyQualifiedErrorId : RedirectionNotSupported
sayedihashimi commented 9 years ago

@rmagruder can you try publishing with the file at https://github.com/sayedihashimi/package-web/blob/issue49/src/Publish-Interactive.ps1 and let me know if it works?

If that doesn't work try this.

In VS create a new web deploy publish profile. The value for application name should be "Default Web Site/MyService". Instead of publishing just save the profile. That will create a .pubxml file under Properties\PublishProfiles add the following property.

<UseMSDeployExe>true</UseMSDeployExe>

In Tools->Options->Projects and Solutions->Build (something like that) set MSBuild verbosity in output window to Detailed.

Then publish in VS. The call to msdeploy.exe will be shown in the output window, just search for "msdeploy.exe".

Then publish with publish-interactive.ps1. Then paste the command line from VS that works here and the one from publish-interactive.ps1 which doesn't work.

The '<' operator is reserved for future use.

Never seen that before, let's try the steps above and then go from there. If that is happening every time please open a new issue to discuss.

rmagruder commented 9 years ago

Okay, from Visual Studio, it created the package then published it. The publish failed because of an untrusted certificate. So, I copied the generated command line to a command prompt, added the missing -allowUntrusted as you'll see below and it published PERFECTLY, creating the appropriate MyService app under Default Web Site. (I've 'dummied' confidential server/user/pw info below, but you get the idea)

C:\Temp\MyService>"C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe" -source:manifest='C:\Users\rmagruder\Source\Repos\MyService\Service\MyService\obj\Release\Package\MyService.SourceManifest.xml' -dest:auto,ComputerName="https://SERVERNAME:8172/msdeploy.axd?site=Default%20Web%20Si te",UserName='DOMAIN\USER',Password='PW',IncludeAcls='False',AuthType='Basic' -verb:sync -enableRule:DoNotDeleteRule -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParamFile:"C:\Users\rmagruder\Source\Repos\MyService\Service\MyService\obj\Release\Pa ckage\MyService.Publish.Parameters.xml" -retryAttempts=2 -allowUntrusted -userAgent="VS12.0:PublishDialog:WTE12.3.51016.0"

Then I copied the web deploy package output from the build to a temporary folder, substituted your latest Powershell script (my apologies for the "<" error, I right-clicked-saved your link in the message not realizing it was a link to a web page containing the file, rather than the file itself), and ran it with the following settings (again, dummied as necessary). There were a few problems with this publish. First, the 'default' connection string was blank, but that may be an error on my side. I edited the ps1 file below to add that.

$settingsFromUser =@() $settingsFromUser += @{name="IIS Web Application Name";value='Default Web Site/MyService'} $settingsFromUser += @{name="Add write permission to App_Data Folder";value='Default Web Site/MyService/AppData'} $settingsFromUser += @{name="ThreeDEntities2-Web.config Connection String";value='metadata=res:///3DEntities.csdl|res://_/3DEntities.ssdl|res://*/3DEntities.msl;provider=Devart.Data.Oracle;provider connection string=""User Id=USER;Password=PASSWORD;Server=SERVER;Direct=True;Sid=SERVER;Port=1523;Persist Security Info=True""'} $settingsFromUser += @{name="Computer name";value='SERVER'} $settingsFromUser += @{name="Username";value='DOMAIN\USER'} $settingsFromUser += @{name="Password";value='PW'} $settingsFromUser += @{name="Allow untrusted certificate";value='true'} $settingsFromUser += @{name="whatif";value='false'} $settingsFromUser += @{name="MSDeployDoNotDelete";value='true'} $settingsFromUser += @{name="AuthType";value='basic'} $settingsFromUser += @{name="ZipFile";value='MyService.zip'} $settingsFromUser += @{name="TransformName";value='Dev'}

This resulted in: C:\temp\MyService>"C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:archiveDir="C:\Users\RMAGRU~1\AppData\Local\Temp\MyService_zip" -dest:auto,includeAcls='False',ComputerName='SERVER',Username=DOMAIN\USER,Password=PW,AuthType='basic' -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParamFile:"C:\Users\RMAGRU~1\AppData\Local\Temp\MyService_zip\SetParameters.xm l" -skip:objectName=dirPath,absolutePath="Deploy" -skip:objectName=filePath,absolutePath=web.._.config -skip:object Name=dirPath,absolutePath=Package -skip:objectName=filePath,absolutePath=..wpp.targets$ -allowUntrusted -enableRule:DoNotDelete Info: Using ID '62d15436-ac6f-4a45-acd5-7361e0c80b52' for connections to the remote server. Error Code: ERROR_USER_NOT_ADMIN More Information: Connected to 'SERVER' using the Web Deployment Agent Service, but could not authorize. Make sure you are an administrator on 'SERVER'. Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_USER_NOT_ADMIN. Error: The remote server returned an error: (401) Unauthorized. Error count: 1.

This error makes no sense to me. These credentials a) worked fine in the command prompt version above and published just fine, b) I double/triple checked the server. This user IS an admin on that box and all the 'stuff' seems to be installed and configured correctly.

Should computer name be in the format https://server:8172/msdeploy.axd? Rather than just "server"? UPDATE: Changed the parameter to:

$settingsFromUser += @{name="Computer name";value='https://SERVER:8172/msdeploy.axd?site=Default Web Site'}

And it deployed!

So it seems as it would be nice if your script properly turned SERVERNAME into the format above, and prompted for both the target site and the IIS Web Application name without assuming they are one and the same. Also, I am still seeing the {IIS Web Application Name}\App_Data in the prompts and I'm having to manually override with the actual IIS Web Application Name, so the powershell script isn't substituting the Web App Name variable for adding that folder/content/rights in interactive mode.

I'll look at why the connection string dropped but that could be user error on my part.

I think we're getting there. Ideally I'd like our build machine to build & deploy the package.zip to a deployment server, and have someone be able to just run the publish aiming at the target environment to publish to each respective environment, without having to worry too much about getting all these parameters exactly right. Honestly the only thing she should have to change, ideally, is 'Dev', 'sqa', etc. (the transform). and the target server name.

sayedihashimi commented 9 years ago

@rmagruder thanks for the details. Did you try with https://github.com/sayedihashimi/package-web/blob/issue49/src/Publish-Interactive.ps1 to see if that worked?

If that doesn't work I'll try and reproduce it and with the details hopefully I can fix it.

mpowers303 commented 8 years ago

Wow, without this post I would have given up on PackageWeb and gone a different direction. I could not get PackageWeb deployments to publish to a nested site. After trying various combinations I found that this works:

  1. in the SetParameters.xml:
    • set the IIS Web Application Name to "Default Web Site"
  2. in the PublishConfiguration:
  3. in Publish-Interactive.ps1 ~ line 630: Change this: $compNameCommandFrag = ",ComputerName='{0}?site={1}'" -f $compNameFixedUp, $siteNameParam.Value To This: $compNameCommandFrag = ",ComputerName='{0}'" -f $compNameFixedUp