Wednesday, February 2, 2011

Encrypting Web.Config part 2

Someone noted that my previous script for encrypting web.config files was missing out some applications and I discovered it was because they where at the root level and my script expected everything to running under a virtual directory.  This was correct for the development machines but on a production machine the site could be anywhere.

Working by file

To fix this I changed the script to simply find all the web.configs on a specific drive and do it that way.  It turned out to be easier than going via IIS and probably more accurate too.  There modified script is below:

$Dir = get-childitem G:\ -recurse
$List = $Dir | where {$_.name -eq "web.config"}

## Sections we want Hashed ###
$configSections = @('connectionStrings','appSettings')
## Command line for the encrypting system ###
$CmdLine = "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pef "

foreach($file in $List)
{
    ### Process the directories ###
    write-Host "processing  -> " $file.fullname;
    foreach($section in $configSections)
    {
        $command = $CmdLine + $section + " " + $file.fullname + "' -prov 'RsaProtectedConfigurationProvider'";
        #invoke-expression -command $command | out-null
    }

}

Tuesday, February 1, 2011

Encrypting Web.Config

Today I spent a few hours getting a script together that would encrypt all the web.config files for all the sites and applications on a server.   It was more difficult than expected, but I think that’s more because I don’t really know PowerShell as well as I figured.  It was also the fact that our servers are running version 1 rather than version 2 which makes things a little more complicated.

The Script

The script is given below (not much sot show for 4 hours work!). 

### Powershell script to encrypt all web.configs###
$objSites = [adsi]"IIS://localhost/W3SVC"
foreach ($objChild in $objSites.psBase.children)
{
    $sitePath=$objChild.psBase.Path + "/Root";
    Write-Host "Processing Site:" + $sitePath;
    $iis=[adsi]$sitePath;
    $vroot = $iis.psbase.children ;
    trap  { continue;}

    ## Sections we want Hashed ###
    $configSections = @('connectionStrings','appSettings')
    ## Command line for the encrypting system ###
    $CmdLine = "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pe "
    ### Process the directories ###
    foreach($vdir in $vroot)
    {   
        Write-Host "processing  -> " $vdir.psBase.Name;
        foreach($section in $configSections)
        {
            $command = $CmdLine + $section + " -app '/" + $vdir.psBase.Name + "' -prov 'RsaProtectedConfigurationProvider'";
            invoke-expression -command $command | out-null
        }
    }
}

In essence its a simple loop, find all teh defined sites, then all the virtual directories below these.  Run teh command line utility “aspnet-regiis –pe ”, which will work it’s magic.

Powershell

One of the major things you need to have on teh server for this work is PowerShell.  This feature is built into Windows 2008 so all you need to do is enable it by adding the “Microsoft Powershell” feature.  For Windows 2003 you’ll need to download the installation package from Microsoft.

If you’ve installed PowerShell for teh first time tehn you’ll also need to set th Execution Policy.  Just enter “Powershell” at the command prompet and enter “Set-ExecutionPolicy RemoteSigned”, then exit.

 

The Timer Job

The simplest way of making sure that this is always applied to all sites is to create a timer job that runs every hour.