Thursday, May 01, 2008

Deployment to IIS 7.0 using Power Shell

Yes, I'm still here. Sorry for not writing anything lately on TFS. I've been in one of those two week Agile (with a capital A) "Iterations" which is when we get all the work done.

I don't really have anything important to share right now on our TFS adoption. Everything is going pretty good. Knock on wood!

While not really related to TFS though, I've fallen in love with Power Shell 1.0. Everyday I find another problem to solve with "commandlets" and all the great things a full featured shell offers. Along with the AppCMD command which ships with IIS 7.0, we're using Power Shell scripts to drive our deployment mechanism. Here is a simple example of what our scripts look like. It's actually working very well for us and far less overhead than creating an msi or Install Shield package.

You'll notice that we take the nuke and pave approach to deployment. That is, we check to see if the application directory is there, and if it is, we purge it. Then we copy over the new application version's code.


#Always get the script root. Per Microsoft's recommendation, each script should know their respected script root.
$SCRIPT_ROOT = Split-Path (Resolve-Path $myInvocation.MyCommand.Path)

#check to see if these values are already set. If not, set them to defalts.
if ($ENV_SITE_NAME -eq $null) {sv ENV_SITE_NAME -value Website}
if ($ENV_APPPOOL_NAME -eq $null) {sv ENV_APPPOOL_NAME -value WebsiteAppPool}
if ($ENV_PORT_NUMBER -eq $null) {sv ENV_PORT_NUMBER -Value "8080"}

sv APPCMD -value $env:systemroot\system32\inetsrv\AppCmd.exe
sv SITE_INSTALL_PATH -value "D:\Web Sites\$ENV_SITE_NAME"
sv APP_SERVICES -Value "aspnet_state", "W3SVC"
# ***************************************************
# Step 1)
# Clean up old install.
Invoke-Expression "$APPCMD delete site $ENV_SITE_NAME"
Invoke-Expression "$APPCMD delete apppool $ENV_APPPOOL_NAME"
if (Test-Path $SITE_INSTALL_PATH) {rmdir -Recurse -Force $SITE_INSTALL_PATH}
# ***************************************************# Step 2)
# Make dirs
New-Item $SITE_INSTALL_PATH -type directory
# ***************************************************
# Step 3)
# Create the AppPool for this site
Invoke-Expression "$APPCMD add apppool /name:$ENV_APPPOOL_NAME"
Invoke-Expression "$APPCMD set apppool /apppool.name:$ENV_APPPOOL_NAME /processModel.identityType:NetworkService"
# ***************************************************
# Step 4)
# This will add the site on port 81. This does not create an App or Virtual Director by default. *****
Invoke-Expression "$APPCMD add site /name:$ENV_SITE_NAME /bindings:`"http/*:${ENV_PORT_NUMBER}:`""
# ***************************************************
# Step 5)
# Craete App with the physical path and set the Apppool we need ******
Invoke-Expression "$APPCMD add app /site.name:$ENV_SITE_NAME /path:/ /physicalPath:`"$SITE_INSTALL_PATH`" /applicationPool:$ENV_APPPOOL_NAME"
# ***************************************************
# Step 6)
# Copy over files recursively (/E and /I), overwrite read only files (/R), surpress comfirmation (/Y), quietly *****
echo "Copy Files to WebSite"
xcopy $SCRIPT_ROOT\Website $SITE_INSTALL_PATH /E /I /R /Y /Q
# ***************************************************
# Step 7)
# Make sure any needed services are started before finishing and spits out their status.
Invoke-Expression "$APPCMD start apppool /apppool.name:$ENV_APPPOOL_NAME"
Invoke-Expression "$APPCMD start site /site.name:$ENV_SITE_NAME"
$APP_SERVICES Start-Service
$APP_SERVICES Get-Service
# ***************************************************
# Step 8)
# Make sure we didn't get any errors at deployment.
if ($error.count -lt 1)
{
Write-Output "" "Deployment Successful!" ""

}
else
{
Write-Output "" "Deployment Failed!" ""
$error
Write-Output ""
}

No comments: