(MSDeploy) Deploying Contents of a Folder to a Remote IIS Server - msdeploy

Is it possible to deploy the contents of a folder (plain Html files) to a specific web application on a remote IIS6/7 server?
The following command does not error, but neither does it publish any files to the remote server:
msdeploy.exe -verb:sync -source:dirPath="c:\myHtmlFiles" -dest:auto,ComputerName="http://deploy.mycompany.co.uk/msdeploy?site=TestSite",includeAcls="false",username="administrator",password="myPassword" -enableRule:DoNotDeleteRule -disableLink:AppPoolExtension -disableLink:ContentExtension -allowUntrusted
NOTE:
WebDeploy is correctly installed on the destination server and works happily with packages created from msbuild scripts for .NET projects.
'http://deploy.mycompany.co.uk/msdeploy' is correct for the listening end-point.
The '?site=TestSite' query string was suggested elsewhere, but does not work.
The 'TestSite' web application exists on the target server.
Parameter files and -setParam do not work, and renders errors relating to the source not supporting the parameter 'IIS Web Application Name' if you attempt to set, declare, or provide it.

I just wrote a blog post to answer this at http://sedodream.com/2012/08/20/WebDeployMSDeployHowToSyncAFolder.aspx. From your question it looks like you are pretty familiar with MSDeploy so the answer might be a bit verbose but I wanted people with less knowledge of MSDeploy to be able to understand. I've pasted the answer below.
Web Deploy (aka MSDeploy) uses a provider model and there are a good number of providers available out of the box. To give you an example of some of the providers; when syncing an IIS web application you will use iisApp, for an MSDeploy package you will use package, for a web server webServer, etc. If you want to sync a local folder to a remote IIS path then you can use the contentPath provider. You can also use this provider to sync a folder from one website to another website.
The general idea of what we want to do in this case is to sync a folder from your PC to your IIS website. Calls to msdeploy.exe can be a bit verbose so let’s construct the command one step at at time. We will use the template below.
msdeploy.exe -verb:sync -source:contentPath="" -dest:contentPath=""
We use the sync verb to describe what we are trying to do, and then use the contentPath provider for both the source and the dest. Now let’s fill in what those values should be. For the source value you will need to pass in the full path to the folder that you want to sync. In my case the files are at C:\temp\files-to-pub. For the dest value you will give the path to the folder as an IIS path. In my case the website that I’m syncing to is named sayedupdemo so the IIS path that I want to sync is ‘sayedupdemo/files-to-pub’. Now that give us.
msdeploy.exe –verb:sync -source:contentPath="C:\temp\files-to-pub" -dest:contentPath='sayedupdemo/files-to-pub'
For the dest value we have not given any parameters indicating what server those command are supposed to be sent to. We will need to add those parameters. The parameters which typically need to be passed in are.
ComputerName – this is the URL or computer name which will handle the publish operation
Username – the username
Password – the password
AuthType – the authType to be used. Either NTLM or Basic. For WMSvc this is typically Basic, for Remote Agent Service this is NTLM
In my case I’m publishing to a Windows Azure Web Site. So the values that I will use are:
ComputerName: https://waws-prod-blu-001.publish.azurewebsites.windows.net/msdeploy.axd?site=sayedupdemo
Username: $sayedupdemo
Password: thisIsNotMyRealPassword
AuthType: Basic
All of these values can be found in the .publishSettings file (can be downloaded from Web Site dashboard from WindowsAzure.com). For the ComputerName value you will need to append the name of your site to get the full URL. In the example above I manually added ?site=sayedupdemo, this is the same name as shown in the Azure portal. So now the command which we have is.
msdeploy.exe
–verb:sync
-source:contentPath="C:\temp\files-to-pub"
-dest:contentPath='sayedupdemo/files-to-pub'
,ComputerName="https://waws-prod-blu-001.publish.azurewebsites.windows.net/msdeploy.axd?site=sayedupdemo"
,UserName='$sayedupdemo'
,Password='thisIsNotMyRealPassword'
,AuthType='Basic'
OK we are almost there! In my case I want to make sure that I do not delete any files from the server during this process. So I will also add –enableRule:DoNotDeleteRule. So our command is now.
msdeploy.exe
–verb:sync
-source:contentPath="C:\temp\files-to-pub"
-dest:contentPath='sayedupdemo/files-to-pub'
,ComputerName="https://waws-prod-blu-001.publish.azurewebsites.windows.net/msdeploy.axd?site=sayedupdemo"
,UserName='$sayedupdemo'
,Password='thisIsNotMyRealPassword'
,AuthType='Basic'
-enableRule:DoNotDeleteRule
At this point before I execute this command I’ll first execute it passing –whatif. This will give me a summary of what operations will be without actually causing any changes. When I do this the result is shown in the image below.
After I verified that the changes are all intentional, I removed the –whatif and executed the command. After that the local files were published to the remote server. Now that I have synced the files each publish after this will be result in only changed files being published.
If you want to learn how to snyc an individual file you can see my previous blog post How to take your web app offline during publishing.
dest:auto
In your case I noted that you were using dest:auto, you can use that but you will have to pass in the IIS app name as a parameter and it will replace the path to the folder. Below is the command.
msdeploy.exe
-verb:sync
-source:contentPath="C:\temp\files-to-pub"
-dest:auto
,ComputerName="https://waws-prod-blu-001.publish.azurewebsites.windows.net/msdeploy.axd?site=sayedupdemo"
,UserName='$sayedupdemo'
,Password='thisIsNotMyRealPassword'
,AuthType='Basic'
-enableRule:DoNotDeleteRule
-setParam:value='sayedupdemo',kind=ProviderPath,scope=contentPath,match='^C:\\temp\\files-to-pub$'

