<?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>Geoff @ UVM</title>
	<atom:link href="http://gcd.w3.uvm.edu/feed/" rel="self" type="application/rss+xml" />
	<link>http://gcd.w3.uvm.edu</link>
	<description>Adventures in System Administration</description>
	<lastBuildDate>Mon, 08 Apr 2013 20:21:16 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Disable SSLv2 on IIS</title>
		<link>http://gcd.w3.uvm.edu/2013/02/disable-sslv2-on-iis/</link>
		<comments>http://gcd.w3.uvm.edu/2013/02/disable-sslv2-on-iis/#comments</comments>
		<pubDate>Thu, 28 Feb 2013 19:04:23 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://gcd.w3.uvm.edu/?p=616</guid>
		<description><![CDATA[Microsoft KB 187498 describes the registry values that can be used to disable various security protocols. Disabling SSLv2 is as easy as This does require a reboot to put into affect.]]></description>
				<content:encoded><![CDATA[<p><a href="http://support.microsoft.com/kb/187498">Microsoft KB 187498</a> describes the registry values that can be used to disable various security protocols. Disabling SSLv2 is as easy as</p>
<pre class="brush: vb; gutter: false; title: ; notranslate">
reg add &quot;HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server&quot; /V Enabled /t REG_DWORD /d 0
</pre>
<p>This does require a reboot to put into affect.</p>
]]></content:encoded>
			<wfw:commentRss>http://gcd.w3.uvm.edu/2013/02/disable-sslv2-on-iis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Which Disk is that volume on?</title>
		<link>http://gcd.w3.uvm.edu/2013/01/which-disk-is-that-volume-on/</link>
		<comments>http://gcd.w3.uvm.edu/2013/01/which-disk-is-that-volume-on/#comments</comments>
		<pubDate>Thu, 31 Jan 2013 19:02:17 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[administration]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[VMware]]></category>
		<category><![CDATA[WMI]]></category>

		<guid isPermaLink="false">http://gcd.w3.uvm.edu/?p=606</guid>
		<description><![CDATA[I administer a server VM with a lot of disks, and many of them are the same size. When I need to make changes to the system&#8217;s storage, I&#8217;m always nervous that I&#8217;m going to poke the wrong disk. I could trust that the order of the disks listed in the vSphere client is the [...]]]></description>
				<content:encoded><![CDATA[<p>I administer a server VM with a lot of disks, and many of them are the same size. When I need to make changes to the system&#8217;s storage, I&#8217;m always nervous that I&#8217;m going to poke the wrong disk. I could trust that the order of the disks listed in the vSphere client is the same as the order that the guest OS lists (starting at 1 and 0 respectively). But I want a little more assurance.</p>
<p>Using <strong>diskpart</strong>, you can list the details for individual disks, partitions and volumes, but I wanted a report showing all the disks, the partitions on those disks, and the volumes residing on those partitions. I have reported some of this info previously, using PowerShell&#8217;s <strong>Get-WMIObject</strong> cmdlet to query the <em>Win32_DiskDrive</em>, <em>Win32_Partition</em>, and <em>Win32_Volume</em> classes. I figured there must me a way to correlate instances of these classes.</p>
<p>I found these two blog posts:</p>
<ul>
<li>Scripting Guy&#8217;s <em><a href="http://blogs.technet.com/b/heyscriptingguy/archive/2005/05/23/how-can-i-correlate-logical-drives-and-physical-disks.aspx">How Can I Correlate Logical Drives and Physical Disks?</a></em></li>
<li>JRich&#8217;s <em><a href="http://jrich523.wordpress.com/2011/12/12/using-wmi-to-link-a-disk-volume-to-a-physical-disk-with-powershell/">Using WMI to link a Disk Volume to a Physical Disk with PowerShell</a></em></li>
</ul>
<p>They did most of the heavy lifting in building the <a href="http://msdn.microsoft.com/en-us/library/aa384793.aspx">WQL <em>ASSOCIATOR OF</em> queries</a>. I put together a short script to give me a little more detail. Here&#8217;s some sample output:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
PS C:\local\scripts&gt; .\Get-DiskInfo.ps1
Disk 0 - SCSI 0:0:2:0 - 45.00 GB
    Partition 0  100.00 MB  Installable File System
    Partition 1  44.90 GB  Installable File System
        C: [NTFS] 44.90 GB ( 3.46 GB free )
[...]
Disk 5 - SCSI 0:0:2:5 - 39.99 GB
    Partition 0  40.00 GB  Installable File System
        B: [NTFS] 40.00 GB ( 34.54 GB free )
</pre>
<p>This will make it easier to be sure about the vSphere storage element that corresponds to a particular volume (or, more accurately, the Physical Disk on which the volume resides).</p>
<p>Here&#8217;s the actual script:</p>
<pre class="brush: powershell; title: ; notranslate">
&lt;#
.SYNOPSIS
Get information about the physical disks and volumes on a system.

.DESCRIPTION
Get details about the physical disks and the volumes located on
those disks, to make it easier to identify corresponding vSphere
storage (VMDKs).

.EXAMPLE

PS C:\&gt; .\Get-DiskInfo.ps1

.NOTES
    Author: Geoff Duke &lt;Geoffrey.Duke@uvm.edu&gt;
    Based on http://bit.ly/XowLns and http://bit.ly/XeIqFh
#&gt;

Set-PSDebug -Strict

Function Main {

    $diskdrives = get-wmiobject Win32_DiskDrive | sort Index

    $colSize = @{Name='Size';Expression={Get-HRSize $_.Size}}

    foreach ( $disk in $diskdrives ) {

        $scsi_details = 'SCSI ' + $disk.SCSIBus         + ':' +
                                  $disk.SCSILogicalUnit + ':' +
                                  $disk.SCSIPort        + ':' +
                                  $disk.SCSITargetID
        write $( 'Disk ' + $disk.Index + ' - ' + $scsi_details +
                 ' - ' + ( Get-HRSize $disk.size) )

        $part_query = 'ASSOCIATORS OF {Win32_DiskDrive.DeviceID=&quot;' +
                      $disk.DeviceID.replace('\','\\') +
                      '&quot;} WHERE AssocClass=Win32_DiskDriveToDiskPartition'

        $partitions = @( get-wmiobject -query $part_query | 
                         sort StartingOffset )
        foreach ($partition in $partitions) {

            $vol_query = 'ASSOCIATORS OF {Win32_DiskPartition.DeviceID=&quot;' +
                         $partition.DeviceID +
                         '&quot;} WHERE AssocClass=Win32_LogicalDiskToPartition'
            $volumes   = @(get-wmiobject -query $vol_query)

            write $( '    Partition ' + $partition.Index + '  ' +
                     ( Get-HRSize $partition.Size) + '  ' +
                     $partition.Type
                   )

            foreach ( $volume in $volumes) {
                write $( '        ' + $volume.name + 
                         ' [' + $volume.FileSystem + '] ' + 
                         ( Get-HRSize $volume.Size ) + ' ( ' +
                         ( Get-HRSize $volume.FreeSpace ) + ' free )'
                       )

            } # end foreach vol

        } # end foreach part

        write ''

    } # end foreach disk

}

#--------------------------------------------------------------------
function Get-HRSize {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$True, ValueFromPipeline=$True)]
        [INT64] $bytes
    )
    process {
        if     ( $bytes -gt 1pb ) { &quot;{0:N2} PB&quot; -f ($bytes / 1pb) }
        elseif ( $bytes -gt 1tb ) { &quot;{0:N2} TB&quot; -f ($bytes / 1tb) }
        elseif ( $bytes -gt 1gb ) { &quot;{0:N2} GB&quot; -f ($bytes / 1gb) }
        elseif ( $bytes -gt 1mb ) { &quot;{0:N2} MB&quot; -f ($bytes / 1mb) }
        elseif ( $bytes -gt 1kb ) { &quot;{0:N2} KB&quot; -f ($bytes / 1kb) }
        else   { &quot;{0:N} Bytes&quot; -f $bytes }
    }
} # End Function:Get-HRSize

Main

</pre>
<p>Please let me know if you find this helpful.</p>
]]></content:encoded>
			<wfw:commentRss>http://gcd.w3.uvm.edu/2013/01/which-disk-is-that-volume-on/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GUID Chase &#8211; Group Policy troubleshooting</title>
		<link>http://gcd.w3.uvm.edu/2013/01/guid-chase-group-policy-troubleshooting/</link>
		<comments>http://gcd.w3.uvm.edu/2013/01/guid-chase-group-policy-troubleshooting/#comments</comments>
		<pubDate>Fri, 18 Jan 2013 15:55:39 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[Group Policy]]></category>
		<category><![CDATA[Troubleshooting]]></category>

		<guid isPermaLink="false">http://gcd.w3.uvm.edu/?p=598</guid>
		<description><![CDATA[It started with an alert from System Center Operations Manager about a failed scheduled task. Of course, the alert references a task name that looks like a SID.  Running schtasks /query show a few jobs with a status that warranted inspection. Looking at the Microsoft-Windows-TaskScheduler/Operational log I found that the task &#8220;\Microsoft\Windows\CertificateServicesClient\UserTask&#8221; is the one [...]]]></description>
				<content:encoded><![CDATA[<p>It started with an alert from System Center Operations Manager about a failed scheduled task. Of course, the alert references a task name that looks like a SID.  Running <strong>schtasks /query</strong> show a few jobs with a status that warranted inspection. Looking at the Microsoft-Windows-TaskScheduler/Operational log I found that the task &#8220;\Microsoft\Windows\CertificateServicesClient\UserTask&#8221; is the one the failed and triggered the alert.</p>
<p>I also noted that there were some Group Policy processing errors occurring at about the same time as the task failure, including a problem applying the Group Policy Scheduled Tasks settings. And the failing task starts at user login.</p>
<p>Next, I ran <strong>gpresult /h</strong> to create a report of the GPOs and settings that applied, and any errors that were generated. The report confirmed that there were failures in applying the <em>Group Policy Files settings</em> and the <em>Group Policy Scheduled Tasks settings</em>.</p>
<p>Some web searching turned up <a href="http://social.technet.microsoft.com/Forums/eu/winserverGP/thread/4f2247df-d3ff-49dc-bd25-2b242946f3b4">this thread</a>, among others, which pointed me to the Group Policy History files in C:\Users\All Users\Microsoft\Group Policy\History. This directory contained four subdirectories named with the GUIDs for the corresponding GPOs. I was able to find three of the four GPOs by inspecting the details in the GPMC, but I couldn&#8217;t find the fourth.</p>
<p>I decided to search more programmatically, and started with an LDAP search with <a href="http://www.joeware.net/freetools/tools/adfind/index.htm">ADFind</a>:</p>
<pre class="brush: plain; title: ; notranslate">
adfind -f &quot;&amp;(objectClass=groupPolicyContainer)(Name={DC257675-89C1-5AA6-5F65-B5D5CFC35E17})&quot;
0 Objects returned
</pre>
<p>Then, just to be sure, I used the <a href="http://technet.microsoft.com/en-us/library/ee461027.aspx">PowerShell GroupPolicy module</a>:</p>
<pre class="brush: powershell; title: ; notranslate">
PS Z:\&gt; import-module GroupPolicy
PS Z:\&gt; get-gpo -guid &quot;{DC257675-89C1-5AA6-5F65-B5D5CFC35E17}&quot;
Get-GPO : A GPO with ID {DC257675-89C1-5AA6-5F65-B5D5CFC35E17} was not found in the campus.ad.uvm.edu domain.
</pre>
<p>So I removed the subdirectory with that name from the GP History directory, and retried <strong>gpupdate /force</strong>. This time, it completed successfully.</p>
]]></content:encoded>
			<wfw:commentRss>http://gcd.w3.uvm.edu/2013/01/guid-chase-group-policy-troubleshooting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>String arrays and mandatory parameters</title>
		<link>http://gcd.w3.uvm.edu/2012/12/string-arrays-and-mandatory-parameters/</link>
		<comments>http://gcd.w3.uvm.edu/2012/12/string-arrays-and-mandatory-parameters/#comments</comments>
		<pubDate>Fri, 07 Dec 2012 21:33:05 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Troubleshooting]]></category>

		<guid isPermaLink="false">http://gcd.w3.uvm.edu/?p=573</guid>
		<description><![CDATA[I have been working on a function to convert the output of NET SHARE &#60;sharename&#62; commands into usable PowerShell objects. In the course of my work, I was storing the output of the command in a variable, which I later pass into a parsing function. Curiously, the function I developed iteratively in the console worked [...]]]></description>
				<content:encoded><![CDATA[<p>I have been working on a function to convert the output of <strong>NET SHARE &lt;sharename&gt;</strong> commands into usable PowerShell objects. In the course of my work, I was storing the output of the command in a variable, which I later pass into a parsing function. Curiously, the function I developed iteratively in the console worked fine, but when I dressed it up in my script, it failed:</p>
<pre class="brush: powershell; gutter: false; title: ; notranslate">
test-array : Cannot bind argument to parameter 'foo' because it is an empty string.
At line:1 char:12
+ test-array $party
+            ~~~~~~
    + CategoryInfo          : InvalidData: (:) [test-array], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,test-array
</pre>
<p>I had verified that the variable was of type <strong>System.Array</strong>, and that it had string elements. After banging my head on it for a while, I decided to break out the parameter handling and test it separately. I wrote a quick function to accept and process the elements of a string array:</p>
<pre class="brush: powershell; title: ; notranslate">
function test-array {
param( [string[]] $foo )
    $i = 0
    foreach ( $line in $foo ) {
        write &quot;[$i] $line&quot;
        $i++
    }
}
</pre>
<p><span id="more-573"></span></p>
<p>When I created an array of strings and passed it into the function, it performed as expected:</p>
<pre class="brush: powershell; gutter: false; title: ; notranslate">
PS Z:\&gt; $party = 'cleric','fighter','rogue','wizard'
PS Z:\&gt; test-array $party
[0] cleric
[1] fighter
[2] rogue
[3] wizard
</pre>
<p>The error message describes an inability to bind an empty string, so I added a empty string value to my array and tried again:</p>
<pre class="brush: powershell; gutter: false; title: ; notranslate">
PS Z:\&gt; $party = 'cleric','fighter','','rogue','wizard'
PS Z:\&gt; test-array $party
[0] cleric
[1] fighter
[2] rogue
[3]
[4] wizard
</pre>
<p>So passing an array of strings to a function works fine. Then I added the <code>mandatory</code> parameter property to the function definition:</p>
<pre class="brush: powershell; highlight: [2]; title: ; notranslate">
function test-array {
param( [parameter(Mandatory=$true)] [string[]] $foo )
    $i = 0
    foreach ( $line in $foo ) {
        write &quot;[$i] $line&quot;
        $i++
    }
}
</pre>
<p>Running the test with the same array elements as before elicited the error seen previously:</p>
<pre class="brush: powershell; gutter: false; title: ; notranslate">
PS Z:\&gt; $party
cleric
fighter

rogue
wizard
PS Z:\&gt; test-array $party
test-array : Cannot bind argument to parameter 'foo' because it is an empty string.
At line:1 char:11
+ test-array &lt;&lt;&lt;&lt;  $party
    + CategoryInfo          : InvalidData: (:) [test-array], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,test-array
</pre>
<p>Since the output of the <strong>NET SHARE &lt;sharename&gt;</strong> command includes blank lines, I&#8217;ll have to forego including the <strong>mandatory</strong> parameter property.</p>
]]></content:encoded>
			<wfw:commentRss>http://gcd.w3.uvm.edu/2012/12/string-arrays-and-mandatory-parameters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Excellent Git Tutorial</title>
		<link>http://gcd.w3.uvm.edu/2012/11/excellent-git-tutorial/</link>
		<comments>http://gcd.w3.uvm.edu/2012/11/excellent-git-tutorial/#comments</comments>
		<pubDate>Wed, 07 Nov 2012 17:04:16 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://gcd.w3.uvm.edu/?p=565</guid>
		<description><![CDATA[This video of a presentation by Scott Chacon has helped me start to get my head around Git. I&#8217;ve started experimenting with Git in my current PowerShell project, and I&#8217;m going to watch it again, now that I&#8217;ve got a little bit of actual expeience.]]></description>
				<content:encoded><![CDATA[<p>This video of a presentation by Scott Chacon has helped me start to get my head around Git.</p>
<p><iframe width="625" height="352" src="http://www.youtube.com/embed/ZDR433b0HJY?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>I&#8217;ve started experimenting with Git in my current PowerShell project, and I&#8217;m going to watch it again, now that I&#8217;ve got a little bit of actual expeience.</p>
]]></content:encoded>
			<wfw:commentRss>http://gcd.w3.uvm.edu/2012/11/excellent-git-tutorial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Powershell, ACLs, and DFS-N</title>
		<link>http://gcd.w3.uvm.edu/2012/09/powershell-acls-and-dfs-n/</link>
		<comments>http://gcd.w3.uvm.edu/2012/09/powershell-acls-and-dfs-n/#comments</comments>
		<pubDate>Fri, 07 Sep 2012 15:42:34 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[permissions]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Server2012]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.uvm.edu/~gcd/?p=548</guid>
		<description><![CDATA[I&#8217;m working on some storage issues with our file services, and DFS Namespace services may the the best solution. But I will need to be able to keep the permissions on the DFS folders with targets in sync with the permissions on the target folders. I&#8217;m hoping that the new DFS-N PowerShell commands will facilitate [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m working on some storage issues with our file services, and DFS Namespace services may the the best solution. But I will need to be able to keep the permissions on the DFS folders with targets in sync with the permissions on the target folders. I&#8217;m hoping that the new DFS-N PowerShell commands will facilitate this process. However, on my Server 2012 test system, I can&#8217;t get the help content to download for the DFSN-related cmdlets.</p>
<p>I did find this gem in the <a href="http://technet.microsoft.com/en-us/library/hh848797" target="_blank">PowerShell Tips of the Week </a>archive:</p>
<p><a href="http://technet.microsoft.com/en-us/library/ff730951.aspx" target="_blank">Windows PowerShell Tip: Working With Security Descriptors</a></p>
<p>Good stuff.</p>
]]></content:encoded>
			<wfw:commentRss>http://gcd.w3.uvm.edu/2012/09/powershell-acls-and-dfs-n/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VSS diagnostics</title>
		<link>http://gcd.w3.uvm.edu/2012/08/vss-diagnostics/</link>
		<comments>http://gcd.w3.uvm.edu/2012/08/vss-diagnostics/#comments</comments>
		<pubDate>Fri, 31 Aug 2012 12:24:18 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[VSS]]></category>
		<category><![CDATA[WindowsServer]]></category>

		<guid isPermaLink="false">https://www.uvm.edu/~gcd/?p=535</guid>
		<description><![CDATA[For the past eight month, I’ve been working with EMC and Microsoft to diagnose a problem. Several time a month, during the backup of our primary Windows 2008 R2 file server, all the VSS shadow copies get deleted for the volume containing all our shared departmental directories. This has two major effects. First, it means [...]]]></description>
				<content:encoded><![CDATA[<p>For the past eight month, I’ve been working with EMC and Microsoft to diagnose a problem. Several time a month, during the backup of our primary Windows 2008 R2 file server, all the VSS shadow copies get deleted for the volume containing all our shared departmental directories.</p>
<p>This has two major effects. First, it means that our clients no longer can recover files using the Previous Versions feature of Windows. Second, it casts significant doubt on the validity of the backups performed at that time, which EMC NetWorker reports as having completed successfully.</p>
<p>We have been unable to find a technical solution to the shadow copy loss, so we will be reconfiguring our storage and shared directories to accommodate the limitations of NetWorker. In the meantime, I want to note a few of resources that have been helpful in diagnosing problems with VSS (it will be easier to find them here than in my pile o’ email):</p>
<p><a href="http://technet.microsoft.com/en-us/library/ee923636(v=ws.10).aspx" target="_blank">Volume Shadow Copy Service</a> (TechNet)</p>
<p><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb968832(v=vs.85).aspx" target="_blank">Volume Shadow Copy Service</a> (MSDN)</p>
<p><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb891959(v=vs.85).aspx" target="_blank">Registry Keys and Values for Backup and Restore</a></p>
<p><a href="http://support.microsoft.com/kb/887013" target="_blank">How to enable the Volume Shadow Copy service&#8217;s debug tracing features in Microsoft Windows Server 2003 and Windows 2008</a></p>
<p><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd765233(v=vs.85).aspx" target="_blank">Using Tracing Tools with VSS</a></p>
]]></content:encoded>
			<wfw:commentRss>http://gcd.w3.uvm.edu/2012/08/vss-diagnostics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Listing parent of AD object in PowerShell</title>
		<link>http://gcd.w3.uvm.edu/2012/07/listing-parent-of-ad-object-in-powershell/</link>
		<comments>http://gcd.w3.uvm.edu/2012/07/listing-parent-of-ad-object-in-powershell/#comments</comments>
		<pubDate>Thu, 12 Jul 2012 17:35:29 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[ActiveDirectory]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">https://www.uvm.edu/~gcd/?p=525</guid>
		<description><![CDATA[Recently, I wanted to provide a client with a list of groups that related to some work he was doing. I wanted the group names as well as their location with AD. Although I often use the ds* commands or excellent ADfind tool for this type of task, I had been working in PowerShell on [...]]]></description>
				<content:encoded><![CDATA[<p>Recently, I wanted to provide a client with a list of groups that related to some work he was doing. I wanted the group names as well as their location with AD. Although I often use the ds* commands or excellent <a href="http://www.joeware.net/freetools/tools/adfind/index.htm" target="_blank">ADfind</a> tool for this type of task, I had been working in PowerShell on another project, so I decided to use the <a href="http://technet.microsoft.com/en-us/library/ee617195" target="_blank">PowerShell ActiveDirectory module</a>.</p>
<p>The <a href="http://technet.microsoft.com/en-us/library/ee617196" target="_blank">Get-ADGroup Cmdlet</a> pulled out the groups easily enough, but the there wasn’t a property representing the group object’s parent, nor is there an LDAP property that I could request (AFAIK). The object’s parent is contained within the DistinguishedName (DN) property, though.</p>
<p>For a group with the following DN:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">CN=FOO-FileServices Administrators,OU=FOO,OU=Departments,DC=uvm,...</pre>
<p>I just need to strip off the CN. I could split the DN on commas, remove the first element, and then reassemble what’s left to get the parent. I also needed to avoid splitting on an LDAP-escaped comma where a value actually contains a comma (e.g., CN=).</p>
<pre class="brush: powershell; gutter: false; title: ; notranslate">PS&gt; $dn -split '(?&lt;![\\]),'</pre>
<p><span id="more-525"></span></p>
<p>I’ve used a regular expression construct called a <a href="http://msdn.microsoft.com/en-US/library/bs2twtah(v=vs.80)" target="_blank">zero-width negative look-behind assertion</a> to match commas only where the <em>aren’t</em> preceeded by a slash. </p>
<p>I put together a small function to break up the DN on non-escaped commas, and then used -join operator to construct the DN of the parent.</p>
<pre class="brush: powershell; gutter: false; title: ; notranslate">
function Get-ADParent ([string] $dn) {
     $parts = $dn -split '(?&lt;![\\]),'
     $parts[1..$($parts.Count-1)] -join ','
}
</pre>
<p><i>FYI: In my function, I used $parts.Count-5 in the array slice to trim the &#8216;DC=&#8217; domain components, which of course are the same for every object in my domain.</i></p>
<p>With that function, I then used a <a href="http://technet.microsoft.com/en-us/library/ff730948.aspx" target="_blank">calculated property</a> to include the parent in an output pipeline. For each object in the pipeline, I need to call Get-ADParent with the object’s DistinguishedName property. I like to store calculated properties in a variable:</p>
<pre class="brush: powershell; gutter: false; title: ; notranslate">PS&gt; $parent = @{Name='Parent'; Expression={ Get-ADParent $_ } }</pre>
<p>This works because the ToString() method for AD objects returns the DN. I could also have been specific in the Expression like so:</p>
<pre class="brush: powershell; gutter: false; title: ; notranslate">PS&gt; $parent = @{Name='Parent'; Expression={ Get-ADParent $_.DistinguishedName } } </pre>
<p>Now, I can create a PowerShell-ish pipeline to create the info that I want:</p>
<pre class="brush: powershell; gutter: false; title: ; notranslate">PS&gt; Get-ADGroup -filter {cn -like 'Foo*'} | sort Name | ft Name,$parent -A </pre>
<p>which returns results like this:</p>
<pre>Name                               Parent
----                               ------
FOO-FileServices Administrators   OU=FOO,OU=Departments,...
FOO-FileServices-BrowseTop        OU=FOO,OU=Departments,...
FOO-FileServices-HR               OU=FOO,OU=Departments,...
FOO-FileServices-Marketing        OU=FOO,OU=Departments,...
FOO-FileServices-THAC0            OU=FOO,OU=Departments,...
FOO-GroupAdmins                   OU=OU Admins,OU=Groups,...
</pre>
<p>This function and calculated property should work with any AD objects that have a DistinguishedName property; users, computers, OUs, anything.</p>
<p>I hope you have found this helpful.</p>
]]></content:encoded>
			<wfw:commentRss>http://gcd.w3.uvm.edu/2012/07/listing-parent-of-ad-object-in-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HoW PGP Whole Disk Encryption Works</title>
		<link>http://gcd.w3.uvm.edu/2012/07/how-pgp-whole-disk-encryption-works/</link>
		<comments>http://gcd.w3.uvm.edu/2012/07/how-pgp-whole-disk-encryption-works/#comments</comments>
		<pubDate>Mon, 02 Jul 2012 17:55:20 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[encryption]]></category>
		<category><![CDATA[pgp]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">https://www.uvm.edu/~gcd/?p=515</guid>
		<description><![CDATA[In my discussion and demo at the IT-Discuss Live – Security event in May, I used a short slide deck to describe—in broad terms—how PGP Whole Disk Encryption works. This laid the foundation for working through some common-ish support scenarios. Having received several requests for a copy of the slides, here they are, in both [...]]]></description>
				<content:encoded><![CDATA[<p>In my discussion and demo at the <em>IT-Discuss Live – Security</em> event in May, I used a short slide deck to describe—in broad terms—how PGP Whole Disk Encryption works. This laid the foundation for working through some common-ish support scenarios.</p>
<p><a href="http://www.uvm.edu/~gcd/files/ITDL-PGPWDE-How_it_works.pptx" target="_blank"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="ITDL-PGPWDE-How_it_works" border="0" alt="ITDL-PGPWDE-How_it_works" src="http://www.uvm.edu/~gcd/files/2012/07/ITDL-PGPWDE-How_it_works.png" width="502" height="306" /></a></p>
<p>Having received several requests for a copy of the slides, here they are, in both <a href="http://www.uvm.edu/~gcd/files/ITDL-PGPWDE-How_it_works.pptx" target="_blank">PowerPoint (.pptx)</a> and <a href="http://www.uvm.edu/~gcd/files/ITDL-PGPWDE-How_it_works.pdf" target="_blank">PDF</a> formats.</p>
]]></content:encoded>
			<wfw:commentRss>http://gcd.w3.uvm.edu/2012/07/how-pgp-whole-disk-encryption-works/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom event log queries</title>
		<link>http://gcd.w3.uvm.edu/2012/06/custom-event-log-queries/</link>
		<comments>http://gcd.w3.uvm.edu/2012/06/custom-event-log-queries/#comments</comments>
		<pubDate>Thu, 14 Jun 2012 19:39:18 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[WindowsServer]]></category>

		<guid isPermaLink="false">https://www.uvm.edu/~gcd/?p=504</guid>
		<description><![CDATA[I really like the newer event log model on Windows 2008 family, and the flexibility of the XML events and the queries that makes possible. Recently, I started noticing a quiet failure of a scheduled task. The Task Scheduler thinks that the task completed successfully, though the executable called by the task action returned an [...]]]></description>
				<content:encoded><![CDATA[<p>I really like the newer event log model on Windows 2008 family, and the flexibility of the XML events and the queries that makes possible.</p>
<p>Recently, I started noticing a quiet failure of a scheduled task. The Task Scheduler thinks that the task completed successfully, though the executable called by the task action returned an error code of 3:</p>
<blockquote><p>Task Scheduler successfully completed task &#8220;\ShareVol_Sync&#8221; , instance &#8220;{92ac3257-f52d-47eb-9a3a-ce02c5196bbd}&#8221; , action &#8220;diskshadow.exe&#8221; with return code 3.</p>
</blockquote>
<p>I wanted to see how long this have been going on, so I switched from the Task Scheduler console to Eventlog Viewer, and navigated to the Operational log under “Applications and Services Logs”- Microsoft &#8211; Windows &#8211; TaskScheduler.</p>
<p>I started by using the using the <em>Filter Current log</em> dialog to select events with Event ID 201, but this included all “Action completed” events for all tasks. So I looked at the XML view for one of the events for the task I was researching. The event includes a data value named “ActionName” with the value “diskshadow.exe” that should allow me to find all the relevant events.</p>
<p><a href="http://www.uvm.edu/~gcd/files/2012/06/eventvwr-evt-xml.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="eventvwr-evt-xml" border="0" alt="eventvwr-evt-xml" src="http://www.uvm.edu/~gcd/files/2012/06/eventvwr-evt-xml_thumb.png" width="504" height="352"></a></p>
<p>Next, I needed to refine my filter to look for this value in the events. I opened the <em>Filter Current log</em> dialog again, and switched to the XML tab, then checked the <em>Edit query manually</em> option. You get a scary warning about not being able to use the GUI again, but that only applies to the current filter. Be bold: click OK.</p>
<p>Next, I edited the query, following examples from this excellent <a href="http://blogs.technet.com/b/askds/archive/2011/09/26/advanced-xml-filtering-in-the-windows-event-viewer.aspx" target="_blank">Ask the Directory Services Team blog post</a>. The query is junk the between the select tags. Originally, the query was simply:</p>
<blockquote><p>*[System[(EventID=201)]]</p>
</blockquote>
<p>To that, I added the following:</p>
<blockquote><p>and<br />*[EventData[Data[@Name='ActionName'] and (Data=&#8217;diskshadow.exe&#8217;)]]</p>
</blockquote>
<p>So that the whole query looks like this:</p>
<pre class="brush: xml; gutter: false; title: ; notranslate">
&lt;QueryList&gt;
  &lt;Query Id=&quot;0&quot; Path=&quot;Microsoft-Windows-TaskScheduler/Operational&quot;&gt;
    &lt;Select Path=&quot;Microsoft-Windows-TaskScheduler/Operational&quot;&gt;
      *[System[(EventID=201)]]
       and
      *[EventData[Data[@Name='ActionName'] and (Data='diskshadow.exe')]]
    &lt;/Select&gt;
  &lt;/Query&gt;
&lt;/QueryList&gt;
</pre>
<p>Now event viewer shows me only the “Action Completed” events for the diskshadow.exe command, and I can see exactly when the behavior changed.</p>
<p>Note that you can save use the query XML with PowerShell’s Get-WinEvent commandlet’s -filterXML parameter [<a href="http://www.uvm.edu/~gcd/2010/11/event-data-mining-with-powershell/" target="_blank">See an example</a>]. You can also use the <em>Save Filter to Custom View</em> option to make this view persistent.</p>
<p>I routinely review Windows&#8217; Event logs during diagnostics and troubleshooting. I find the ability to query those logs for specific data is an indispensable technique. No more dumping to CSV and running findstr! I hope you find it helpful, too.</p>
]]></content:encoded>
			<wfw:commentRss>http://gcd.w3.uvm.edu/2012/06/custom-event-log-queries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
