We have multiple websites in IIS on each of our servers, and we have PowerShell scripts that can create/update an individual website, along with configuring the bindings, SSL, app pools etc.
Given the size of the server farm, and the number of websites, it is highly desirable to be able to upgrade more than one website concurrently.
However, this raises the issue that updates to applicationHost.config of site A, could be overwritten by the concurrent updates for site B.
Is this possible?
Always best to test this:
Lets start with a simple script that create some sites, 20 in this case.
Param
(
[Parameter(Mandatory=$true)]
[int]
$offset
)
Import-Module WebAdministration
ForEach ($number in 1..20 ) {
$id = $offset + $number
New-WebSite -Name $("Test_" + $id) -Port $id -Id $id -PhysicalPath "$env:systemdrive\inetpub\wwwroot"
}
I save this into C:\temp\New-TestSite.ps1
Now run that script three times at the same time, I created another script: C:\temp\Run-Test.ps1
with the following content:
start-job -ScriptBlock {& C:\temp\New-TestSite.ps1 -offset 10000}
start-job -ScriptBlock {& C:\temp\New-TestSite.ps1 -offset 20000}
start-job -ScriptBlock {& C:\temp\New-TestSite.ps1 -offset 30000}
After running Run-Test.ps1
, let check how many sites we created:
ls iis:\sites | group {$_.Name.substring(0,6)} | Select Count,Name | Format-Table -AutoSize
I got:
Count Name
----- ----
19 Test_1
18 Test_2
15 Test_3
So we created 52 out of 60
When creating 50 per script, I got:
Count Name
----- ----
31 Test_1
31 Test_2
30 Test_3
that's 92 out of 150
Even worse in some test cases, one of the PowerShell processes crashed:
At least Get-Job
shows:
Id Name PSJobTypeName State
36 Job36 BackgroundJob Failed
38 Job38 BackgroundJob Completed
40 Job40 BackgroundJob Completed
So in conclusion, we can say it is not save to modify applicationHost.config concurrently.
Of course, this is an extreme test case and doing manual changes concurrently may work, but we should be careful.
Tests ran on Server 2012 R2 (IIS 8.5)