powershellsharepointurl-rewritingdsc

How do I configure URL Rewrite for IIS using Desired State Configuration (DSC)?


When automating a setup of an IIS site, I run into an issue that required me to use URL Rewrite. However, I don't seem to get the grip of how to use the DSC Resource command WebConfigProperty correctly.

I've tried using

Configuration ConfigureRewriteRules {

  Import-DscResource -ModuleName WebAdministrationDsc -ModuleVersion 4.1.0
  Import-DscResource -ModuleName PSDesiredStateConfiguration

  node localhost {
    File 'Create_RewriteRulesFile' {
      Ensure          = 'Present'
      Type            = 'File'
      DestinationPath = 'c:\inetpub\wwwroot\rewriterules.config'
      Contents        = '<!-- some rules -->'
      Force           = $true
      MatchSource     = $true
    }

    WebConfigProperty 'Create_RewriteSection' {
      Ensure      = 'Present'
      WebSitePath = 'c:\inetpub\wwwroot'
      Filter      = 'system.WebServer/rewrite/rules'
      Value       = 'configSource = "rewriterules.config"'
      DependsOn   = '[File]Create_RewriteRulesFile'
    }

  }
}

ConfigureRewriteRules
Start-DscConfiguration -Path .\ConfigureRewriteRules -Wait -Verbose -Force

[WebConfigProperty]Create_RewriteSection will generate the error

Path doesn't belong to 'WebAdministration' provider.

So obviously I've got the parameter WebSitePath wrong.
According to dsccommunity/WebAdministrationDsc, the resource command should support both IIS and WebAdministration format paths.

Note: I've specified Default Website for ease of use in this example, but I've verified that the specified path do contain the web.config file.

Edit: To allow you as a reader to better track my findings, I've rolled back the question to the original wordings and will add any findings below instead.

Finding 1

The DSC resource requires PropertyName

    WebConfigProperty 'Create_RewriteSection' {
      Ensure       = 'Present'
      WebSitePath  = 'c:\inetpub\wwwroot'
      Filter       = 'system.WebServer/rewrite/rules'
      PropertyName = 'rules'
      Value        = 'configSource = "rewriterules.config"'
      DependsOn    = '[File]Create_RewriteRulesFile'
    }

Finding 2

The WebSitePath isn't the physical path of web.config.
The possible paths was found when using the IIS path and got the WebAdministration path back in an error message about the Filter.

    WebConfigProperty 'Create_RewriteSection' {
      Ensure       = 'Present'
      WebSitePath  = 'MACHINE/WEBROOT/APPHOST/Default Web Site'
  #or WebSitePath  = 'IIS:\inetpub\wwwroot'\Sites\Default WebSite\'
      Filter       = 'system.WebServer/rewrite/rules'
      PropertyName = 'rules'
      Value        = 'configSource = "rewriterules.config"'
      DependsOn    = '[File]Create_RewriteRulesFile'
    }

This will change the error returned to

Target configuration object 'system.WebServer/rewrite/rules' is not found
at path 'MACHINE/WEBROOT/APPHOST/Default Web Site'.

Finding 3

PropertyName should not be part of the Filter

  WebConfigProperty 'Create_RewriteSection' {
      Ensure       = 'Present'
      WebSitePath  = 'MACHINE/WEBROOT/APPHOST/Default Web Site'
  #or WebSitePath  = 'IIS:\Sites\Default Web Site\'
      Filter       = 'system.WebServer/rewrite/rules'
      PropertyName = 'configSource'
      Value        = 'rewriteRules.config'
      DependsOn    = '[File]Create_RewriteRulesFile'
    }

This will still generate the error

Target configuration object 'system.WebServer/rewrite/rules' is not found
at path 'MACHINE/WEBROOT/APPHOST/Default Web Site'.

Finding 4

Creating the section in web.config using XML-manipulation instead will still result in errors using WebAdministrationDsc to set properties.

$webxml = [xml](Get-Content c:\intetpub\wwwroot\web.config)

$rewrite = $webxml.CreateElement('rewrite')
$rules   = $rewrite.AppendChild($webxml.CreateElement('rules'))
$webxml.configuration.'system.webServer'.AppendChild($rewrite)

$webxml.Save('c:\intetpub\wwwroot\web.config')

Solution

  • I managed to find a solution by side stepping WebAdministrationDsc and using the DSC resource xXMLConfigFile instead.

    The drawback is that the web application will be restarted if web.config is altered from outside of the IIS. So this solution is best suited using service windows.

    Configuration Set_RewriteRules {
    
      Import-DscResource -ModuleName xXMLConfigFile
      Import-DscResource -ModuleName PSDesiredStateConfiguration
    
      node localhost {
        File 'Create_RewriteRulesFile' {
          Ensure          = 'Present'
          Type            = 'File'
          DestinationPath = 'c:\inetpub\wwwroot\rewriteRules.config'
          Contents        = '<!-- some rules -->'
          Force           = $true
          MatchSource     = $true
        }
    
        XMLConfigFile 'Create_RewriteSection' {
          Ensure      = 'Present'
          ConfigPath  = 'c:\inetpub\wwwroot\web.config'
          XPath       = 'system.webServer'
          Name        = 'rewrite'
          isElementTextValue = $true
        }
    
        XMLConfigFile 'Set_configSource' {
          Ensure      = 'Present'
          ConfigPath  = 'c:\inetpub\wwwroot\web.config'
          XPath       = 'system.webServer/rewrite/rules'
          Name        = 'configSource'
          Value       = 'rewriteRules.config'
          isAttribute = $false
    
          DependsOn   = '[File]Create_RewriteRulesFile',
                        '[XMLConfigFile]Create_RewriteSection'
        }
    
      }
    
    }
    
    Set_RewriteRules
    Start-DscConfiguration -Path .\Set_RewriteRules -Wait -Verbose -Force
    

    Note: XPath is case sensitive.