<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>grokgarble.com &#187; IIS 7</title>
	<atom:link href="http://jeffmurr.com/blog/?feed=rss2&#038;tag=iis-7" rel="self" type="application/rss+xml" />
	<link>http://jeffmurr.com/blog</link>
	<description>Database, Software, and System Engineering</description>
	<lastBuildDate>Tue, 26 Sep 2017 19:07:40 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.30</generator>
	<item>
		<title>HTTP Error 500.19 &#8220;Failed to decrypt attribute &#8220;password&#8221;&#8221;</title>
		<link>http://jeffmurr.com/blog/?p=77</link>
		<comments>http://jeffmurr.com/blog/?p=77#comments</comments>
		<pubDate>Sat, 16 Feb 2013 19:45:22 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Murr]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[IIS 6]]></category>
		<category><![CDATA[IIS 7]]></category>
		<category><![CDATA[Regisrty]]></category>

		<guid isPermaLink="false">http://jeffmurr.com/blog/?p=77</guid>
		<description><![CDATA[Background Important information within IIS is stored in flat files with encrypted sections.  The specific sections encrypted are identity of the application pool along with ACL information.  When you move the configurations to a new server, or when you&#8217;ve used a hypervisor to clone a server, keys used to decrypt these values will no longer work.  Or more specifically, [&#8230;]]]></description>
				<content:encoded><![CDATA[<h3><strong><big>Background</big></strong></h3>
<p>Important information within IIS is stored in flat files with encrypted sections.  The specific sections encrypted are identity of the application pool along with ACL information.  When you move the configurations to a new server, or when you&#8217;ve used a hypervisor to clone a server, keys used to decrypt these values will no longer work.  Or more specifically, they&#8217;re not found&#8230;I&#8217;ll get to that (the fourth solution to this problem explains it all).</p>
<p><a href="http://jeffmurr.com/blog/wp-content/uploads/2013/02/500.19Error1.png"><img class="alignnone size-full wp-image-108" alt="500.19Error" src="http://jeffmurr.com/blog/wp-content/uploads/2013/02/500.19Error1.png" width="249" height="293" /></a></p>
<p>The 500 primary error means it is a server error. The .19 secondary error code indicates that &#8220;The requested page can not be accessed because the related configuration data is invalid.&#8221; IIS, points out that the issue is due to its inability to decrypt an attribute of a configuration file for us. <a href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/a0ea8e51-fb2a-4e80-9d5a-7fe3ae246570.mspx?mfr=true" target="_blank">Metabase.xml</a> is the central store where IIS 6.0 stores most of its configuration information.  In IIS 7.0 Microsoft shifted to a new XML based configuration store that is modeled after ASP.NET.  The same model is maintained in IIS 7.5.  IIS no longer centralized into a single file. The hierarchical store starts with the <a href="http://technet.microsoft.com/en-us/library/cc753369(v=WS.10).aspx" target="_blank">applicationHost.config</a> file and can be distributed among web.config files under your application for a more modular inheritance  exposed through the app.configs (web.config).</p>
<p>In IIS 7 the local accounts and groups that IIS 6.0 used (IUSR_MACHINENAME / IIS_WPG) were also replaced by built-in accounts (IUSR / IIS_IUSRS). The built-in accounts have the same SID across Windows 2008/2008 R2 servers and are not machine specific.  The idea is that, like web applications&#8217; configurations, you should be able to have an IIS configuration that could be machine independent.  Therefore, like web.configs, you should be able to just <a href="http://technet.microsoft.com/en-us/library/cc770873(v=ws.10).aspx" target="_blank">copy </a>your <a href="http://technet.microsoft.com/en-us/library/cc753369(v=WS.10).aspx" target="_blank">applicationHost.config</a><strong> </strong>from one server to another and IIS will pick up the settings and work.</p>
<h3><strong><big>Problem</big></strong></h3>
<p>This all works perfectly, if you don&#8217;t care about the identity your application runs under.  In a distributed environment this isn&#8217;t always the case.  If you modify the identity of your application pool servicing your application hosted in IIS, then move the <a href="http://technet.microsoft.com/en-us/library/cc753369(v=WS.10).aspx" target="_blank">applicationHost.config</a> to a different IIS 7.0 server, or <strong>clone</strong> it you&#8217;re greeted with this error when trying to render a page, web service, or worse a failure of application pools with an error from WAS in your event log looking like this:</p>
<blockquote><p>Application pool &lt;ApplicationPool&gt; has been disabled. Windows Process Activation Service (WAS) did not create a worker process to serve the application pool because the application pool identity is invalid.</p></blockquote>
<p>If you try to modify the account, depending on how you installed the application  you may not be able to change the password and &#8220;reset&#8221; this problem away that&#8217;s truly a the mismatch of identity on multiple levels.</p>
<p>This issues results in this error:</p>
<blockquote><p>There was an error while performing this operation.  Details: Bad Data. (Exception from HRESULT: 0&#215;80090005)</p></blockquote>
<p>It is rooted in the inability to decrypt the sections of the <a href="http://technet.microsoft.com/en-us/library/cc753369(v=WS.10).aspx" target="_blank">applicationHost.config</a><strong> </strong>that&#8217;s encrypted with machine keys.  Any custom username / password tried for the identity of the application pool may result in either of these error conditions.  A work around is to set application pool to one of the built in accounts works or remove the encryption in the configuration file.  Both not that great of solutions if you need some level of identity on a remote system or security by encrypting this sensitive data at rest, as it should be.</p>
<p>The issue is with your machine keys used to decrypt sections of your <a href="http://technet.microsoft.com/en-us/library/cc753369(v=WS.10).aspx" target="_blank">applicationHost.config</a><strong>.  </strong>For example, IIS keeps a local copy of the username and password of a custom identity in the <a href="http://technet.microsoft.com/en-us/library/cc753369(v=WS.10).aspx" target="_blank">applicationHost.config</a><strong> </strong>and and encrypts it.  If you open the file you&#8217;ll see this:</p>
<p><code>&lt;processModel identityType="User" userName="domain\username" password="[enc:IISWASOnlyAesProvider:2Woq1bHFmcDxzSEKLe9q1eZsvlUuBcmb0Luy3DzkZWg=:enc]" /&gt;</code></p>
<p>When the <a href="http://technet.microsoft.com/en-us/library/cc753369(v=WS.10).aspx" target="_blank">applicationHost.config</a><strong> </strong>is used on a server it didn&#8217;t originate on,  IIS can no longer decrypt the <a href="http://www.iis.net/configreference">iisConfiguration </a>and <a href="http://www.iis.net/configreference">iisWasKey </a>containers in this file since it uses the original machine keys to do they encryption.</p>
<h2><strong><big>Solutions<big></big></big></strong></h2>
<p>To get this working you have four options, in order of suggested implementation.  The first requires<em><strong> A </strong><strong>working </strong></em>server with a similar configuration, the second requires <span style="color: #000000;"><b><i>THE  actual </i></b></span>source server, the third is down right insecure, the fourth I would challenge that anyone should use &#8211; but works, and is important to understanding the under pinning of what&#8217;s going on.</p>
<p>The first three are supported methods by Microsoft documentation, the fourth isn&#8217;t &#8211; and with all, take proper precautions.</p>
<h3><strong><em>First one (best/easiest)&#8230;</em></strong></h3>
<p>Export the IIS config of a working web server and import using the <a href="http://www.iis.net/learn/manage/managing-your-configuration-settings/shared-configuration_264" target="_blank">Shared Configuration</a> of IIS 7.</p>
<p>1. Navigate to the root of you server in IIS admin console<br />
2. Double click shared Configuration</p>
<p><a href="http://jeffmurr.com/blog/wp-content/uploads/2013/02/IISRoot.png"><img alt="IISRoot" src="http://jeffmurr.com/blog/wp-content/uploads/2013/02/IISRoot-300x168.png" width="300" height="168" /></a></p>
<p>3. Click Export Configuration on the left hand pane</p>
<p><a href="http://jeffmurr.com/blog/wp-content/uploads/2013/02/ExportConfig.png"><img alt="ExportConfig" src="http://jeffmurr.com/blog/wp-content/uploads/2013/02/ExportConfig.png" width="153" height="120" /></a></p>
<p>4. Select a location<br />
5. Select a Password<br />
6. And Select OK</p>
<p><a href="http://jeffmurr.com/blog/wp-content/uploads/2013/02/6Password.png"><img alt="6Password" src="http://jeffmurr.com/blog/wp-content/uploads/2013/02/6Password.png" width="220" height="120" /></a></p>
<p>7. This process creates files to be imported on target machine<br />
8. Move the files to a location on the target server<br />
9. In Shared Configuration manager on the target machine check the Enable Shared Configuration and select Apply</p>
<p><a href="http://jeffmurr.com/blog/wp-content/uploads/2013/02/SharedConfig.png"><img alt="SharedConfig" src="http://jeffmurr.com/blog/wp-content/uploads/2013/02/SharedConfig-300x51.png" width="300" height="51" /></a></p>
<p>10. Enter the password when prompted<br />
11. Ok to the follow couple of prompts<br />
12. IISReset<br />
13. Navigate to your resource to confirm it renders (no longer an 500.19 error)</p>
<p><a href="http://jeffmurr.com/blog/wp-content/uploads/2013/02/ServiceWSDLIIS.png"><img alt="ServiceWSDLIIS" src="http://jeffmurr.com/blog/wp-content/uploads/2013/02/ServiceWSDLIIS.png" width="153" height="120" /></a></p>
<p>14. In Shared Configuration manager on the target machine un-check the Enable <a href="http://www.iis.net/learn/manage/managing-your-configuration-settings/shared-configuration_264" target="_blank">Shared Configuration</a> and select Apply<br />
15. Select yes to overwrite</p>
<p><a href="http://jeffmurr.com/blog/wp-content/uploads/2013/02/Confirm.png"><img alt="Confirm" src="http://jeffmurr.com/blog/wp-content/uploads/2013/02/Confirm-300x161.png" width="300" height="161" /></a></p>
<p>16. Yes when prompted to IISReset<br />
17. Perform IISReset</p>
<p>&nbsp;</p>
<h3><strong><em>Second (easy)&#8230;</em></strong></h3>
<p>Export keys from source server:</p>
<div>
<pre class="brush:shell">aspnet_regiis -px "iisConfigurationKey" "C:\IISKEY\iisConfigurationKey.xml" -pri
aspnet_regiis -px "iisWasKey" "C:\IISKEY\iisWasKey.xml" -pri</pre>
</div>
<p>Import on your target/problem server:</p>
<div>
<pre class="brush:shell">aspnet_regiis -pi "iisConfigurationKey" "C:\IISKEY\iisConfigurationKey.xml"
aspnet_regiis -pi "iisWasKey" "C:\IISKEY\iisWasKey.xml"</pre>
<p>&nbsp;</p>
<h3><b><i>Third</i></b><strong><em> one (work intensive/insecure)  </em></strong></h3>
<p>Remove the encryption tags in the <a href="http://technet.microsoft.com/en-us/library/cc753369(v=WS.10).aspx" target="_blank">applicationHost.config</a><strong>.  </strong>Depending on how big your problem is this may be extensive work.</p>
<p>Open your <a href="http://technet.microsoft.com/en-us/library/cc753369(v=WS.10).aspx" target="_blank">applicationHost.config</a> in %windir%\system32\inetsrv\config and search for &#8220;<em>[enc:</em>&#8221; and put the configurations that are encrypted in the file in clear text.</p>
<p>Example Before:</p>
<p><code>&lt;processModel identityType="User" userName="domain\username" password="[enc:IISWASOnlyAesProvider:2Woq1bHFmcDxzSEKLe9q1eZsvlUuBcmb0Luy3DzkZWg=:enc]" /&gt;</code></p>
<p>Example After:</p>
<p><code>&lt;processModel identityType="User" userName="domain\username" password="UserNamesPasswordInClearText" /&gt;</code></p>
<p>&nbsp;</p>
<p><strong><em>The Fourth, (absolutely crazy, but explains what&#8217;s really going on on the file system)&#8230;</em></strong></p>
<p>Modify your <strong>MahineGuid</strong> to match your keys needed to decrypt.</p>
<p>This is pretty aggressive and I would suggest this only as an academic exercise in figuring out the inner workings of the RSA suite and usage within the Windows OS.  But <strong>explains what&#8217;s really going on</strong>.  I&#8217;m not comfortable suggesting any use this as a policy since I can find no documentation on Microsoft&#8217;s site to support its validity; but, it was something I spent a good amount of time on and it worked, I&#8217;d hate to not post the findings.  It also gives you the whole story of the problem.</p>
<p>In <strong>C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys</strong> are all of your private keys.  The appropriate key is called up by an application needing the machine key portion by a <strong>MachineGuid</strong> registry key.  When xcopy-ing or cloning your flat files no longer match your <strong>MachineGuid</strong> nested in the registry.</p>
<p><strong>So, your inability to decrypt is actually rooted in your inability to find the key required to do the decryption!</strong></p>
<p>The naming convention of all of the keys stored in this location is &lt;KEYGUID&gt;_&lt;MACHINEGUID&gt;.  If you flip the <strong>MachineGuid</strong> in <strong>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography </strong>to match the suffix of the keys stored in <strong>C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys </strong>IIS will start referencing the previous certificates and IIS will be able to decrypt the password sections again.</p>
<p><em id="__mceDel"><a href="http://jeffmurr.com/blog/wp-content/uploads/2013/02/RSAKeys.png"><img class="alignnone size-medium wp-image-86" alt="RSAKeys" src="http://jeffmurr.com/blog/wp-content/uploads/2013/02/RSAKeys-300x102.png" width="300" height="102" /></a></em></p>
<p>Extensive testing was not done on this solution so again, proceed with caution.  Only a cool trick in my book, no telling what else this could break along the way.  You will notice however, both of the other solutions in this post create *new* keys in this location with the correct <strong>MachineGuid</strong>, so a good troubleshooting skill and confirmation technique to store away for future use.</p>
<p>&nbsp;</p>
</div>
<div data-counters='1' data-style='square' data-size='regular' data-url='http://jeffmurr.com/blog/?p=77' data-title='HTTP Error 500.19 &#8220;Failed to decrypt attribute &#8220;password&#8221;&#8221;' class='linksalpha_container linksalpha_app_3'><a href='//www.linksalpha.com/share?network='facebook' class='linksalpha_icon_facebook'></a><a href='//www.linksalpha.com/share?network='twitter' class='linksalpha_icon_twitter'></a><a href='//www.linksalpha.com/share?network='googleplus' class='linksalpha_icon_googleplus'></a><a href='//www.linksalpha.com/share?network='mail' class='linksalpha_icon_mail'></a></div><div data-position='' data-url='http://jeffmurr.com/blog/?p=77' data-title='HTTP Error 500.19 &#8220;Failed to decrypt attribute &#8220;password&#8221;&#8221;' class='linksalpha_container linksalpha_app_7'><a href='//www.linksalpha.com/share?network='facebook' class='linksalpha_icon_facebook'></a><a href='//www.linksalpha.com/share?network='twitter' class='linksalpha_icon_twitter'></a><a href='//www.linksalpha.com/share?network='googleplus' class='linksalpha_icon_googleplus'></a><a href='//www.linksalpha.com/share?network='mail' class='linksalpha_icon_mail'></a></div>
<!-- NgfbSharing::get_buttons content filter skipped: buttons not allowed in rss feeds -->
]]></content:encoded>
			<wfw:commentRss>http://jeffmurr.com/blog/?feed=rss2&#038;p=77</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>&#8220;Unable to load one or more of the requested types.&#8221;</title>
		<link>http://jeffmurr.com/blog/?p=55</link>
		<comments>http://jeffmurr.com/blog/?p=55#comments</comments>
		<pubDate>Wed, 30 Jan 2013 04:06:17 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Murr]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[IIS 7]]></category>

		<guid isPermaLink="false">http://jeffmurr.com/blog/?p=55</guid>
		<description><![CDATA[This annoying exception greeted me this morning&#8230; Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.Reflection.ReflectionTypeLoadException: Unable to load [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>This annoying exception greeted me this morning&#8230;</p>
<p><a href="http://jeffmurr.com/blog/wp-content/uploads/2013/01/LoaderError1.png"><img class="alignnone size-medium wp-image-70" alt="LoaderError" src="http://jeffmurr.com/blog/wp-content/uploads/2013/01/LoaderError1-300x100.png" width="300" height="100" /></a></p>
<blockquote><p>Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.</p>
<p>Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.</p>
<p>Exception Details: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.</p></blockquote>
<p>It occurs when an assembly type was not able to load properly during the start-up of your application hosted in IIS.  Specifically, when a dependency is missing.  Depending on when the error occurs in the compile of your solution, you may not get a good error in IIS failed request trace, IIS logs proper (a simple 500 result is logged), or any extended logging assemblies you have included in your solution since the error very well could occur before those logging logic libraries have included/loaded.</p>
<p>To correct it you need to find the missing dependency.  To find that missing dependency you can stage an add of all binaries using PowerShell.  Specifically, all by a <a href="http://technet.microsoft.com/library/hh849800.aspx">Get-ChildItem</a>, that you can properly filter by name as needed, one by one in a &#8220;foreach&#8221; loop using the <a href="http://technet.microsoft.com/en-us/library/hh849914">Add-Type </a>cmdlet to stage the same .NET load performed at start-up   You can closely inspect the details of the exception raised during the load of each to find any missing dependencies.  Specifically, inspect the <a href="http://msdn.microsoft.com/en-us/library/system.reflection.reflectiontypeloadexception.loaderexceptions.aspx">LoaderExceptions</a> property that holds the I/O details holding the &#8220;file not found&#8221; error [like the error message in IIS suggests].</p>
<p>Here&#8217;s a quick script snippet.  Modify the file location of your binary folder and/or your gci filter as needed:</p>
<pre class="brush:powershell">$BinPath = "D:\Webroot\wwwroot\bin"
  try
  {
    $Error.Clear()
    Push-Location $BinPath
    Get-ChildItem "*.dll" | Foreach {
	Write-Host $_.Name;
        $assembly = Add-Type -Path $_.FullName;    
    }
  }
  catch 
  {
    Write-Host -foreground yellow "LoadException";
    $Error | format-list -force
    Write-Host -foreground red $Error[0].Exception.LoaderExceptions;
  }

Write-Host "Complete."
Pop-Location</pre>
<div data-counters='1' data-style='square' data-size='regular' data-url='http://jeffmurr.com/blog/?p=55' data-title='&#8220;Unable to load one or more of the requested types.&#8221;' class='linksalpha_container linksalpha_app_3'><a href='//www.linksalpha.com/share?network='facebook' class='linksalpha_icon_facebook'></a><a href='//www.linksalpha.com/share?network='twitter' class='linksalpha_icon_twitter'></a><a href='//www.linksalpha.com/share?network='googleplus' class='linksalpha_icon_googleplus'></a><a href='//www.linksalpha.com/share?network='mail' class='linksalpha_icon_mail'></a></div><div data-position='' data-url='http://jeffmurr.com/blog/?p=55' data-title='&#8220;Unable to load one or more of the requested types.&#8221;' class='linksalpha_container linksalpha_app_7'><a href='//www.linksalpha.com/share?network='facebook' class='linksalpha_icon_facebook'></a><a href='//www.linksalpha.com/share?network='twitter' class='linksalpha_icon_twitter'></a><a href='//www.linksalpha.com/share?network='googleplus' class='linksalpha_icon_googleplus'></a><a href='//www.linksalpha.com/share?network='mail' class='linksalpha_icon_mail'></a></div>
<!-- NgfbSharing::get_buttons content filter skipped: buttons not allowed in rss feeds -->
]]></content:encoded>
			<wfw:commentRss>http://jeffmurr.com/blog/?feed=rss2&#038;p=55</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Automated PICS-Label Generation Using PowerShell for IIS 7</title>
		<link>http://jeffmurr.com/blog/?p=27</link>
		<comments>http://jeffmurr.com/blog/?p=27#comments</comments>
		<pubDate>Sun, 27 Jan 2013 15:27:35 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Murr]]></dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[IIS 7]]></category>

		<guid isPermaLink="false">http://jeffmurr.com/blog/?p=27</guid>
		<description><![CDATA[Need the correct PICS-Label HTTP response headers for 0 ratings added to your Default Web Site in IIS 7 using PowerShell?  This post has you covered. This is for that age old &#8220;Content Advisor&#8221; requirement in IE feature for me.  It is a feature of some browsers, primarily Internet Explorer, that enable end users to safeguard children from [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Need the correct PICS-Label HTTP response headers for 0 ratings added to your Default Web Site in IIS 7 using PowerShell?  This post has you covered.</p>
<p>This is for that age old &#8220;<a href="http://windows.microsoft.com/en-us/windows7/Using-Content-Advisor-to-helpa-block-inappropriate-web-content" target="_blank">Content Advisor</a>&#8221; requirement in IE feature for me.  It is a feature of some browsers, primarily Internet Explorer, that enable end users to safeguard children from places on the net with a parental password.  There are ratings that can be embedded within, so read the standards if you&#8217;re wanting something specific for your site.  Keep in mind that this is header usage is  deprecated.  If you&#8217;re interested in the new method, you can check POWDER out <a href="http://www.w3.org/2007/powder/">here</a>.</p>
<p>Here&#8217;s a script answer using the WebAdministration PowerShell module and its cmdlets that takes your URL as a parameter:</p>
<p>Usage: <code>.\Set-PICSLabel.ps1 -URL http://jeffmurr.com</code></p>
<pre class="brush:powershell">param (
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $URL
)
Import-Module WebAdministration
$PICSLabel = Get-WebConfiguration system.webServer/httpProtocol/customHeaders/* 'IIS:\sites\Default Web Site' | where {$_.name -eq "pics-label"}
if($PICSLabel) {write-host "PICS-Label already exists. No updates made."}
else {
write-host "PICS-Label does not exists. Adding PICS-Label..."
Add-WebConfiguration -Filter /system.webServer/httpProtocol/customHeaders -PSPath "IIS:\sites\Default Web Site" -Value @{name='PICS-Label';value="(pics-1.1 `"http://www.icra.org/pics/vocabularyv03/`" l gen true for `"$URL `" r (c 0 l 0 n 0 oa 0 ob 0 oc 0 od 0 oe 0 of 0 og 0 oh 0 s 0 v 0))"}
write-host "PICS-Label created."
}</pre>
<p>The script above imports the <a title="Technet Reference for WebAdministration Module" href="http://technet.microsoft.com/en-us/library/ee790599.aspx" target="_blank">WebAdministration</a> module and uses that module&#8217;s <a title="Technet Reference for Get-WebConfiguration" href="http://technet.microsoft.com/en-us/library/ee790561.aspx" target="_blank">Get-WebConfiguration</a> cmdlet to create and array object of all of the customer headers where the name is &#8220;<a href="http://www.w3.org/PICS/labels.html" target="_blank">pics-label</a>&#8221; called $PICSLabel.  This is only a test to see if its already exists and is recursed through all child objects under the default site object.  If the object is not NULL it returns &#8220;true&#8221; for the if statement and the <a title="Technet Reference for Add-WebConfiguration" href="http://technet.microsoft.com/en-us/library/ee807834.aspx" target="_blank">Add-WebConfiguration</a> cmdlet is used to add the correct values to the default web.config at the site&#8217;s root.</p>
<p>A formatted header looks like this:</p>
<p><code>(pics-1.1 "http://www.icra.org/pics/vocabularyv03/" l gen true for "http://jeffmurr.com " r (c 0 l 0 n 0 oa 0 ob 0 oc 0 od 0 oe 0 of 0 og 0 oh 0 s 0 v 0))</code></p>
<p><strong>Note:  </strong>Spacing and format are critical or end user errors will result.</p>
<p>It is not required that the definition of the pics-label header be at the site level; however, not doing so can be confusing of the URL content of the header to the parsing engine and browser.  For that reason, its just simpler and easier to always define the header at the site&#8217;s root unless specific child applications have different ratings than that of the site.</p>
<p>The response header name &#8220;pics-label&#8221; is what is parsed for content ratings.  PICS stands for &#8220;Platform for Internet Content Selection&#8221;.  Its use in standards are defined by World Wide Web Consortium (W3) <a title="PICS Label Reference from w3" href="http://www.w3.org/PICS/labels.html" target="_blank">here</a>.  In short, it is a voluntarily rating system that is used to protect children from inappropriate content on the web.  Parents can configure it to allow sites based on the voluntary ratings made by the site&#8217;s owner or block based on those ratings.  Most use it to require a password to visit regardless of the voluntary ratings provided in the header.</p>
<p>Internet explorer uses this in the its <a href="http://windows.microsoft.com/en-us/windows7/Using-Content-Advisor-to-help-block-inappropriate-web-content" target="_blank">Content Advisor</a> feature.  It is enabled and configured when accessed under the internet options section of IE under the content tab.</p>
<p><a href="http://jeffmurr.com/blog/wp-content/uploads/2013/01/InternetExplorer-ContentAdvisor.png"><img class="alignnone size-medium wp-image-28" alt="InternetExplorer-ContentAdvisor" src="http://jeffmurr.com/blog/wp-content/uploads/2013/01/InternetExplorer-ContentAdvisor-234x300.png" width="234" height="300" /></a></p>
<p>For Internet Explorer&#8217;s <a href="http://windows.microsoft.com/en-us/windows7/Using-Content-Advisor-to-helpa-block-inappropriate-web-content" target="_blank">Content Advisor</a> feature, parents can set up ratings that they want to allow and trust site administrators to be honest about the material on their site.  More often than not, the password option is used for the URL content to all/not allow a site.  The password can be required on each visit or the parent can &#8220;white list&#8221; a site after providing the password using the URL content of the pics-label header.</p>
<p>Even though the <a href="http://icra.org/" target="_blank">ICRA </a>has discontinued its ratings dictionary, many users still use it as an easy parenting tool to protect children from wandering into unknown areas of the net.  There are other rating dictionaries other than the <a href="http://icra.org/" target="_blank">ICRA</a>, but it still seems to be the most widely used and why it was my choice in the script.</p>
<div data-counters='1' data-style='square' data-size='regular' data-url='http://jeffmurr.com/blog/?p=27' data-title='Automated PICS-Label Generation Using PowerShell for IIS 7' class='linksalpha_container linksalpha_app_3'><a href='//www.linksalpha.com/share?network='facebook' class='linksalpha_icon_facebook'></a><a href='//www.linksalpha.com/share?network='twitter' class='linksalpha_icon_twitter'></a><a href='//www.linksalpha.com/share?network='googleplus' class='linksalpha_icon_googleplus'></a><a href='//www.linksalpha.com/share?network='mail' class='linksalpha_icon_mail'></a></div><div data-position='' data-url='http://jeffmurr.com/blog/?p=27' data-title='Automated PICS-Label Generation Using PowerShell for IIS 7' class='linksalpha_container linksalpha_app_7'><a href='//www.linksalpha.com/share?network='facebook' class='linksalpha_icon_facebook'></a><a href='//www.linksalpha.com/share?network='twitter' class='linksalpha_icon_twitter'></a><a href='//www.linksalpha.com/share?network='googleplus' class='linksalpha_icon_googleplus'></a><a href='//www.linksalpha.com/share?network='mail' class='linksalpha_icon_mail'></a></div>
<!-- NgfbSharing::get_buttons content filter skipped: buttons not allowed in rss feeds -->
]]></content:encoded>
			<wfw:commentRss>http://jeffmurr.com/blog/?feed=rss2&#038;p=27</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
