<?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; .NET</title>
	<atom:link href="http://jeffmurr.com/blog/?feed=rss2&#038;tag=net" 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>Grant NTFS Permissions to a Domain Group using C#</title>
		<link>http://jeffmurr.com/blog/?p=244</link>
		<comments>http://jeffmurr.com/blog/?p=244#comments</comments>
		<pubDate>Tue, 22 Apr 2014 12:54:11 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Murr]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://jeffmurr.com/blog/?p=244</guid>
		<description><![CDATA[Coupled with creating a network file share, you need to also ensure NTFS permissions are not more restrictive than the permissions you create on your share.  Otherwise, they will trump those permissions and your file share will be half done.  The least restrictive permissions always win.  See technet for more details on the security model. Using [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Coupled with creating a network <a href="http://jeffmurr.com/blog/?p=241">file share</a>, you need to also ensure NTFS permissions are not more restrictive than the permissions you create on your share.  Otherwise, they will trump those permissions and your file share will be half done.  The least restrictive permissions always win.  See <a href="http://technet.microsoft.com/en-us/library/cc754178.aspx">technet </a>for more details on the security model.</p>
<p>Using a mix of the <a href="http://msdn.microsoft.com/en-us/library/System.Security.Principal(v=vs.110).aspx">Security.Principal</a> and <a href="http://msdn.microsoft.com/en-us/library/system.security.accesscontrol(v=vs.110).aspx">Security.AccessControl </a>.NET Classes you can couple this with your file share create class and get a complete set up of a file share; or, just use it to set NTFS permissions without all the file share portions in the previous post to set NTFS permissions on their own.</p>
<pre class="brush:csharp">using System.Security.Principal;
using System.Security.AccessControl;

        public static void GrantNTFSPermissions(string FolderPath, string Domain, string Group)
        {
            // Create a new DirectoryInfo object.
            DirectoryInfo directoryInfo = new DirectoryInfo(FolderPath);

            // Get a DirectorySecurity object that represents the 
            // current security settings.
            DirectorySecurity directorySecurity = directoryInfo.GetAccessControl();

            // Add the FileSystemAccessRule to the security settings. 
            directorySecurity.AddAccessRule(
                new FileSystemAccessRule(
                    new NTAccount(Domain, Group), 
                    FileSystemRights.Modify | FileSystemRights.ReadAndExecute | FileSystemRights.ListDirectory | FileSystemRights.Read | FileSystemRights.Write, 
                    InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None,
                    AccessControlType.Allow)
                );

            // Set the new access settings.
            directoryInfo.SetAccessControl(directorySecurity);

        }</pre>
<p><strong>Important Note:</strong>  Passing mulitple values separated with a &#8220;|&#8221; to the <a href="http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesystemaccessrule(v=vs.110).aspx">FileSystemAccessRule </a>class constructor&#8217;s parameters, allows you to set multiple options at once over mutliple calls/rewrites.</p>
<div data-counters='1' data-style='square' data-size='regular' data-url='http://jeffmurr.com/blog/?p=244' data-title='Grant NTFS Permissions to a Domain Group using C#' 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=244' data-title='Grant NTFS Permissions to a Domain Group using C#' 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=244</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Network File Share in .NET C#</title>
		<link>http://jeffmurr.com/blog/?p=241</link>
		<comments>http://jeffmurr.com/blog/?p=241#comments</comments>
		<pubDate>Wed, 19 Feb 2014 22:41:31 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Murr]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://jeffmurr.com/blog/?p=241</guid>
		<description><![CDATA[Well, kinda&#8230; Using the ManagmentClass class (someone might be regretting the naming here) we can expose WMI in .NET.  Then, we can operate on methods of the Windows Managment Interface to create shares in C# code. Like all Windows API work, this isn&#8217;t super clear throughout MSDN or the Internet.  I also find that Windows [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Well, kinda&#8230;</p>
<p>Using the <a href="http://msdn.microsoft.com/en-us/library/system.management.managementclass(v=vs.110).aspx">ManagmentClass</a> class (someone might be regretting the naming here) we can expose WMI in .NET.  Then, we can operate on methods of the Windows Managment Interface to create shares in C# code.</p>
<p>Like all Windows API work, this isn&#8217;t super clear throughout MSDN or the Internet.  I also find that Windows API return codes are a pain.  When I operate in that old schools space I try to take the next step and get a return code description method created.</p>
<p>Below, we create a security descriptor and share using .NET and WMI objects (with some return code flare).</p>
<p>Enjoy!</p>
<p>1) Figure out who you want access to your share.  This must be done with the use of of a <a href="http://msdn.microsoft.com/en-us/library/aa394402(v=vs.85).aspx">Win32_SecurityDescriptor</a> in WMI:</p>
<pre class="brush:csharp">        private static ManagementBaseObject SecurityDescriptor()
        {
            NTAccount account = new NTAccount("NT Authority", "Everyone");
            SecurityIdentifier sid = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier));
            byte[] sidArray = new byte[sid.BinaryLength];
            sid.GetBinaryForm(sidArray, 0);
            ManagementObject Trustee = new ManagementClass(new ManagementPath("Win32_Trustee"), null);
            Trustee["Domain"] = "NT Authority";
            Trustee["Name"] = "Everyone";
            Trustee["SID"] = sidArray;
            ManagementObject AdminACE = new ManagementClass(new ManagementPath("Win32_Ace"), null);
            AdminACE["AccessMask"] = 2032127;
            AdminACE["AceFlags"] = 3;
            AdminACE["AceType"] = 0;
            AdminACE["Trustee"] = Trustee;
            ManagementObject SecurityDescriptor = new ManagementClass(new ManagementPath("Win32_SecurityDescriptor"), null);
            SecurityDescriptor["ControlFlags"] = 4; //SE_DACL_PRESENT
            SecurityDescriptor["DACL"] = new object[] { AdminACE };
            return SecurityDescriptor;
        }</pre>
<p>It&#8217;s never easy with security&#8230;.</p>
<p>So for an explaination of the above; first, you look up your principle using <a href="http://msdn.microsoft.com/en-us/library/system.security.principal.ntaccount(v=vs.110).aspx">NTAccount</a> then create a <a href="http://msdn.microsoft.com/en-us/library/aa394501(v=vs.85).aspx">Win32_Trustee</a> from that principal.</p>
<p><strong><em>note:</em></strong>  this method can *easily* be parameterized for a domain:</p>
<pre class="brush:csharp">        private static ManagementBaseObject SecurityDescriptor(string domain, string user)
        {
            NTAccount account = new NTAccount(domain, user);
            SecurityIdentifier sid = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier));

