Stop IIS 7 Application Pool from build script - msbuild

How can I stop and then restart an IIS 7 application pool from an MSBuild script running inside TeamCity. I want to deploy our nightly builds to an IIS server for out testers to view.
I have tried using appcmd like so:
appcmd stop apppool /apppool.name:MYAPP-POOL
... but I have run into elevation issues in Windows 2008 that so far have stopped me from being able to run that command from my TeamCity build process because Windows 2008 requires elevation in order to run appcmd.
If I do not stop the application pool before I copy my files to the web server my MSBuild script is unable to copy the files to the server.
Has anybody else seen and solved this issue when deploying web sites to IIS from TeamCity?

This article describes using an htm file named App_offline.htm to take a site offline. Once the IIS detectes this file in the root of a web application directory,
ASP.NET 2.0 will shut-down the application, unload the application
domain from the server, and stop processing any new incoming requests
for that application.
In App_offline-htm, you can put a user-friendly message indicating that the site is currently under maintainance.
Jason Lee shows the MSDeploy calls you need to use (plus much more about integrating these steps in your build scripts!).
MSDeploy
-verb:sync
-source:contentPath="[absolute_path]App_offline-Template.htm"
-dest:contentPath="name_of_site/App_offline.htm",computerName="copmuter_name",
username=user_with_administrative priviliges,password=passwort
After deployment you can remove the App_offline.htm file using the following call:
MSDeploy
-verb:delete
-dest:contentPath="name_of_site/App_offline.htm",computerName="computer_name",
username=user_with_administrative_priviliges,password=passwort

The msbuild community tasks includes an AppPoolController that appears to do what you want (though as noted it is dated and at present only supports IIS6.) An example:
<AppPoolController ApplicationPoolName="MyAppPool" Action="Restart" />
Note that you can also provide a username and password if necessary.
Edit: Just noticed that the MSBuild Extension Pack has an Iis7AppPool task that is probably more appropriate.

this is the fairly hackey workaround I ended up using:
1) Set up a limited-access account for your service to run as. Since I'm running a CruiseControl.NET service, I'll call my user 'ccnet'. He does NOT have admin rights.
2) Make a new local user account, and assign to the Administrators group (I'll call him 'iis_helper' for this example). Give him some password, and set it to never expire.
3) Change iis_helper's access permissions to NOT allow local login or remote desktop login, and anything else you might want to do to lock down this account.
4) Log in (either locally or through remote desktop) as your non-admin user, 'ccnet' in this example.
5) Open a command terminal, and use the 'runas' command to execute whatever it is that needs to be run escalated. Use the /savecred option. Specify your new administrative user.
runas /savecred /user:MYMACHINE\iis_helper "C:\Windows\System32\inetsrv\appcmd.exe"
The first time it will prompt you for 'iis_helper's password. After that, it will be stored thanks to the /savecred option (this is why we're running it once from a real command prompt, so we can enter the password once).
6) Assuming that command executed OK, you can now log out. I then logged back in as a local admin and turned off the 'ccnet' user for local interactive login, and remote desktop. The account is only used to run a service, but no real logins. This isnt a mandatory step.
7) Set up your service to run as your user account ('ccnet').
8) Configure whatever service is running (CruiseControl.NET in my case) to execute the 'runas' command instead of 'appcmd.exe' directly, the same as before:
replace:
"C:\Windows\System32\inetsrv\appcmd.exe" start site "My Super Site"
with:
runas /savecred /user:MYMACHINE\iis_helper "\"C:\Windows\System32\inetsrv\appcmd.exe\" start site \"My Super Site\""
The thing to note there is that the command should be in one set of quotes, with all the inner quotes escaped (slash-quote).
9) Test, call it a day, hit the local pub.
Edit: I apparently did #9 in the wrong order and had a few too many before testing...
This method also doesn't completely work. It does attempt to run as the administrative account, however it still runs as a non-escalated process under the administrative user, so still no admin permissions. I didn't initially catch the failure because the 'runas' command spawns a separate cmd window then closes right away, so I wasn't seeing the failure output.
Its starting to seem like the only real possibility might be writing a windows service that will run as admin, and its only purpose is to run appcmd.exe, then somehow call that service to start/stop IIS.
Isn't it great how UAC is there to secure things, but in actuality just unsecures more servers, because anything you want to do you have to do as admin, so its easier to just always run everything as admin and forget it?

