43

I have been having lots of difficulty automating the setup of a Web application and configuring IIS appropriately with the Application Pool Identity. I am doing this in a Web application deployment script written in PowerShell. My requirement is that I need my PowerShell script to set the application pool identity user to a specific service account mydomain\svcuser and password. Here is the sample code:

$pool = New-Item "IIS:\AppPools\MyAppPool" -Force
$svcuser = "mydomain\svcuser"
$pool.processModel.userName = $svcuser
$password = "somepassword"
$pool.processModel.password = $password
$pool.processModel.identityType = 3
$pool | Set-Item -ErrorAction Stop

When I run this, everything appears to work correctly--no errors are thrown and the application identity user name appears in IIS--but for some reason the password does not get set correctly, if at all. Since it is a password I cannot verify whether it has been set, but I can conclude that it if it is, it is not set correctly. It will not authenticate the resulting application pool user until I manually go in and enter the password in IIS. As a result the application fails after being deployed to the Web server and requires manual intervention.

Am I missing something here?

paulyphonic
  • 854
  • 1
  • 6
  • 15
  • 3
    I think you can actually verify the password set on the processmodel object if you check it using powershell. Just try get-itemproperty 'IIS':\AppPools\myapppoolnamehere' "ProcessModel" – Robert Westerlund Jan 28 '14 at 20:08
  • Great, thank you. Now at least I can verify what it is actually doing with the password. Hopefully that will let me get closer to a path to a solution. – paulyphonic Jan 28 '14 at 22:25
  • I have confirmed that the password is in fact being set correctly. Therefore the only possible conclusion is that this was either repeated user error of some kind, or that IIS doing something else behind the scenes when you specify the password manually in the UI versus using the Web Administration module in PowerShell. The basic symptom is that, after running the deployment of my Web applications, the application pools fail and stop the first time they are hit. Then manually re-entering the same password fixes the problem. – paulyphonic Jan 31 '14 at 18:55
  • Anything in the event log? Does it solve the problem if you set the password in the processmodel object again? Does it make any difference if you set the identitytype to "SpecificUser" (as a string) instead of 3 (as an int)? – Robert Westerlund Jan 31 '14 at 19:26
  • 1
    As it turns out, this whole thing was a red herring. The reason that the password is not getting entered correctly is something that I had not expected. The script runs correctly when I run from PowerShell console, but in my actual script I am obtaining an encrypted password from a file, then decrypting it using keys that are in the registry, and all this is being called remotely using PSExec. When I run in PowerShell, it is decrypted properly, but when I do it over PSExec, the same user cannot access the keys from the registry and thus cannot decrypt the password and sets it incorrectly. – paulyphonic Feb 05 '14 at 03:02
  • But thank you for your comment above, as it helped me to see that I could actually access the password directly from the store. Which brings up some questions: isn't this a security vulnerability? I don't know of other areas where MS would allow you to get the unencrypted password to a user account simply by asking for it. Makes me wonder why I am even bothering to encrypt it to begin with. – paulyphonic Feb 05 '14 at 03:04
  • 1
    Unfortunately I cannot reproduce the PSExec claim I made above, and running PSExec manually I can most certainly read a registry on the machines (same machines, same account) so the search goes on. I may just close or edit the question once I get the details I need in order to even ask the right question. :( – paulyphonic Feb 05 '14 at 03:47
  • Could it be that when you were using PsExec, you had specified the "-e" switch, which prevents it from loading the user's profile? Or.... possibly, the profile hadn't been built yet? – Nathan Hartley Jan 06 '16 at 18:29
  • I have seen similar behavior to what you describe. For me, the first time I set the password in a time period (perhaps a day, not sure here) it will set. Then subsequent attempts appear to have no effect. It is as if there is a cache somewhere that can only be updated once in a while. – Prof Von Lemongargle Jul 11 '18 at 21:56

4 Answers4

75

You would do this as follows:

Import-Module WebAdministration
Set-ItemProperty IIS:\AppPools\app-pool-name -name processModel -value @{userName="user_name";password="password";identitytype=3}

See this document here for an explanation, and a reference of the indentity type numeric for the user type you will run the app pool under: http://www.iis.net/configreference/system.applicationhost/applicationpools/add/processmodel

feupeu
  • 819
  • 7
  • 25
Vitorrio Brooks
  • 871
  • 6
  • 4
  • 1
    This answer is really already part of the question. I was already setting the user name and password. As documented in the comments above, the actual issue is that running the code sets the password correctly but not when it is run in my particular case which is TFSDeployer calling PowerShell calling PSExec calling PowerShell. Something gets lost here. I have moved on to a different role at a different company and am unlikely to ever return to this problem and figure out what caused it though, so I hope it provides someone some use somewhere down the line. – paulyphonic Nov 01 '14 at 04:26
  • 4
    Using this answer without `Import-Module WebAdministration` will result in an `Set-ItemProperty : Cannot find drive. A drive with the name 'IIS' does not exist.` error. as per http://stackoverflow.com/questions/24392696/getting-cant-find-the-drive-the-drive-called-iis-does-not-exist – Loftx Aug 05 '15 at 11:39
  • Thanks. This was not the issue I experienced. For me this was an issue that was most likely caused by combining the proposed solution with the use of PSExec and TFSDeployer, so the PowerShell was being run remotely by a third party, which caused something to get lost in translation and resulted in a null parameter. When I ran the same script directly it worked as expected. The purpose of the tool was to build a Web application in Visual Studio, and then use TFSDeployer to deploy the build to a specific environment, remotely configuring IIS based on properties for that environment. – paulyphonic Aug 07 '15 at 17:52
  • 2
    Note that this doesn't encrypt the password like going through the UI does. (I'm not sure that makes it more secure, but I'm not sure I'm comfortable with the plain text password sitting there, either.) – jpmc26 Mar 09 '17 at 21:16
  • This answer helped solve the problem I was having. I was using three separate Set-ItemProperty calls (as described by @vishnu's answer) to try and assign a custom identity to an application pool -- for whatever reason, using the three-in-one `-Value` syntax got it to work. – Mass Dot Net Dec 24 '19 at 17:57
  • `identitytype=3` means 'SpecificUser'. – Aage Jun 15 '21 at 09:12
  • @jpmc26 when you say "this doesn't encrypt the password..." to which location is the plaintext password being written ? 1. it's plaintext in memory for the duration of the script execution, 2. it's plaintext in network traffic between the host executing the script and the IIS server, 3. it's written as plaintext to the configuration files on the IIS server ? – Walter Stabosz May 24 '22 at 16:18
10

After few experiments

Here is my Answer, I hope this will helps , I've worked on IIS 8.5

$credentials = (Get-Credential -Message "Please enter the Login credentials including Domain Name").GetNetworkCredential()

$userName = $credentials.Domain + '\' + $credentials.UserName

Set-ItemProperty IIS:\AppPools\$app_pool_name -name processModel.identityType -Value SpecificUser 

Set-ItemProperty IIS:\AppPools\$app_pool_name -name processModel.userName -Value $username

Set-ItemProperty IIS:\AppPools\$app_pool_name -name processModel.password -Value $credentials.Password
LW001
  • 2,452
  • 6
  • 27
  • 36
vishnu
  • 149
  • 1
  • 4
  • Application pools modified in this way fail the next time they're used and their dependent web applications stop. Haven't been able to make this work. – DWRoelands Feb 12 '20 at 22:25
4

seems you can do this a little more directly now

appcmd set apppool junkapp /processmodel.password:junkpassword
mtneagle
  • 136
  • 3
0

I'm on powershell v4 which doesn't have 'ConvertFrom-SecureString', in the end I got the following to work for me:

Import-Module WebAdministration

$cred = Get-Credential -Message "Please enter username and new password to reset IIS app pool password (for app pools running as username)"

$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($cred.Password)
$plaintext = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)

$applicationPools = Get-ChildItem IIS:\AppPools | where { $_.processModel.userName -eq 
$cred.UserName }

foreach($pool in $applicationPools)
{
    $apppool = "IIS:\AppPools\" + $pool.Name

    Set-ItemProperty $apppool -name processModel.password -Value $plaintext
}

Write-Host "Application pool passwords updated..." -ForegroundColor Magenta 
Write-Host "" 
Read-Host -Prompt "Press Enter to exit"
John Warlow
  • 2,922
  • 1
  • 34
  • 49