IIS マネージャーのアクセス許可を Active Directory のグループで制御する

### 概要

IIS による web サイトへのアクセス許可ではなく、IIS マネージャーの操作へのアクセス許可設定を Active Directory のグループで実施します。

Active Directory ユーザはデフォルトで IIS マネージャーの起動はできますが、設定をするためには administrator のパスワーを入力しなければなりませんので、これを一般ユーザでもできるようにします。

今回は WEB サーバへリモートデスクトップ接続が可能なユーザを IIS マネージャーを操作できるようにします。
この時、ユーザでの管理はしんどいので、グループで管理できるようにします。  

### 環境

|役割|OS|
|:----|:---|
|ドメインコントローラ(ADDS)|Windows Server 2012 R2|
|WEBサーバ(IIS)|Windows Server 2012 R2|

なお、AWS VPCで構築したドメインネットワークです。

### 前提

* WEBサーバはドメインに参加済み
* ローカルの Remote Desktop Users グループにドメイン内のグループ(SecurityGroup)が追加済み

```
net localgroup "Remote Desktop Users" example.local\SecurityGroup /add
```

* example.local\SecurityGroup のユーザがWEBサーバにRDPログオンできること

### 注意事項

* サーバレベルでのアクセス許可は一般ユーザに付与できず、administrator のみが接続できる
* 一般ユーザは各サーバのサイトごとにしかアクセスできない
* 一般ユーザの IIS マネージャーでの操作は administrator 権限より限定的になる
    * ex) IISマネージャーのアクセス許可は設定できない

### GUIでやる

1. administrator 権限でIISマネージャを開く
1. サイトレベルのIISマネージャーのアクセス許可を開く
1. ユーザの許可をクリック
1. ユーザーの種類を windows にチェックを入れ、Remote Desktop Users と入力する

### コマンドラインでやる

Remote Desktop Users グループメンバーが IIS マネージャーの全てのサイトに接続できるようにするスクリプトを書いてみました。

```ps1
[xml]$sites = C:\Windows\System32\inetsrv\appcmd.exe list config -section:sites
$siteNames = $sites.'system.applicationHost'.sites.site | foreach-object { 
    $site = [System.String]$_.name
    $file = "C:\Windows\System32\inetsrv\config\administration.config"
    $config = [xml](Get-Content -Path $file)

    $authorizationRules = $config.configuration.'system.webServer'.management.authorization.authorizationRules.scope
    $RuleEntry = ($authorizationRules | Where-Object {$_.path -eq "/$site"}).path.count
    
    if ( $RuleEntry -eq "0" )
    {
        [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Management") | Out-Null
        [Microsoft.Web.Management.Server.ManagementAuthorization]::Grant("Remote Desktop Users","$site", 1)
    }
}
```

すると、`C:¥Windows¥System32¥inetsrv¥config¥administration.config` にエントリが追加されます。

```xml
<configuration>
    <system.webServer>
        <management>
            <authorization defaultProvider="ConfigurationAuthorizationProvider">
                <authorizationRules>
                    <scope path="/サイト名">
                        <add name="BUILTIN\Remote Desktop Users" isRole="true" />
                    </scope>
                </authorizationRules>
            </authorization>
        </management>
    </system.webServer>
</configuration>
```

[Adding IIS Manager Users and Permissions using Powershell](http://blogs.msdn.com/b/carlosag/archive/2009/10/23/adding-iis-manager-users-and-permissions-through-powershell.aspx)

### バグ

このコマンドを chef の `powershell_script` で実行したところ、例外で落ちることがあります。

```
問題の署名:
  問題イベント名:	PowerShell
  NameOfExe:	powershell.exe
  FileVersionOfSystemManagementAutomation:	6.3.9600.17400
  InnermostExceptionType:	Runtime.InteropServices.InvalidComObject
  OutermostExceptionType:	Runtime.InteropServices.InvalidComObject
  DeepestPowerShellFrame:	unknown
  DeepestFrame:	System.StubHelpers.StubHelpers.GetCOMIPFromRCW
  ThreadName:	unknown
  OS バージョン:	6.3.9600.2.0.0.272.7
  ロケール ID:	1041

オンラインのプライバシーに関する声明をお読みください:
  http://go.microsoft.com/fwlink/?linkid=280262

オンラインのプライバシーに関する声明が利用できない場合は、プライバシーに関する声明をオフラインでお読みください:
  C:\Windows\system32\ja-JP\erofflps.txt
```

ぐぐるとバグとして報告されている模様。

http://serverfault.com/questions/587305/powershell-has-stopped-working-on-ps-exit-after-creating-iis-user

### 関連

[administrator 以外のユーザから Web Deploy 3.5 でデプロイする](http://rriifftt.hatenablog.com/entry/2015/07/09/163955)