You can try changing the Build Agent Service settings to log-on as a normal user account instead of SYSTEM (the default), this can be done from the services control panel (Start | Run | services.msc).
If it doesn't help, you can also try configuring the appcmd to always run elevated, refer to this document for details.
In case such option is not available for appcmd or it still doesn't work, you can disable UAC completely for this user.

Here you go. You can use this from CC.NET with NAnt or just with NAnt:
http://nantcontrib.sourceforge.net/release/latest/help/tasks/iisapppool.html

Related

Windows could not start the Apache CouchDB service on Local Computer

I have installed CouchDB on my Windows machine but while starting the CouchDB service, I am getting a message like:
Windows could not start the Apache CouchDB service on Local Computer. The service did not return an error. This could be an internal Windows error or an internal service error. If the problem persists, please contact your system administrator.
As the service is not running, I am unable to access Fauxton too.
I am using Windows 7. CouchDB is 2.0.0. Port 5984 is not in use.
I don't think your question is a duplicate of https://stackoverflow.com/a/44107335/219187 because you are on Windows 7, and the problem described there is for Windows 10 with the creators update.
But maybe the solution fixes your problem as well? Here is the procedure:
Download the prelease build 2.2.4-101 from https://nssm.cc/download
Stop the CouchDB service through the Windows Services dialog (paused is not enough)
Overwrite nssm.exe in <CouchDbInstallDir>\bin with the one from the downloaded ZIP file (make sure you pick the right version 32 bit / 64 bit)
Start the CouchDB service
Issue it's happening since the last updates released by Microsoft. I'm not completely aware of what's causing it, but I think it's something related to CouchDB service not been able to start using Local Administrator rights.
However I've managed to start the service manually, by doing so:
Open Command Prompt - in the Search from the Start Menu or Task Bar type "cmd"
Run it as an Administrator - right click on the Command Prompt application and choose "Run as administrator" option /this is really IMPORTANT as it will allow the service to have administrator access/
Navigate to the folder where CouchDB is install - default path is "D:/CouchDB", but could be anywhere else; you have to find it
Go to the "bin" folder in there
Type "couchdb" as a command to start the service
You will see a message showing after this - "kernel-poll not supported; "K" parameter ignored"
If it adds some error messages after it or closes the whole terminal, you're making some things bad from this guide, so follow it strictly.
You can now open up the Fauxton application in the browser like normal from here - http://localhost:5984/_utils/
Keep in mind that you have to leave the cmd opened in order the service to be working as expected. As far as I saw no information was lost, so it's all good.
This is a temporary solution though, as we are waiting a relase from either Microsoft or Apache to solve the issue, or at least give us more explanation about it.
i just met the same problem.
the cause is space, you have to install CouchDB in a path without any space, even Program Files folder, because there is a space between Program and Files...

msdeploy returning unauthorized when using the admin account and correct username / password

I am trying to use msdeploy on my web servers using the /MSDEPLOYAGENTSERVICE method and it is continually saying i am not an admin and not authorized but i am using the administrator account and am using the correct password. Internally if i try the webdeploy.axd it works but that method is not an option for me due to port concerns.
Here is one of the command strings i use
"%ProgramFiles(x86)%\MSBuild\12.0\Bin\amd64\msbuild.exe" ..\mysolution.sln /t:Clean;Rebuild /p:Configuration=%CONFIG% /verbosity:m /fileLogger /maxcpucount:4 /p:DeployOnBuild=true /p:PublishProfile=%CONFIG% /p:MSDeployServiceURL=http://%SERVER% /p:UserName=Administrator /p:Password=%PWORD%
Here is another one that is returning the same issue:
msdeploy -verb:sync -source:webserver,computername=%MACHINE%,username=Administrator,password=%PASSWORD% -dest:webserver 2<&1
This happened after i updated msdeploy to version 3.5 and moved my development environment to vs2013. Unfortunately i can not downgrade either of these. Aside from those changes nothing else has been changed.
As always asking the question has reveled the answer.
If this group policy key is set to 'Guest Only' msdeploy will NOT work.
I switched it back to 'Classic' and now it works properly.
Computer Configuration\Windows Settings\ Security Settings\Local Policies\Security Options\Network Access: Sharing and security model for local accounts.
I know i said nothing changed but my admin seemed to have forgotten about that change. He has since been feed to the sharks with laser beams on their foreheads.

Can't run vb.net application as administrator across network

I have created a small application that auto elevates as administrator using the command:
requestedExecutionLevel level="highestAvailable" uiAccess="false"
This works fine if I run the application locally on the computer. However, if the computer tries to run my execuatable across the netork, it simply crashes on startup with a message "Do you want to send more information about the problem?" error. If I right click and run as administrator, my application will work and will prompt for admin credentials.
The folder I am running my application from (across the network) has full read/write permissions for 'everyone'.
My question is: Is there something I've missed? Why can I run my application locally and not get prompted but across the network crashes or requires admin?
Can anyone help explain what might be causing this issue?
UPDATE
I have checked my event viewer log and it shows the following:
Application: AutoUpdater.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Net.Sockets.SocketException
Stack:
at System.Net.Sockets.Socket..ctor(System.Net.Sockets.AddressFamily, System.Net.Sockets.SocketType, System.Net.Sockets.ProtocolType)
at System.Net.Sockets.TcpListener..ctor(System.Net.IPAddress, Int32)
at System.Runtime.Remoting.Channels.Tcp.TcpServerChannel.SetupChannel()
at System.Runtime.Remoting.Channels.Tcp.TcpServerChannel..ctor(System.Collections.IDictionary, System.Runtime.Remoting.Channels.IServerChannelSinkProvider, System.Runtime.Remoting.Channels.IAuthorizeRemotingConnection)
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.RegisterChannel(ChannelType, Boolean)
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(System.String[])
at AutoUpdater.My.MyApplication.Main(System.String[])
I don't understand why it is making reference to System.Net.Sockets?? But that is what seems to be crashing my app.
Make sure that the other computers attempting to run your application have the correct .Net framework versions installed. If users are able to open the executable, there shouldn't be any other issues with permission.
If you have verified the framework versions, see if there is anything in the error report that might point to a reason for the crash. A lot of times there may be something in there that can point you in the right direction.
.NET applications don't like to run from the intranet by default.
Try this:
Go to Control Panel -> Administrative Tools -> Microsoft .NET Framework 2.0 Configuration
Click Configure Code Access Security Policy link
Click Adjust Zone Security
Set the My Computer and Local Intranet to Full Trust
If this works, then it is a local security issue. If you need it scripted out, you can use the caspol exe that is in the framework. Sample
C:
cd %windir%\Microsoft.NET\Framework\v2.0.50727
CasPol.exe -pp off -m -ag 1. -URL Z:\folder\EXEName.exe FullTrust -n FriendlyNameOfEXE

Installing a win32 service using MSBuild and Microsoft.Sdc.Tasks

I'm trying to install windows service using the Microsoft.Sdc.Tasks library.
<ControlService Action="Install"
ServiceName="Service1"
User="XXX
Password="XXX"
ServiceExePath="$(DeployFolder)\XXX.exe"/>
But I keep getting prompted for the user and password! This will not work as I'd like to have it as an automated build on the build server. I mean, the user and password that I want to run the service under are in the actual target. How do I get it to install the service using the configured user and password and not prompt for it?
Found this post and since all my service does is writing and reading from local file I should be OK running under the Local Service account instead of a specific user. Even after updated the service installer the ControlService-target requires a user and password to run but then I actually doesn't prompt me for the user and password. But then I don't want to run a specific user and the target fails when not provided with a user and password in the config ... Strange.
I solved by shelling out to the InstallUtil.exe instead. That works fine after set the I set service installer to run as a Local Service account.
<Exec WorkingDirectory="C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727"
Command="InstallUtil.exe -i XXX.exe" />
Just an FYI, to install to a remote server, you should use the SericeController task listed here:
http://weblogs.asp.net/scottgu/archive/2006/02/12/438061.aspx

Logoff script to change user

