When configuring permissions for IIS application pools, many administrators encounter issues with the special IIS APPPOOL\
account prefix. Unlike domain accounts, these local virtual accounts require specific handling in PowerShell ACL operations.
The error you're seeing occurs because IIS APPPOOL
isn't a traditional domain or local machine reference. The correct approach is to use the local computer name (or just the account name with the IIS APPPOOL\
prefix) when constructing the NTAccount object.
Here's the corrected function that properly handles IIS application pool identities:
function Set-IISAppPoolPermission {
param (
[Parameter(Mandatory=$true)]
[string]$Directory,
[Parameter(Mandatory=$true)]
[string]$AppPoolName,
[string]$Permission = "Modify"
)
$inherit = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$propagation = [System.Security.AccessControl.PropagationFlags]"None"
$acl = Get-Acl -Path $Directory
# Correct way to reference IIS AppPool accounts
$account = New-Object System.Security.Principal.NTAccount("IIS APPPOOL\$AppPoolName")
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
$account,
$Permission,
$inherit,
$propagation,
"Allow"
)
$acl.AddAccessRule($accessRule)
Set-Acl -Path $Directory -AclObject $acl
}
# Example usage:
Set-IISAppPoolPermission -Directory "C:\Websites\MySite" -AppPoolName "MyAppPool"
After running the script, you can verify the permissions were applied correctly with:
Get-Acl "C:\Websites\MySite" | Format-List
- For IIS 10.0 or later, application pools run as virtual accounts by default
- The account must include the full
IIS APPPOOL\
prefix - If running remotely, you may need to use the computer name (e.g.,
SERVER01\IIS APPPOOL\MyAppPool
) - Always test with the least privileged permissions first
For those who prefer command-line tools, icacls
provides another option:
icacls "C:\Websites\MySite" /grant "IIS APPPOOL\MyAppPool:(OI)(CI)M"
This grants Modify (M) permissions with Object Inherit (OI) and Container Inherit (CI) flags.
When implementing this in production:
- Consider using a dedicated application pool identity
- Restrict permissions to only necessary directories
- Document all permission changes
- Include these commands in your deployment scripts
When automating permissions for IIS websites, many administrators encounter the same frustrating error:
Set-Acl : The trust relationship between this workstation and the primary domain failed
This occurs because IIS application pool identities aren't traditional domain accounts. They're virtual accounts with a special naming convention that Windows manages differently.
IIS application pool identities follow this pattern:
IIS APPPOOL\AppPoolName
The key insight: IIS APPPOOL
isn't a domain but rather a special virtual account namespace. PowerShell's security provider needs to handle these differently than regular domain accounts.
Here's the proper way to modify your function:
function Set-AppPoolPermission {
param(
[Parameter(Mandatory=$true)]
[string]$Directory,
[Parameter(Mandatory=$true)]
[string]$AppPoolName
)
$inherit = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$propagation = [System.Security.AccessControl.PropagationFlags]"None"
$acl = Get-Acl $Directory
# The critical change is using the full account name format
$accountName = "IIS APPPOOL\$AppPoolName"
$user = New-Object System.Security.Principal.NTAccount($accountName)
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
$user,
"Modify",
$inherit,
$propagation,
"Allow"
)
$acl.AddAccessRule($accessRule)
Set-Acl -Path $Directory -AclObject $acl
}
Grant modify permissions to DefaultAppPool:
Set-AppPoolPermission -Directory "C:\WebSites\MySite" -AppPoolName "DefaultAppPool"
For multiple directories:
$directories = @("C:\WebSites\Site1", "C:\WebSites\Site2", "D:\WebApps\Store")
foreach ($dir in $directories) {
Set-AppPoolPermission -Directory $dir -AppPoolName "ECommerceAppPool"
}
For environments with strict security requirements, you might need to:
1. First verify the application pool exists
2. Handle potential permission inheritance issues
3. Add logging for audit trails
Here's an enhanced version with error handling:
function Set-AppPoolPermissionAdvanced {
param(
[Parameter(Mandatory=$true)]
[string]$Directory,
[Parameter(Mandatory=$true)]
[string]$AppPoolName,
[Parameter(Mandatory=$false)]
[string]$LogPath = "C:\Logs\PermissionChanges.log"
)
try {
if (-not (Test-Path $Directory)) {
throw "Directory $Directory does not exist"
}
$acl = Get-Acl $Directory
$accountName = "IIS APPPOOL\$AppPoolName"
$user = New-Object System.Security.Principal.NTAccount($accountName)
$sid = $user.Translate([System.Security.Principal.SecurityIdentifier])
$inherit = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$propagation = [System.Security.AccessControl.PropagationFlags]"None"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
$user,
"Modify",
$inherit,
$propagation,
"Allow"
)
$acl.AddAccessRule($accessRule)
Set-Acl -Path $Directory -AclObject $acl
"$(Get-Date) - Successfully granted modify permissions to $accountName on $Directory" | Out-File $LogPath -Append
}
catch {
"$(Get-Date) - ERROR: $_" | Out-File $LogPath -Append
throw
}
}