PowerShellでIISのWebサイトの有効化されたプリロード(preloadEnabled)の値を取得する

# はじめに
以前、「[【ASP.NET】IIS Application Initializationによる初回アクセスの高速化](https://qiita.com/yaju/items/29e1e51f4a4811a50d56)」の記事を書きました。
その際にIISの対象のWebサイトの詳細設定ダイアログを[有効化されたプリロード]を[True]に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/90dc59e6-be7e-4bd7-9d74-0050490586f4.png)

導入設定した際にIIS設定が正しく行われたのかチェックするプログラムを組んでいたのですが、「有効化されたプリロード」の値がどうにも取得することが出来ない、ネットで調べてもプリロードを設定する方法は見つかるのに取得方法が見つからない。
休日になったので自宅で調べてみました。

# 調査
Get-Itemでは、有効化されたプリロード（preloadEnabled）が見当たりません。

```Powershell
PS>Get-Item IIS:\Sites\test
Name             ID   State      Physical Path                  Bindings
----             --   -----      -------------                  --------
test             2    Stopped    C:\Inetpub\wwwroot\Test        http *:80:
```

ネットで調べると、値をセットする方法が見つかります。だったら値をセット出来るなら取得も出来るのではないかと考えますよね。
[IIS7.5 PowerShell preloadEnabled - stackoverflow](https://stackoverflow.com/questions/10721484/iis7-5-powershell-preloadenabled)

```
PS>import-module webadministration
PS>set-itemproperty IIS:\Sites\SiteName -name applicationDefaults.preloadEnabled -value True
```

確かに値は取得出来たのですが、結果は`False`ですから違います。`applicationDefaults`となっているので、継承元の値を取得しているようである。

```
PS>import-module webadministration
PS>get-itemproperty IIS:\Sites\test -name applicationDefaults.preloadEnabled | Select Value
Value
-----
False
```

別の回答を試してみました。これも設定なので、取得する方法に変更します。
"YOUR_SITE_NAME"は、対象サイト名に変更する。

```
PS>[System.Reflection.Assembly]::LoadFrom("C:\windows\system32\inetsrv\Microsoft.Web.Administration.dll")
PS>$serverManager = (New-Object Microsoft.Web.Administration.ServerManager)
PS>$serverManager.Sites["YOUR_SITE_NAME"].Applications["/"].SetAttributeValue("preloadEnabled", $true)
PS>$serverManager.CommitChanges()
```

この方法なら値を取得することが出来ました。また上記方法で対象サイトの有効化されたプリロード（preloadEnabled）の設定も出来ます。

```
PS>[System.Reflection.Assembly]::LoadFrom("C:\windows\system32\inetsrv\Microsoft.Web.Administration.dll")
PS>$serverManager = (New-Object Microsoft.Web.Administration.ServerManager)
PS>$serverManager.Sites["test"].Applications["/"].GetAttributeValue("preloadEnabled")
True
```

さて、上記方法を見つける前に値を取得することが出来た方法がありました。
IISの設定は、「applicationHost.config」ファイルに出力されます。XML形式なのでGet-Contentを使用すれば辿って取得ができます。
この方法だと管理者モードのPowershellにしなくても取得が出来ます。

```
PS>$xml = [XML](Get-Content C:\Windows\System32\inetsrv\config\applicationHost.config) 
PS>$xml.SelectNodes("//sites/site[`test`]/application").preloadEnabled
true
```

# 調査見直し
会社で意気揚々と試したら取得できなかった(^-^;
対象のWebサイトは、Default Web Siteの配下のアプリケーション「test」であったため。

よって、アプリケーション「test」まで対象にすれば取得できました。

```
PS>[System.Reflection.Assembly]::LoadFrom("C:\windows\system32\inetsrv\Microsoft.Web.Administration.dll")
PS>$serverManager = (New-Object Microsoft.Web.Administration.ServerManager)
PS>$serverManager.Sites["Default Web Site"].Applications["/test"].GetAttributeValue("preloadEnabled")
True
```

Get-Contentでも、アプリケーション「test」まで対象にすれば取得できました。

```
PS>$xml = [XML](Get-Content C:\Windows\System32\inetsrv\config\applicationHost.config) 
PS>$xml.SelectNodes($xml.SelectNodes("//sites/site['Default Web Site']/application[@path='/test']").preloadEnabled
true
```

Get-WebConfigurationでも取得することができました。

```
PS>Get-WebConfiguration "//sites/site['Default Web Site']/application[@path='/test']" | foreach { $_.attributes | select name, value }

Name                     Value
----                     -----
path                     /test
applicationPool          DefaultAppPool
enabledProtocols         http
serviceAutoStartEnabled  False
serviceAutoStartProvider
preloadEnabled           True
```

preloadEnabledだけを対象とする。

```
PS>(Get-WebConfiguration "//sites/site['Default Web Site']/application[@path='/test']").GetAttributeValue("preloadEnabled")
True
```

# 最後に
設定画面に「有効化されたプリロード」あるんだから、Get-Itemで最初から取得できるようになっていれば、苦労しなくても済んだんだけどね。

PowerShellをまだ使いこなせていないな。