Monday, November 29, 2010

Powershell Scripts For WCF Site Deployment

A WCF service needs to be deployed to IIS in a web farm environment with 8 physical servers. To simplify the deployment work, I created Powershell scripts to do following job:
1. Check if powershell is installed or not. Prompt error and exit if powershell is not installed.
2. Check if IIS 7 powershell snap-in is installed or not. Install Powershell snap-in silently
if it's not installed.
3. Create application pool with desired identity
4. Create IIS Site using appPool created in step 3
5. Copy supporting files to related folders
6. Set permission for related folders
There are three scripts in total. The one to run is called Deploy.cmd:
@REM file: Deploy.cmd
@echo off
set PowershellExe="C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
set IISSnapin="C:\Program Files\IIS\PowerShellSnapin\IIsConsole.psc1"

echo.
if not exist %PowershellExe% (
echo "Powershell 2.0 is not installed. Please install it and try again."
endlocal
)

%PowershellExe% -command "& .\InstallPowershellSnapin.ps1"

if not exist %IISSnapin% (
echo "IIS 7.0 Powershell Snap-in is not installed. Please install it and try again."
endlocal
)

%PowershellExe% -psconsolefile %IISSnapin% -command "& .\InstallWcfService.ps1"
The powershell script to install the IIS 7 Snap-in:
# file: InstallPowershellSnapin.ps1

Set-ExecutionPolicy Unrestricted

$LogFile = "DeploymentLog.log"
$SnapinInstallLog = "IIS7PowerShellSnappin.log"
$SnapinFile = "C:\Program Files\IIS\PowerShellSnapin\IIsConsole.psc1"
$SnapinInstaller = "iis7psprov_x64.msi"

Start-Transcript $LogFile -Append -Force

write-host "Checking IIS 7 Powershell Snapin..."

if (! (Test-Path $SnapinFile))
{
write-host "Install IIS 7 Powershell Snap-in..."
if ( !(Test-Path $SnapinInstaller))
{
write-error "`nCan not find IIS 7 Powershell Snap-in."
exit
}

trap {
write-error "`nInstallation of IIS 7 Powershell Snap-in failed."
}
msiexec.exe /i iis7psprov_x64.msi -qn /l* $SnapinInstallLog
start-sleep -second 10
}

Stop-Transcript
The last Powershell script to setup IIS:
# file: InstallWcfService.ps1

$MachineName = "Machine123"
$LogFile = "DeploymentLog.log"
$SnappinFile = "C:\Program Files\IIS\PowerShellSnapin\IIsConsole.psc1"

$DeploymentSourceFolder = "DeployFiles"
$SitePath = "C:\inetpub\WCFService"

$SiteName = "WCF Service"
$PortNumber = 80
$AppPoolName = "WCF Service Pool"
$AppPoolAccount = "Domain1\User1"
$AppPoolPassword = "SecretPassword"
$AppPoolType = 3

Start-Transcript $LogFile -Append -Force

write-host "Checking Site Path..."
if ( !(Test-Path $SitePath))
{
write-host "Creating Site Path" $SitePath
trap {
write-error "Error in creating site path:" $_.Exception.Message
}
mkdir $SitePath > $null

$SitePathPermission = Get-Acl $SitePath
$AccessRight = New-Object system.security.accesscontrol.
filesystemaccessrule($AppPoolAccount,"FullControl","Allow")
$SitePathPermission.SetAccessRule($AccessRight)
Set-Acl $SitePath $SitePathPermission
}

write-host "Checking application pool..."
$pcAppPool = Get-Item IIS:\AppPools\$AppPoolName
if ( !$pcAppPool)
{
Write-Host "Creating application pool..."
trap {
write-error "Error in creating application pool:" $_.Exception.Message
}
new-webapppool -name $AppPoolName > $null

Write-Host "Configuring application pool..."
$pcAppPool = Get-Item IIS:\AppPools\$AppPoolName
$pcAppPool.processModel.userName = $AppPoolAccount
$pcAppPool.processModel.password = $AppPoolPassword
$pcAppPool.processModel.identityType = $AppPoolType
$pcAppPool.managedRuntimeVersion = "v4.0"
$pcAppPool | Set-Item
}

write-host "Checking IIS Site..."
if ( !(get-website | where {$_.Name -eq $SiteName}))
{
Write-Host "Creating Site..."
trap {
write-error "Error in creating IIS site:" $_.Exception.Message
}
New-Website -name $SiteName -ApplicationPool $AppPoolName -PhysicalPath $SitePath
-port $PortNumber -HostHeader $MachineName > $null
}

Write-Host "Copying deployment files.."
copy-item $DeploymentSourceFolder\* $SitePath -recurse -force

Write-Host "Deployment completed."
Stop-Transcript