8

PowerShell を使用してサーバー上で IIS サイトを作成/更新するための自動化されたスクリプトを作成中です。

目的は、構成オブジェクトを 1 つのスクリプトで処理してすべての面倒な作業を実行できるようにすることです。

私の設定HashTableは次のようになります:

$config = @{
    AppPools = (
        @{
            Name="AppPool1"
            Properties = @{
                Enable32BitAppOnWin64=$true
                ManagedRuntimeVersion="v4.0"
                ProcessModel = @{
                    IdentityType = "NetworkService"
                }
            }
        }
    )
    Websites = (
        @{
            Name="Site1"
            Properties = @{
                PhysicalPath = "C:\sites\site1"
                ApplicationPool = "AppPool1"
            }
        }
    )    
}

次に、スクリプトは構成を使用して、各アプリケーション プールと Web サイトを処理します。

 Import-Module WebAdministration

 $config.AppPools | 
    % {
        $poolPath = "IIS:\AppPools\$($_.Name)"
        
        # Create if not exists
        if(-not(Test-Path $poolPath)){ New-WebAppPool $_.Name }            
        
        # Update the properties from the config
        $pool = Get-Item $poolPath
        Set-PropertiesFromHash $pool $_.Properties
        $pool | Set-Item            
    }
        
 $config.Websites | 
    %{        
        $sitePath = "IIS:\Sites\$($_.Name)"
            
        # Create if not exists
        if(-not(Test-Path $sitePath)){ New-WebSite $_.Name -HostHeader $_.Name }
            
        # Update the properties from the config
        $site = Get-Item $sitePath
        Set-PropertiesFromHash $site $_.Properties
        $site | Set-Item 
    }      

ご覧のとおり、プロセスは実質的に同じです (アイテムのパスと作成されるタイプを除いて)。これはもちろん、機能するようになればリファクタリングされます!

という関数を書きましたSet-PropertiesFromHash。これは基本的に、ハッシュ テーブルをプロパティ パスにフラット化します。

Function Set-PropertiesFromHash{
    Param(
        [Parameter(Mandatory=$true, HelpMessage="The object to set properties on")]        
        $on,
        [Parameter(Mandatory=$true, HelpMessage="The HashTable of properties")]
        [HashTable]$properties,
        [Parameter(HelpMessage="The property path built up")]
        $path
    )
    foreach($key in $properties.Keys){
        if($properties.$key -is [HashTable]){
            Set-PropertiesFromHash $on $properties.$key ($path,$key -join '.')
        } else {            
            & ([scriptblock]::Create( "`$on$path.$key = `$properties.$key"))            
        }
    }
}

句で作成さscriptblockれた結果は実行されます(各ループのプロパティオブジェクトは最後に見つかった HashTable 値であるため、これにより正しい値が割り当てられます)else$on.ProcessModel.IdentityType = $properties.IdentityType

質問

まだここ?ありがとう!

上記のすべては、アプリケーション プールでは期待どおりに機能しますが、Web サイトでは完全に失敗しますこれが Web サイトでのみ失敗するのはなぜですか?

使用できることはわかっていますSet-ItemPropertyが、ここでの目的は、構成オブジェクトが設定されているプロパティを駆動できるようにすることです。

以下に、より簡単な例を示します。

# Setting an app pool property this way works as expected
$ap = gi IIS:\apppools\apppool1
$ap.enable32BitAppOnWin64 # returns False
$ap.enable32BitAppOnWin64 = $true
$ap | Set-Item
$ap = gi IIS:\apppools\apppool1
$ap.enable32BitAppOnWin64 # returns True

# Setting a website property this way fails silently
$site = gi IIS:\sites\site1
$site.physicalpath # returns "C:\sites\site1"
$site.physicalpath = "C:\sites\anothersite"
$site | Set-Item
$site = gi IIS:\sites\site1
$site.physicalpath # returns "C:\sites\site1"

AfterSet-Itemが呼び出された後、アイテムが再度取得され$ap、更新された値が$site含まれていますが、更新された値は含まれていません。

PowerShell v2 と IIS7 を使用しています

部分的な解決 ... 回避策の詳細

私は次のように動作するように変更Set-PropertiesFromHashしました:

Function Set-PropertiesFromHash{
    Param(
        [Parameter(Mandatory=$true, HelpMessage="The object to set properties on")]        
        $on,
        [Parameter(Mandatory=$true, HelpMessage="The HashTable of properties")]
        [HashTable]$properties,
        [Parameter(HelpMessage="The property path built up")]
        $pathParts = @()
    )
    foreach($key in $properties.Keys){        
        if($properties.$key -is [HashTable]){
            Set-PropertiesFromHash $on $properties.$key ($pathParts + $key)
        } else {                  
            $path = ($pathParts + $key) -join "."
            Set-ItemProperty $on $path $properties.$key
        }
    }
}

それが今のところ続けることを可能にしました。しかし、私の最初の質問はまだ残っています。

$site | Set-Itemがサイトで失敗するのはなぜですか?

4

1 に答える 1

1

これはうまくいくようです

(gi IIS:\sites\site1).physicalpath
(gi IIS:\sites\site1).physicalpath = "C:\sites\anothersite"
(gi IIS:\sites\site1).physicalpath
于 2012-11-05T16:09:00.207 に答える