Powershell 使用$site | Set项不会将更改保存回IIS站点

Powershell 使用$site | Set项不会将更改保存回IIS站点,powershell,iis-7,powershell-2.0,Powershell,Iis 7,Powershell 2.0,我正在编写一些自动化脚本,以便使用PowerShell在服务器上创建/更新IIS站点 其目的是拥有一个配置对象,然后可以通过单个脚本处理该对象来完成所有繁重的工作 我的configHashTable如下所示: $config = @{ AppPools = ( @{ Name="AppPool1" Properties = @{ Enable32BitAppOnWin64=

我正在编写一些自动化脚本,以便使用PowerShell在服务器上创建/更新IIS站点

其目的是拥有一个配置对象,然后可以通过单个脚本处理该对象来完成所有繁重的工作

我的config
HashTable
如下所示:

$config = @{
    AppPools = (
        @{
            Name="AppPool1"
            Properties = @{
                Enable32BitAppOnWin64=$true
                ManagedRuntimeVersion="v4.0"
                ProcessModel = @{
                    IdentityType = "NetworkService"
                }
            }
        }
    )
    Websites = (
        @{
            Name="Site1"
            Properties = @{
                PhysicalPath = "C:\sites\site1"
                ApplicationPool = "AppPool1"
            }
        }
    )    
}
然后,我的脚本使用配置来处理每个应用程序池和网站:

 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 properties fromHash
的函数。这基本上将哈希表展平为属性路径:

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"))            
        }
    }
}
else
子句中创建的
scriptblock
将导致执行
$on.ProcessModel.IdentityType=$properties.IdentityType
(每个循环中的properties对象是最后找到的哈希表值,因此它不会指定正确的值)

问题 还在这儿吗?谢谢

上述所有功能对于应用程序池的效果与预期一样,但对于网站则完全失败为什么这只适用于网站?

我知道我可以使用
Set ItemProperty
,但这里的目标是允许config对象驱动正在设置的属性

下面详细介绍了一个更简单的示例:

# 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"
调用
设置项
,然后再次检索项后,
$ap
具有更新值,但
$site
不包含更新值

我正在使用PowerShell v2和IIS7

部分分辨率。。。更多的是一种工作方式 我已将
设置属性fromHash
更改为如下工作方式:

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
失败?

这似乎有效

(gi IIS:\sites\site1).physicalpath
(gi IIS:\sites\site1).physicalpath = "C:\sites\anothersite"
(gi IIS:\sites\site1).physicalpath

您是否尝试过
Set ItemProperty
,而不是
Set Item
?我知道这不能解释不一致性,但它可能有助于解除阻止。谢谢,是的,我现在已经用
Set ItemProperty
实现了它。我承认我假设这不允许我对属性使用点符号,但我会研究它。我假设它与底层提供者有关,并希望在v3中进行测试,看看事情是否发生了变化,Hanks@latkin让我再次审视这个问题(为什么我在不知道之前没有尝试点符号…)。我已经更新了我的工作细节,但最初的问题仍然存在