Web Deploy is a great way to publish websites if you use Windows + IIS hosting, especially inside company’s infrastructure.
Why do I like it:
- It can be used from Visual Studio as well as from commandline - this means developers can publish right from VS, without any additional tools, but also script and commandline freaks like me can automate it
- It only syncs modified files - if you have low bandwith, deploy often or have large sites - it beats other methods that require full package to be deployed every time
- Active Directory can be used for authentication
Allowing a user to publish with Web Deploy
The goal is to allow non-administrator user to publish IIS website using Web Deploy.
There are two parts here:
- Add IIS Manager permissions
- Add File System permissions
If you like clicking through it, see Installing and Configuring Web Deploy on IIS 8.0 or Later. Remember that you should also add appropriate permissions to site’s physical folder or else the user won’t be able to publish any files.
If you want to do it from commandline, here’s a snippet for setting IIS Manager permissions:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Management")
[Microsoft.Web.Management.Server.ManagementAuthorization]::Grant($username, "$site", $false)
Then, use Set-Acl
to set physical path permissions. Here’s a full script:
<#
.SYNOPSIS
adds ACL rules to specific path. it's a helper wrapper for Set-ACL from Microsoft.PowerShell.Security
#>
function set-acl2(
[Parameter(Mandatory=$true)] $path,
[Parameter(Mandatory=$true)] [System.Security.AccessControl.FileSystemRights] $rights,
[Parameter(Mandatory=$true)] $user,
[System.Security.AccessControl.InheritanceFlags] $InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None,
[System.Security.AccessControl.PropagationFlags] $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
) {
$colRights = $rights
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
$objType =[System.Security.AccessControl.AccessControlType]::Allow
$objUser = New-Object System.Security.Principal.NTAccount($user)
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule ($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType)
$objACL = (Get-Item $path).GetAccessControl('Access')#(Get-ACL $path).GetAccessControl('Access')
$objACL.AddAccessRule($objACE)
Set-ACL -Path $path -AclObject $objACL
}
<#
.SYNOPSIS
Allows the specified user to publish website through webdeploy
#>
function allow-iiswebdeploy {
param(
[Parameter(Mandatory=$true)] $username,
[Parameter(Mandatory=$true)] $site,
[Switch][bool] $isgroup
)
ipmo webadministration
$iissite = get-item "iis:\sites\$site" -ErrorAction Stop
if ($iissite -eq $null) { throw "site '$site' not found" }
# add IIS Manager Users and Permissions
# from: https://blogs.iis.net/carlosag/adding-iis-manager-users-and-permissions-using-powershell
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Management")
[Microsoft.Web.Management.Server.ManagementAuthorization]::Grant($username, "$site", $isgroup)
# grant file system permissions!
$dir = $iissite.physicalPath
set-acl2 -path $dir -rights CreateFiles,Delete,Modify,CreateDirectories,ReadAndExecute -user $username -InheritanceFlag ObjectInherit,ContainerInherit
}
Just call:
PS> allow-iiswebdeploy -username "MYDOMAIN\user" -site "Default Web Site"
And that’s it! Note that site’s physical path is obtained directly from IIS.
Resources
https://www.iis.net/learn/publish/using-web-deploy/web-deploy-powershell-cmdlets