[...]</pre>
<p>Then, you estable what access controll entry (<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa374868(v=vs.85).aspx">ACE)</a> you want to grant to the principal(s) using the <a href="http://msdn.microsoft.com/en-us/library/aa394063(v=vs.85).aspx">Win32_Ace</a> object.  The SecurityDescriptor method above includes it all.  Side note: ACL and ACE&#8217;s are the most confusing things to code in Windows for me, bar none.  It&#8217;s not easy, play with the code to taste if you need specific access and don&#8217;t forget to review the <a href="http://msdn.microsoft.com/en-us/library/aa394063(v=vs.85).aspx">AccessMask</a> and <a href="http://msdn.microsoft.com/en-us/library/aa394063(v=vs.85).aspx">AceTypes</a> to limit down from full control as needed.  To add multiple add them as comma separated DACL&#8217;s like so:</p>
<pre class="brush:csharp">SecurityDescriptor["DACL"] = new object[] { AdminACE, MyACE, YourACE, OurACE };</pre>
<p>2) Finally, create your share</p>
<p>First, create your <a href="http://msdn.microsoft.com/en-us/library/system.management.managementclass(v=vs.110).aspx">ManagmentClass object</a> and parameters (using your above security principal(s)) for the &#8220;Create&#8221; method of the <a href="http://msdn.microsoft.com/en-us/library/aa389393(v=vs.85).aspx">Win32_Share</a>.  If anything funky happens decode the response code description.</p>
<pre class="brush:csharp">        public static void CreateShare(string FolderPath, string ShareName, string Description)
        {
            //create a ManagementClass object
            ManagementClass managementClass = new ManagementClass("Win32_Share");

            //create ManagementBaseObjects for in and out parameters
            ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
            ManagementBaseObject outParams;

            // Set the input parameters
            inParams["Description"] = Description;
            inParams["Name"] = ShareName;
            inParams["Path"] = FolderPath;
            inParams["Type"] = 0x0; // Disk Drive

            //invoke the method
            outParams = managementClass.InvokeMethod("Create", inParams, null);

            //check to see if the method invocation was successful
            uint rVal = (uint)(outParams.Properties["ReturnValue"].Value);
            if (rVal != 0 &amp;&amp; rVal != 22) //ok if it already exists
            {
                throw new Exception(String.Format("Unable to share directory. \nReturn Code: {0} \nDescription: {1}", rVal, getCreateShareReturnCodeDescription(rVal)));
            }
        }

        private static string getCreateShareReturnCodeDescription(uint returnValue)
        {
            switch (returnValue)
            {
                case 0:
                    return "Success";
                case 2:
                    return "Access Denied";
                case 8:
                    return "Unknown Failure";
                case 9:
                    return "Invalid Name";
                case 10:
                    return "Invalid Level";
                case 21:
                    return "Invalid Parameter";
                case 22:
                    return "Duplicate Share";
                case 23:
                    return "Redirect Path";
                case 24:
                    return "Unknown Device or Directory";
                case 25:
                    return "Net Name Not Found";
            }
            return "Unknown";
        }</pre>
<div data-counters='1' data-style='square' data-size='regular' data-url='http://jeffmurr.com/blog/?p=241' data-title='Network File Share in .NET C#' 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=241' data-title='Network File Share in .NET C#' 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=241</wfw:commentRss>
		<slash:comments>4</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>&#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>
	</channel>
</rss>
