How to specify application pool identity user and password from PowerShell
Asked Answered
J

4

45

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?

Jersey answered 28/1, 2014 at 19:44 Comment(9)
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"Willwilla
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.Jersey
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.Jersey
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)?Willwilla
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.Jersey
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.Jersey
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. :(Jersey
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?Perishing
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.Bony
O
79

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

Ohalloran answered 15/10, 2014 at 20:52 Comment(7)
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.Jersey
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 #24393196Riggall
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.Jersey
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.)Proportional
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.Darnley
identitytype=3 means 'SpecificUser'.Newspaperman
@Proportional 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 ?Attest
C
11

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
Coagulate answered 30/1, 2018 at 15:19 Comment(1)
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.Nictitate
G
4

seems you can do this a little more directly now

appcmd set apppool junkapp /processmodel.password:junkpassword
Green answered 11/9, 2020 at 22:14 Comment(0)
B
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"
Baluchistan answered 9/3, 2020 at 10:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.