Turns out an unprivileged user can be given permissions to configure IIS and IIS web sites.

Note that absolutely none of this is authoritative or directly based on relevant documentation. It’s mostly what I found and figured out and guessed and (in some cases) made up. Some of it may be wrong or dangerous or lead to disaster or confusion. I am not taking responsibility here for anything, not even minor crimes or good taste. Read and act on it at your own peril!

Create a Just-Enough-Admin configuration named IIS.

PS C:\Program Files\WindowsPowerShell\Modules\JEA> New-PSSessionConfigurationFile IIS.pssc

And create a group JEA_IIS.

PS C:\Program Files\WindowsPowerShell\Modules\JEA> New-LocalGroup JEA_IIS

Make three changes to the IIS.pssc file created:

  1. Set SessionType to ‘RestrictedRemoteServer’.
# Session type defaults to apply for this session configuration. Can be 'RestrictedRemoteServer' (recommended), 'Empty', or 'Default'
SessionType = 'RestrictedRemoteServer'
  1. Set RunAsVirtualAccount to $true.
# Whether to run this session configuration as the machine's (virtual) administrator account
RunAsVirtualAccount = $true
  1. Configure RoleDefinitions to use IIS.psrc.
RoleDefinitions = @{'JEA_IIS' = @{RoleCapabilities='IIS'}} 

Then create a role capability file for this thing.

PS C:\Program Files\WindowsPowerShell\Modules\JEA\RoleCapabilities> New-PSRoleCapabilityFile IIS.psrc

Add the following entries to the file, at the appropriate places per the hints given in the template file.

ModulesToImport = 'IISAdministration','WebAdministration'
VisibleCmdlets = '*-IIS*','*-Web*'
VisibleExternalCommands = 'C:\Windows\System32\iisreset.exe'
VisibleProviders = 'Variable'

While you can add iisreset.exe as a visible external command, I would recommend against doing the same for appcmd.exe, a much more general tool to control IIS that can output passwords as well as configure application pools to use the LocalSystem account.

Register the hell out of this JEA:

PS C:\Program Files\WindowsPowerShell\Modules\JEA> Register-PSSessionConfiguration IIS -Path .\IIS.pssc

Now add a user to the JEA_IIS group and let him enjoy his powers.

PS C:\> Add-LocalGroupMember -Group JEA_IIS -Member benoit
PS C:\> Get-LocalGroupMember JEA_IIS

ObjectClass Name              PrincipalSource
----------- ----              ---------------
User        CHAMPIGNAC\benoit Local


PS C:\>

Benoit:

PS C:\> Get-ChildItem 'C:\Program Files\WindowsPowerShell\Modules\JEA\' -Filter *.pssc|ForEach-Object{Import-PSSession (New-PSSession -ConfigurationName $_.BaseName) -AllowClobber}

This will load and include all JEA configurations and give an error for each for which user benoit is not permissioned.

User benoit can now create web sites and, luckily, all application pools created automatically will run as AppPoolIdentity and not LocalSystem, allowing us to grant users full access to the cmdlets.

PS C:\BriseferSite> New-Website -Name Brisefer -PhysicalPath C:\BriseferSite\

Name             ID   State      Physical Path                  Bindings
----             --   -----      -------------                  --------
Brisefer         1               C:\BriseferSite\


PS C:\BriseferSite> New-WebAppPool -Name BriseferPool

Name                     State        Applications
----                     -----        ------------
BriseferPool

PS C:\>

Assume that C:\BriseferSite is a folder to which user benoit has access.

Note that running iisreset.exe in that session is a bit more complicated as it does not clobber the real (non-virtualised) iisreset.exe. Hence benoit has explicitly to call iisreset.exe from the JEA session:

PS C:\> Invoke-Command (Get-PSSession|Where-Object{$_.ConfigurationName -eq "IIS"}) {iisreset}
Attempting stop...

Internet services successfully stopped

Attempting start...

Internet services successfully restarted

PS C:\>

It is advisable for the system administrator to give the group JEA_IIS (or other groups or even users) access to the sites in IIS Manager to allow access via IIS Manager.

image

For completeness’ sake you can also add the JEA group to the ACL of the web server service.

PS C:\> Get-Service *w3*

Status   Name               DisplayName
------   ----               -----------
Stopped  W32Time            Windows Time
Stopped  w3logsvc           W3C Logging Service
Running  W3SVC              World Wide Web Publishing Service

PS C:\> sc.exe sdshow W3SVC

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
PS C:\> Get-LocalGroup JEA_IIS|Format-List

Description     :
Name            : JEA_IIS
SID             : S-1-5-21-344341352-2539047333-2300305637-1003
PrincipalSource : Local
ObjectClass     : Group

PS C:\> sc.exe sdset W3SVC "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-344341352-2539047333-2300305637-1003)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"
[SC] SetServiceObjectSecurity SUCCESS
PS C:\> sc.exe sdshow W3SVC

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-344341352-2539047333-2300305637-1003)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
PS C:\>

IIS.pssc
IIS.psrc

Next: File shares JEA