Using Windows 2003, I'm look for a way to create a "logoff script" that will continue with the current logoff then immediately login another user. So, "UserA" logs off. Script fires to login "UserB".
This is part of an application upgrade for a computer where we have written the 'shell'; similar to a kiosk application. For the upgrade we need to logon as 'Adminstrator' then, when the upgrade has completed, logoff 'Administrator' and logon as 'sample_user'. We would like to accomplish this WITHOUT rebooting.
Note, I do not want a script that will initiate the logoff (i.e. "shutdown"). I'm looking for a script that will run upon the user logging off (set via Group Policies). As above, the script should log a different user on.
Thanks.
Don't think it's possible in the stated way (script at logoff).
You'd have to set the machine to logon automatically as a specified account and then log off (having it log on automatically for you) and then you'd have to disable that feature again afterwards, by placing a temporary logon script... generally sounds messy.
The actual setting can be made using tools like Microsofts Shared Computer Toolkit or similar (not so sure how the "normal" registry auto-login behaves at manual logout but I've had an XP kiosk that would automatically log on instantly, even if you logged out manually - you had to override it using some key like shift+logoff to be able to manually specify the login again, so somehow it can be made).
The "easiest" way might be to replace msgina.dll with someone of your own making...
But why are you doing this? Just use runas and start whatever you need to do as that other user without logging off the console user - it's a multi-user system afterall? The desktop is just fluff ^^
(This will anyhow require that the user credentials are available to your script, which kind of makes it redundant as you compromise the security of that account - defying the purpose of having that second account in the first place, for whatever purpose it exists?)
I would try setting the registry to autologon with the user you want, and then simply logging off the admin user. That should log your kiosk-user right back on.
Not sure how to login another user once the current user logs off (not sure if windows would let you...)
But you can use shutdown to logoff:
shutdown /?
Here's some ideas that probaly fall into the "cheap hack" category:
How about logging in at UserB in the first place, and then using runas /user:userA <cmd> to run the first part of the install process?
If that's unacceptable, I know there's a way to make Windows workstations (those that aren't part of a Domain) automatically log in into a certain user account after a restart. Perhaps if you looked into which Registry changes happen, and duplicated them, a reboot would automatically log in that user. (Of course, as a final stage, after userB logs in, you would have to revert those changes :-)
It also occurs to me to wonder if perhaps there's a way for a service to force an open "login screen" to log in as a certain user. Maybe using some method like the way the Remote Desktop does it remotely... If that's possible, then you could create a service that you install before logoff of userA, that would trigger the login of userB.
You can script it with VNC (there are many free versions, take your pick). Set up a VNC server process on the machine to listen on localhost. When the user logs off, your logoff script will connect to the machine using VNC and send the keystrokes necessary to log on the next user. VNC uses the RFB (remote framebuffer) protocol; there are libraries for most popular languages, so you should be able to get something working quickly. Or there are related tools that might help.
If you were to run something like this as a normal script in a given language, it would most likely not work as when you log out of your account, all processes should be killed along with your running script.
You might be able to create some sort of 'service' that would run on a service account (i.e. always active) that would automatically do this user switching for you.
My bets are on Windows Powershell, although I'm not entirely sure what functionality it has as far as actually creating a service.
A quick search brings up the following (The second link is to a forum but it mentions running Powershell as a service and sending that service a parameter which would be the path to your user switching script)
How to Create a Windows Service using Powershel
Powershell Script as a Windows Service
I don't have a Windows 2003 server or a system with a "Group Policies" setup to test my hunch but you could take a look at SU ("switch user") for Windows. Originally part of the Resource Toolkit this has been extended to a new SUperior SU. Do post the results/script if this works.
You could approach this from the perspective of building a remote control utility (like VNC, etc). The big thing here is that if you want access to the Logon screen (i.e. the CTRL + ALT + DEL / username/password) part, the only kicker is that a Windows Service is the only component that can access this, so you'd have to create one.
The only problem I see with this technique as a whole is that even if you spent a great deal of effort getting it to work (and it would be a pretty big effort), the chances of this working successfully with the whole thing originating from a logoff script (i.e. when stuff is shutting down) are low even due to the number of things that can go wrong when logging back on as Administrator.
Just remember that for anything you need to run as an Administrator, there are easier ways in Windows to make that happen (such as Run As, changing the user permissions on the items that need to update, etc).