我正在編寫一些自動化腳本以使用PowerShell在服務器上創建/更新IIS站點。
目的是讓配置對象可以通過單個腳本進行處理,完成所有繁重工作。
我的配置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-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"))
}
}
}
的else
子句將導致$on.ProcessModel.IdentityType = $properties.IdentityType
執行(屬性在每個循環中的對象創建的scriptblock
是最後發現的HashTable值,因此這並分配正確的值)
問題
還在嗎?謝謝!
以上所有工作與應用程序池的預期一致,但完全無法針對網站。 爲什麼這隻會失敗的網站?
我知道我可以使用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"
Set-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
網站失敗?
代替'設置Item',你嘗試'設置ItemProperty'的?我知道這並不能解釋這種不一致,但它可能會幫助你解除封鎖。 – latkin
謝謝,是的,我現在用'Set-ItemProperty'實現了它。我承認我認爲這不會讓我用點符號來表示屬性,但會考慮它。我假設它與底層提供商有關,並希望在v3中進行測試以查看事情是否發生了變化 – Kieranties
感謝@latkin,這讓我再次看到了這個問題(爲什麼我在嘗試之前不嘗試點符號不知道...)。 我已經更新了我的工作細節,但原始問題仍然是 – Kieranties