Related

How can I get the root of my project in ASP.NET and not the location of IIS Express using .CurrentDirectory()?

I have an ASP.NET Core project that I'm developing and I'm making use of LiteDB as a database solution. In order to instantiate my database I need to provide a URI so that the program knows where to create the database.
Usually I'd do something like System.Environment.CurrentDirectory() to find the current directory I'm in and modify that, however the result of this command turns out to be C:\program files\IIS Express or something similar. Basically the current directory points to the location of IIS Express.
Instead I want to get the root of my ASP.NET project, the location that contains my controllers folder, appsettings.json, bin and obj folders.
What command do I need to use to get a string representing this location? I don't want to use a hard coded string for obvious reasons.
If you don't have access to DI you could try:
Assembly.GetExecutingAssembly().Location
If you have access to DI, try this:
Inject the IHostingEnvironment and call environment.ContentRootPath
How to get root directory of project in asp.net core. Directory.GetCurrentDirectory() doesn't seem to work correctly on a mac
You may be better served by using a dedicated location (such as a network share) rather than the folder that contains the executable code. Having user data mixed into deployed code comes with a lot of headaches:
Deployments become more complex as they need to account for the presence of user data. This is especially true if you need to delete pre-existing code during a deployment.
If the user data is sensitive, developers may be denied access to read the deployed code. This can make troubleshooting issues much harder.
Backups of deployed code will contain user data, which means they will always appear to be different even if nothing (code-wise) has changed.
Of course, this all assumes that the production environment is configured differently from developers' local machines.

Is it possible to publish/deploy a web package, using a non-admin account, from the command line only?

The title needs some expansion. In summary, I am finding it impossible to:
Deploy a web site to an IIS 8 host
Using a Web Deploy Package
Using the out-of-the-box publish functionality in VS 2013
Using a non-admin IIS Manager User, which is delegated permission to deploy to the given site
It all seems to come down to one small detail that messes it all up, but I should describe my process up to the point where it all falls apart.
I create a publish profile Publish in VS 2013, configured to publish to a web package. I then fire the following command at a developer command prompt:
msbuild Solution.sln /t:Build /p:DeployOnBuild=true;PublishProfile=Publish;IsDesktopBuild=false
This goes through a build process and I now see the expected package and deployment files in the _PublishedWebsites\Web_Package folder. My next step is run this from the Web_Package folder:
Web.deploy.cmd /Y /M:https://example.blah:8172/MsDeploy.axd /U:user /P:p#44w0rd /A:Basic
This is where the problem comes in. This results in the following expanded command (formatted for ease of reading):
msdeploy.exe
-source:package='.\Web.zip'
-dest:auto,computerName="https://example.blah:8172/MsDeploy.axd",userName="user",password="p#44w0rd",authtype="Basic",includeAcls="False"
-verb:sync
-disableLink:AppPoolExtension
-disableLink:ContentExtension
-disableLink:CertificateExtension
-setParamFile:".\Web.SetParameters.xml"
whose execution results in:
Error Code: ERROR_USER_UNAUTHORIZED
More Information: Connected to the remote computer ("example.blah") using the Web Management Service, but could not authorize. 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. Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_USER_UNAUTHORIZED.
I can fix this problem by manually re-running just the expanded command and tagging on the site parameter to the MsDeploy.axd URL, like so:
msdeploy.exe
-source:package='.\Web.zip'
-dest:auto,computerName="https://example.blah:8172/MsDeploy.axd?site=example.blah",userName="user",password="p#44w0rd",authtype="Basic",includeAcls="False"
-verb:sync
-disableLink:AppPoolExtension
-disableLink:ContentExtension
-disableLink:CertificateExtension
-setParamFile:".\Web.SetParameters.xml"
However, I cannot see any way to have this set through Web.deploy.cmd which was auto-generated by MSBuild. If I try this:
Web.deploy.cmd /Y /M:https://example.blah:8172/MsDeploy.axd?site=example.blah /U:user /P:p#44w0rd /A:Basic
It results in this (again, formatted for ease of reading):
msdeploy.exe
-source:package='D:\DEV\Solution\Web\bin\_PublishedWebsites\Web_Package\Web.zip'
-dest:auto,computerName="https://example.blah:8172/MsDeploy.axd?site",userName="user",password="p#44w0rd",authtype="Basic",includeAcls="False"
-verb:sync
-disableLink:AppPoolExtension
-disableLink:ContentExtension
-disableLink:CertificateExtension
-setParamFile:"D:\DEV\Solution\Web\bin\_PublishedWebsites\Web_Package\Web.SetParameters.xml" example.blah
Error: Unrecognized argument 'example.blah'. All arguments must begin with "-".
Error count: 1.
I can perform this process fine using an admin account. But it seems that the non-admin requires this site= querystring value and the auto-generated Web.deploy.cmd just isn't having any of that.
Am I missing something obvious here? Is there a permission I'm missing on the IIS Management side? I've made sure I have the Management Service Delegation rule set up, as directed in this blog post.
I can't see a way around this using the process I've laid out. My solution here is to simply take the expanded MSDeploy.exe command line and use it directly instead of the generated *.deploy.cmd file.
Of course, if anyone comes along with an actual solution to my original problem, I'll happily mark that one as the answer. Until then, this is my solution.
You can put the /M: parameter in quotes like so:
Web.deploy.cmd /Y "/M:https://example.blah:8172/MsDeploy.axd?site=example.blah" /U:user /P:p#44w0rd /A:Basic

