Where is the metabase key for my IIS7 web site? - iis-7

I'm trying to set up the automated (nightly) installation of my web site setup project. I can specify some install-time values on the command line; in particular, adding a TARGETSITE value defines the web site to which my new deployment will go.
How do I find the metabase key to my web site (eg. "/LM/W3SVC/213548468") in an IIS7 installation? (I do have IIS6 compatibility all set up, but I can't find anything about my site in the metabase.xml file.)
Also, since the web deployment setup projects are obviously outdated mechanisms (I guess they were too easy to use?), does anyone have a better idea for my nightly automated deployments?

In IIS 7 and above we do not use the metabase anymore and instead moved to a ".config" model where we store all the settings inside "%windir%\system32\inetsrv\config\applicationHost.config", that is where you will find all the information and settings you apply. If you enable IIS 6 compatibility we will run all the commands by translating them directly into the new ApplicationHost.config.
It would be useful to know more about how you are doing it today, If you use Managed code probably the best solution is using Microsoft.Web.Administration (Link) which includes a class called ServerManager to allow you to set everything you need.
If you use scripts (vbscript/jscript) you can continue using your scripts or instead use AHADMIN which is our new underlying COM configuration api.
if you use powershell we also have a PowerShell provider (http://www.iis.net/download/PowerShell) provide which should be the best in that case.
Also, if you actually want to package contents and configuration and other stuff like Registry settings, COM objects, GAC dlls, etc, you should use Web Deploy (http://www.iis.net/download/WebDeploy)

I know nothing about metabase, but from your posts I was able to cobble together the following:
import-module WebAdministration
$site = get-website | Where-object {$_.Name -eq "SiteName"}
$id=$site.ID
setup.msi /passive TARGETAPPPOOL=`"ASP.NET v4.0`" TARGETSITE="/LM/W3SVC/"$id
The backtick marks are the escape characters for powershell.

Related

How can I delete existing files when deploying an ASP.Net 5 Web App to Azure

I've got a web application in ASP.Net 5 with the source in VS Team Services. Using the Team Services build system, I'd like to deploy it directly to Azure for Continuous Deployment.
I've followed the steps here: https://msdn.microsoft.com/Library/vs/alm/Build/azure/deploy-aspnet5
However, when the website is deployed, only the new files are added and existing ones are overridden. Any deleted files are not removed. This means that extra controllers that were removed during refactoring (for example) still hang around.
Is there a way to force the deployment to wipe out any existing deployed website before putting the new one in place?
I've already run into an issue where the site is unable to deploy due to files being locked. I fixed this by wrapping the publish command in commands to start/stop the site:
Stop-AzureWebsite -Name $websiteName
. $publishScript -publishProperties $publishProperties -packOutput $packOutput
Start-AzureWebsite -Name $websiteName
In theory I could instead remove and create the website, but that seems a bit heavy handed...
Another option, using the publish profile:
Add this to your MSBuild parameters:
/p:SkipExtraFilesOnServer=False
Additional parameters here:
Valid Parameters for MSDeploy via MSBuild

Deploying AD FS web application to multiple environments

Background:
I have an ASP.NET web app configured for federation with AD FS. I'm using VS 2012, and have TFS for source control, builds and deployments.
We're currently deploying by copying the built files from the build server (TFS) to the alpha environment. From there we would copy from alpha to beta, then from beta to production. So there is not a unique build for each environment. The way we're handling environment-specific settings right now is there is one config file that has all the settings for each environment Let's call this EnvironmentSpecificSettings.config (I'll refer to it below). There is a static file on each server that indicates which environment the server should be in, and so when that config file is read in, the matching settings can be applied.
The problem:
The ADFS configuration is handled in the web.config. There are a few things that are specific to the environment. How might I handle this within my current deployment paradigm? I had a couple of ideas:
include a file reference in the web.config that reads in a static environment-specific file that would not be part of the deployment.
Try to pull something off in Application_Start that would read in settings from EnvironmentSpecificSettings.config (mentioned above) and alter the web.config.
Try to tweak the configuration of the WSFederationAuthenticationModule at runtime
the first idea (#1) is less than optimal because it requires files hanging around outside of source control and outside of deployments, however it should work easily enough. Next, #2 I kinda think isn't possible. I'm not sure you can change your web.config like I am hoping, but maybe? Finally, #3 Is only reasonable because I'm in a special situation where I'm not doing regular passive authentication, instead I'm manually redirecting to adfs, so I have a chance to change settings, such as injecting the whr parameter to avoid HRD. So, it might be possible, however, I'm not sure how or if you can change some of these values on the fly such as thumbprint, or wsFederation issuer or realm.
Does anyone have any better ideas or experience in handling environment-specific settings without doing the visual studio web deploys with transforms?

How to detect if ASP.NET is enabled in IIS 7

The challenge is to determine whether ASP.NET is enabled within IIS7 in a reliable and correct way.
Enabling/Disabling is done in this case by going into:
Server Manager ->
Roles ->
Web Server (IIS) ->
Remove Role Services ->
Remove ASP.NET
The natural place to determine this should be within the applicationHost.config file. However, with ASP.NET enabled or disabled, we still have the "ManagedEngine" module available, and we still have the isapi filter record in the tag.
The best I can find at the moment is to check if the <isapiCgiRestriction> tag includes the aspnet_isapi.dll, or that the ASPNET trace provider is available.
However these aren't detecting the presence of the ASP.NET config directly, just a side effect that could conceivably be reconfigured by the user.
I'd rather do this by examining the IIS configuration/setup rather than the OS itself, if possible, although enumerating the Roles & Services on the server might be acceptable if we can guarantee that this technique will always work whenever IIS7 is used.
Update
Thanks for the responses. Clarifying exactly what I want to do, I'm pulling settings from a variety of places in the server's configuration into a single (readonly) view to show what the user needs to have configured to allow the software to work.
One of the settings I need to bring in is this one:
The one highlighted in red.
I don't need to manipulate the setting, just reproduce it. I want to see whether the user checked the ASP.NET box when they added the IIS role to the server, as in this example they clearly didn't.
I'd like to do this by looking at something reliable in IIS rather than enumerating the role services because I don't want to add any platform specific dependencies on the check that I don't need. I don't know if it will ever be possible to install IIS7 on a server that doesn't have the Roles/Services infrastructure, but in preference, I'd rather not worry about it. I also have a load of libraries for scrubbing around IIS already.
However, I'm also having trouble finding out how to enumerate the Roles/Services at all, so if there's a solution that involves doing that, it would certainly be useful, and much better than checking the side effect of having the ASPNET trace provider lying around.
Unfortunately, if you don't check the ASP.NET button, you can still get the ManagedEngine module in the IIS applicationHost.config file, so it's not a reliable check. You can also have ASP.NET mapped as an isapi filter, so checking them isn't enough. These things are especially problematic in the case where ASP.NET was installed but has been removed.
It looks like the best solution would be to examine the Role Services. However, API information on this is looking pretty rare, hence the cry for help.
The absolute way to know if they checked that or not is to search the following registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp\Components
In there you should see two values set to 1, ASPNET and NetFxEnvironment and NetFxExtensibility. This registry key is the IIS Setup key that contains all the components that have been enabled in IIS.
Determining if asp.net is even an installed feature (prerequisite for enabling it) can be done through PowerShell, which implies there is .net api out there for it if you dig hard enough. The PowerShell methods:
Import-Module servermanager
Get-WindowsFeature web-asp-net
Which will return an object of type Microsoft.Windows.ServerManager.Commands.Feature. The installed property is boolean and indicates whether or not the feature is installed.
So do you want the easy way? Make a nice pretty .aspx page that displays as HTML with an error block in a div in a placeholder saying "You need to install ASP.NET" and have it change on ASP.NET being installed to instead say "ASP.NET is installed" and then just have the tool launch this webpage in the default browser after copying it to the directory identified in IIS as the *:80 site (or create the directory mapping in IIS programmatically by altering the XML and then removing it later)
May not be the most elegant but it does ensure that testing shows what features are truly installed versus what's in an XML file.
Because that will scream "do it the lazy ignorant way" I'll remind you that the only way for me to know in javascript what features I can use is to test them before I try to use them, or assume they're there and watch it blow up. My point is, it doesn't matter what gets reported in a file, it matters what you can actually use. Just because C:\Windows\Micrsoft.Net\Framework\v3.xxxxxxxx exists and has files doesn't mean the dll's are registered in the GAC, does it?

Problem with Team Build 2010 and web.config transformation

I'm struggling to get web.config transformations working with automated builds.
We have a reasonably large solution, containing one ASP.NET web application and eight class libraries. We have three developers working on the project and, up to now, each has "published" the solution to a local folder then used file copy to deploy to a test server. I'm trying to put an automated build/deploy solution in place using TFS 2010.
I created a build definition and added a call to msdeploy.exe in the build process template, to get the application deployed to the test server. So far, so good!
I then tried to implement web.config transforms and I just can't get them to work. If I build and publish locally on my PC, the "publish" folder has the correct, transformed web.config file.
Using team build, the transformation just does not happen, and I just have the base web.config file.
I tried adding a post-build step in the web application's project file, as others have suggested, similar to:
<target name="AfterBuild">
<TransformXml Source="Web.generic.config"
Transform="$(ProjectConfigTransformFileName)"
Destination="Web.Config" />
</target>
but this fails beacuse the source web.config file has an "applicationSettings" section. I get the error
Could not find schema information for the element 'applicationSettings'.
I've seen suggstions around adding arguments to the MSBuild task in the build definition like
/t:TransformWebConfig /p:Configuration=Debug
But this falls over when the class library projects are built, presumably because they don't have a web.config file.
Any ideas? Like others, I thought this would "just work", but apparently not. This is the last part I need to get working and it's driving me mad. I'm not an msbuild expert, so plain and simple please!
Thanks in advance.
Doug
I just went through this. Our build was a bit more complicated in that we have 8 class libraries and 9 web applications in one solution. But the flow is the same.
First off get rid of your after build target. You won't need that.
You need to use the MSDeployPublish service. This will require that it be installed and configured properly on the destination server. Check the following links for info on this part:
Note that the server in question MUST be configured properly with the correct user rights. The following sites helped me get that properly set up.
http://william.jerla.me/post/2010/03/20/Configuring-MSDeploy-in-IIS-7.aspx
http://vishaljoshi.blogspot.com/2010/11/team-build-web-deployment-web-deploy-vs.html
How can I get TFS2010 to run MSDEPLOY for me through MSBUILD?
The next part requires that your build definition have the correct MSBuild parameters set up to do the publish. Those parameters are entered in the Process > 3.Advanced > MS Build Arguments line of the build definition. Here's a hint:
(don't change the following for any reason)
/p:DeployOnBuild=True
/p:DeployTarget=MsDeployPublish
/p:CreatePackageOnPublish=False
/p:MSDeployPublishMethod=WMSVC
/p:SkipExtraFilesOnServer=True
/p:AllowUntrustedCertificate=True
(These control where it's going)
/p:MSDeployServiceUrl="https://testserver.domain:8172/msdeploy.axd"
/p:UserName=testserver\buildaccount
/p:Password=buildacctpassword
/p:DeployIisAppPath="MyApp - TESTING"
Obviously the user will have to be configured in IIS on the target server to be allowed access to that axd (see previous links). And the IisAppPath is the name of the website on the target server.
You won't have to do anything special for the config transformations as the build itself will take care of that for you. Just have the correct setting in the line at Process > 1. Required > Items to Build > Configurations To Build.
Instead of trying to do the deploy by adding tasks myself into the build process template, I followed advice in Vishal Joshi's blog post here.
Now the entire project is built and deployed and the web.config transformations work also. Brilliant!
I now have another problem to solve! The web application references web services and the build process results in an XmlSerializers dll. However, although this is built OK, it does not get deployed to the web host. I think this needs a new post!
Doug

How can you change the name of the web.config file and have IIS read from the newly-named file?

Is it possible to configure an IIS site to read ASP.Net settings from a site OTHER than web.config?
We'd like to have three config files in our codebase -- web-dev.config, web-test.config, and web-prod.config. Each IIS instance would be configured to read from their specific file. This way we have version control them all next to each other (and one-click deploy the entire site) but know that each IIS instance will read the settings specific to itself.
I've found in IIS where it shows where the web.config is, but I can't see how to change the location.
I use the configSource property to specify an external config file for sections that need different values for dev and production.
<connectionStrings configSource="Config\ConnDev.config"/>
Then you only have to change one setting (manually or with a tool) to switch from Dev to Production configs.
The best solution right now is to use different configs for development and production. This however will change with .net 4 and VS 2010 which they have added Web.Debug.config, Web.Release.config, Web.Staging.config and Web.Testing.config which will then publish the config you need in relation to the environment.
At my company we just have our deployment tool set to copy the appropriate file to web.config depending on what kind of deployment we're doing.
I believe it has to be named web.config.
You are facing a common problem.
One solution that I have used that worked really well in a large organization was to set environment variables on the web servers. Such as DEV, QA, UAT, PROD. Then, in code, you can query the environment variable to see which machine you are on, and then choose the values of appSettings accordingly. For example, you could have a database connection string named DEVconnection, and another named UATconnection. If your code determines from the environment variable that you are on UAT, then it would use UATconnection.
This does assume that you have the ability to set environment variables on the web server. In this instance, the admins running the servers were the ones who suggested this solution.
What was sweet about this was that there was ever only one version of web.config.
I do not think we can make web.config declaratively so that we can specify different config file. One thing you can do you can split your configuration file and set for different environments.
Please go through this article
http://jetmathew.wordpress.com/2011/02/07/split-web-config-for-different-environment/
cheers

Resources