遇到接手現有網站主機、網站搬家規劃等需求,我想要有個工具可以盤點 IIS 上設了哪些網站應用程式、對映哪些 AppPool、Runtime 是 .NET 2.0 還是 4.0、哪些目錄特別設了匿名或 Winodws 整合驗證、鎖哪些來源 IP... 等種種細節。

自己許願自己實現,決定寫個 PowerShell 簡單搞定。研究了一下,各種設定的查詢指令要蒐羅完整有點煩人,而 IIS 相關設定其實都集中在 ApplicationHost.config,不如讀取檔案解析 XML,一次拿到所有設定。

確定方向,剩下來就是找到設定所在路徑,寫 PowerShell 程式把它們讀出來,沒太多技術含量,純回顧 .NET 2.0 時代的 XML 手工活兒。

依各環境應用,要讀取的設定重點不同,這裡先抓我常用到的,未來若發現有缺,要補上也不難。

$ErrorActionPreference = "Stop"
[xml]$xml = Get-Content (Join-Path $Env:SystemRoot\System32\inetsrv\config "applicationHost.config")

Write-Output "** App Pool List **"

$appPools = $xml.SelectSingleNode("//applicationPools").SelectNodes('add') 
$appPools | ForEach-Object {
    $procModel = $_.SelectSingleNode("processModel")
    $idleTimeout = ''
    if ($procModel -ne $null) {
        $idleTimeout = $procModel.Attributes["idleTimeout"].Value
    }
    $runtime = $_.Attributes["managedRuntimeVersion"].Value 
    if ([string]::IsNullOrEmpty($runtime)) { $runtime = 'v4.0' }    
    return [PSCustomObject]@{
        Name        = $_.Attributes["name"].Value
        Runtime     = $runtime
        Pipeline    = $_.Attributes["managedPipelineMode"].Value
        Enable32Bit = $_.Attributes["enable32BitAppOnWin64"].Value
        StartMode   = $_.Attributes["startMode"].Value
        IdleTimeout = $idleTimeout
    }
} | Format-Table -AutoSize

Write-Output "** Web Application List **"

$sites = $xml.SelectSingleNode("//sites").SelectNodes('site')
$sites | ForEach-Object {
    $siteName = $_.Attributes["name"].Value
    $binings = ($_.SelectNodes('bindings').SelectNodes('binding') | ForEach-Object {
            $binding = $_.Attributes["protocol"].Value + "://" + $_.Attributes["bindingInformation"].Value
            if ($binding.StartsWith('http')) {
                $binding = $binding.TrimEnd(':')
            }
            return $binding
        }) -join ", "
    $apps = $_.SelectNodes('application')
    $apps | ForEach-Object {
        $app = $_
        $appName = $app.Attributes["path"].Value
        $appPoolName = $app.Attributes["applicationPool"].Value
        $vdirs = $app.SelectNodes('virtualDirectory')
        $vdirs | ForEach-Object {
            $phPath = $_.Attributes["physicalPath"].Value 
            $vdirPath = $_.Attributes["path"].Value
            if ($vdirPath -eq "/") {
                return [PSCustomObject]@{
                    SiteName = $siteName
                    AppName  = $appName
                    AppPool  = $appPoolName
                    Path     = $phPath
                    Bindings = $binings
                }
            }
            else {
                return [PSCustomObject]@{
                    SiteName = $siteName
                    AppName  = "$appName<$vdirPath>"
                    AppPool  = ''
                    Path     = $phPath
                    Bindings = $binings
                }
            }
        }
    } 
} | Format-Table -AutoSize

function TryReadAttribute($node, $path, $attrName) {
    $target = $node.SelectSingleNode($path)
    if ($null -ne $target) {
        return $target.Attributes[$attrName].Value
    }
    return ''
}

Write-Output "** Authentication and IP Restriction List **"

$xml.SelectNodes('//location') | ForEach-Object {

    $path = $_.Attributes["path"].Value
    $sysWebSvr = $_.SelectSingleNode('system.webServer');
    $anonymous = ''
    $winAuth = ''
    $ipAddrs = ''
    if ($sysWebSvr -ne $null) {
        $winAuth = TryReadAttribute $sysWebSvr 'security/authentication/windowsAuthentication' 'enabled'
        $anonymous = TryReadAttribute $sysWebSvr 'security/authentication/anonymousAuthentication' 'enabled'
        $ipSec = $sysWebSvr.SelectSingleNode('security/ipSecurity')
        if ($ipSec -ne $null -and $ipSec.Attributes["allowUnlisted"].Value -eq "false") {
            $ipAddrs = ($ipSec.SelectNodes('add') | ForEach-Object {
                return $_.Attributes["ipAddress"].Value
            }) -join ", "
        }
    }   
    return [PSCustomObject]@{
        Path = $path
        WindowsAuth = $winAuth
        AnonymousAuth = $anonymous
        IPAddresses = $ipAddrs
    }
} | Format-Table -AutoSize

程式是直接讀取 C:\Windows\System32\intesrv\config\applicationHost.config 並解析,實務上也可將檔案蒐集備份在其他主機處理,其餘就是什麼設定要找什麼 XPATH 路徑取得 Attribute。

以下是結果範例,展示一次列出整台 IIS 下的多個 Site 及 Web Application,包含 Runtime 版本、32Bit 啟用、有無 AlwaysRunning 及 IdleTimeout、網站目錄、虛擬目錄、繫結 Port/Host、匿名/Windows驗證、限制IP清單... 等資訊。

** App Pool List **

Name                 Runtime Pipeline Enable32Bit StartMode     IdleTimeout
----                 ------- -------- ----------- ---------     -----------
DefaultAppPool       v4.0
.NET v4.5 Classic    v4.0    Classic
.NET v4.5            v4.0
Classic .NET AppPool v2.0    Classic
.NET v2.0 Classic    v2.0    Classic
.NET v2.0            v2.0             true
Portal               v4.0                         AlwaysRunning 00:00:00


** Web Application List **

SiteName         AppName          AppPool   Path            Bindings                               
--------         -------          -------   ----            --------                               
Default Web Site /                .NET v2.0 C:\WWW\Root     http://*:80                            
Default Web Site /AspNet35        .NET v2.0 C:\WWW\AspNet35 http://*:80                            
Default Web Site /AspNet35</VDir>           C:\WWW\VDir     http://*:80                            
Default Web Site /AspNet45        .NET v4.5 C:\WWW\AspNet45 http://*:80                            
Portal           /                Portal    C:\WWW\Portal   https://10.4.0.4:443:addc.dot-net.cloud


** Authentication and IP Restriction List **

Path                           WindowsAuth AnonymousAuth IPAddresses       
----                           ----------- ------------- -----------       
                                                                           
Default Web Site               true        false                           
Default Web Site/AspNet35      true        false                           
Default Web Site/AspNet35/VDir             true          10.4.0.4, 10.4.0.6

收入常用工具箱。

A simple PowerShell script to parse applicationHost.config and dump required IIS application settings.


Comments

# by Wilson Shen

慼謝黑暗大!

# by T小米

感謝黑暗大! IIS站台盤點器. Go

Post a comment