msdeploy and runCommand results in vague "Access is denied" error

I have a preexisting deployment process which successfully deploys a site to its staging environment. Attempting the same process against a new production environment is failing at the point where we try to invoke msdeploy's "runCommand" option.
We're using pstrami, which ultimately uses msdeploy twice. msdeploy successfully copies files to the target machine. pstrami then tries to use msdeploy a second time, this time to use "runCommand" on a bat file that should actually install everything under IIS.
The first use of msdeploy works, copying the files. Therefore, the credentials we're working with are correct.
The second use of msdeploy outputs the following:
Info: Updating runCommand (bootstrap.bat).
Warning: Access is denied.
It appears that bootstrap.bat is not actually reached. It is unclear who is being denied access to what. I suspect that the user is not allowed to perform "runCommand", but advice about runCommand online is inconsistent and has not revealed anything different between my staging and production machines.
What should it take for msdeploy 'runCommand' to be granted access?
MSDeploy supports configuring permissions on a per-provider basis, so your hosting provider may have disabled it. It might be worth checking with them.

Deploying not happening in publishing process

I am trying to publish to local file system, however publishing is not happening properly and its failed to deploy in my 2011 GA VM environment.
I am getting "Polling for notification for destination: YTnMgU6u5Vh09cOGUG7ouA== has exceeded polling attempts for transaction: tcm:0-121257-66560" error in "Preparing Deployment" stage.
I have used the “Local File System” protocol in my publication target and I have provided path like d:\tridion\publish.
And I have provided the same path in cd_storage_conf.xml under the <storage type=”filesystem”>. All other storage types are commented.
And in cd_deployer_conf.xml , quee location path is c:\tridion\incoming.
When I publish any page into my publication target, the zipped package is placed in the d:\tridion\publish and it’s not deployed.
Do I need to do any other thing to deploy the zipped package?
The path provided in the cd_deployer_conf.xml (the one you specify in Queue/Location!!!) needs to be the same one you provide in your publication target (in your case you have in the publicationTarget some path on D drive while in the deployer conf you have another one from C drive). Then you also need make sure that your deployer is initialized. You can easily determine if your deployer is initialized by looking if the meta.xml is regenerated in the deployer incoming folder.
Not sure if this is relavant but you might be interested also in how to install the deployer: as a .NET WebSite, as a Java WebSite or Windows Service
Hope this helps.
You say your working sites use HTTP sender/deployer. In that scenario your deployer is triggered by the HTTP servlet which receives the transport package.
When you use local file system - you MUST configure your deployer to work in a different way. It has to run as some form of background service. Typically on a windows box this means installing the deployer as a windows service. Keep in mind that this will then probably have additional config files for the deployer and broker/storage.

How to retain folder permission during website deployment?

I have a production website that, once built in TFS is re-deployed and updated using xcopy. The entire site (excluding the root directory) it deleted then the new site copied in. This works well.
We use a 3rd party charting package that creates images at runtime and then renders a link to them. In order to do this it needs write permissions to a browsable folder.
Unfortunately, every time we update the website the write permissions of IIS_USRS is lost. Is there any way to retain this?
I guess it depends on what operating system the server is running, and whether you are building on the same server as you're deploying to, or a remote one.
The simplest thing to do is to put your xcopy command into a batch file, and include something like the following after the xcopy:
cacls c:\[PathToWebsite]\[ChartImagesFolder] /E /G [AccountSiteRunsUnder]:C
Or a more up to date option (I've not used this, so my parameters may be off):
icacls c:\[PathToWebsite]\[ChartImagesFolder] /grant [AccountSiteRunsUnder]:M
Basically, either of those should give the user account that the site is running under modify (change) rights in the folder specified. This should be in addition to any existing rights on the folder, there are modifiers or switches to replace the existing rights.
If you are deploying to a remote server, you'll need some mechanism to run commands on there, we've found that PSExec works a treat (part of the PS tools from SysInternals).

Resources