Skip to content

Instantly share code, notes, and snippets.

@CJHarmath
Last active October 14, 2021 02:59
Show Gist options
  • Save CJHarmath/b2af0f50700ce9fbdd8c5c3e582fd41b to your computer and use it in GitHub Desktop.
Save CJHarmath/b2af0f50700ce9fbdd8c5c3e582fd41b to your computer and use it in GitHub Desktop.
# Setup
Import-Module WebAdministration
# create 2 site root directories
$a = 'C:\inetpub\AspNetCoreSampleA'
$b = 'C:\inetpub\AspNetCoreSampleB'
$siteRoot = 'C:\inetpub\aspnetcoresample'
$siteName = 'AspNetCoreSample'
$poolName = "aspnetcore"
New-Item -Type Directory $a
New-Item -Type Directory $b
# create a symlink to targeting one side
New-Item -Type SymbolicLink -Path $siteRoot -Target $a
# point the site root to the symlink
Set-ItemProperty "IIS:\Sites\$siteName" -name physicalPath -value $siteRoot
# make sure it get's picked up
Restart-WebAppPool -Name $poolName
# this tells you the active side
Get-Item -Path $siteRoot | Select-Object -ExpandProperty target
# Flip the symlink
$current = (Get-Item -Path $siteRoot).Target
$newTarget = if ($current -eq $a) {$b} else {$a}
New-Item -Type SymbolicLink -Path $siteRoot -Target $newTarget -Force
# at this point w3wp.exe still locks the current target folder until it's getting recycled
# Deploy new version to the symlink which is now pointing to the other side which should have no locks
robocopy \\myshare\myapp $siteRoot /mir
# recycle app pool, so it picks up the new files
Restart-WebAppPool -Name $poolName
# bonus point: rollback is easy
$current = (Get-Item -Path $siteRoot).Target
$newTarget = if ($current -eq $a) {$b} else {$a}
New-Item -Type SymbolicLink -Path $siteRoot -Target $newTarget -Force
Restart-WebAppPool -Name $poolName
@joelmandell
Copy link

Okay thx for your reply. But why is the script creating the directories $a and $b?
It throws an exception creating symbolic link target $a because that is a folder.

@joelmandell
Copy link

Okay, I think I got it now. The site root is supposed to be a symbolic link that points to the newly created folder $a.
Anyway having a hard time understanding the concept. I will dig into this again.

@CJHarmath
Copy link
Author

keep on playing with it until it clicks.
Create 2 folders with 2 different files, then create a symlink pointing to the first, confirm. then update the symlink to the second folder then confirm that you now see the second folder contents.

I've added a diagram here showing that the IIS site root points to a symlink.
dotnet/aspnetcore#3793 (comment)

@alex-jitbit
Copy link

Thanks for the script, (and for the comment on the GH issue at MS repo) used it as an inspiration for our deploy script! I owe you.

PS. we used to switch IIS application path during deploys, but symlinks are so much better and in-flight requests are not being dropped. Thanks again. ❤ 🙌

@CJHarmath
Copy link
Author

Sure thing, glad it helped someone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment