Functions/Iis.ps1
# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. function Add-CIisDefaultDocument { <# .SYNOPSIS Adds a default document name to a website. .DESCRIPTION If you need a custom default document for your website, this function will add it. The `FileName` argument should be a filename IIS should use for a default document, e.g. home.html. If the website already has `FileName` in its list of default documents, this function silently returns. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Add-CIisDefaultDocument -SiteName MySite -FileName home.html Adds `home.html` to the list of default documents for the MySite website. #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string] # The name of the site where the default document should be added. $SiteName, [Parameter(Mandatory=$true)] [string] # The default document to add. $FileName ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $section = Get-CIisConfigurationSection -SiteName $SiteName -SectionPath 'system.webServer/defaultDocument' if( -not $section ) { return } [Microsoft.Web.Administration.ConfigurationElementCollection]$files = $section.GetCollection('files') $defaultDocElement = $files | Where-Object { $_["value"] -eq $FileName } if( -not $defaultDocElement ) { Write-IisVerbose $SiteName 'Default Document' '' $FileName $defaultDocElement = $files.CreateElement('add') $defaultDocElement["value"] = $FileName $files.Add( $defaultDocElement ) $section.CommitChanges() } } filter Add-IisServerManagerMember { [CmdletBinding()] param( [Parameter(Mandatory=$true,ValueFromPipeline=$true)] # The object on which the server manager members will be added. $InputObject, [Parameter(Mandatory=$true)] [Microsoft.Web.Administration.ServerManager] # The server manager object to use as the basis for the new members. $ServerManager, [Switch] # If set, will return the input object. $PassThru ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $InputObject | Add-Member -MemberType NoteProperty -Name 'ServerManager' -Value $ServerManager -PassThru | Add-Member -MemberType ScriptMethod -Name 'CommitChanges' -Value { $this.ServerManager.CommitChanges() } if( $PassThru ) { return $InputObject } } function Disable-CIisSecurityAuthentication { <# .SYNOPSIS Disables anonymous or basic authentication for all or part of a website. .DESCRIPTION By default, disables an authentication type for an entire website. You can disable an authentication type at a specific path under a website by passing the virtual path (*not* the physical path) to that directory as the value of the `VirtualPath` parameter. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .LINK Enable-CIisSecurityAuthentication .LINK Get-CIisSecurityAuthentication .LINK Test-CIisSecurityAuthentication .EXAMPLE Disable-CIisSecurityAuthentication -SiteName Peanuts -Anonymous Turns off anonymous authentication for the `Peanuts` website. .EXAMPLE Disable-CIisSecurityAuthentication -SiteName Peanuts Snoopy/DogHouse -Basic Turns off basic authentication for the `Snoopy/DogHouse` directory under the `Peanuts` website. #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] [string] # The site where anonymous authentication should be set. $SiteName, [Alias('Path')] [string] # The optional path where anonymous authentication should be set. $VirtualPath = '', [Parameter(Mandatory=$true,ParameterSetName='Anonymous')] [Switch] # Enable anonymouse authentication. $Anonymous, [Parameter(Mandatory=$true,ParameterSetName='Basic')] [Switch] # Enable basic authentication. $Basic, [Parameter(Mandatory=$true,ParameterSetName='Windows')] [Switch] # Enable Windows authentication. $Windows ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $authType = $pscmdlet.ParameterSetName $getArgs = @{ $authType = $true; } $authSettings = Get-CIisSecurityAuthentication -SiteName $SiteName -VirtualPath $VirtualPath @getArgs if( -not $authSettings.GetAttributeValue('enabled') ) { return } $authSettings.SetAttributeValue('enabled', 'False') $fullPath = Join-CIisVirtualPath $SiteName $VirtualPath if( $pscmdlet.ShouldProcess( $fullPath, ("disable {0} authentication" -f $authType) ) ) { $authSettings.CommitChanges() } } function Enable-CIisDirectoryBrowsing { <# .SYNOPSIS Enables directory browsing under all or part of a website. .DESCRIPTION Enables directory browsing (i.e. showing the contents of a directory by requesting that directory in a web browser) for a website. To enable directory browsing on a directory under the website, pass the virtual path to that directory as the value to the `Directory` parameter. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Enable-CIisDirectoryBrowsing -SiteName Peanuts Enables directory browsing on the `Peanuts` website. .EXAMPLE Enable-CIisDirectoryBrowsing -SiteName Peanuts -Directory Snoopy/DogHouse Enables directory browsing on the `/Snoopy/DogHouse` directory under the `Peanuts` website. #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string] # The name of the site where the virtual directory is located. $SiteName, [Alias('Path')] [string] # The directory where directory browsing should be enabled. $VirtualPath ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $section = Get-CIisConfigurationSection -SiteName $SiteName -SectionPath 'system.webServer/directoryBrowse' if( $section['enabled'] -ne 'true' ) { Write-IisVerbose $SiteName 'Directory Browsing' 'disabled' 'enabled' $section['enabled'] = $true $section.CommitChanges() } } function Enable-CIisSecurityAuthentication { <# .SYNOPSIS Enables anonymous or basic authentication for an entire site or a sub-directory of that site. .DESCRIPTION By default, enables an authentication type on an entire website. You can enable an authentication type at a specific path under a website by passing the virtual path (*not* the physical path) to that directory as the value of the `VirtualPath` parameter. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .LINK Disable-CIisSecurityAuthentication .LINK Get-CIisSecurityAuthentication .LINK Test-CIisSecurityAuthentication .EXAMPLE Enable-CIisSecurityAuthentication -SiteName Peanuts -Anonymous Turns on anonymous authentication for the `Peanuts` website. .EXAMPLE Enable-CIisSecurityAuthentication -SiteName Peanuts Snoopy/DogHouse -Basic Turns on anonymous authentication for the `Snoopy/DogHouse` directory under the `Peanuts` website. #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] [string] # The site where anonymous authentication should be set. $SiteName, [Alias('Path')] [string] # The optional path where anonymous authentication should be set. $VirtualPath = '', [Parameter(Mandatory=$true,ParameterSetName='Anonymous')] [Switch] # Enable anonymouse authentication. $Anonymous, [Parameter(Mandatory=$true,ParameterSetName='Basic')] [Switch] # Enable basic authentication. $Basic, [Parameter(Mandatory=$true,ParameterSetName='Windows')] [Switch] # Enable Windows authentication. $Windows ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $authType = $pscmdlet.ParameterSetName $getArgs = @{ $authType = $true; } $authSettings = Get-CIisSecurityAuthentication -SiteName $SiteName -VirtualPath $VirtualPath @getArgs if( $authSettings.GetAttributeValue('enabled') ) { return } $authSettings.SetAttributeValue('enabled', 'true') $fullPath = Join-CIisVirtualPath $SiteName $VirtualPath if( $pscmdlet.ShouldProcess( $fullPath, ("enable {0}" -f $authType) ) ) { $authSettings.CommitChanges() } } function Enable-CIisSsl { <# .SYNOPSIS Turns on and configures SSL for a website or part of a website. .DESCRIPTION This function enables SSL and optionally the site/directory to: * Require SSL (the `RequireSsl` switch) * Ignore/accept/require client certificates (the `AcceptClientCertificates` and `RequireClientCertificates` switches). * Requiring 128-bit SSL (the `Require128BitSsl` switch). By default, this function will enable SSL, make SSL connections optional, ignores client certificates, and not require 128-bit SSL. Changing any SSL settings will do you no good if the website doesn't have an SSL binding or doesn't have an SSL certificate. The configuration will most likely succeed, but won't work in a browser. So sad. Beginning with IIS 7.5, the `Require128BitSsl` parameter won't actually change the behavior of a website since [there are no longer 128-bit crypto providers](https://forums.iis.net/p/1163908/1947203.aspx) in versions of Windows running IIS 7.5. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .LINK http://support.microsoft.com/?id=907274 .EXAMPLE Enable-CIisSsl -Site Peanuts Enables SSL on the `Peanuts` website's, making makes SSL connections optional, ignoring client certificates, and making 128-bit SSL optional. .EXAMPLE Enable-CIisSsl -Site Peanuts -VirtualPath Snoopy/DogHouse -RequireSsl Configures the `/Snoopy/DogHouse` directory in the `Peanuts` site to require SSL. It also turns off any client certificate settings and makes 128-bit SSL optional. .EXAMPLE Enable-CIisSsl -Site Peanuts -AcceptClientCertificates Enables SSL on the `Peanuts` website and configures it to accept client certificates, makes SSL optional, and makes 128-bit SSL optional. .EXAMPLE Enable-CIisSsl -Site Peanuts -RequireSsl -RequireClientCertificates Enables SSL on the `Peanuts` website and configures it to require SSL and client certificates. You can't require client certificates without also requiring SSL. .EXAMPLE Enable-CIisSsl -Site Peanuts -Require128BitSsl Enables SSL on the `Peanuts` website and require 128-bit SSL. Also, makes SSL connections optional and ignores client certificates. .LINK Set-CIisWebsiteSslCertificate #> [CmdletBinding(SupportsShouldProcess=$true,DefaultParameterSetName='IgnoreClientCertificates')] param( [Parameter(Mandatory=$true)] [string] # The website whose SSL flags should be modifed. $SiteName, [Alias('Path')] [string] # The path to the folder/virtual directory/application under the website whose SSL flags should be set. $VirtualPath = '', [Parameter(ParameterSetName='IgnoreClientCertificates')] [Parameter(ParameterSetName='AcceptClientCertificates')] [Parameter(Mandatory=$true,ParameterSetName='RequireClientCertificates')] [Switch] # Should SSL be required? $RequireSsl, [Switch] # Requires 128-bit SSL. Only changes IIS behavior in IIS 7.0. $Require128BitSsl, [Parameter(ParameterSetName='AcceptClientCertificates')] [Switch] # Should client certificates be accepted? $AcceptClientCertificates, [Parameter(Mandatory=$true,ParameterSetName='RequireClientCertificates')] [Switch] # Should client certificates be required? Also requires SSL ('RequireSsl` switch). $RequireClientCertificates ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $SslFlags_Ssl = 8 $SslFlags_SslNegotiateCert = 32 $SslFlags_SslRequireCert = 64 $SslFlags_SslMapCert = 128 $SslFlags_Ssl128 = 256 $intFlag = 0 $flags = @() if( $RequireSSL -or $RequireClientCertificates ) { $flags += 'Ssl' $intFlag = $intFlag -bor $SslFlags_Ssl } if( $AcceptClientCertificates -or $RequireClientCertificates ) { $flags += 'SslNegotiateCert' $intFlag = $intFlag -bor $SslFlags_SslNegotiateCert } if( $RequireClientCertificates ) { $flags += 'SslRequireCert' $intFlag = $intFlag -bor $SslFlags_SslRequireCert } if( $Require128BitSsl ) { $flags += 'Ssl128' $intFlag = $intFlag -bor $SslFlags_Ssl128 } $section = Get-CIisConfigurationSection -SiteName $SiteName -VirtualPath $VirtualPath -SectionPath 'system.webServer/security/access' if( -not $section ) { return } $flags = $flags -join ',' $currentIntFlag = $section['sslFlags'] $currentFlags = @( ) if( $currentIntFlag -band $SslFlags_Ssl ) { $currentFlags += 'Ssl' } if( $currentIntFlag -band $SslFlags_SslNegotiateCert ) { $currentFlags += 'SslNegotiateCert' } if( $currentIntFlag -band $SslFlags_SslRequireCert ) { $currentFlags += 'SslRequireCert' } if( $currentIntFlag -band $SslFlags_SslMapCert ) { $currentFlags += 'SslMapCert' } if( $currentIntFlag -band $SslFlags_Ssl128 ) { $currentFlags += 'Ssl128' } if( -not $currentFlags ) { $currentFlags += 'None' } $currentFlags = $currentFlags -join ',' if( $section['sslFlags'] -ne $intFlag ) { Write-IisVerbose $SiteName 'SslFlags' ('{0} ({1})' -f $currentIntFlag,$currentFlags) ('{0} ({1})' -f $intFlag,$flags) -VirtualPath $VirtualPath $section['sslFlags'] = $flags if( $pscmdlet.ShouldProcess( (Join-CIisVirtualPath $SiteName $VirtualPath), "enable SSL" ) ) { $section.CommitChanges() } } } function Get-CIisApplication { <# .SYNOPSIS Gets an IIS application as an `Application` object. .DESCRIPTION Uses the `Microsoft.Web.Administration` API to get an IIS application object. If the application doesn't exist, `$null` is returned. The objects returned have two dynamic properties and one dynamic methods added. * `ServerManager { get; }` - The `ServerManager` object which created the `Application` object. * `CommitChanges()` - Persists any configuration changes made to the object back into IIS's configuration files. * `PhysicalPath { get; }` - The physical path to the application. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .OUTPUTS Microsoft.Web.Administration.Application. .EXAMPLE Get-CIisApplication -SiteName 'DeathStar` Gets all the applications running under the `DeathStar` website. .EXAMPLE Get-CIisApplication -SiteName 'DeathStar' -VirtualPath '/' Demonstrates how to get the main application for a website: use `/` as the application name. .EXAMPLE Get-CIisApplication -SiteName 'DeathStar' -VirtualPath 'MainPort/ExhaustPort' Demonstrates how to get a nested application, i.e. gets the application at `/MainPort/ExhaustPort` under the `DeathStar` website. #> [CmdletBinding()] [OutputType([Microsoft.Web.Administration.Application])] param( [Parameter(Mandatory=$true)] [string] # The site where the application is running. $SiteName, [Parameter()] [Alias('Name')] [string] # The name of the application. Default is to return all applications running under the website `$SiteName`. $VirtualPath ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $site = Get-CIisWebsite -SiteName $SiteName if( -not $site ) { return } $site.Applications | Where-Object { if( $VirtualPath ) { return ($_.Path -eq "/$VirtualPath") } return $true } | Add-IisServerManagerMember -ServerManager $site.ServerManager -PassThru } function Get-CIisAppPool { <# .SYNOPSIS Gets a `Microsoft.Web.Administration.ApplicationPool` object for an application pool. .DESCRIPTION The `Get-CIisAppPool` function returns an IIS application pools as a `Microsoft.Web.Administration.ApplicationPool` object. Use the `Name` parameter to return the application pool. If that application pool isn't found, `$null` is returned. Carbon adds a `CommitChanges` method on each object returned that you can use to save configuration changes. Beginning in Carbon 2.0, `Get-CIisAppPool` will return all application pools installed on the current computer. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .LINK http://msdn.microsoft.com/en-us/library/microsoft.web.administration.applicationpool(v=vs.90).aspx .OUTPUTS Microsoft.Web.Administration.ApplicationPool. .EXAMPLE Get-CIisAppPool Demonstrates how to get *all* application pools. .EXAMPLE Get-CIisAppPool -Name 'Batcave' Gets the `Batcave` application pool. .EXAMPLE Get-CIisAppPool -Name 'Missing!' Returns `null` since, for purposes of this example, there is no `Missing~` application pool. #> [CmdletBinding()] [OutputType([Microsoft.Web.Administration.ApplicationPool])] param( [string] # The name of the application pool to return. If not supplied, all application pools are returned. $Name ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $mgr = New-Object Microsoft.Web.Administration.ServerManager $mgr.ApplicationPools | Where-Object { if( -not $PSBoundParameters.ContainsKey('Name') ) { return $true } return $_.Name -eq $Name } | Add-IisServerManagerMember -ServerManager $mgr -PassThru } function Get-CIisConfigurationSection { <# .SYNOPSIS Gets a Microsoft.Web.Adminisration configuration section for a given site and path. .DESCRIPTION Uses the Microsoft.Web.Administration API to get a `Microsoft.Web.Administration.ConfigurationSection`. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .OUTPUTS Microsoft.Web.Administration.ConfigurationSection. .EXAMPLE Get-CIisConfigurationSection -SiteName Peanuts -Path Doghouse -Path 'system.webServer/security/authentication/anonymousAuthentication' Returns a configuration section which represents the Peanuts site's Doghouse path's anonymous authentication settings. #> [CmdletBinding(DefaultParameterSetName='Global')] [OutputType([Microsoft.Web.Administration.ConfigurationSection])] param( [Parameter(Mandatory=$true,ParameterSetName='ForSite')] [string] # The site whose configuration should be returned. $SiteName, [Parameter(ParameterSetName='ForSite')] [Alias('Path')] [string] # The optional site path whose configuration should be returned. $VirtualPath = '', [Parameter(Mandatory=$true,ParameterSetName='ForSite')] [Parameter(Mandatory=$true,ParameterSetName='Global')] [string] # The path to the configuration section to return. $SectionPath, [Type] # The type of object to return. Optional. $Type = [Microsoft.Web.Administration.ConfigurationSection] ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $mgr = New-Object 'Microsoft.Web.Administration.ServerManager' $config = $mgr.GetApplicationHostConfiguration() $section = $null $qualifier = '' try { if( $PSCmdlet.ParameterSetName -eq 'ForSite' ) { $qualifier = Join-CIisVirtualPath $SiteName $VirtualPath $section = $config.GetSection( $SectionPath, $Type, $qualifier ) } else { $section = $config.GetSection( $SectionPath, $Type ) } } catch { } if( $section ) { $section | Add-IisServerManagerMember -ServerManager $mgr -PassThru } else { Write-Error ('IIS:{0}: configuration section {1} not found.' -f $qualifier,$SectionPath) return } } function Get-CIisHttpHeader { <# .SYNOPSIS Gets the HTTP headers for a website or directory under a website. .DESCRIPTION For each custom HTTP header defined under a website and/or a sub-directory under a website, returns a `Carbon.Iis.HttpHeader` object. This object has two properties: * Name: the name of the HTTP header * Value: the value of the HTTP header Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .OUTPUTS Carbon.Iis.HttpHeader. .LINK Set-CIisHttpHeader .EXAMPLE Get-CIisHttpHeader -SiteName SopwithCamel Returns the HTTP headers for the `SopwithCamel` website. .EXAMPLE Get-CIisHttpHeader -SiteName SopwithCamel -Path Engine Returns the HTTP headers for the `Engine` directory under the `SopwithCamel` website. .EXAMPLE Get-CIisHttpHeader -SiteName SopwithCambel -Name 'X-*' Returns all HTTP headers which match the `X-*` wildcard. #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string] # The name of the website whose headers to return. $SiteName, [Alias('Path')] [string] # The optional path under `SiteName` whose headers to return. $VirtualPath = '', [string] # The name of the HTTP header to return. Optional. If not given, all headers are returned. Wildcards supported. $Name = '*' ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $httpProtocol = Get-CIisConfigurationSection -SiteName $SiteName ` -VirtualPath $VirtualPath ` -SectionPath 'system.webServer/httpProtocol' $httpProtocol.GetCollection('customHeaders') | Where-Object { $_['name'] -like $Name } | ForEach-Object { New-Object Carbon.Iis.HttpHeader $_['name'],$_['value'] } } function Get-CIisHttpRedirect { <# .SYNOPSIS Gets the HTTP redirect settings for a website or virtual directory/application under a website. .DESCRIPTION Returns a `Carbon.Iis.HttpRedirectConfigurationSection` object for the given HTTP redirect settings. The object contains the following properties: * Enabled - `True` if the redirect is enabled, `False` otherwise. * Destination - The URL where requests are directed to. * HttpResponseCode - The HTTP status code sent to the browser for the redirect. * ExactDestination - `True` if redirects are to destination, regardless of the request path. This will send all requests to `Destination`. * ChildOnly - `True` if redirects are only to content in the destination directory (not subdirectories). Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .LINK http://www.iis.net/configreference/system.webserver/httpredirect .OUTPUTS Carbon.Iis.HttpRedirectConfigurationSection. .EXAMPLE Get-CIisHttpRedirect -SiteName ExampleWebsite Gets the redirect settings for ExampleWebsite. .EXAMPLE Get-CIisHttpRedirect -SiteName ExampleWebsite -Path MyVirtualDirectory Gets the redirect settings for the MyVirtualDirectory virtual directory under ExampleWebsite. #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string] # The site's whose HTTP redirect settings will be retrieved. $SiteName, [Alias('Path')] [string] # The optional path to a sub-directory under `SiteName` whose settings to return. $VirtualPath = '' ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState Get-CIisConfigurationSection -SiteName $SiteName ` -VirtualPath $VirtualPath ` -SectionPath 'system.webServer/httpRedirect' ` -Type ([Carbon.Iis.HttpRedirectConfigurationSection]) } function Get-CIisMimeMap { <# .SYNOPSIS Gets the file extension to MIME type mappings. .DESCRIPTION IIS won't serve static content unless there is an entry for it in the web server or website's MIME map configuration. This function will return all the MIME maps for the current server. The objects returned are instances of the `Carbon.Iis.MimeMap` class, and contain the following properties: * `FileExtension`: the mapping's file extension * `MimeType`: the mapping's MIME type Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .OUTPUTS Carbon.Iis.MimeMap. .LINK Set-CIisMimeMap .EXAMPLE Get-CIisMimeMap Gets all the the file extension to MIME type mappings for the web server. .EXAMPLE Get-CIisMimeMap -FileExtension .htm* Gets all the file extension to MIME type mappings whose file extension matches the `.htm*` wildcard. .EXAMPLE Get-CIisMimeMap -MimeType 'text/*' Gets all the file extension to MIME type mappings whose MIME type matches the `text/*` wildcard. .EXAMPLE Get-CIisMimeMap -SiteName DeathStar Gets all the file extenstion to MIME type mappings for the `DeathStar` website. .EXAMPLE Get-CIisMimeMap -SiteName DeathStar -VirtualPath ExhaustPort Gets all the file extension to MIME type mappings for the `DeathStar`'s `ExhausePort` directory. #> [CmdletBinding(DefaultParameterSetName='ForWebServer')] [OutputType([Carbon.Iis.MimeMap])] param( [Parameter(Mandatory=$true,ParameterSetName='ForWebsite')] [string] # The website whose MIME mappings to return. If not given, returns the web server's MIME map. $SiteName, [Parameter(ParameterSetName='ForWebsite')] [Alias('Path')] [string] # The directory under the website whose MIME mappings to return. Optional. $VirtualPath = '', [string] # The name of the file extensions to return. Wildcards accepted. $FileExtension = '*', [string] # The name of the MIME type(s) to return. Wildcards accepted. $MimeType = '*' ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $getIisConfigSectionParams = @{ } if( $PSCmdlet.ParameterSetName -eq 'ForWebsite' ) { $getIisConfigSectionParams['SiteName'] = $SiteName $getIisConfigSectionParams['VirtualPath'] = $VirtualPath } $staticContent = Get-CIisConfigurationSection -SectionPath 'system.webServer/staticContent' @getIisConfigSectionParams $staticContent.GetCollection() | Where-Object { $_['fileExtension'] -like $FileExtension -and $_['mimeType'] -like $MimeType } | ForEach-Object { New-Object 'Carbon.Iis.MimeMap' ($_['fileExtension'],$_['mimeType']) } } function Get-CIisSecurityAuthentication { <# .SYNOPSIS Gets a site's (and optional sub-directory's) security authentication configuration section. .DESCRIPTION You can get the anonymous, basic, digest, and Windows authentication sections by using the `Anonymous`, `Basic`, `Digest`, or `Windows` switches, respectively. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .OUTPUTS Microsoft.Web.Administration.ConfigurationSection. .EXAMPLE Get-CIisSecurityAuthentication -SiteName Peanuts -Anonymous Gets the `Peanuts` site's anonymous authentication configuration section. .EXAMPLE Get-CIisSecurityAuthentication -SiteName Peanuts -VirtualPath Doghouse -Basic Gets the `Peanuts` site's `Doghouse` sub-directory's basic authentication configuration section. #> [CmdletBinding()] [OutputType([Microsoft.Web.Administration.ConfigurationSection])] param( [Parameter(Mandatory=$true)] [string] # The site where anonymous authentication should be set. $SiteName, [Alias('Path')] [string] # The optional path where anonymous authentication should be set. $VirtualPath = '', [Parameter(Mandatory=$true,ParameterSetName='anonymousAuthentication')] [Switch] # Gets a site's (and optional sub-directory's) anonymous authentication configuration section. $Anonymous, [Parameter(Mandatory=$true,ParameterSetName='basicAuthentication')] [Switch] # Gets a site's (and optional sub-directory's) basic authentication configuration section. $Basic, [Parameter(Mandatory=$true,ParameterSetName='digestAuthentication')] [Switch] # Gets a site's (and optional sub-directory's) digest authentication configuration section. $Digest, [Parameter(Mandatory=$true,ParameterSetName='windowsAuthentication')] [Switch] # Gets a site's (and optional sub-directory's) Windows authentication configuration section. $Windows ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $sectionPath = 'system.webServer/security/authentication/{0}' -f $pscmdlet.ParameterSetName Get-CIisConfigurationSection -SiteName $SiteName -VirtualPath $VirtualPath -SectionPath $sectionPath } function Get-CIisVersion { <# .SYNOPSIS Gets the version of IIS. .DESCRIPTION Reads the version of IIS from the registry, and returns it as a `Major.Minor` formatted string. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Get-CIisVersion Returns `7.0` on Windows 2008, and `7.5` on Windows 7 and Windows 2008 R2. #> [CmdletBinding()] param( ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $props = Get-ItemProperty hklm:\Software\Microsoft\InetStp return $props.MajorVersion.ToString() + "." + $props.MinorVersion.ToString() } function Get-CIisWebsite { <# .SYNOPSIS Returns all the websites installed on the local computer, or a specific website. .DESCRIPTION Returns a Microsoft.Web.Administration.Site object. Each object will have a `CommitChanges` script method added which will allow you to commit/persist any changes to the website's configuration. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .OUTPUTS Microsoft.Web.Administration.Site. .LINK http://msdn.microsoft.com/en-us/library/microsoft.web.administration.site.aspx .EXAMPLE Get-CIisWebsite Returns all installed websites. .EXAMPLE Get-CIisWebsite -SiteName 'WebsiteName' Returns the details for the site named `WebsiteName`. #> [CmdletBinding()] [OutputType([Microsoft.Web.Administration.Site])] param( [string] [Alias('SiteName')] # The name of the site to get. $Name ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState if( $Name -and -not (Test-CIisWebsite -Name $Name) ) { return $null } $mgr = New-Object 'Microsoft.Web.Administration.ServerManager' $mgr.Sites | Where-Object { if( $Name ) { $_.Name -eq $Name } else { $true } } | Add-IisServerManagerMember -ServerManager $mgr -PassThru } function Install-CIisApplication { <# .SYNOPSIS Creates a new application under a website. .DESCRIPTION Creates a new application at `VirtualPath` under website `SiteName` running the code found on the file system under `PhysicalPath`, i.e. if SiteName is is `example.com`, the application is accessible at `example.com/VirtualPath`. If an application already exists at that path, it is removed first. The application can run under a custom application pool using the optional `AppPoolName` parameter. If no app pool is specified, the application runs under the same app pool as the website it runs under. Beginning with Carbon 2.0, returns a `Microsoft.Web.Administration.Application` object for the new application if one is created or modified. Beginning with Carbon 2.0, if no app pool name is given, existing application's are updated to use `DefaultAppPool`. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Install-CIisApplication -SiteName Peanuts -VirtualPath CharlieBrown -PhysicalPath C:\Path\To\CharlieBrown -AppPoolName CharlieBrownPool Creates an application at `Peanuts/CharlieBrown` which runs from `Path/To/CharlieBrown`. The application runs under the `CharlieBrownPool`. .EXAMPLE Install-CIisApplication -SiteName Peanuts -VirtualPath Snoopy -PhysicalPath C:\Path\To\Snoopy Create an application at Peanuts/Snoopy, which runs from C:\Path\To\Snoopy. It uses the same application as the Peanuts website. #> [CmdletBinding()] [OutputType([Microsoft.Web.Administration.Application])] param( [Parameter(Mandatory=$true)] [string] # The site where the application should be created. $SiteName, [Parameter(Mandatory=$true)] [Alias('Name')] [string] # The name of the application. $VirtualPath, [Parameter(Mandatory=$true)] [Alias('Path')] [string] # The path to the application. $PhysicalPath, [string] # The app pool for the application. Default is `DefaultAppPool`. $AppPoolName, [Switch] # Returns IIS application object. This switch is new in Carbon 2.0. $PassThru ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $site = Get-CIisWebsite -SiteName $SiteName if( -not $site ) { Write-Error ('[IIS] Website ''{0}'' not found.' -f $SiteName) return } $iisAppPath = Join-CIisVirtualPath $SiteName $VirtualPath $PhysicalPath = Resolve-CFullPath -Path $PhysicalPath if( -not (Test-Path $PhysicalPath -PathType Container) ) { Write-Verbose ('IIS://{0}: creating physical path {1}' -f $iisAppPath,$PhysicalPath) $null = New-Item $PhysicalPath -ItemType Directory } $appPoolDesc = '' if( $AppPoolName ) { $appPoolDesc = '; appPool: {0}' -f $AppPoolName } $apps = $site.GetCollection() $appPath = "/{0}" -f $VirtualPath $app = Get-CIisApplication -SiteName $SiteName -VirtualPath $VirtualPath $modified = $false if( -not $app ) { Write-Verbose ('IIS://{0}: creating application' -f $iisAppPath) $app = $apps.CreateElement('application') | Add-IisServerManagerMember -ServerManager $site.ServerManager -PassThru $app['path'] = $appPath $apps.Add( $app ) | Out-Null $modified = $true } if( $app['path'] -ne $appPath ) { $app['path'] = $appPath $modified = $true } if( $AppPoolName -and $app['applicationPool'] -ne $AppPoolName) { $app['applicationPool'] = $AppPoolName $modified = $true } $vdir = $null if( $app | Get-Member 'VirtualDirectories' ) { $vdir = $app.VirtualDirectories | Where-Object { $_.Path -eq '/' } } if( -not $vdir ) { Write-Verbose ('IIS://{0}: creating virtual directory' -f $iisAppPath) $vdirs = $app.GetCollection() $vdir = $vdirs.CreateElement('virtualDirectory') $vdir['path'] = '/' $vdirs.Add( $vdir ) | Out-Null $modified = $true } if( $vdir['physicalPath'] -ne $PhysicalPath ) { Write-Verbose ('IIS://{0}: setting physical path {1}' -f $iisAppPath,$PhysicalPath) $vdir['physicalPath'] = $PhysicalPath $modified = $true } if( $modified ) { Write-Verbose ('IIS://{0}: committing changes' -f $iisAppPath) $app.CommitChanges() } if( $PassThru ) { return Get-CIisApplication -SiteName $SiteName -VirtualPath $VirtualPath } } function Install-CIisAppPool { <# .SYNOPSIS Creates a new app pool. .DESCRIPTION By default, creates a 64-bit app pool running as the `ApplicationPoolIdentity` service account under .NET v4.0 with an integrated pipeline. You can control which version of .NET is used to run an app pool with the `ManagedRuntimeVersion` parameter: versions `v1.0`, `v1.1`, `v2.0`, and `v4.0` are supported. Use an empty string if you're running .NET Core or to set the .NET framework version to `No Managed Code`. To run an application pool using the classic pipeline mode, set the `ClassicPipelineMode` switch. To run an app pool using the 32-bit version of the .NET framework, set the `Enable32BitApps` switch. An app pool can run as several built-in service accounts, by passing one of them as the value of the `ServiceAccount` parameter: `NetworkService`, `LocalService`, or `LocalSystem` The default is `ApplicationPoolIdentity`, which causes IIS to create and use a custom local account with the name of the app pool. See [Application Pool Identities](http://learn.iis.net/page.aspx/624/application-pool-identities/) for more information. To run the app pool as a specific user, pass the credentials with the `Credential` parameter. (In some versions of Carbon, there is no `Credential` parameter, so use the `UserName` and `Password` parameters instead.) The user will be granted the `SeBatchLogonRight` privilege. If an existing app pool exists with name `Name`, it's settings are modified. The app pool isn't deleted. (You can't delete an app pool if there are any websites using it, that's why.) By default, this function will create an application pool running the latest version of .NET, with an integrated pipeline, as the NetworkService account. Beginning with Carbon 2.0, the `PassThru` switch will cause this function to return a `Microsoft.Web.Administration.ApplicationPool` object for the created/updated application pool. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .LINK http://learn.iis.net/page.aspx/624/application-pool-identities/ .LINK New-CCredential .EXAMPLE Install-CIisAppPool -Name Cyberdyne -ServiceAccount NetworkService Creates a new Cyberdyne application pool, running as NetworkService, using .NET 4.0 and an integrated pipeline. If the Cyberdyne app pool already exists, it is modified to run as NetworkService, to use .NET 4.0 and to use an integrated pipeline. .EXAMPLE Install-CIisAppPool -Name Cyberdyne -ServiceAccount NetworkService -Enable32BitApps -ClassicPipelineMode Creates or sets the Cyberdyne app pool to run as NetworkService, in 32-bit mode (i.e. 32-bit applications are enabled), using the classic IIS request pipeline. .EXAMPLE Install-CIisAppPool -Name Cyberdyne -Credential $charlieBrownCredential Creates or sets the Cyberdyne app pool to run as the `PEANUTS\charliebrown` domain account, under .NET 4.0, with an integrated pipeline. #> [CmdletBinding(DefaultParameterSetName='AsServiceAccount')] [OutputType([Microsoft.Web.Administration.ApplicationPool])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams","")] param( [Parameter(Mandatory=$true)] [string] # The app pool's name. $Name, [string] [ValidateSet('v1.0','v1.1','v2.0','v4.0','')] # The managed .NET runtime version to use. Default is 'v4.0'. Valid values are `v1.0`, `v1.1`, `v2.0`, or `v4.0`. Use an empty string if you're using .NET Core or to set the .NET framework version to `No Managed Code`. $ManagedRuntimeVersion = 'v4.0', [int] [ValidateScript({$_ -gt 0})] #Idle Timeout value in minutes. Default is 0. $IdleTimeout = 0, [Switch] # Use the classic pipeline mode, i.e. don't use an integrated pipeline. $ClassicPipelineMode, [Switch] # Enable 32-bit applications. $Enable32BitApps, [string] [ValidateSet('NetworkService','LocalService','LocalSystem')] # Run the app pool under the given local service account. Valid values are `NetworkService`, `LocalService`, and `LocalSystem`. The default is `ApplicationPoolIdentity`, which causes IIS to create a custom local user account for the app pool's identity. The default is `ApplicationPoolIdentity`. $ServiceAccount, [Parameter(ParameterSetName='AsSpecificUser',Mandatory=$true,DontShow=$true)] [string] # OBSOLETE. The `UserName` parameter will be removed in a future major version of Carbon. Use the `Credential` parameter instead. $UserName, [Parameter(ParameterSetName='AsSpecificUser',Mandatory=$true,DontShow=$true)] # OBSOLETE. The `Password` parameter will be removed in a future major version of Carbon. Use the `Credential` parameter instead. $Password, [Parameter(ParameterSetName='AsSpecificUserWithCredential',Mandatory=$true)] [pscredential] # The credential to use to run the app pool. # # The `Credential` parameter is new in Carbon 2.0. $Credential, [Switch] # Return an object representing the app pool. $PassThru ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState if( $PSCmdlet.ParameterSetName -like 'AsSpecificUser*' ) { if( $PSCmdlet.ParameterSetName -notlike '*WithCredential' ) { Write-CWarningOnce ('`Install-CIisAppPool` function''s `UserName` and `Password` parameters are obsolete and will be removed in a future major version of Carbon. Please use the `Credential` parameter instead.') $Credential = New-CCredential -UserName $UserName -Password $Password } } if( $PSCmdlet.ParameterSetName -eq 'AsSpecificUser' -and -not (Test-CIdentity -Name $Credential.UserName) ) { Write-Error ('Identity {0} not found. {0} IIS websites and applications assigned to this app pool won''t run.' -f $Credential.UserName,$Name) } if( -not (Test-CIisAppPool -Name $Name) ) { Write-Verbose ('Creating IIS Application Pool {0}' -f $Name) $mgr = New-Object 'Microsoft.Web.Administration.ServerManager' $appPool = $mgr.ApplicationPools.Add($Name) $mgr.CommitChanges() } $appPool = Get-CIisAppPool -Name $Name $updated = $false if( $appPool.ManagedRuntimeVersion -ne $ManagedRuntimeVersion ) { Write-Verbose ('IIS Application Pool {0}: Setting ManagedRuntimeVersion = {0}' -f $Name,$ManagedRuntimeVersion) $appPool.ManagedRuntimeVersion = $ManagedRuntimeVersion $updated = $true } $pipelineMode = [Microsoft.Web.Administration.ManagedPipelineMode]::Integrated if( $ClassicPipelineMode ) { $pipelineMode = [Microsoft.Web.Administration.ManagedPipelineMode]::Classic } if( $appPool.ManagedPipelineMode -ne $pipelineMode ) { Write-Verbose ('IIS Application Pool {0}: Setting ManagedPipelineMode = {0}' -f $Name,$pipelineMode) $appPool.ManagedPipelineMode = $pipelineMode $updated = $true } $idleTimeoutTimeSpan = New-TimeSpan -Minutes $IdleTimeout if( $appPool.ProcessModel.IdleTimeout -ne $idleTimeoutTimeSpan ) { Write-Verbose ('IIS Application Pool {0}: Setting idle timeout = {0}' -f $Name,$idleTimeoutTimeSpan) $appPool.ProcessModel.IdleTimeout = $idleTimeoutTimeSpan $updated = $true } if( $appPool.Enable32BitAppOnWin64 -ne ([bool]$Enable32BitApps) ) { Write-Verbose ('IIS Application Pool {0}: Setting Enable32BitAppOnWin64 = {0}' -f $Name,$Enable32BitApps) $appPool.Enable32BitAppOnWin64 = $Enable32BitApps $updated = $true } if( $PSCmdlet.ParameterSetName -like 'AsSpecificUser*' ) { if( $appPool.ProcessModel.UserName -ne $Credential.UserName ) { Write-Verbose ('IIS Application Pool {0}: Setting username = {0}' -f $Name,$Credential.UserName) $appPool.ProcessModel.IdentityType = [Microsoft.Web.Administration.ProcessModelIdentityType]::SpecificUser $appPool.ProcessModel.UserName = $Credential.UserName $appPool.ProcessModel.Password = $Credential.GetNetworkCredential().Password # On Windows Server 2008 R2, custom app pool users need this privilege. Grant-CPrivilege -Identity $Credential.UserName -Privilege SeBatchLogonRight -Verbose:$VerbosePreference $updated = $true } } else { $identityType = [Microsoft.Web.Administration.ProcessModelIdentityType]::ApplicationPoolIdentity if( $ServiceAccount ) { $identityType = $ServiceAccount } if( $appPool.ProcessModel.IdentityType -ne $identityType ) { Write-Verbose ('IIS Application Pool {0}: Setting IdentityType = {0}' -f $Name,$identityType) $appPool.ProcessModel.IdentityType = $identityType $updated = $true } } if( $updated ) { $appPool.CommitChanges() } # TODO: Pull this out into its own Start-IisAppPool function. I think. $appPool = Get-CIisAppPool -Name $Name if($appPool -and $appPool.state -eq [Microsoft.Web.Administration.ObjectState]::Stopped ) { try { $appPool.Start() } catch { Write-Error ('Failed to start {0} app pool: {1}' -f $Name,$_.Exception.Message) } } if( $PassThru ) { $appPool } } function Install-CIisVirtualDirectory { <# .SYNOPSIS Installs a virtual directory. .DESCRIPTION The `Install-CIisVirtualDirectory` function creates a virtual directory under website `SiteName` at `/VirtualPath`, serving files out of `PhysicalPath`. If a virtual directory at `VirtualPath` already exists, it is updated in palce. (Before Carbon 2.0, the virtual directory was deleted before installation.) Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Install-CIisVirtualDirectory -SiteName 'Peanuts' -VirtualPath 'DogHouse' -PhysicalPath C:\Peanuts\Doghouse Creates a /DogHouse virtual directory, which serves files from the C:\Peanuts\Doghouse directory. If the Peanuts website responds to hostname `peanuts.com`, the virtual directory is accessible at `peanuts.com/DogHouse`. .EXAMPLE Install-CIisVirtualDirectory -SiteName 'Peanuts' -VirtualPath 'Brown/Snoopy/DogHouse' -PhysicalPath C:\Peanuts\DogHouse Creates a DogHouse virtual directory under the `Peanuts` website at `/Brown/Snoopy/DogHouse` serving files out of the `C:\Peanuts\DogHouse` directory. If the Peanuts website responds to hostname `peanuts.com`, the virtual directory is accessible at `peanuts.com/Brown/Snoopy/DogHouse`. #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string] # The site where the virtual directory should be created. $SiteName, [Parameter(Mandatory=$true)] [Alias('Name')] [string] # The name of the virtual directory. This can contain multiple directory segments for virtual directories not at the root of the website, e.g. First/Second/VirtualDirectory. $VirtualPath, [Parameter(Mandatory=$true)] [Alias('Path')] [string] # The file system path to the virtual directory. $PhysicalPath, [Switch] # Deletes the virttual directory before installation, if it exists. Preserves default beheaviro in Carbon before 2.0. # # *Does not* delete custom configuration for the virtual directory, just the virtual directory. If you've customized the location of the virtual directory, those customizations will remain in place. # # The `Force` switch is new in Carbon 2.0. $Force ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $site = Get-CIisWebsite -Name $SiteName [Microsoft.Web.Administration.Application]$rootApp = $site.Applications | Where-Object { $_.Path -eq '/' } if( -not $rootApp ) { Write-Error ('Default website application not found.') return } $PhysicalPath = Resolve-CFullPath -Path $PhysicalPath $VirtualPath = $VirtualPath.Trim('/') $VirtualPath = '/{0}' -f $VirtualPath $vdir = $rootApp.VirtualDirectories | Where-Object { $_.Path -eq $VirtualPath } if( $Force -and $vdir ) { Write-IisVerbose $SiteName -VirtualPath $VirtualPath 'REMOVE' '' '' $rootApp.VirtualDirectories.Remove($vdir) $site.CommitChanges() $vdir = $null $site = Get-CIisWebsite -Name $SiteName $rootApp = $site.Applications | Where-Object { $_.Path -eq '/' } } $modified = $false if( -not $vdir ) { [Microsoft.Web.Administration.ConfigurationElementCollection]$vdirs = $rootApp.GetCollection() $vdir = $vdirs.CreateElement('virtualDirectory') Write-IisVerbose $SiteName -VirtualPath $VirtualPath 'VirtualPath' '' $VirtualPath $vdir['path'] = $VirtualPath [void]$vdirs.Add( $vdir ) $modified = $true } if( $vdir['physicalPath'] -ne $PhysicalPath ) { Write-IisVerbose $SiteName -VirtualPath $VirtualPath 'PhysicalPath' $vdir['physicalPath'] $PhysicalPath $vdir['physicalPath'] = $PhysicalPath $modified = $true } if( $modified ) { $site.CommitChanges() } } function Install-CIisWebsite { <# .SYNOPSIS Installs a website. .DESCRIPTION `Install-CIisWebsite` installs an IIS website. Anonymous authentication is enabled, and the anonymous user is set to the website's application pool identity. Before Carbon 2.0, if a website already existed, it was deleted and re-created. Beginning with Carbon 2.0, existing websites are modified in place. If you don't set the website's app pool, IIS will pick one for you (usually `DefaultAppPool`), and `Install-CIisWebsite` will never manage the app pool for you (i.e. if someone changes it manually, this function won't set it back to the default). We recommend always supplying an app pool name, even if it is `DefaultAppPool`. By default, the site listens on (i.e. is bound to) all IP addresses on port 80 (binding `http/*:80:`). Set custom bindings with the `Bindings` argument. Multiple bindings are allowed. Each binding must be in this format (in BNF): <PROTOCOL> '/' <IP_ADDRESS> ':' <PORT> ':' [ <HOSTNAME> ] * `PROTOCOL` is one of `http` or `https`. * `IP_ADDRESS` is a literal IP address, or `*` for all of the computer's IP addresses. This function does not validate if `IPADDRESS` is actually in use on the computer. * `PORT` is the port to listen on. * `HOSTNAME` is the website's hostname, for name-based hosting. If no hostname is being used, leave off the `HOSTNAME` part. Valid bindings are: * http/*:80: * https/10.2.3.4:443: * http/*:80:example.com ## Troubleshooting In some situations, when you add a website to an application pool that another website/application is part of, the new website will fail to load in a browser with a 500 error saying `Failed to map the path '/'.`. We've been unable to track down the root cause. The solution is to recycle the app pool, e.g. `(Get-CIisAppPool -Name 'AppPoolName').Recycle()`. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .LINK Get-CIisWebsite .LINK Uninstall-CIisWebsite .EXAMPLE Install-CIisWebsite -Name 'Peanuts' -PhysicalPath C:\Peanuts.com Creates a website named `Peanuts` serving files out of the `C:\Peanuts.com` directory. The website listens on all the computer's IP addresses on port 80. .EXAMPLE Install-CIisWebsite -Name 'Peanuts' -PhysicalPath C:\Peanuts.com -Binding 'http/*:80:peanuts.com' Creates a website named `Peanuts` which uses name-based hosting to respond to all requests to any of the machine's IP addresses for the `peanuts.com` domain. .EXAMPLE Install-CIisWebsite -Name 'Peanuts' -PhysicalPath C:\Peanuts.com -AppPoolName 'PeanutsAppPool' Creates a website named `Peanuts` that runs under the `PeanutsAppPool` app pool #> [CmdletBinding()] [OutputType([Microsoft.Web.Administration.Site])] param( [Parameter(Position=0,Mandatory=$true)] [string] # The name of the website. $Name, [Parameter(Position=1,Mandatory=$true)] [Alias('Path')] [string] # The physical path (i.e. on the file system) to the website. If it doesn't exist, it will be created for you. $PhysicalPath, [Parameter(Position=2)] [Alias('Bindings')] [string[]] # The site's network bindings. Default is `http/*:80:`. Bindings should be specified in protocol/IPAddress:Port:Hostname format. # # * Protocol should be http or https. # * IPAddress can be a literal IP address or `*`, which means all of the computer's IP addresses. This function does not validate if `IPAddress` is actually in use on this computer. # * Leave hostname blank for non-named websites. $Binding = @('http/*:80:'), [string] # The name of the app pool under which the website runs. The app pool must exist. If not provided, IIS picks one for you. No whammy, no whammy! It is recommended that you create an app pool for each website. That's what the IIS Manager does. $AppPoolName, [int] # The site's IIS ID. IIS picks one for you automatically if you don't supply one. Must be greater than 0. # # The `SiteID` switch is new in Carbon 2.0. $SiteID, [Switch] # Return a `Microsoft.Web.Administration.Site` object for the website. # # The `PassThru` switch is new in Carbon 2.0. $PassThru, [Switch] # Deletes the website before installation, if it exists. Preserves default beheaviro in Carbon before 2.0. # # The `Force` switch is new in Carbon 2.0. $Force ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $bindingRegex = '^(?<Protocol>https?):?//?(?<IPAddress>\*|[\d\.]+):(?<Port>\d+):?(?<HostName>.*)$' filter ConvertTo-Binding { param( [Parameter(ValueFromPipeline=$true,Mandatory=$true)] [string] $InputObject ) Set-StrictMode -Version 'Latest' $InputObject -match $bindingRegex | Out-Null [pscustomobject]@{ 'Protocol' = $Matches['Protocol']; 'IPAddress' = $Matches['IPAddress']; 'Port' = $Matches['Port']; 'HostName' = $Matches['HostName']; } | Add-Member -MemberType ScriptProperty -Name 'BindingInformation' -Value { '{0}:{1}:{2}' -f $this.IPAddress,$this.Port,$this.HostName } -PassThru } $PhysicalPath = Resolve-CFullPath -Path $PhysicalPath if( -not (Test-Path $PhysicalPath -PathType Container) ) { New-Item $PhysicalPath -ItemType Directory | Out-String | Write-Verbose } $invalidBindings = $Binding | Where-Object { $_ -notmatch $bindingRegex } if( $invalidBindings ) { $invalidBindings = $invalidBindings -join "`n`t" $errorMsg = "The following bindings are invalid. The correct format is protocol/IPAddress:Port:Hostname. Protocol and IP address must be separted by a single slash, not ://. IP address can be * for all IP addresses. Hostname is optional. If hostname is not provided, the binding must end with a colon.`n`t{0}" -f $invalidBindings Write-Error $errorMsg return } if( $Force ) { Uninstall-CIisWebsite -Name $Name } [Microsoft.Web.Administration.Site]$site = $null $modified = $false if( -not (Test-CIisWebsite -Name $Name) ) { Write-Verbose -Message ('Creating website ''{0}'' ({1}).' -f $Name,$PhysicalPath) $firstBinding = $Binding | Select-Object -First 1 | ConvertTo-Binding $mgr = New-Object 'Microsoft.Web.Administration.ServerManager' $site = $mgr.Sites.Add( $Name, $firstBinding.Protocol, $firstBinding.BindingInformation, $PhysicalPath ) $mgr.CommitChanges() } $site = Get-CIisWebsite -Name $Name $expectedBindings = New-Object 'Collections.Generic.Hashset[string]' $Binding | ConvertTo-Binding | ForEach-Object { [void]$expectedBindings.Add( ('{0}/{1}' -f $_.Protocol,$_.BindingInformation) ) } $bindingsToRemove = $site.Bindings | Where-Object { -not $expectedBindings.Contains( ('{0}/{1}' -f $_.Protocol,$_.BindingInformation ) ) } foreach( $bindingToRemove in $bindingsToRemove ) { Write-IisVerbose $Name 'Binding' ('{0}/{1}' -f $bindingToRemove.Protocol,$bindingToRemove.BindingInformation) $site.Bindings.Remove( $bindingToRemove ) $modified = $true } $existingBindings = New-Object 'Collections.Generic.Hashset[string]' $site.Bindings | ForEach-Object { [void]$existingBindings.Add( ('{0}/{1}' -f $_.Protocol,$_.BindingInformation) ) } $bindingsToAdd = $Binding | ConvertTo-Binding | Where-Object { -not $existingBindings.Contains( ('{0}/{1}' -f $_.Protocol,$_.BindingInformation ) ) } foreach( $bindingToAdd in $bindingsToAdd ) { Write-IisVerbose $Name 'Binding' '' ('{0}/{1}' -f $bindingToAdd.Protocol,$bindingToAdd.BindingInformation) $site.Bindings.Add( $bindingToAdd.BindingInformation, $bindingToAdd.Protocol ) | Out-Null $modified = $true } [Microsoft.Web.Administration.Application]$rootApp = $null if( $site.Applications.Count -eq 0 ) { $rootApp = $site.Applications.Add("/", $PhysicalPath) $modifed = $true } else { $rootApp = $site.Applications | Where-Object { $_.Path -eq '/' } } if( $site.PhysicalPath -ne $PhysicalPath ) { Write-IisVerbose $Name 'PhysicalPath' $site.PhysicalPath $PhysicalPath [Microsoft.Web.Administration.VirtualDirectory]$vdir = $rootApp.VirtualDirectories | Where-Object { $_.Path -eq '/' } $vdir.PhysicalPath = $PhysicalPath $modified = $true } if( $AppPoolName ) { if( $rootApp.ApplicationPoolName -ne $AppPoolName ) { Write-IisVerbose $Name 'AppPool' $rootApp.ApplicationPoolName $AppPoolName $rootApp.ApplicationPoolName = $AppPoolName $modified = $true } } if( $modified ) { $site.CommitChanges() } if( $SiteID ) { Set-CIisWebsiteID -SiteName $Name -ID $SiteID } # Make sure anonymous authentication is enabled and uses the application pool identity $security = Get-CIisSecurityAuthentication -SiteName $Name -VirtualPath '/' -Anonymous Write-IisVerbose $Name 'Anonymous Authentication UserName' $security['username'] '' $security['username'] = '' $security.CommitChanges() # Now, wait until site is actually running $tries = 0 $website = $null do { $website = Get-CIisWebsite -SiteName $Name $tries += 1 if($website.State -ne 'Unknown') { break } else { Start-Sleep -Milliseconds 100 } } while( $tries -lt 100 ) if( $PassThru ) { return $website } } function Join-CIisVirtualPath { <# .SYNOPSIS Combines a path and a child path for an IIS website, application, virtual directory into a single path. .DESCRIPTION Removes extra slashes. Converts backward slashes to forward slashes. Relative portions are not removed. Sorry. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Join-CIisVirtualPath 'SiteName' 'Virtual/Path' Demonstrates how to join two IIS paths together. REturns `SiteName/Virtual/Path`. #> [CmdletBinding()] param( [Parameter(Mandatory=$true,Position=0)] [string] # The parent path. $Path, [Parameter(Position=1)] [string] $ChildPath ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState if( $ChildPath ) { $Path = Join-Path -Path $Path -ChildPath $ChildPath } $Path.Replace('\', '/').Trim('/') } function Lock-CIisConfigurationSection { <# .SYNOPSIS Locks an IIS configuration section so that it can't be modified/overridden by individual websites. .DESCRIPTION Locks configuration sections globally so they can't be modified by individual websites. For a list of section paths, run C:\Windows\System32\inetsrv\appcmd.exe lock config /section:? Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Lock-CIisConfigurationSection -SectionPath 'system.webServer/security/authentication/basicAuthentication' Locks the `basicAuthentication` configuration so that sites can't override/modify those settings. #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] [string[]] # The path to the section to lock. For a list of sections, run # # C:\Windows\System32\inetsrv\appcmd.exe unlock config /section:? $SectionPath ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $SectionPath | ForEach-Object { $section = Get-CIisConfigurationSection -SectionPath $_ $section.OverrideMode = 'Deny' if( $pscmdlet.ShouldProcess( $_, 'locking IIS configuration section' ) ) { $section.CommitChanges() } } } function Remove-CIisMimeMap { <# .SYNOPSIS Removes a file extension to MIME type map from an entire web server. .DESCRIPTION IIS won't serve static files unless they have an entry in the MIME map. Use this function toremvoe an existing MIME map entry. If one doesn't exist, nothing happens. Not even an error. If a specific website has the file extension in its MIME map, that site will continue to serve files with those extensions. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .LINK Get-CIisMimeMap .LINK Set-CIisMimeMap .EXAMPLE Remove-CIisMimeMap -FileExtension '.m4v' -MimeType 'video/x-m4v' Removes the `.m4v` file extension so that IIS will no longer serve those files. #> [CmdletBinding(DefaultParameterSetName='ForWebServer')] param( [Parameter(Mandatory=$true,ParameterSetName='ForWebsite')] [string] # The name of the website whose MIME type to set. $SiteName, [Parameter(ParameterSetName='ForWebsite')] [string] # The optional site path whose configuration should be returned. $VirtualPath = '', [Parameter(Mandatory=$true)] [string] # The file extension whose MIME map to remove. $FileExtension ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $getIisConfigSectionParams = @{ } if( $PSCmdlet.ParameterSetName -eq 'ForWebsite' ) { $getIisConfigSectionParams['SiteName'] = $SiteName $getIisConfigSectionParams['VirtualPath'] = $VirtualPath } $staticContent = Get-CIisConfigurationSection -SectionPath 'system.webServer/staticContent' @getIisConfigSectionParams $mimeMapCollection = $staticContent.GetCollection() $mimeMapToRemove = $mimeMapCollection | Where-Object { $_['fileExtension'] -eq $FileExtension } if( -not $mimeMapToRemove ) { Write-Verbose ('MIME map for file extension {0} not found.' -f $FileExtension) return } $mimeMapCollection.Remove( $mimeMapToRemove ) $staticContent.CommitChanges() } function Set-CIisHttpHeader { <# .SYNOPSIS Sets an HTTP header for a website or a directory under a website. .DESCRIPTION If the HTTP header doesn't exist, it is created. If a header exists, its value is replaced. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .LINK Get-CIisHttpHeader .EXAMPLE Set-CIisHttpHeader -SiteName 'SopwithCamel' -Name 'X-Flown-By' -Value 'Snoopy' Sets or creates the `SopwithCamel` website's `X-Flown-By` HTTP header to the value `Snoopy`. .EXAMPLE Set-CIisHttpHeader -SiteName 'SopwithCamel' -VirtualPath 'Engine' -Name 'X-Powered-By' -Value 'Root Beer' Sets or creates the `SopwithCamel` website's `Engine` sub-directory's `X-Powered-By` HTTP header to the value `Root Beer`. #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] [string] # The name of the website where the HTTP header should be set/created. $SiteName, [Alias('Path')] [string] # The optional path under `SiteName` where the HTTP header should be set/created. $VirtualPath = '', [Parameter(Mandatory=$true)] [string] # The name of the HTTP header. $Name, [Parameter(Mandatory=$true)] [string] # The value of the HTTP header. $Value ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $httpProtocol = Get-CIisConfigurationSection -SiteName $SiteName ` -VirtualPath $VirtualPath ` -SectionPath 'system.webServer/httpProtocol' $headers = $httpProtocol.GetCollection('customHeaders') $header = $headers | Where-Object { $_['name'] -eq $Name } if( $header ) { $action = 'setting' $header['name'] = $Name $header['value'] = $Value } else { $action = 'adding' $addElement = $headers.CreateElement( 'add' ) $addElement['name'] = $Name $addElement['value'] = $Value [void] $headers.Add( $addElement ) } $fullPath = Join-CIisVirtualPath $SiteName $VirtualPath if( $pscmdlet.ShouldProcess( $fullPath, ('{0} HTTP header {1}' -f $action,$Name) ) ) { $httpProtocol.CommitChanges() } } function Set-CIisHttpRedirect { <# .SYNOPSIS Turns on HTTP redirect for all or part of a website. .DESCRIPTION Configures all or part of a website to redirect all requests to another website/URL. By default, it operates on a specific website. To configure a directory under a website, set `VirtualPath` to the virtual path of that directory. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .LINK http://www.iis.net/configreference/system.webserver/httpredirect#005 .LINK http://technet.microsoft.com/en-us/library/cc732969(v=WS.10).aspx .EXAMPLE Set-CIisHttpRedirect -SiteName Peanuts -Destination 'http://new.peanuts.com' Redirects all requests to the `Peanuts` website to `http://new.peanuts.com`. .EXAMPLE Set-CIisHttpRedirect -SiteName Peanuts -VirtualPath Snoopy/DogHouse -Destination 'http://new.peanuts.com' Redirects all requests to the `/Snoopy/DogHouse` path on the `Peanuts` website to `http://new.peanuts.com`. .EXAMPLE Set-CIisHttpRedirect -SiteName Peanuts -Destination 'http://new.peanuts.com' -StatusCode 'Temporary' Redirects all requests to the `Peanuts` website to `http://new.peanuts.com` with a temporary HTTP status code. You can also specify `Found` (HTTP 302), or `Permanent` (HTTP 301). #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] [string] # The site where the redirection should be setup. $SiteName, [Alias('Path')] [string] # The optional path where redirection should be setup. $VirtualPath = '', [Parameter(Mandatory=$true)] [string] # The destination to redirect to. $Destination, [Carbon.Iis.HttpResponseStatus] # The HTTP status code to use. Default is `Found`. Should be one of `Found` (HTTP 302), `Permanent` (HTTP 301), or `Temporary` (HTTP 307). [Alias('StatusCode')] $HttpResponseStatus = [Carbon.Iis.HttpResponseStatus]::Found, [Switch] # Redirect all requests to exact destination (instead of relative to destination). I have no idea what this means. [Maybe TechNet can help.](http://technet.microsoft.com/en-us/library/cc732969(v=WS.10).aspx) $ExactDestination, [Switch] # Only redirect requests to content in site and/or path, but nothing below it. I have no idea what this means. [Maybe TechNet can help.](http://technet.microsoft.com/en-us/library/cc732969(v=WS.10).aspx) $ChildOnly ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $settings = Get-CIisHttpRedirect -SiteName $SiteName -Path $VirtualPath $settings.Enabled = $true $settings.Destination = $destination $settings.HttpResponseStatus = $HttpResponseStatus $settings.ExactDestination = $ExactDestination $settings.ChildOnly = $ChildOnly if( $pscmdlet.ShouldProcess( (Join-CIisVirtualPath $SiteName $VirtualPath), "set HTTP redirect settings" ) ) { $settings.CommitChanges() } } function Set-CIisMimeMap { <# .SYNOPSIS Creates or sets a file extension to MIME type map for an entire web server. .DESCRIPTION IIS won't serve static files unless they have an entry in the MIME map. Use this function to create/update a MIME map entry. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .LINK Get-CIisMimeMap .LINK Remove-CIisMimeMap .EXAMPLE Set-CIisMimeMap -FileExtension '.m4v' -MimeType 'video/x-m4v' Adds a MIME map so that IIS will serve `.m4v` files as `video/x-m4v`. #> [CmdletBinding(SupportsShouldProcess=$true,DefaultParameterSetName='ForWebServer')] param( [Parameter(Mandatory=$true,ParameterSetName='ForWebsite')] [string] # The name of the website whose MIME type to set. $SiteName, [Parameter(ParameterSetName='ForWebsite')] [string] # The optional site path whose configuration should be returned. $VirtualPath = '', [Parameter(Mandatory=$true)] [string] # The file extension to set. $FileExtension, [Parameter(Mandatory=$true)] [string] # The MIME type to serve the files as. $MimeType ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $getIisConfigSectionParams = @{ } if( $PSCmdlet.ParameterSetName -eq 'ForWebsite' ) { $getIisConfigSectionParams['SiteName'] = $SiteName $getIisConfigSectionParams['VirtualPath'] = $VirtualPath } $staticContent = Get-CIisConfigurationSection -SectionPath 'system.webServer/staticContent' @getIisConfigSectionParams $mimeMapCollection = $staticContent.GetCollection() $mimeMap = $mimeMapCollection | Where-Object { $_['fileExtension'] -eq $FileExtension } if( $mimeMap ) { $action = 'setting' $mimeMap['fileExtension'] = $FileExtension $mimeMap['mimeType'] = $MimeType } else { $action = 'adding' $mimeMap = $mimeMapCollection.CreateElement("mimeMap"); $mimeMap["fileExtension"] = $FileExtension $mimeMap["mimeType"] = $MimeType [void] $mimeMapCollection.Add($mimeMap) } if( $PSCmdlet.ShouldProcess( 'IIS web server', ('{0} MIME map {1} -> {2}' -f $action,$FileExtension,$MimeType) ) ) { $staticContent.CommitChanges() } } function Set-CIisWebsiteID { <# .SYNOPSIS Sets a website's ID to an explicit number. .DESCRIPTION IIS handles assigning websites individual IDs. This method will assign a website explicit ID you manage (e.g. to support session sharing in a web server farm). If another site already exists with that ID, you'll get an error. When you change a website's ID, IIS will stop the site, but not start the site after saving the ID change. This function waits until the site's ID is changed, and then will start the website. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Set-CIisWebsiteID -SiteName Holodeck -ID 483 Sets the `Holodeck` website's ID to `483`. #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] [string] # The website name. $SiteName, [Parameter(Mandatory=$true)] [int] # The website's new ID. $ID ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState if( -not (Test-CIisWebsite -Name $SiteName) ) { Write-Error ('Website {0} not found.' -f $SiteName) return } $websiteWithID = Get-CIisWebsite | Where-Object { $_.ID -eq $ID -and $_.Name -ne $SiteName } if( $websiteWithID ) { Write-Error -Message ('ID {0} already in use for website {1}.' -f $ID,$SiteName) -Category ResourceExists return } $website = Get-CIisWebsite -SiteName $SiteName $startWhenDone = $false if( $website.ID -ne $ID ) { if( $PSCmdlet.ShouldProcess( ('website {0}' -f $SiteName), ('set site ID to {0}' -f $ID) ) ) { $startWhenDone = ($website.State -eq 'Started') $website.ID = $ID $website.CommitChanges() } } if( $PSBoundParameters.ContainsKey('WhatIf') ) { return } # Make sure the website's ID gets updated $website = $null $maxTries = 100 $numTries = 0 do { Start-Sleep -Milliseconds 100 $website = Get-CIisWebsite -SiteName $SiteName if( $website -and $website.ID -eq $ID ) { break } $numTries++ } while( $numTries -lt $maxTries ) if( -not $website -or $website.ID -ne $ID ) { Write-Error ('IIS:/{0}: site ID hasn''t changed to {1} after waiting 10 seconds. Please check IIS configuration.' -f $SiteName,$ID) } if( -not $startWhenDone ) { return } # Now, start the website. $numTries = 0 do { # Sometimes, the website is invalid and Start() throws an exception. try { if( $website ) { $null = $website.Start() } } catch { $website = $null } Start-Sleep -Milliseconds 100 $website = Get-CIisWebsite -SiteName $SiteName if( $website -and $website.State -eq 'Started' ) { break } $numTries++ } while( $numTries -lt $maxTries ) if( -not $website -or $website.State -ne 'Started' ) { Write-Error ('IIS:/{0}: failed to start website after setting ID to {1}' -f $SiteName,$ID) } } function Set-CIisWebsiteSslCertificate { <# .SYNOPSIS Sets a website's SSL certificate. .DESCRIPTION SSL won't work on a website if an SSL certificate hasn't been bound to all the IP addresses it's listening on. This function binds a certificate to all a website's IP addresses. Make sure you call this method *after* you create a website's bindings. Any previous SSL bindings on those IP addresses are deleted. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Set-CIisWebsiteSslCertificate -SiteName Peanuts -Thumbprint 'a909502dd82ae41433e6f83886b00d4277a32a7b' -ApplicationID $PeanutsAppID Binds the certificate whose thumbprint is `a909502dd82ae41433e6f83886b00d4277a32a7b` to the `Peanuts` website. It's a good idea to re-use the same GUID for each distinct application. #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] [string] # The name of the website whose SSL certificate is being set. $SiteName, [Parameter(Mandatory=$true)] [string] # The thumbprint of the SSL certificate to use. $Thumbprint, [Parameter(Mandatory=$true)] [Guid] # A GUID that uniquely identifies this website. Create your own. $ApplicationID ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $site = Get-CIisWebsite -SiteName $SiteName if( -not $site ) { Write-Error "Unable to find website '$SiteName'." return } $site.Bindings | Where-Object { $_.Protocol -eq 'https' } | ForEach-Object { $installArgs = @{ } if( $_.Endpoint.Address -ne '0.0.0.0' ) { $installArgs.IPAddress = $_.Endpoint.Address.ToString() } if( $_.Endpoint.Port -ne '*' ) { $installArgs.Port = $_.Endpoint.Port } Set-CSslCertificateBinding @installArgs -ApplicationID $ApplicationID -Thumbprint $Thumbprint } } function Set-CIisWindowsAuthentication { <# .SYNOPSIS Configures the settings for Windows authentication. .DESCRIPTION By default, configures Windows authentication on a website. You can configure Windows authentication at a specific path under a website by passing the virtual path (*not* the physical path) to that directory. The changes only take effect if Windows authentication is enabled (see `Enable-CIisSecurityAuthentication`). Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .LINK http://blogs.msdn.com/b/webtopics/archive/2009/01/19/service-principal-name-spn-checklist-for-kerberos-authentication-with-iis-7-0.aspx .LINK Disable-CIisSecurityAuthentication .LINK Enable-CIisSecurityAuthentication .EXAMPLE Set-CIisWindowsAuthentication -SiteName Peanuts Configures Windows authentication on the `Peanuts` site to use kernel mode. .EXAMPLE Set-CIisWindowsAuthentication -SiteName Peanuts -VirtualPath Snoopy/DogHouse -DisableKernelMode Configures Windows authentication on the `Doghouse` directory of the `Peanuts` site to not use kernel mode. #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] [string] # The site where Windows authentication should be set. $SiteName, [Alias('Path')] [string] # The optional path where Windows authentication should be set. $VirtualPath = '', [Switch] # Turn on kernel mode. Default is false. [More information about Kerndel Mode authentication.](http://blogs.msdn.com/b/webtopics/archive/2009/01/19/service-principal-name-spn-checklist-for-kerberos-authentication-with-iis-7-0.aspx) $DisableKernelMode ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $useKernelMode = 'True' if( $DisableKernelMode ) { $useKernelMode = 'False' } $authSettings = Get-CIisSecurityAuthentication -SiteName $SiteName -VirtualPath $VirtualPath -Windows $authSettings.SetAttributeValue( 'useKernelMode', $useKernelMode ) $fullPath = Join-CIisVirtualPath $SiteName $VirtualPath if( $pscmdlet.ShouldProcess( $fullPath, "set Windows authentication" ) ) { $authSettings.CommitChanges() } } function Test-CIisAppPool { <# .SYNOPSIS Checks if an app pool exists. .DESCRIPTION Returns `True` if an app pool with `Name` exists. `False` if it doesn't exist. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Test-CIisAppPool -Name Peanuts Returns `True` if the Peanuts app pool exists, `False` if it doesn't. #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string] # The name of the app pool. $Name ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $appPool = Get-CIisAppPool -Name $Name if( $appPool ) { return $true } return $false } Set-Alias -Name 'Test-IisAppPoolExists' -Value 'Test-CIisAppPool' function Test-CIisConfigurationSection { <# .SYNOPSIS Tests a configuration section. .DESCRIPTION You can test if a configuration section exists or wheter it is locked. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .OUTPUTS System.Boolean. .EXAMPLE Test-CIisConfigurationSection -SectionPath 'system.webServer/I/Do/Not/Exist' Tests if a configuration section exists. Returns `False`, because the given configuration section doesn't exist. .EXAMPLE Test-CIisConfigurationSection -SectionPath 'system.webServer/cgi' -Locked Returns `True` if the global CGI section is locked. Otherwise `False`. .EXAMPLE Test-CIisConfigurationSection -SectionPath 'system.webServer/security/authentication/basicAuthentication' -SiteName `Peanuts` -VirtualPath 'SopwithCamel' -Locked Returns `True` if the `Peanuts` website's `SopwithCamel` sub-directory's `basicAuthentication` security authentication section is locked. Otherwise, returns `False`. #> [CmdletBinding(DefaultParameterSetName='CheckExists')] param( [Parameter(Mandatory=$true)] [string] # The path to the section to test. $SectionPath, [Parameter()] [string] # The name of the site whose configuration section to test. Optional. The default is the global configuration. $SiteName, [Parameter()] [Alias('Path')] [string] # The optional path under `SiteName` whose configuration section to test. $VirtualPath, [Parameter(Mandatory=$true,ParameterSetName='CheckLocked')] [Switch] # Test if the configuration section is locked. $Locked ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $getArgs = @{ SectionPath = $SectionPath; } if( $SiteName ) { $getArgs.SiteName = $SiteName } if( $VirtualPath ) { $getArgs.VirtualPath = $VirtualPath } $section = Get-CIisConfigurationSection @getArgs -ErrorAction SilentlyContinue if( $pscmdlet.ParameterSetName -eq 'CheckExists' ) { if( $section ) { return $true } else { return $false } } if( -not $section ) { Write-Error ('IIS:{0}: section {1} not found.' -f (Join-CIisVirtualPath $SiteName $VirtualPath),$SectionPath) return } if( $pscmdlet.ParameterSetName -eq 'CheckLocked' ) { return $section.OverrideMode -eq 'Deny' } } function Test-CIisSecurityAuthentication { <# .SYNOPSIS Tests if IIS authentication types are enabled or disabled on a site and/or virtual directory under that site. .DESCRIPTION You can check if anonymous, basic, or Windows authentication are enabled. There are switches for each authentication type. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .OUTPUTS System.Boolean. .EXAMPLE Test-CIisSecurityAuthentication -SiteName Peanuts -Anonymous Returns `true` if anonymous authentication is enabled for the `Peanuts` site. `False` if it isn't. .EXAMPLE Test-CIisSecurityAuthentication -SiteName Peanuts -VirtualPath Doghouse -Basic Returns `true` if basic authentication is enabled for`Doghouse` directory under the `Peanuts` site. `False` if it isn't. #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string] # The site where anonymous authentication should be set. $SiteName, [Alias('Path')] [string] # The optional path where anonymous authentication should be set. $VirtualPath = '', [Parameter(Mandatory=$true,ParameterSetName='Anonymous')] [Switch] # Tests if anonymous authentication is enabled. $Anonymous, [Parameter(Mandatory=$true,ParameterSetName='Basic')] [Switch] # Tests if basic authentication is enabled. $Basic, [Parameter(Mandatory=$true,ParameterSetName='Digest')] [Switch] # Tests if digest authentication is enabled. $Digest, [Parameter(Mandatory=$true,ParameterSetName='Windows')] [Switch] # Tests if Windows authentication is enabled. $Windows ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $getConfigArgs = @{ $pscmdlet.ParameterSetName = $true } $authSettings = Get-CIisSecurityAuthentication -SiteName $SiteName -VirtualPath $VirtualPath @getConfigArgs return ($authSettings.GetAttributeValue('enabled') -eq 'true') } function Test-CIisWebsite { <# .SYNOPSIS Tests if a website exists. .DESCRIPTION Returns `True` if a website with name `Name` exists. `False` if it doesn't. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Test-CIisWebsite -Name 'Peanuts' Returns `True` if the `Peanuts` website exists. `False` if it doesn't. #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string] # The name of the website whose existence to check. $Name ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $manager = New-Object 'Microsoft.Web.Administration.ServerManager' try { $site = $manager.Sites | Where-Object { $_.Name -eq $Name } if( $site ) { return $true } return $false } finally { $manager.Dispose() } } Set-Alias -Name Test-IisWebsiteExists -Value Test-CIisWebsite function Uninstall-CIisAppPool { <# .SYNOPSIS Removes an IIS application pool. .DESCRIPTION If the app pool doesn't exist, nothing happens. Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Uninstall-CIisAppPool -Name Batcave Removes/uninstalls the `Batcave` app pool. #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] [string] # The name of the app pool to remove. $Name ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $appPool = Get-CIisAppPool -Name $Name if( $appPool ) { if( $pscmdlet.ShouldProcess( ('IIS app pool {0}' -f $Name), 'remove' ) ) { $appPool.Delete() $appPool.CommitChanges() } } } function Uninstall-CIisWebsite { <# .SYNOPSIS Removes a website .DESCRIPTION Pretty simple: removes the website named `Name`. If no website with that name exists, nothing happens. Beginning with Carbon 2.0.1, this function is not available if IIS isn't installed. .LINK Get-CIisWebsite .LINK Install-CIisWebsite .EXAMPLE Uninstall-CIisWebsite -Name 'MyWebsite' Removes MyWebsite. .EXAMPLE Uninstall-CIisWebsite 1 Removes the website whose ID is 1. #> [CmdletBinding()] param( [Parameter(Position=0,Mandatory=$true)] [string] # The name or ID of the website to remove. $Name ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState if( Test-CIisWebsite -Name $Name ) { $manager = New-Object 'Microsoft.Web.Administration.ServerManager' try { $site = $manager.Sites | Where-Object { $_.Name -eq $Name } $manager.Sites.Remove( $site ) $manager.CommitChanges() } finally { $manager.Dispose() } } } Set-Alias -Name 'Remove-IisWebsite' -Value 'Uninstall-CIisWebsite' function Unlock-CIisConfigurationSection { <# .SYNOPSIS Unlocks a section in the IIS server configuration. .DESCRIPTION Some sections/areas are locked by IIS, so that websites can't enable those settings, or have their own custom configurations. This function will unlocks those locked sections. You have to know the path to the section. You can see a list of locked sections by running: C:\Windows\System32\inetsrv\appcmd.exe unlock config /section:? Beginning with Carbon 2.0.1, this function is available only if IIS is installed. .EXAMPLE Unlock-IisConfigSection -Name 'system.webServer/cgi' Unlocks the CGI section so that websites can configure their own CGI settings. #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] [string[]] # The path to the section to unlock. For a list of sections, run # # C:\Windows\System32\inetsrv\appcmd.exe unlock config /section:? $SectionPath ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $SectionPath | ForEach-Object { $section = Get-CIisConfigurationSection -SectionPath $_ $section.OverrideMode = 'Allow' if( $pscmdlet.ShouldProcess( $_, 'unlocking IIS configuration section' ) ) { $section.CommitChanges() } } } function Write-IisVerbose { [CmdletBinding()] param( [Parameter(Mandatory=$true,Position=0)] [string] # The name of the site. $SiteName, [string] $VirtualPath = '', [Parameter(Position=1)] [string] # The name of the setting. $Name, [Parameter(Position=2)] [string] $OldValue = '', [Parameter(Position=3)] [string] $NewValue = '' ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState if( $VirtualPath ) { $SiteName = Join-CIisVirtualPath -Path $SiteName -ChildPath $VirtualPath } Write-Verbose -Message ('[IIS Website] [{0}] {1,-34} {2} -> {3}' -f $SiteName,$Name,$OldValue,$NewValue) } |