<?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; PowerShell</title>
	<atom:link href="http://jeffmurr.com/blog/?feed=rss2&#038;tag=powershell" 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>Importing and Exporting Windows Features with PowerShell</title>
		<link>http://jeffmurr.com/blog/?p=273</link>
		<comments>http://jeffmurr.com/blog/?p=273#comments</comments>
		<pubDate>Tue, 06 Jan 2015 15:39:28 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Murr]]></dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://jeffmurr.com/blog/?p=273</guid>
		<description><![CDATA[This applies to Windows 7, Windows Server 2008 and Windows Server 2008 R2 and the use of Get-WindowsFeature and Add-WindowsFeature.  For Windows 8, Windows Server 2012, and Windows Server 2012 R2 Microsoft has overhauled these two cmdlets that I&#8217;ll handle the same usage in a different post. First the cmdlets we need are in the server manager module [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>This applies to Windows 7, Windows Server 2008 and Windows Server 2008 R2 and the use of <a href="http://technet.microsoft.com/en-us/library/jj205469.aspx">Get-WindowsFeature</a> and <a href="http://msdn.microsoft.com/en-us/library/ee662309.aspx">Add-WindowsFeature</a>.  For Windows 8, Windows Server 2012, and Windows Server 2012 R2 Microsoft has overhauled these two <a href="http://technet.microsoft.com/en-us/library/jj205467.aspx">cmdlets </a>that I&#8217;ll handle the same usage in a different post.</p>
<p>First the cmdlets we need are in the server manager module so import that:</p>
<pre class="brush:powershell">Import-Module ServerManager</pre>
<p>Create your windows features xml or text file with the one of the following commands from a reference server:</p>
<pre class="brush:powershell">Get-WindowsFeature | ? { $_.Installed } | Export-Clixml .\Features.xml</pre>
<p>OR</p>
<pre class="brush:powershell">Get-WindowsFeature | ? { $_.Installed } | Select Name | ForEach-Object { $_.Name } | Out-File .\Features.txt</pre>
<p>To install these features:</p>
<pre class="brush:powershell">$(Import-Clixml .\Features.xml) | Add-WindowsFeature</pre>
<p>OR</p>
<pre class="brush:powershell">$(Get-Content .\Features.txt) | Add-WindowsFeature</pre>
<p>I prefer the TXT file and a Sort for an easy way to compare the files to easily compare of two servers.  Therefore my final scripts:</p>
<p>Export:</p>
<pre class="brush:powershell">Import-Module ServerManager
Get-WindowsFeature | 
  ? { $_.Installed } | 
  Sort-Object Name | 
  Select Name | 
  ForEach-Object { $_.Name } | 
  Out-File .\Features.txt</pre>
<p>Import:</p>
<pre class="brush:powershell">Import-Module ServerManager
$(Get-Content .\Features.txt) | 
  Add-WindowsFeature</pre>
<p>..and you should be all set.</p>
<div data-counters='1' data-style='square' data-size='regular' data-url='http://jeffmurr.com/blog/?p=273' data-title='Importing and Exporting Windows Features with PowerShell' 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=273' data-title='Importing and Exporting Windows Features with PowerShell' 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=273</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Write-EventLog cmdlet in PowerShell</title>
		<link>http://jeffmurr.com/blog/?p=231</link>
		<comments>http://jeffmurr.com/blog/?p=231#comments</comments>
		<pubDate>Sat, 07 Dec 2013 18:45:40 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Murr]]></dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://jeffmurr.com/blog/?p=231</guid>
		<description><![CDATA[I set out to create a standard method of interacting with the Write-EventLog cmdlet.  Simply put it will fail and I think it shouldn&#8217;t.  It could be a little more robust, so I created my own function that is.  The big thing that most people will benefit from is the ability to create a new [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I set out to create a standard method of interacting with the Write-EventLog cmdlet.  Simply put it will fail and I think it shouldn&#8217;t.  It could be a little more robust, so I created my own function that is.  The big thing that most people will benefit from is the ability to create a new source within a log.  When they execute Write-EventLog they&#8217;re met with an error telling them that a source doesn&#8217;t exist within their log they specified:</p>
<pre><span style="color: #ff0000;">Write-EventLog : The source name "MyScript" does not exist on computer "localhost".</span></pre>
<p>Here&#8217;s a simple way to get around that do that:</p>
<pre class="brush:powershell">PS C:&gt; New-Eventlog -LogName "Application"  -Source "MyScript"</pre>
<p>Change &#8220;MyScript&#8221; to whatever you want the source element to reflect in your event log.</p>
<p>A more robust way of doing check, create if needed, then write and event can be seen here:</p>
<pre class="brush:powershell">$ErrorActionPreference = "SilentlyContinue"
if(!(Get-Eventlog -LogName $LogName -Source $Source)){
     New-Eventlog -LogName "Application"  -Source "MyScript" | Out-Null
}
$ErrorActionPreference = "Continue"
Write-EventLog -LogName "Application" -Source "MyScript" -EntryType "Information" -EventId 0 -Message "Script Started."</pre>
<p>First, I need to explain the &#8220;SilentlyContinue&#8221;.  At least in 2.0, the Get-EventLog cmdlet has problems throwing exceptions.  It doesn&#8217;t throw the exceptions correctly to be in a proper try/catch as discussed <a href="http://social.technet.microsoft.com/Forums/systemcenter/en-US/df254730-b21d-4355-9d06-7ed375bb1bd9/citslibraryps1-geteventlog-no-matches-found?forum=operationsmanagermgmtpacks">here</a>.  It appears to throw a PowerShell error that can&#8217;t be properly try/catched.  After troubleshooting for a few hours, tracing the exception all over, I settled on a workaround.  I set the $ErrorActionPreference variable to &#8220;SilentlyContinue&#8221; and test for a NULL return from Get-EventLog.  If it&#8217;s return is NULL I create the log/source pair for logging and continue on my way.  Any following Write-EventLog executions using the same LogName/Source pairing will log without the source error since you&#8217;ve created it on the machine from now to the end of time.</p>
<p>If you want to expand to include some permissions catching I suggest this approach:</p>
<pre class="brush:powershell">$ErrorActionPreference = "SilentlyContinue"
if(!(Get-Eventlog -LogName $LogName -Source $Source)){
     $ErrorActionPreference = "Continue"
     try {
          New-Eventlog -LogName "Application"  -Source "MyScript" | Out-Null
          Write-EventLog -LogName "Application" -Source MyScript" -EntryType "Information" -EventId 0 -Message "Script Started."
     }

     catch [System.Security.SecurityException] {
          Write-Error "Error:  Run as elevated user.  Unable to write or read to event logs."
     }
}
$ErrorActionPreference = "Continue"</pre>
<p>&nbsp;</p>
<p>I wanted to try and parameterize all of the options that the Write-Event cmdlet could do a little differently so the invocation of it within a script could be more standardized and much cleaner.  So, I extended my working through integrating my own Write-EventLog cmdlet further to exposes all of the power around the cmdlet without getting hung up on errors and unknowns.  Completed function script can be downloaded from <a href="http://jeffmurr.com/blog/?attachment_id=232" rel="attachment wp-att-232">here</a> as well as viewed below:</p>
<pre class="brush:powershell">Function Write-Event {
	&lt;#
		.SYNOPSIS
			Write-Event function writes messages to the event log.

		.DESCRIPTION
			Write-Event function writes messages to the event log 
			after creating the logname and source if not already defined.

		.PARAMETER  $Message
			The message you want displayed in the event log body. 
			Required.

		.PARAMETER  $EventId
			The entryid number you wanted displayed in the event log. 
			Default is 0.

		.PARAMETER  $Source
			The source of the event log you wanted displayed in the event log. 
			Default is the PowerShell script name the function was invoked from.

		.PARAMETER  $LogName
			The log that you want the event loged in. Default is the Application log.
			If the Log and source pair do not exist on the machine this scirpt is 
			invoked on the pair will be created.

		.EXAMPLE
			PS C:\&gt; Write-Event -Message "Process Started." -EntryId 0 -Information

		.EXAMPLE
			PS C:\&gt; Write-Event "Process Started." -Information

		.EXAMPLE
			PS C:\&gt; Write-Event "Process Failed." -EntryId 161 -Error

		.EXAMPLE
			PS C:\&gt; Write-Event "Process Started."

		.INPUTS
			System.String,System.Int32,System.String,System.String,System.Switch,System.Switch

		.OUTPUTS
			None

		.NOTES
			Additional information about the function go here.

		.LINK

http://jeffmurr.com/blog

	#&gt;
	[CmdletBinding()]	
	param(
		[Parameter(Position=0, Mandatory=$true)]
		[ValidateNotNullOrEmpty()]
		[System.String]
		$Message,

		[Parameter(Position=1, Mandatory=$false)]
		[ValidateNotNullOrEmpty()]
		[System.Int32]
		$EventId = 0,

		[Parameter(Position=2, Mandatory=$false)]
		[System.String]
		$Source = "PowerShellScript",

		[Parameter(Position=3, Mandatory=$false)]
		[ValidateNotNullOrEmpty()]
		[System.String]
		$LogName = "Application",

		[Switch]
		$Information,

		[Switch]
		$Warning,

		[Switch]
		$Error
	)

	$ErrorActionPreference = "SilentlyContinue"
	if(!(Get-Eventlog -LogName $LogName -Source $Source)){
		$ErrorActionPreference = "Continue"
		try {New-Eventlog -LogName $LogName -Source $Source | Out-Null}
		catch [System.Security.SecurityException] {
			Write-Error "Error:  Run as elevated user.  Unable to write or read to event logs."
		}
	}

	If ($Warning.IsPresent){	
		try { Write-EventLog -LogName $LogName -Source $Source -EntryType "Warning" -EventId $EventId -Message $Message | Out-Null}
		catch [System.Security.SecurityException] {
			Write-Error "Error:  Run as elevated user.  Unable to write or read to event logs."
		}
	}
	ElseIf ($Error.IsPresent) {
		try { Write-EventLog -LogName $LogName -Source $Source -EntryType "Error" -EventId $EventId -Message $Message | Out-Null}
		catch [System.Security.SecurityException] {
			Write-Error "Error:  Run as elevated user.  Unable to write or read to event logs."
		}	
	}
	Else {
		try { Write-EventLog -LogName $LogName -Source $Source -EntryType "Information" -EventId $EventId -Message $Message | Out-Null}
		catch [System.Security.SecurityException] {
			Write-Error "Error:  Run as elevated user.  Unable to write or read to event logs."
		}
	}
}</pre>
<p>Get to writing to the event log!</p>
<div data-counters='1' data-style='square' data-size='regular' data-url='http://jeffmurr.com/blog/?p=231' data-title='Using Write-EventLog cmdlet in PowerShell' 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=231' data-title='Using Write-EventLog cmdlet in PowerShell' 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=231</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Asymmetric Encryption of Text using x.509 Certificates in PowerShell</title>
		<link>http://jeffmurr.com/blog/?p=228</link>
		<comments>http://jeffmurr.com/blog/?p=228#comments</comments>
		<pubDate>Sat, 07 Dec 2013 18:29:00 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Murr]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Encryption]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://jeffmurr.com/blog/?p=228</guid>
		<description><![CDATA[I&#8217;ve been requested to encryption sections of my script (user name/password) using a certificate issued by a trusted CA.  No problem. To do this in the blog, I&#8217;ll I created a self-signed x.509 certificate and a CN of &#8220;PowerShellCert&#8221;.  I will use the public portion of the certificate in a file that&#8217;s base64 .cer to encrypt the [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve been requested to encryption sections of my script (user name/password) using a certificate issued by a trusted CA.  No problem.</p>
<p>To do this in the blog, I&#8217;ll I created a self-signed <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms721636(v=vs.85).aspx#_security_x.509_gly">x.509</a> certificate and a CN of &#8220;PowerShellCert&#8221;.  I will use the public portion of the certificate in a file that&#8217;s base64 .cer to encrypt the sections.  That certificate I&#8217;ll place in the Windows key store and referenced by thumbprint for decryption.  For the actual work, I&#8217;ll import the CA trusted certificate into the same key store, replace the thumbprint with that CA trusted one and make sure the certificate is trusted either by the user or machine the script is running.</p>
<p>Here&#8217;s the command used with the <a href="http://msdn.microsoft.com/en-us/library/bfsktky3(v=vs.110).aspx">makecert </a>utility to create a 2048 length cert:</p>
<pre class="brush:shell">C:\Program Files\Microsoft SDKs\Windows\v7.1&gt;makecert.exe -r -pe -n "CN=PowerShellCert" -ss my -sr localmachine -eku 1.3.6.1.5.5.7.3.2 -len 2048 -e 01/01/2030 C:\Scripts\PowerShell\Asymmetrical-Encryption\PowerShellAsymmetrical.cer</pre>
<p>Here&#8217;s the encryption function:</p>
<pre class="brush:powershell">Function Encrypt-Asymmetric {
	[CmdletBinding()]
	[OutputType([System.String])]
	param(
		[Parameter(Position=0, Mandatory=$true)][ValidateNotNullOrEmpty()][System.String]
		$ClearText,
		[Parameter(Position=1, Mandatory=$true)][ValidateNotNullOrEmpty()][ValidateScript({Test-Path $_ -PathType Leaf})][System.String]
		$PublicCertFilePath
	)
    # Encrypts a string with a public key
    $PublicCert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($PublicCertFilePath)
    $ByteArray = [System.Text.Encoding]::UTF8.GetBytes($ClearText)
	$EncryptedByteArray = $PublicCert.PublicKey.Key.Encrypt($ByteArray,$true)
	$Base64String = [Convert]::ToBase64String($EncryptedByteArray)

	Return $Base64String 
}</pre>
<p>&#8230;here&#8217;s the decryption function:</p>
<pre class="brush:powershell">Function Decrypt-Asymmetric
{
	[CmdletBinding()]
	[OutputType([System.String])]
	param(
		[Parameter(Position=0, Mandatory=$true)][ValidateNotNullOrEmpty()][System.String]
		$EncryptedBase64String,
		[Parameter(Position=1, Mandatory=$true)][ValidateNotNullOrEmpty()][System.String]
		$CertThumbprint
	)
    # Decrypts cipher text using the private key
    # Assumes the certificate is in the LocalMachine\My (Personal) Store
    $Cert = Get-ChildItem cert:\LocalMachine\My | where { $_.Thumbprint -eq $CertThumbprint }
	if($Cert) {
	    $EncryptedByteArray = [Convert]::FromBase64String($EncryptedBase64String)
	    $ClearText = [System.Text.Encoding]::UTF8.GetString($Cert.PrivateKey.Decrypt($EncryptedByteArray,$true))
    }
	Else {Write-Error "Certificate with thumbprint: $CertThumbprint not found!"}

	Return $ClearText
}</pre>
<p>To Encrypt clear text:</p>
<pre class="brush:shell">PS C:\&gt;Encrypt-Asymmetric -ClearText "CLEAR TEXT DATA" -PublicCertFilePath "C:\Scripts\PowerShell\Asymmetrical-Encryption\PowerShellAsymmetricalTest.cer"</pre>
<p>To Decrypt clear text:</p>
<pre>PS C:\&gt;Decrypt-Asymmetric -EncryptedBase64String $Base64String -CertThumbprint "83D2D68907681EF3D823B23DEE24B0CBB3FA3C51"</pre>
<p>To find your Certificate&#8217;s thumbprint (assuming you gave it the same name as I did above):</p>
<pre class="brush:powershell">PS C:\&gt; Get-ChildItem cert:\LocalMachine\My | where { $_.Subject -eq "CN=PowerShellCert" } | select Thumbprint</pre>
<p>Now, encryption keys can be garded under the Windows key store.</p>
<div data-counters='1' data-style='square' data-size='regular' data-url='http://jeffmurr.com/blog/?p=228' data-title='Asymmetric Encryption of Text using x.509 Certificates in PowerShell' 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=228' data-title='Asymmetric Encryption of Text using x.509 Certificates in PowerShell' 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=228</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PowerShell for Free Space?</title>
		<link>http://jeffmurr.com/blog/?p=208</link>
		<comments>http://jeffmurr.com/blog/?p=208#comments</comments>
		<pubDate>Tue, 10 Sep 2013 13:47:11 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Murr]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://jeffmurr.com/blog/?p=208</guid>
		<description><![CDATA[I needed a script that could be executed to report free space.  I&#8217;ll review how to do it locally and how to wrap it around an array of computer names so it can be ran from anywhere with RPC access to the target machines. For Starters Here&#8217;s the script that gets my my report from [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I needed a script that could be executed to report free space.  I&#8217;ll review how to do it locally and how to wrap it around an array of computer names so it can be ran from anywhere with RPC access to the target machines.</p>
<h3>For Starters</h3>
<p>Here&#8217;s the script that gets my my report from a local computer:</p>
<pre class="brush:powershell">Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3" |
Select-Object Name, FileSystem,FreeSpace,BlockSize,Size |
ForEach-Object {
	$_.BlockSize=(($_.FreeSpace)/($_.Size))*100;$_.FreeSpace=($_.FreeSpace/1GB);$_.Size=($_.Size/1GB);$_
	} |
Format-Table @{n='Server';e={$env:COMPUTERNAME}}, @{n='Disk';e={$_.Name}}, @{n='FS';e={$_.FileSystem}},@{n='Capacity (GB)';e={'{0:N3}' -f $_.Size}},@{n='GB Free';e={'{0:N2}'-f $_.FreeSpace}}, @{n='% Free';e={'{0:N2}'-f $_.BlockSize}} -AutoSize</pre>
<h3>Do it Remote:</h3>
<p>Keep in mind the entire script can be wrapped around a &#8220;<strong>foreach</strong>&#8221; statement and pass in the <strong>ComputerName</strong> parameter for remote execution.</p>
<pre class="brush:powershell">$ComputerNames = @("Server1", "Server2", "Server3")

foreach ($ComputerName in $ComputerNames) {

	Get-WmiObject -ComputerName $ComputerName -Class Win32_LogicalDisk -Filter "DriveType=3" |
	Select-Object Name, FileSystem,FreeSpace,BlockSize,Size |
	ForEach-Object {
		$_.BlockSize=(($_.FreeSpace)/($_.Size))*100;$_.FreeSpace=($_.FreeSpace/1GB);$_.Size=($_.Size/1GB);$_
		} |
	Format-Table @{n='Server';e={$ComputerName}}, @{n='Disk';e={$_.Name}}, @{n='FS';e={$_.FileSystem}},@{n='Capacity (GB)';e={'{0:N3}' -f $_.Size}},@{n='GB Free';e={'{0:N2}'-f $_.FreeSpace}}, @{n='% Free';e={'{0:N2}'-f $_.BlockSize}} -AutoSize

}</pre>
<h3>Report What You Found:</h3>
<p>Afterward, sprinkle in the export type you&#8217;d like (file, CSV, etc.) to deliver.</p>
<pre class="brush:powershell">$ComputerNames = @("Server1", "Server2", "Server3")

$DiskSpaceReport = foreach ($ComputerName in $ComputerNames) {

	Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3" |
	Select-Object Name, FileSystem,FreeSpace,BlockSize,Size |
	ForEach-Object {
		$_.BlockSize=(($_.FreeSpace)/($_.Size))*100;$_.FreeSpace=($_.FreeSpace/1GB);$_.Size=($_.Size/1GB);$_
		} |
	Format-Table @{n='Server';e={$ComputerName}}, @{n='Disk';e={$_.Name}}, @{n='FS';e={$_.FileSystem}},@{n='Capacity (GB)';e={'{0:N3}' -f $_.Size}},@{n='GB Free';e={'{0:N2}'-f $_.FreeSpace}}, @{n='% Free';e={'{0:N2}'-f $_.BlockSize}} -AutoSize

}

$DiskSpaceReport | Export-Csv
$DiskSpaceReport | Out-File
$DiskSpaceReport | Out-GridView</pre>
<p>&nbsp;</p>
<div data-counters='1' data-style='square' data-size='regular' data-url='http://jeffmurr.com/blog/?p=208' data-title='PowerShell for Free Space?' 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=208' data-title='PowerShell for Free Space?' 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=208</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WinRM for an Environment Simplified</title>
		<link>http://jeffmurr.com/blog/?p=178</link>
		<comments>http://jeffmurr.com/blog/?p=178#comments</comments>
		<pubDate>Fri, 02 Aug 2013 22:28:44 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Murr]]></dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[WinRM]]></category>

		<guid isPermaLink="false">http://jeffmurr.com/blog/?p=178</guid>
		<description><![CDATA[Windows Remote Management (WinRM) is the Microsoft implementation of WS-Management Protocol.  In many key items within the latest offerings from Microsoft management, included most obviously for me, PowerShell, it is the under pinning of many of the remote management operations. The idea is a good one.  Align with a standard in your latest technologies methods used to manage [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Windows Remote Management (<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa384426(v=vs.85).aspx">WinRM</a>) is the Microsoft implementation of <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa384470(v=vs.85).aspx">WS-Management Protocol</a>.  In many key items within the latest offerings from Microsoft management, included most obviously for me, <a href="http://technet.microsoft.com/en-us/library/bb978526.aspx">PowerShell</a>, it is the under pinning of many of the remote management operations.</p>
<p>The idea is a good one.  Align with a standard in your latest technologies methods used to manage yourself, making you more usable by others.</p>
<p>In this post I&#8217;ll offer a quick WinRM configuration PowerShell script to get this feature configured on a Windows 2008, R2, and Windows 2012 server.  I&#8217;ll also offer feedback on the security objection and what I think is the best solution for a native Windows environment since I&#8217;ve hand to handle these often in my line of work.</p>
<p><strong>Configuration Simplified</strong></p>
<p>Get right to it for those not wanting to read any more.  Open a PowerShell Console as Administrator on both the client and server, servers and execute:</p>
<pre class="brush:powershell">Write-Host "Configuring WinRM for remote deployment..."
Enable-PSRemoting -Force 
winrm set winrm/config/client `@`{TrustedHosts=`"*`"`}</pre>
<p><strong>More detail&#8230;</strong></p>
<p>For PowerShell, WinRM is the basis of many cmdlets performing remote commands and tasks.  This includes <a href="http://technet.microsoft.com/en-us/library/hh849707.aspx">Enter-PSSession</a> and <a href="http://technet.microsoft.com/en-us/library/hh849719.aspx">Invoke-Command</a>.  These cmdlets offer powerful abilities to perform tasks on a remote computer both synchronously and in parallel, asynchronously to an array object of server names.</p>
<p>Believe it or not (from this <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa384372(v=vs.85).aspx">lengthy </a>write up), Microsoft wanted taking advantage of the protocol easier and less of a burden to implement.  As a result, <strong>WinRM.exe</strong> comes with a &#8220;-<strong>quickconfig</strong>&#8221; option for quick local configuration of itself, complete with a set of Microsoft&#8217;s best practice defaults.  Almost too good, and I&#8217;ll get to that below.</p>
<p>Therefore, the easiest thing to do is to go to a cmd prompt as an admin and run to get it all started:</p>
<pre class="brush:shell">WinRM quickconfig</pre>
<p>This will set up your local service with everything to get started.  Essentially, turning on the lights.</p>
<p>Powershell&#8217;s flavor of this command is rolled up into  <a href="http://technet.microsoft.com/library/hh849867.aspx">Set-WSManQuickConfig</a>.  However, these both only modify the config of the service.  For the windows firewall, Microsoft gave us another cmdlet that&#8217;s a wrapper for <a href="http://technet.microsoft.com/library/hh849867.aspx">Set-WSManQuickConfig</a>.  <a href="http://technet.microsoft.com/en-us/library/hh849694.aspx">Enable-PSRemoting</a> cmdlet performs a few other functions as well as executing the <a href="http://technet.microsoft.com/library/hh849867.aspx">Set-WSManQuickConfig</a>.  Things like configuring the Windows firewall (in 2.0 it creates the exception, in 3.0 it creates a rule).</p>
<p>If you ride the defaults of these configurations with regards to network port, any external firewalls between your client and server will need to allow tcp 5986 bidirectional for WinRM 2.0 and above, 443 for WinRM 1.1.</p>
<p>Even after you run the &#8220;<strong>WinRM -quickconfig</strong>&#8221; or &#8220;<strong>Enable-PSRemoting&#8221;</strong>, you&#8217;ll find commands attempted remotely like <strong>Invoke-Command</strong> or <strong>Enter-PSSession</strong> will still fail complaining about a configuration error.  The reason is that you&#8217;ve only turned on the lights, you haven&#8217;t told the bouncer who is allowed in.  Be default, these tools do not trust anyone to connect other than&#8230;localhost.  The list of allowed servers is listed in the &#8220;<em><strong>TrustedHost</strong></em>&#8221; property of WinRM configuration.  Both of these tools the default <strong>TrustedHost</strong> list is blank.</p>
<p>Therefore, lets get back to the PowerShell.  Its a quick and dirty solution that&#8217;s wide open and will that need to be executed on both machines you want to configure to talk remote to one another:</p>
<pre class="brush:powershell">Write-Host "Configuring WinRM for remote deployment..."
Enable-PSRemoting -Force 
winrm set winrm/config/client `@`{TrustedHosts=`"*`"`} 
winrm set winrm/config/winrs `@`{MaxMemoryPerShellMB=`"2048`"`}</pre>
<p>As you can guess, &#8220;*&#8221; is everyone and may not be good enough for your needs.  Below we discuss more security aspects of a quick configuration.</p>
<p><strong>Locking it down</strong></p>
<p>There are complex scripts on the internet that allow for the setup of servers, even doing it <a href="http://gallery.technet.microsoft.com/scriptcenter/Enable-PSRemoting-Remotely-6cedfcb0">remotely</a>.  Out of the box both the WinRM and the cmdlets leave you with blank <strong>TrustedHosts</strong>.  Servers that will send or receive commands from other hosts must either have a white listed &#8220;*&#8221; or the specific servernames/IP in this list before you can connect.</p>
<p>The next script creates a list of servers passed as a CSV file and establishes it as your <strong>TrustedHost</strong> property.  As long as a column within your CSV file contains &#8220;Server&#8221; as a heading, those values will be included in the trusted hosts configuration and applied to the machine&#8217;s <strong>TrustedHost </strong>configuration of WinRM.</p>
<pre class="brush:powershell">param(
	[Parameter(Position=0, Mandatory=$true)]
	[ValidateNotNullOrEmpty()]
	[System.String]
	$CSVFilePath
)

function Get-ServerList {
	param(
		$CSVFilePath
	)

	$Servers = Import-Csv $CSVFilePath
	$Servers | % {$List += $_.Server + ","}

	Return $List.Substring(0,$List.Length - 1)

}

function Configure-WinRM {
	param(
		$ServerList
	)
	Write-Host "Configuring WinRM for remote deployment..."
	Enable-PSRemoting -Force 
	winrm set winrm/config/client `@`{TrustedHosts=`"$ServerList`"`}  
	winrm set winrm/config/winrs `@`{MaxMemoryPerShellMB=`"2048`"`}
}

Configure-WinRm -ServerList $(Get-ServerList -CSVFilePath $CSVFilePath)</pre>
<p><strong>Note:</strong>  In both examples within the explanation, I&#8217;ve up the <strong>MaxMemoryPerShellMB</strong>.  This is optional; however, I&#8217;ve found that many tools that I may need or objects that I create are heavier than the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ee309367(v=vs.85).aspx">default 150 MB</a> amount.  I&#8217;ve found that upping it to 2048 will mitigate my running out of remote memory during processing large commands like regasm or installation packages.  Mis-configuration usually results in an obfuscated -1 exit code or just instability.  It wasn&#8217;t until I popped open process explorer that I found I was hitting a limit that most bigger executables require more of.  Totally up to you, but it is part of my server buildout now along with a correct server.csv list and features.</p>
<p><strong>The Remaining Security Concerns (For Windows Environments)</strong></p>
<p><strong>TrustedHosts</strong> means only these computers can connect.  Security engineers will wonder what those connections are passing, even if its in a protected zone, between the servers listed and if that&#8217;s secure.</p>
<p>First the obvious, SSL is an option for WinRM.  However, I caution configuring it if your talking Windows to Windows. When asked, if you should configure SSL for security loving systems folks it can be tempting to think it is better.  The balance between and security, support and use is something we all have to deal with constantly.  In banking and healthcare it constantly audited, as it should be and I understand, layers is the answer to security.  But, WinRM with <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa384291(v=vs.85).aspx">WS-Management</a> encrypts all content transmitted over the network using Kerberos and these NTLM (machine) keys.  With Windows, a minimum of 128 bit encryption (Windows 7/2008 and up) is already in place with most later OS&#8217;s pushing the AES 256 button now.</p>
<p>The only thing that HTTPS will do is encrypt commands <strong><em>differently, that can be watered down</em></strong>.  Not to mention give a shelf life to your configuration the length of the validity of your certificates, before they expire.  I applaud the extensiblility, but its truly overkill in a windows environment and making something that needs to remain easy too complex; hence me leaving it out of the configuration and discussing it here.</p>
<p>Now, if you&#8217;re leaving a Windows environment, yes; install and configure if you&#8217;re using a non Windows product to manage a Windows machine.  That&#8217;s part of the the initiative behind WS-Management, uniform cross platform communication.  Everyone OS doesn&#8217;t have the same encryption methods as Windows baked in.  For that, I&#8217;ll have to cover another day.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div data-counters='1' data-style='square' data-size='regular' data-url='http://jeffmurr.com/blog/?p=178' data-title='WinRM for an Environment Simplified' 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=178' data-title='WinRM for an Environment Simplified' 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=178</wfw:commentRss>
		<slash:comments>1</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>
