<?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>Indented!</title>
	<atom:link href="http://www.indented.co.uk/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.indented.co.uk</link>
	<description></description>
	<lastBuildDate>Fri, 02 Jul 2010 10:45:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>DnsShell: Zone and Server CmdLets</title>
		<link>http://www.indented.co.uk/index.php/2010/04/16/dnsshell-zone-and-server-cmdlets/</link>
		<comments>http://www.indented.co.uk/index.php/2010/04/16/dnsshell-zone-and-server-cmdlets/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 15:10:49 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[DnsShell]]></category>
		<category><![CDATA[Microsoft DNS]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.indented.co.uk/?p=1470</guid>
		<description><![CDATA[After fixing a couple of authentication bugs with Set-DnsRecord and New-DnsRecord I decided to make an attempt to finish off some of the zone and server CmdLets. The module now contains these additional CmdLets. Refresh-DnsZone &#8211; Implements the ForceRefresh method for Secondary Zones Reload-ADDnsZone &#8211; Implements the UpdateFromDS method for AD Integrated Zones Reload-DnsZone Reset-DnsZoneType [...]


Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2010/03/29/dnsshell-alpha/' rel='bookmark' title='Permanent Link: DnsShell &#8211; alpha release'>DnsShell &#8211; alpha release</a> <small>DnsShell is my PowerShell module intended to help administer MS...</small></li>
<li><a href='http://www.indented.co.uk/index.php/2010/04/14/dnsshell-get-ad/' rel='bookmark' title='Permanent Link: DnsShell: Get-AD*'>DnsShell: Get-AD*</a> <small>A new version of DnsShell has been released, this release...</small></li>
<li><a href='http://www.indented.co.uk/index.php/dnsshell/' rel='bookmark' title='Permanent Link: DnsShell'>DnsShell</a> <small>DnsShell is a Microsoft DNS administration module for PowerShell 2.0....</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>After fixing a couple of authentication bugs with Set-DnsRecord and New-DnsRecord I decided to make an attempt to finish off some of the zone and server CmdLets.</p>
<p>The module now contains these additional CmdLets.</p>
<ul>
<li><b>Refresh-DnsZone</b> &#8211; Implements the ForceRefresh method for Secondary Zones</li>
<li><b>Reload-ADDnsZone</b> &#8211; Implements the UpdateFromDS method for AD Integrated Zones</li>
<li><b>Reload-DnsZone</b></li>
<li><b>Reset-DnsZoneType</b> &#8211; Implements the ChangeZoneType method</li>
<li><b>Resume-DnsZone</b></li>
<li><b>Set-DnsZoneTransfer</b> &#8211; Implements the ResetSecondaries method</li>
<li><b>Start-DnsScavenging</b></li>
<li><b>Start-DnsService</b></li>
<li><b>Stop-DnsService</b></li>
<li><b>Suspend-DnsZone</b> &#8211; Implements the Pause method</li>
<li><b>Update-DnsZoneFile</b></li>
</ul>
<p>As usual, the module can be downloaded from <a href='http://code.msdn.microsoft.com/dnsshell'>code.msdn.microsoft.com/dnsshell</a>.</p>


<p>Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2010/03/29/dnsshell-alpha/' rel='bookmark' title='Permanent Link: DnsShell &#8211; alpha release'>DnsShell &#8211; alpha release</a> <small>DnsShell is my PowerShell module intended to help administer MS...</small></li>
<li><a href='http://www.indented.co.uk/index.php/2010/04/14/dnsshell-get-ad/' rel='bookmark' title='Permanent Link: DnsShell: Get-AD*'>DnsShell: Get-AD*</a> <small>A new version of DnsShell has been released, this release...</small></li>
<li><a href='http://www.indented.co.uk/index.php/dnsshell/' rel='bookmark' title='Permanent Link: DnsShell'>DnsShell</a> <small>DnsShell is a Microsoft DNS administration module for PowerShell 2.0....</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2010/04/16/dnsshell-zone-and-server-cmdlets/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>DnsShell: Get-AD*</title>
		<link>http://www.indented.co.uk/index.php/2010/04/14/dnsshell-get-ad/</link>
		<comments>http://www.indented.co.uk/index.php/2010/04/14/dnsshell-get-ad/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 13:09:51 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[DnsShell]]></category>
		<category><![CDATA[Microsoft DNS]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.indented.co.uk/?p=1467</guid>
		<description><![CDATA[A new version of DnsShell has been released, this release improves Get-ADDnsRecord and adds Get-ADDnsPartition and Get-ADDnsZone. The updated release is available on MSDN as version 0.2.0. code.msdn.microsoft.com/dnsshell Basic help is available for each of the new CmdLets. Related posts:DnsShell &#8211; alpha release DnsShell is my PowerShell module intended to help administer MS... DnsShell DnsShell [...]


Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2010/03/29/dnsshell-alpha/' rel='bookmark' title='Permanent Link: DnsShell &#8211; alpha release'>DnsShell &#8211; alpha release</a> <small>DnsShell is my PowerShell module intended to help administer MS...</small></li>
<li><a href='http://www.indented.co.uk/index.php/dnsshell/' rel='bookmark' title='Permanent Link: DnsShell'>DnsShell</a> <small>DnsShell is a Microsoft DNS administration module for PowerShell 2.0....</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>A new version of DnsShell has been released, this release improves Get-ADDnsRecord and adds Get-ADDnsPartition and Get-ADDnsZone.</p>
<p>The updated release is available on MSDN as version 0.2.0.</p>
<p><a href='http://code.msdn.microsoft.com/dnsshell'>code.msdn.microsoft.com/dnsshell</a></p>
<p>Basic help is available for each of the new CmdLets.</p>


<p>Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2010/03/29/dnsshell-alpha/' rel='bookmark' title='Permanent Link: DnsShell &#8211; alpha release'>DnsShell &#8211; alpha release</a> <small>DnsShell is my PowerShell module intended to help administer MS...</small></li>
<li><a href='http://www.indented.co.uk/index.php/dnsshell/' rel='bookmark' title='Permanent Link: DnsShell'>DnsShell</a> <small>DnsShell is a Microsoft DNS administration module for PowerShell 2.0....</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2010/04/14/dnsshell-get-ad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DnsShell &#8211; alpha release</title>
		<link>http://www.indented.co.uk/index.php/2010/03/29/dnsshell-alpha/</link>
		<comments>http://www.indented.co.uk/index.php/2010/03/29/dnsshell-alpha/#comments</comments>
		<pubDate>Mon, 29 Mar 2010 14:47:26 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[DnsShell]]></category>
		<category><![CDATA[Microsoft DNS]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.indented.co.uk/?p=1451</guid>
		<description><![CDATA[DnsShell is my PowerShell module intended to help administer MS DNS. This is an alpha relaese, it may contain bugs, it should be tested in a safe environment first. The module is currently available on MSDN. The following CmdLets are implemented at this stage: Get-Dns Clear-DnsCache Get-DnsRecord Get-DnsServer Get-DnsZone New-DnsRecord New-DnsZone Remove-DnsObject Set-DnsRecord Get-ADDnsRecord I [...]


Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2010/04/16/dnsshell-zone-and-server-cmdlets/' rel='bookmark' title='Permanent Link: DnsShell: Zone and Server CmdLets'>DnsShell: Zone and Server CmdLets</a> <small>After fixing a couple of authentication bugs with Set-DnsRecord and...</small></li>
<li><a href='http://www.indented.co.uk/index.php/2010/04/14/dnsshell-get-ad/' rel='bookmark' title='Permanent Link: DnsShell: Get-AD*'>DnsShell: Get-AD*</a> <small>A new version of DnsShell has been released, this release...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>DnsShell is my PowerShell module intended to help administer MS DNS. This is an alpha relaese, it may contain bugs, it should be tested in a safe environment first.</p>
<p>The module is currently available on <a href='http://code.msdn.microsoft.com/dnsshell'>MSDN</a>.</p>
<p>The following CmdLets are implemented at this stage:</p>
<ul>
<li>Get-Dns</li>
<li>Clear-DnsCache</li>
<li>Get-DnsRecord</li>
<li>Get-DnsServer</li>
<li>Get-DnsZone</li>
<li>New-DnsRecord</li>
<li>New-DnsZone</li>
<li>Remove-DnsObject</li>
<li>Set-DnsRecord</li>
<li>Get-ADDnsRecord</li>
</ul>
<p>I am in the process of writing detailed CmdLet help, it will be made available as soon as possible.</p>


<p>Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2010/04/16/dnsshell-zone-and-server-cmdlets/' rel='bookmark' title='Permanent Link: DnsShell: Zone and Server CmdLets'>DnsShell: Zone and Server CmdLets</a> <small>After fixing a couple of authentication bugs with Set-DnsRecord and...</small></li>
<li><a href='http://www.indented.co.uk/index.php/2010/04/14/dnsshell-get-ad/' rel='bookmark' title='Permanent Link: DnsShell: Get-AD*'>DnsShell: Get-AD*</a> <small>A new version of DnsShell has been released, this release...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2010/03/29/dnsshell-alpha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DHCP Discovery</title>
		<link>http://www.indented.co.uk/index.php/2010/02/17/dhcp-discovery/</link>
		<comments>http://www.indented.co.uk/index.php/2010/02/17/dhcp-discovery/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 12:46:24 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[DHCP]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.indented.co.uk/?p=1436</guid>
		<description><![CDATA[A PowerShell script to send a DHCP Discover request and listen for DHCP Offer responses, it can be used for finding DHCP servers (including rogue servers), or for testing DHCP servers and relays. The output from this script is an object containing a decode of the DHCP packet and a number of options. By default [...]


No related posts.

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>A PowerShell script to send a DHCP Discover request and listen for DHCP Offer responses, it can be used for finding DHCP servers (including rogue servers), or for testing DHCP servers and relays. The output from this script is an object containing a decode of the DHCP packet and a number of options.<br />
<span id="more-1436"></span><br />
By default the script uses a spoofed MAC address of AA:BB:CC:DD:EE:FF to send the offer, a specific MAC address can be specified using the MacAddressString parameter. </p>
<p>The script can listen for DHCP offers for a specified number of seconds by using the DiscoverTimeout parameter, by default the script listens for 60 seconds. Note that a timeout is set for the ReceiveFrom method, this is set to 10 seconds in the script and applies to each receive attempt. If the connection times out the script will stop listening for offers regardless of the value for DiscoverTimeout.</p>
<p>This script has only been tested using PowerShell 2.0.</p>
<pre class="brush: powershell;">
&lt;#
  Net-DhcpDiscover.ps1

  Author: Chris Dent
  Date: 16/02/2010

  A script to send a DHCPDISCOVER request and report on DHCPOFFER
  responses returned by all DHCP Servers on the current subnet.

  DHCP Packet Format (RFC 2131 - http://www.ietf.org/rfc/rfc2131.txt):

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |     op (1)    |   htype (1)   |   hlen (1)    |   hops (1)    |
  +---------------+---------------+---------------+---------------+
  |                            xid (4)                            |
  +-------------------------------+-------------------------------+
  |           secs (2)            |           flags (2)           |
  +-------------------------------+-------------------------------+
  |                          ciaddr  (4)                          |
  +---------------------------------------------------------------+
  |                          yiaddr  (4)                          |
  +---------------------------------------------------------------+
  |                          siaddr  (4)                          |
  +---------------------------------------------------------------+
  |                          giaddr  (4)                          |
  +---------------------------------------------------------------+
  |                                                               |
  |                          chaddr  (16)                         |
  |                                                               |
  |                                                               |
  +---------------------------------------------------------------+
  |                                                               |
  |                          sname   (64)                         |
  +---------------------------------------------------------------+
  |                                                               |
  |                          file    (128)                        |
  +---------------------------------------------------------------+
  |                                                               |
  |                          options (variable)                   |
  +---------------------------------------------------------------+

   FIELD      OCTETS       DESCRIPTION
   -----      ------       -----------

   op            1  Message op code / message type.
                    1 = BOOTREQUEST, 2 = BOOTREPLY
   htype         1  Hardware address type, see ARP section in &quot;Assigned
                    Numbers&quot; RFC; e.g., '1' = 10mb ethernet.
   hlen          1  Hardware address length (e.g.  '6' for 10mb
                    ethernet).
   hops          1  Client sets to zero, optionally used by relay agents
                    when booting via a relay agent.
   xid           4  Transaction ID, a random number chosen by the
                    client, used by the client and server to associate
                    messages and responses between a client and a
                    server.
   secs          2  Filled in by client, seconds elapsed since client
                    began address acquisition or renewal process.
   flags         2  Flags (see figure 2).
   ciaddr        4  Client IP address; only filled in if client is in
                    BOUND, RENEW or REBINDING state and can respond
                    to ARP requests.
   yiaddr        4  'your' (client) IP address.
   siaddr        4  IP address of next server to use in bootstrap;
                    returned in DHCPOFFER, DHCPACK by server.
   giaddr        4  Relay agent IP address, used in booting via a
                    relay agent.
   chaddr       16  Client hardware address.
   sname        64  Optional server host name, null terminated string.
   file        128  Boot file name, null terminated string; &quot;generic&quot;
                    name or null in DHCPDISCOVER, fully qualified
                    directory-path name in DHCPOFFER.
   options     var  Optional parameters field.  See the options
                    documents for a list of defined options.
#&gt;

#
# Parameters
#

Param(
  # MAC Address String in Hex-Decimal Format can be delimited with
  # dot, dash or colon (or none)
  [String]$MacAddressString = &quot;AA:BB:CC:DD:EE:FF&quot;,
  # Length of time (in seconds) to spend waiting for Offers if
  # the connection does not timeout first
  [Byte]$DiscoverTimeout = 60
)

# Build a DHCPDISCOVER packet to send
#
# Caller: Main

Function New-DhcpDiscoverPacket
{
  Param(
    [String]$MacAddressString = &quot;AA:BB:CC:DD:EE:FF&quot;
  )

  # Generate a Transaction ID for this request

  $XID = New-Object Byte[] 4
  $Random = New-Object Random
  $Random.NextBytes($XID)

  # Convert the MAC Address String into a Byte Array

  # Drop any characters which might be used to delimit the string
  $MacAddressString = $MacAddressString -Replace &quot;-|:|\.&quot;
  $MacAddress = [BitConverter]::GetBytes((
    [UInt64]::Parse($MacAddressString,
    [Globalization.NumberStyles]::HexNumber)))
  # Reverse the MAC Address array
  [Array]::Reverse($MacAddress)

  # Create the Byte Array
  $DhcpDiscover = New-Object Byte[] 243

  # Copy the Transaction ID Bytes into the array
  [Array]::Copy($XID, 0, $DhcpDiscover, 4, 4)

  # Copy the MacAddress Bytes into the array (drop the first 2 bytes,
  # too many bytes returned from UInt64)
  [Array]::Copy($MACAddress, 2, $DhcpDiscover, 28, 6)

  # Set the OP Code to BOOTREQUEST
  $DhcpDiscover[0] = 1
  # Set the Hardware Address Type to Ethernet
  $DhcpDiscover[1] = 1
  # Set the Hardware Address Length (number of bytes)
  $DhcpDiscover[2] = 6
  # Set the Broadcast Flag
  $DhcpDiscover[10] = 128
  # Set the Magic Cookie values
  $DhcpDiscover[236] = 99
  $DhcpDiscover[237] = 130
  $DhcpDiscover[238] = 83
  $DhcpDiscover[239] = 99
  # Set the DHCPDiscover Message Type Option
  $DhcpDiscover[240] = 53
  $DhcpDiscover[241] = 1
  $DhcpDiscover[242] = 1

  Return $DhcpDiscover
}

# Parse a DHCP Packet, returning an object containing each field
#
# Caller: Main

Function Read-DhcpPacket( [Byte[]]$Packet )
{
  $Reader = New-Object IO.BinaryReader(New-Object IO.MemoryStream(@(,$Packet)))

  $DhcpResponse = New-Object Object

  # Get and translate the Op code
  $DhcpResponse | Add-Member NoteProperty Op $Reader.ReadByte()
  if ($DhcpResponse.Op -eq 1)
  {
    $DhcpResponse.Op = &quot;BootRequest&quot;
  }
  else
  {
    $DhcpResponse.Op = &quot;BootResponse&quot;
  }

  $DhcpResponse | Add-Member NoteProperty HType -Value $Reader.ReadByte()
  if ($DhcpResponse.HType -eq 1) { $DhcpResponse.HType = &quot;Ethernet&quot; }

  $DhcpResponse | Add-Member NoteProperty HLen $Reader.ReadByte()
  $DhcpResponse | Add-Member NoteProperty Hops $Reader.ReadByte()
  $DhcpResponse | Add-Member NoteProperty XID $Reader.ReadUInt32()
  $DhcpResponse | Add-Member NoteProperty Secs $Reader.ReadUInt16()
  $DhcpResponse | Add-Member NoteProperty Flags $Reader.ReadUInt16()
  # Broadcast is the only flag that can be present, the other bits are reserved
  if ($DhcpResponse.Flags -BAnd 128) { $DhcpResponse.Flags = @(&quot;Broadcast&quot;) }

  $DhcpResponse | Add-Member NoteProperty CIAddr `
    $(&quot;$($Reader.ReadByte()).$($Reader.ReadByte()).&quot; + `
    &quot;$($Reader.ReadByte()).$($Reader.ReadByte())&quot;)
  $DhcpResponse | Add-Member NoteProperty YIAddr `
    $(&quot;$($Reader.ReadByte()).$($Reader.ReadByte()).&quot; + `
    &quot;$($Reader.ReadByte()).$($Reader.ReadByte())&quot;)
  $DhcpResponse | Add-Member NoteProperty SIAddr `
    $(&quot;$($Reader.ReadByte()).$($Reader.ReadByte()).&quot; + `
    &quot;$($Reader.ReadByte()).$($Reader.ReadByte())&quot;)
  $DhcpResponse | Add-Member NoteProperty GIAddr `
    $(&quot;$($Reader.ReadByte()).$($Reader.ReadByte()).&quot; + `
    &quot;$($Reader.ReadByte()).$($Reader.ReadByte())&quot;)

  $MacAddrBytes = New-Object Byte[] 16
  [Void]$Reader.Read($MacAddrBytes, 0, 16)
  $MacAddress = [String]::Join(
    &quot;:&quot;, $($MacAddrBytes[0..5] | %{ [String]::Format('{0:X2}', $_) }))
  $DhcpResponse | Add-Member NoteProperty CHAddr $MacAddress

  $DhcpResponse | Add-Member NoteProperty SName `
    $([String]::Join(&quot;&quot;, $Reader.ReadChars(64)).Trim())
  $DhcpResponse | Add-Member NoteProperty File `
    $([String]::Join(&quot;&quot;, $Reader.ReadChars(128)).Trim())

  $DhcpResponse | Add-Member NoteProperty MagicCookie `
    $(&quot;$($Reader.ReadByte()).$($Reader.ReadByte()).&quot; + `
    &quot;$($Reader.ReadByte()).$($Reader.ReadByte())&quot;)

  # Start reading Options

  $DhcpResponse | Add-Member NoteProperty Options @()
  While ($Reader.BaseStream.Position -lt $Reader.BaseStream.Length)
  {
    $Option = New-Object Object
    $Option | Add-Member NoteProperty OptionCode $Reader.ReadByte()
    $Option | Add-Member NoteProperty OptionName &quot;&quot;
    $Option | Add-Member NoteProperty Length 0
    $Option | Add-Member NoteProperty OptionValue &quot;&quot;

    If ($Option.OptionCode -ne 0 -And $Option.OptionCode -ne 255)
    {
      $Option.Length = $Reader.ReadByte()
    }

    Switch ($Option.OptionCode)
    {
      0 { $Option.OptionName = &quot;PadOption&quot; }
      1 {
        $Option.OptionName = &quot;SubnetMask&quot;
        $Option.OptionValue = `
          $(&quot;$($Reader.ReadByte()).$($Reader.ReadByte()).&quot; + `
          &quot;$($Reader.ReadByte()).$($Reader.ReadByte())&quot;) }
      3 {
        $Option.OptionName = &quot;Router&quot;
        $Option.OptionValue = `
          $(&quot;$($Reader.ReadByte()).$($Reader.ReadByte()).&quot; + `
          &quot;$($Reader.ReadByte()).$($Reader.ReadByte())&quot;) }
      6 {
        $Option.OptionName = &quot;DomainNameServer&quot;
        $Option.OptionValue = @()
        For ($i = 0; $i -lt ($Option.Length / 4); $i++)
        {
          $Option.OptionValue += `
            $(&quot;$($Reader.ReadByte()).$($Reader.ReadByte()).&quot; + `
            &quot;$($Reader.ReadByte()).$($Reader.ReadByte())&quot;)
        } }
      15 {
        $Option.OptionName = &quot;DomainName&quot;
        $Option.OptionValue = [String]::Join(
          &quot;&quot;, $Reader.ReadChars($Option.Length)) }
      51 {
        $Option.OptionName = &quot;IPAddressLeaseTime&quot;
        # Read as Big Endian
        $Value = ($Reader.ReadByte() * [Math]::Pow(256, 3)) + `
          ($Reader.ReadByte() * [Math]::Pow(256, 2)) + `
          ($Reader.ReadByte() * 256) + `
          $Reader.ReadByte()
        $Option.OptionValue = $(New-TimeSpan -Seconds $Value) }
      53 {
        $Option.OptionName = &quot;DhcpMessageType&quot;
        Switch ($Reader.ReadByte())
        {
          1 { $Option.OptionValue = &quot;DHCPDISCOVER&quot; }
          2 { $Option.OptionValue = &quot;DHCPOFFER&quot; }
          3 { $Option.OptionValue = &quot;DHCPREQUEST&quot; }
          4 { $Option.OptionValue = &quot;DHCPDECLINE&quot; }
          5 { $Option.OptionValue = &quot;DHCPACK&quot; }
          6 { $Option.OptionValue = &quot;DHCPNAK&quot; }
          7 { $Option.OptionValue = &quot;DHCPRELEASE&quot; }
        } }
      54 {
        $Option.OptionName = &quot;DhcpServerIdentifier&quot;
        $Option.OptionValue = `
          $(&quot;$($Reader.ReadByte()).$($Reader.ReadByte()).&quot; + `
          &quot;$($Reader.ReadByte()).$($Reader.ReadByte())&quot;) }
      58 {
        $Option.OptionName = &quot;RenewalTime&quot;
        # Read as Big Endian
        $Value = ($Reader.ReadByte() * [Math]::Pow(256, 3)) + `
          ($Reader.ReadByte() * [Math]::Pow(256, 2)) + `
          ($Reader.ReadByte() * 256) + `
          $Reader.ReadByte()
        $Option.OptionValue = $(New-TimeSpan -Seconds $Value) }
      59 {
        $Option.OptionName = &quot;RebindingTime&quot;
        # Read as Big Endian
        $Value = ($Reader.ReadByte() * [Math]::Pow(256, 3)) + `
          ($Reader.ReadByte() * [Math]::Pow(256, 2)) + `
          ($Reader.ReadByte() * 256) + `
          $Reader.ReadByte()
        $Option.OptionValue = $(New-TimeSpan -Seconds $Value) }
      255 { $Option.OptionName = &quot;EndOption&quot; }
      default {
        # For all options which are not decoded here
        $Option.OptionName = &quot;NoOptionDecode&quot;
        $Buffer = New-Object Byte[] $Option.Length
        [Void]$Reader.Read($Buffer, 0, $Option.Length)
        $Option.OptionValue = $Buffer
      }
    }

    # Override the ToString method
    $Option | Add-Member ScriptMethod ToString `
        { Return &quot;$($this.OptionName) ($($this.OptionValue))&quot; } -Force

    $DhcpResponse.Options += $Option
  }

  Return $DhcpResponse
}

# Create a UDP Socket with Broadcast and Address Re-use enabled.
#
# Caller: Main

Function New-UdpSocket
{
  Param(
    [Int32]$SendTimeOut = 5,
    [Int32]$ReceiveTimeOut = 5
  )

  $UdpSocket = New-Object Net.Sockets.Socket(
    [Net.Sockets.AddressFamily]::InterNetwork,
    [Net.Sockets.SocketType]::Dgram,
    [Net.Sockets.ProtocolType]::Udp)
  $UdpSocket.EnableBroadcast = $True
  $UdpSocket.ExclusiveAddressUse = $False
  $UdpSocket.SendTimeOut = $SendTimeOut * 1000
  $UdpSocket.ReceiveTimeOut = $ReceiveTimeOut * 1000

  Return $UdpSocket
}

# Close down a Socket
#
# Caller: Main

Function Remove-Socket
{
  Param(
    [Net.Sockets.Socket]$Socket
  )

  $Socket.Shutdown(&quot;Both&quot;)
  $Socket.Close()
}

#
# Main
#

# Create a Byte Array for the DHCPDISCOVER packet
$Message = New-DhcpDiscoverPacket -Send 10 -Receive 10

# Create a socket
$UdpSocket = New-UdpSocket

# UDP Port 68 (Server-to-Client port)
$EndPoint = [Net.EndPoint](
  New-Object Net.IPEndPoint($([Net.IPAddress]::Any, 68)))
# Listen on $EndPoint
$UdpSocket.Bind($EndPoint)

# UDP Port 67 (Client-to-Server port)
$EndPoint = [Net.EndPoint](
 New-Object Net.IPEndPoint($([Net.IPAddress]::Broadcast, 67)))
# Send the DHCPDISCOVER packet
$BytesSent = $UdpSocket.SendTo($Message, $EndPoint)

# Begin receiving and processing responses
$NoConnectionTimeOut = $True

$Start = Get-Date

While ($NoConnectionTimeOut)
{
  $BytesReceived = 0
  Try
  {
    # Placeholder EndPoint for the Sender
    $SenderEndPoint = [Net.EndPoint](
      New-Object Net.IPEndPoint($([Net.IPAddress]::Any, 0)))
    # Receive Buffer
    $ReceiveBuffer = New-Object Byte[] 1024
    $BytesReceived = $UdpSocket.ReceiveFrom($ReceiveBuffer, [Ref]$SenderEndPoint)
  }
  #
  # Catch a SocketException, thrown when the Receive TimeOut value is reached
  #
  Catch [Net.Sockets.SocketException]
  {
    $NoConnectionTimeOut = $False
  }

  If ($BytesReceived -gt 0)
  {
    Read-DhcpPacket $ReceiveBuffer[0..$BytesReceived]
  }

  If ((Get-Date) -gt $Start.AddSeconds($DiscoverTimeout))
  {
    # Exit condition, not error condition
    $NoConnectionTimeOut = $False
  }
}

Remove-Socket $UdpSocket
</pre>


<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2010/02/17/dhcp-discovery/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>IPv4 subnet math with PowerShell</title>
		<link>http://www.indented.co.uk/index.php/2010/01/23/powershell-subnet-math/</link>
		<comments>http://www.indented.co.uk/index.php/2010/01/23/powershell-subnet-math/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 15:35:10 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Subnet Math]]></category>

		<guid isPermaLink="false">http://www.indented.co.uk/?p=1370</guid>
		<description><![CDATA[Written to complement the VbScript version of this post. This collection of functions handles subnet math in PowerShell. Download all the functions and examples at once: Net-SubnetMath.ps1 Convert an IP to binary This function uses System.Convert to change each octet of an IP address into it&#8217;s binary form. PadLeft is used to add leading zero&#8217;s [...]


No related posts.

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Written to complement the <a href='http://www.indented.co.uk/index.php/2008/10/21/vbscript-subnet-math/'>VbScript version</a> of this post. This collection of functions handles subnet math in PowerShell.</p>
<p>Download all the functions and examples at once: <a href='http://www.indented.co.uk/wp-content/uploads/2010/01/Net-SubnetMath.ps1_.txt'>Net-SubnetMath.ps1</a><br />
<span id="more-1370"></span></p>
<h3>Convert an IP to binary</h3>
<p>This function uses System.Convert to change each octet of an IP address into it&#8217;s binary form. PadLeft is used to add leading zero&#8217;s if required.</p>
<pre class="brush: powershell;">
Function ConvertTo-BinaryIP( [String]$IP ) {

  $IPAddress = [Net.IPAddress]::Parse($IP)

  Return [String]::Join('.',
    $( $IPAddress.GetAddressBytes() | %{
      [Convert]::ToString($_, 2).PadLeft(8, '0') } ))
}
</pre>
<h3>Convert an IP to a 32-bit decimal</h3>
<p>Allows conversion of an IP Address to an unsigned 32-bit integer.</p>
<pre class="brush: powershell;">
Function ConvertTo-DecimalIP( [String]$IP ) {

  $IPAddress = [Net.IPAddress]::Parse($IP)
  $i = 3
  $IPAddress.GetAddressBytes() | %{
    $DecimalIP += $_ * [Math]::Pow(256, $i); $i-- }

  Return [UInt32]$DecimalIP
}
</pre>
<h3>Convert a decimal number or binary IP to a dotted IP</h3>
<p>Used to switch a decimal or binary IP back to the more common dotted decimal format. The function uses a simple pair of regular expressions to determine which format is presented.</p>
<pre class="brush: powershell;">
Function ConvertTo-DottedDecimalIP( [String]$IP ) {

  Switch -RegEx ($IP) {
    &quot;([01]{8}\.){3}[01]{8}&quot; {

      Return [String]::Join('.', $( $IP.Split('.') | %{
        [Convert]::ToInt32($_, 2) } ))
    }
    &quot;\d&quot; {

      $IP = [UInt32]$IP
      $DottedIP = $( For ($i = 3; $i -gt -1; $i--) {
        $Remainder = $IP % [Math]::Pow(256, $i)
        ($IP - $Remainder) / [Math]::Pow(256, $i)
        $IP = $Remainder
       } )

      Return [String]::Join('.', $DottedIP)
    }
    default {
      Write-Error &quot;Cannot convert this format&quot;
    }
  }
}
</pre>
<h3>Convert a subnet mask to a mask length</h3>
<p>Occasionally it is desirable to calculate the subnet mask bit length. This can be done using the following.</p>
<pre class="brush: powershell;">
Function ConvertTo-MaskLength( [String]$Mask ) {

  $IPMask = [Net.IPAddress]::Parse($Mask)
  $Bits = &quot;$( $IPMask.GetAddressBytes() | %{
    [Convert]::ToString($_, 2) } )&quot; -Replace &quot;[\s0]&quot;

  Return $Bits.Length
}
</pre>
<h3>Convert a mask length to a subnet mask</h3>
<p>To a dotted decimal IP via binary and an unsigned 32-bit integer.</p>
<pre class="brush: powershell;">
Function ConvertTo-Mask( [Byte]$MaskLength ) {

  Return ConvertTo-DottedDecimalIP ([Convert]::ToUInt32(
    $((&quot;1&quot; * $MaskLength).PadRight(32, &quot;0&quot;)), 2))
}
</pre>
<h3>Calculate the subnet network address</h3>
<p>The functions above can be used with along with a bitwise AND operation against an IP address and subnet mask to calculate the network address.</p>
<p>Note that this function includes calls to both ConvertTo-DottedDecimalIP and ConvertTo-DecimalIP.</p>
<pre class="brush: powershell;">
Function Get-NetworkAddress( [String]$IP, [String]$Mask ) {

  Return ConvertTo-DottedDecimalIP $(
    (ConvertTo-DecimalIP $IP) -BAnd
    (ConvertTo-DecimalIP $Mask))
}
</pre>
<h3>Calculate the subnet broadcast address</h3>
<p>The function is right at the bottom, the explanation is, of course, entirely optional.</p>
<p>Getting to the Broadcast Address is a bit more complicated than the Network Address. A Bitwise Or is executed against an Inverted Subnet Mask. For example, the Inverted form of 255.255.255.0 is 0.0.0.255.</p>
<p>Inverting the decimal value of the subnet mask can be performed using BNot, the Complement Operator (see Get-Help About_Comparison_Operators).</p>
<p>Unfortunately BNot only returns a signed 64-bit integer (in the range -9223372036854775808 to 9223372036854775807).</p>
<pre class="brush: plain;">
PS C:\&gt; $Value = ConvertTo-DecimalIP 255.255.255.0; $Value
4294967040
PS C:\&gt; $Value.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     UInt32                                   System.ValueType

PS C:\&gt; $Inverted = -BNot $Value; $Inverted
-4294967041
PS C:\&gt; $Inverted.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int64                                    System.ValueType

PS C:\&gt; # Convert to Binary (Base 2)
PS C:\&gt; [Convert]::ToString($Inverted, 2)
1111111111111111111111111111111100000000000000000000000011111111
</pre>
<p>The first 32 bits have are 1 (feel free to count). This happens because of the implicit conversion between UInt32 and Int64. Those 32 leading 1&#8242;s must go; Back to Binary And.</p>
<pre class="brush: plain;">
PS C:\&gt; $Inverted -BAnd [UInt32]::MaxValue
255
</pre>
<p>The operation takes advantage of the implicit conversion between types to get [UInt32]::MaxValue and to an Int64 type. As a result, this is what BAnd did:</p>
<pre class="brush: plain;">
1: 11111111 11111111 11111111 11111111 00000000 00000000 00000000 11111111
2: 00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111111
3: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11111111
</pre>
<p>Where 1 is the Int64 value from -BNot, 2 is the implicit conversion of [Int32]::MaxValue to Int64, and 3 is the result of the And operation. Finally, the resulting value can be implicitly (or explicitly) converted back to UInt32.</p>
<p>A very long explanation for a very short function.</p>
<pre class="brush: powershell;">
Function Get-BroadcastAddress( [String]$IP, [String]$Mask ) {

  Return ConvertTo-DottedDecimalIP $(
    (ConvertTo-DecimalIP $IP) -BOr
    ((-BNot (ConvertTo-DecimalIP $Mask)) -BAnd [UInt32]::MaxValue))
}
</pre>
<h3>Get-NetworkInfo</h3>
<p>Putting the functions above to work, providing a summary of an IP address range.</p>
<pre class="brush: powershell;">
Function Get-NetworkInfo( [String]$IP, [String]$Mask ) {
  If ($IP.Contains(&quot;/&quot;))
  {
    $Temp = $IP.Split(&quot;/&quot;)
    $IP = $Temp[0]
    $Mask = $Temp[1]
  }

  If (!$Mask.Contains(&quot;.&quot;))
  {
    $Mask = ConvertTo-Mask $Mask
  }

  $DecimalIP = ConvertTo-DecimalIP $IP
  $DecimalMask = ConvertTo-DecimalIP $Mask

  $Network = $DecimalIP -BAnd $DecimalMask
  $Broadcast = $DecimalIP -BOr
    ((-BNot $DecimalMask) -BAnd [UInt32]::MaxValue)
  $NetworkAddress = ConvertTo-DottedDecimalIP $Network
  $RangeStart = ConvertTo-DottedDecimalIP ($Network + 1)
  $RangeEnd = ConvertTo-DottedDecimalIP ($Broadcast - 1)
  $BroadcastAddress = ConvertTo-DottedDecimalIP $Broadcast
  $MaskLength = ConvertTo-MaskLength $Mask

  $BinaryIP = ConvertTo-BinaryIP $IP; $Private = $False
  Switch -RegEx ($BinaryIP)
  {
    &quot;^1111&quot;  { $Class = &quot;E&quot;; $SubnetBitMap = &quot;1111&quot; }
    &quot;^1110&quot;  { $Class = &quot;D&quot;; $SubnetBitMap = &quot;1110&quot; }
    &quot;^110&quot;   {
      $Class = &quot;C&quot;
      If ($BinaryIP -Match &quot;^11000000.10101000&quot;) { $Private = $True } }
    &quot;^10&quot;    {
      $Class = &quot;B&quot;
      If ($BinaryIP -Match &quot;^10101100.0001&quot;) { $Private = $True } }
    &quot;^0&quot;     {
      $Class = &quot;A&quot;
      If ($BinaryIP -Match &quot;^00001010&quot;) { $Private = $True } }
   }   

  $NetInfo = New-Object Object
  Add-Member NoteProperty &quot;Network&quot; -Input $NetInfo -Value $NetworkAddress
  Add-Member NoteProperty &quot;Broadcast&quot; -Input $NetInfo -Value $BroadcastAddress
  Add-Member NoteProperty &quot;Range&quot; -Input $NetInfo `
    -Value &quot;$RangeStart - $RangeEnd&quot;
  Add-Member NoteProperty &quot;Mask&quot; -Input $NetInfo -Value $Mask
  Add-Member NoteProperty &quot;MaskLength&quot; -Input $NetInfo -Value $MaskLength
  Add-Member NoteProperty &quot;Hosts&quot; -Input $NetInfo `
    -Value $($Broadcast - $Network - 1)
  Add-Member NoteProperty &quot;Class&quot; -Input $NetInfo -Value $Class
  Add-Member NoteProperty &quot;IsPrivate&quot; -Input $NetInfo -Value $Private

  Return $NetInfo
}
</pre>
<h3>Get-NetworkRange</h3>
<p>Calculate each host address within the network range.</p>
<pre class="brush: powershell;">
Function Get-NetworkRange( [String]$IP, [String]$Mask ) {
  If ($IP.Contains(&quot;/&quot;))
  {
    $Temp = $IP.Split(&quot;/&quot;)
    $IP = $Temp[0]
    $Mask = $Temp[1]
  }

  If (!$Mask.Contains(&quot;.&quot;))
  {
    $Mask = ConvertTo-Mask $Mask
  }

  $DecimalIP = ConvertTo-DecimalIP $IP
  $DecimalMask = ConvertTo-DecimalIP $Mask

  $Network = $DecimalIP -BAnd $DecimalMask
  $Broadcast = $DecimalIP -BOr ((-BNot $DecimalMask) -BAnd [UInt32]::MaxValue)

  For ($i = $($Network + 1); $i -lt $Broadcast; $i++) {
    ConvertTo-DottedDecimalIP $i
  }
}
</pre>
<h3>Examples</h3>
<pre class="brush: powershell;">
# Use of Convert Functions
ConvertTo-BinaryIP 192.168.1.1
ConvertTo-DecimalIP 192.168.1.1
ConvertTo-DottedDecimalIP 11000000.10101000.00000001.00000001
ConvertTo-DottedDecimalIP 3232235777
ConvertTo-MaskLength 255.255.128.0
ConvertTo-Mask 17

# Use of Network and Broadcast Address Functions
Get-NetworkAddress 192.168.1.1 255.255.255.0
Get-BroadcastAddress 192.168.1.1 255.255.255.0

# Use of Network Info
Get-NetworkInfo 229.168.1.1 255.255.248.0
Get-NetworkInfo 172.16.1.243 18
Get-NetworkInfo 10.0.0.3/14

# Use of Network Range
Get-NetworkRange 192.168.1.5 255.255.255.248
Get-NetworkRange 172.18.0.23 30
Get-NetworkRange 172.18.0.23/29
</pre>


<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2010/01/23/powershell-subnet-math/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Changing the Primary Group with PowerShell</title>
		<link>http://www.indented.co.uk/index.php/2010/01/22/changing-the-primary-group-with-powershell/</link>
		<comments>http://www.indented.co.uk/index.php/2010/01/22/changing-the-primary-group-with-powershell/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 14:48:59 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[DirectorySearcher]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[memberOf]]></category>

		<guid isPermaLink="false">http://www.indented.co.uk/?p=1366</guid>
		<description><![CDATA[Exactly as the title says, an example of how to change the Primary Group for a set of users returned by a search with PowerShell. # The current Domain $DomainNC = ([ADSI]&#34;LDAP://RootDSE&#34;).DefaultNamingContext # The Primary Group Token for Domain Users and Guests will always be # the same value (no matter the forest). Used as [...]


Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2009/08/27/accept-or-reject-messages-from/' rel='bookmark' title='Permanent Link: Accept or reject messages from'>Accept or reject messages from</a> <small>This function reads delivery restrictions from objects in Active Directory....</small></li>
<li><a href='http://www.indented.co.uk/index.php/2009/10/02/get-dsacl/' rel='bookmark' title='Permanent Link: Get-DsAcl'>Get-DsAcl</a> <small>The goal of this PowerShell function is to create a...</small></li>
<li><a href='http://www.indented.co.uk/index.php/2009/08/27/building-ldap-filters-for-date-based-attributes/' rel='bookmark' title='Permanent Link: Building LDAP filters for date based attributes'>Building LDAP filters for date based attributes</a> <small>Active Directory contains a number of attributes which hold date...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Exactly as the title says, an example of how to change the Primary Group for a set of users returned by a search with PowerShell.<br />
<span id="more-1366"></span></p>
<pre class="brush: powershell;">
# The current Domain

$DomainNC = ([ADSI]&quot;LDAP://RootDSE&quot;).DefaultNamingContext

# The Primary Group Token for Domain Users and Guests will always be
# the same value (no matter the forest). Used as a demonstration of
# how the value can be retrieved

$OldGroup = [ADSI]&quot;LDAP://CN=Domain Users,CN=Users,$DomainNC&quot;
$OldGroup.GetInfoEx(@(&quot;primaryGroupToken&quot;), 0)
$OldGroupToken = $DomainUsers.Get(&quot;primaryGroupToken&quot;)

$NewGroup = [ADSI]&quot;LDAP://CN=Domain Guests,CN=Users,$DomainNC&quot;
$NewGroup.GetInfoEx(@(&quot;primaryGroupToken&quot;), 0)
$NewGroupToken = $DomainGuests.Get(&quot;primaryGroupToken&quot;)

# Determine which accounts will be effected by the change

$BaseOU = [ADSI]&quot;LDAP://OU=SomeWhere,$DomainNC&quot;
$LdapFilter = &quot;(&amp;(objectClass=user)(objectCategory=person)&quot; + `
  &quot;(primaryGroupId=$OldGroupToken))&quot;

# Find the users

$Searcher = New-Object DirectoryServices.DirectorySearcher($BaseOU, $LdapFilter)
$Searcher.PageSize = 1000

$Searcher.FindAll() | %{
  $User = $_.GetDirectoryEntry()

  # The user must be a member of the group first

  $NewGroup.Add($User.AdsPath)

  # Change the Primary Group

  $User.Put(&quot;primaryGroupId&quot;, $NewGroupToken)
  $User.SetInfo()

  # Then the old group can be removed

  $OldGroup.Remove($User.AdsPath)
}
</pre>


<p>Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2009/08/27/accept-or-reject-messages-from/' rel='bookmark' title='Permanent Link: Accept or reject messages from'>Accept or reject messages from</a> <small>This function reads delivery restrictions from objects in Active Directory....</small></li>
<li><a href='http://www.indented.co.uk/index.php/2009/10/02/get-dsacl/' rel='bookmark' title='Permanent Link: Get-DsAcl'>Get-DsAcl</a> <small>The goal of this PowerShell function is to create a...</small></li>
<li><a href='http://www.indented.co.uk/index.php/2009/08/27/building-ldap-filters-for-date-based-attributes/' rel='bookmark' title='Permanent Link: Building LDAP filters for date based attributes'>Building LDAP filters for date based attributes</a> <small>Active Directory contains a number of attributes which hold date...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2010/01/22/changing-the-primary-group-with-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Limit recursion depth with Get-ChildItem</title>
		<link>http://www.indented.co.uk/index.php/2010/01/22/limit-recursion-depth-with-get-childitem/</link>
		<comments>http://www.indented.co.uk/index.php/2010/01/22/limit-recursion-depth-with-get-childitem/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 14:15:18 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.indented.co.uk/?p=1356</guid>
		<description><![CDATA[A PowerShell function that allows directory recursion to a specified depth. Function Get-ChildItemToDepth { Param( [String]$Path = $PWD, [String]$Filter = &#34;*&#34;, [Byte]$ToDepth = 255, [Byte]$CurrentDepth = 0, [Switch]$DebugMode ) $CurrentDepth++ If ($DebugMode) { $DebugPreference = &#34;Continue&#34; } Get-ChildItem $Path &#124; %{ $_ &#124; ?{ $_.Name -Like $Filter } If ($_.PsIsContainer) { If ($CurrentDepth -le $ToDepth) [...]


No related posts.

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>A PowerShell function that allows directory recursion to a specified depth.<br />
<span id="more-1356"></span></p>
<pre class="brush: powershell;">
Function Get-ChildItemToDepth {
  Param(
    [String]$Path = $PWD,
    [String]$Filter = &quot;*&quot;,
    [Byte]$ToDepth = 255,
    [Byte]$CurrentDepth = 0,
    [Switch]$DebugMode
  )

  $CurrentDepth++
  If ($DebugMode) { $DebugPreference = &quot;Continue&quot; }

  Get-ChildItem $Path | %{
    $_ | ?{ $_.Name -Like $Filter }

    If ($_.PsIsContainer) {
      If ($CurrentDepth -le $ToDepth) {

        # Callback to this function
        Get-ChildItemToDepth -Path $_.FullName -Filter $Filter `
          -ToDepth $ToDepth -CurrentDepth $CurrentDepth

      } Else {

        Write-Debug $(&quot;Skipping GCI for Folder: $($_.FullName) &quot; + `
          &quot;(Why: Current depth $CurrentDepth vs limit depth $ToDepth)&quot;)

      }
    }
  }
}
</pre>


<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2010/01/22/limit-recursion-depth-with-get-childitem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell, IIS and log settings</title>
		<link>http://www.indented.co.uk/index.php/2010/01/12/powershell-iis-and-log-settings/</link>
		<comments>http://www.indented.co.uk/index.php/2010/01/12/powershell-iis-and-log-settings/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 10:06:45 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[IIS]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[wmi]]></category>

		<guid isPermaLink="false">http://www.indented.co.uk/?p=1353</guid>
		<description><![CDATA[A function to retrieve IIS log settings from a local or remote IIS 6 server. Written to be compatible with PowerShell 1.0. Function Get-IISLogSetting { Param([String[]]$Servers = $Env:Computername) $Servers &#124; %{ $Server = $_ $WMI = New-Object Management.ManagementScope(&#34;\\$Server\root\MicrosoftIISv2&#34;) $WMI.Options.Authentication = &#34;PacketPrivacy&#34; $Query = New-Object Management.ObjectQuery( ` &#34;SELECT Name, LogFileDirectory, LogFileTruncateSize, &#34; + ` &#34;LogType, LogFilePeriod [...]


Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2009/08/27/accept-or-reject-messages-from/' rel='bookmark' title='Permanent Link: Accept or reject messages from'>Accept or reject messages from</a> <small>This function reads delivery restrictions from objects in Active Directory....</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>A function to retrieve IIS log settings from a local or remote IIS 6 server. Written to be compatible with PowerShell 1.0.<br />
<span id="more-1353"></span></p>
<pre class="brush: powershell;">
Function Get-IISLogSetting
{
  Param([String[]]$Servers = $Env:Computername)

  $Servers | %{
    $Server = $_

    $WMI = New-Object Management.ManagementScope(&quot;\\$Server\root\MicrosoftIISv2&quot;)
    $WMI.Options.Authentication = &quot;PacketPrivacy&quot;
    $Query = New-Object Management.ObjectQuery( `
      &quot;SELECT Name, LogFileDirectory, LogFileTruncateSize, &quot; + `
      &quot;LogType, LogFilePeriod FROM IIsWebServerSetting&quot;)

    $Searcher = New-Object Management.ManagementObjectSearcher($WMI, $Query)

    Trap [UnauthorizedAccessException]
    {
      Write-Error &quot;$($Server): Unable to connect or Access is denied&quot;
      continue
    }
    $Searcher.Get() | Select-Object `
      @{n='Name';e={ $Server }}, `
      @{n='Site';e={ $_.Name }}, `
      @{n='IIS Logging';e={
        Switch ($_.LogType) {
          0 { &quot;Disabled&quot; }
          1 { &quot;Enabled&quot; }
        } }}, `
      @{n='Log Path';e={ $_.LogFileDirectory }}, `
      @{n='Log File Size';e={
        If ([Int]$_.LogFileTruncateSize -eq -1) { &quot;Unlimited&quot; } else {
          &quot;$([Int]$_.LogFileTruncateSize / 1Gb) Gb&quot; } }}, `
      @{n='Log File Rollover';e={
        Switch ($_.LogFilePeriod) {
          0 { &quot;Size&quot; }
          1 { &quot;Date&quot; }
        } }}
  }
}
</pre>


<p>Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2009/08/27/accept-or-reject-messages-from/' rel='bookmark' title='Permanent Link: Accept or reject messages from'>Accept or reject messages from</a> <small>This function reads delivery restrictions from objects in Active Directory....</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2010/01/12/powershell-iis-and-log-settings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SysLog in PowerShell</title>
		<link>http://www.indented.co.uk/index.php/2009/12/01/syslog-in-powershell/</link>
		<comments>http://www.indented.co.uk/index.php/2009/12/01/syslog-in-powershell/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 16:01:07 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SysLog]]></category>

		<guid isPermaLink="false">http://www.highorbit.co.uk/?p=1215</guid>
		<description><![CDATA[I bumped into a requirement to run a SysLog relay on one of my Windows 2008 R2 systems. After poking around on Google, and after getting a bit bored with the third-party offerings, I threw together a simple server of my own. There is plenty of room for improvement here, but it works (for me [...]


Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2010/02/17/dhcp-discovery/' rel='bookmark' title='Permanent Link: DHCP Discovery'>DHCP Discovery</a> <small>A PowerShell script to send a DHCP Discover request and...</small></li>
<li><a href='http://www.indented.co.uk/index.php/2010/01/23/powershell-subnet-math/' rel='bookmark' title='Permanent Link: IPv4 subnet math with PowerShell'>IPv4 subnet math with PowerShell</a> <small>Written to complement the VbScript version of this post. This...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>I bumped into a requirement to run a SysLog relay on one of my Windows 2008 R2 systems. After poking around on Google, and after getting a bit bored with the third-party offerings, I threw together a simple server of my own.<br />
<span id="more-1215"></span><br />
There is plenty of room for improvement here, but it works (for me at least) as it stands.</p>
<p>Written for and tested under PowerShell 2.0. The script could probably use some error handling.</p>
<pre class="brush: powershell;">
# SysLog.ps1
#
# A basic SysLog server. Behaviour should be fairly consistent with
# RFC 3164 (http://www.ietf.org/rfc/rfc3164.txt).

# Network Configuration

$SysLogPort = 514                  # Default SysLog Port
$Buffer = New-Object Byte[] 1024   # Maximum SysLog message size

# Server Configuration

$EnableMessageValidation = $True   # Enable check of the PRI and Header
$EnableRelay = $True               # Enable relay to $RelayTargetIP
$EnableLocalLogging = $True        # Enable local logging of received messages
$EnableConsoleLogging = $False     # Enable logging to the console
$EnableHostNameLookup = $True      # Lookup hostname for connecting IP
$EnableHostNamesOnly = $True       # Uses Host Name only instead of FQDNs

$RelayTargetIP = &quot;10.0.0.1&quot;        # Must be an IP Address
$LogFolder = &quot;C:\SysLog\LogFiles&quot;  # Path must exist

# Global variables used to store day and date-stamp for log roll-over

$Day = (Get-Date).Day
$DateStamp = (Get-Date).ToString(&quot;yyyy.MM.dd&quot;)

# Relay Initialisation

If ($EnableRelay)
{
  $RelayTarget = [Net.IPAddress]::Parse($RelayTargetIP)
  $RelayTargetEndPoint = New-Object Net.IPEndPoint($RelayTarget, $SysLogPort)
}

# A launcher for the process
#
# Caller: Manual / Script

Function Start-SysLog
{
  $Socket = CreateSocket
  StartReceive $Socket
}

# Create and bind to the socket
#
# Caller: Start-SysLog

Function CreateSocket
{
  $Socket = New-Object Net.Sockets.Socket(
    [Net.Sockets.AddressFamily]::Internetwork,
    [Net.Sockets.SocketType]::Dgram,
    [Net.Sockets.ProtocolType]::Udp)

  $ServerIPEndPoint = New-Object Net.IPEndPoint(
    [Net.IPAddress]::Any,
    $SysLogPort)

  $Socket.Bind($ServerIPEndPoint)

  Return $Socket
}

# Recieve a single message
#
# Caller: Start-SysLog

Function StartReceive([Net.Sockets.Socket]$Socket)
{
  # Placeholder to store source of incoming packet
  $SenderIPEndPoint = New-Object Net.IPEndPoint([Net.IPAddress]::Any, 0)
  $SenderEndPoint = [Net.EndPoint]$SenderIPEndPoint

  $ServerRunning = $True
  While ($ServerRunning -eq $True)
  {
    $BytesReceived = $Socket.ReceiveFrom($Buffer, [Ref]$SenderEndPoint)
    $Message = $Buffer[0..$($BytesReceived - 1)]

    $Message = ValidateMessage $Message $SenderEndPoint.Address.IPAddressToString

    If ($EnableRelay)
    {
      RelayMessage $Socket $Message
    }
  }
}

# Relay the message to an upstream SysLog server. Either basic forwarding,
# or full validation.
#
# Caller: StartReceive

Function RelayMessage([Net.Sockets.Socket]$Socket, [Byte[]]$Message)
{
  [Void]$Socket.SendTo($Message, $RelayTargetEndPoint)
}

# Check the validity of the message (if option is enabled). Adjust message
# according to recommendations in RFC 3164.
#
# Caller: StartReceive

Function ValidateMessage([Byte[]]$Message, [String]$HostName)
{
  If ($EnableMessageValidation)
  {
    $MessageString = [Text.Encoding]::ASCII.GetString($Message)

    If (IsValidPRI($MessageString))
    {
      If (!(IsValidDateTime($MessageString)))
      {
        $PRI = [Int]($MessageString -Replace &quot;&lt;|&gt;.*&quot;)
        $HostName = GetHostName $HostName
        $MessageString = &quot;&lt;$PRI&gt;$(NewDateTimeString) $HostName $MessageString&quot;
        $Message = EncodeMessage $MessageString
      }
    }
    Else
    {
      $HostName = GetHostName $HostName
      $MessageString = &quot;&lt;13&gt;$(NewDateTimeString) $HostName $MessageString&quot;
      $Message = EncodeMessage $MessageString
    }
  }
  If ($EnableLocalLogging -Or $EnableConsoleLogging)
  {
    If ($MessageString -eq $Null)
    {
      $MessageString = [Text.Encoding]::ASCII.GetString($Message)
    }
    If ($EnableLocalLogging) { WriteToLog $MessageString $HostName }
    If ($EnableConsoleLogging) { Write-Host $MessageString }
  }
  Return $Message
}

# Validate the PRI (Priority Field - Facility and Severity)
# No parsing is performed. No network prioritisation is implemented
#
# Caller: ValidateMessage

Function IsValidPRI([String]$MessageString)
{
  If ($MessageString.SubString(0, 1) -ne &quot;&lt;&quot;)
  {
    Return $False
  }
  If (!$MessageString.SubString(2, 3).Contains(&quot;&gt;&quot;))
  {
    Return $False
  }

  $PRI = [Int]($MessageString -Replace &quot;&lt;|&gt;.*&quot;)
  # PRI = (Facility * 8) + Severity. Maximum and minimum values from RFC 3164
  If ($PRI -lt 1 -Or $PRI -gt 191)
  {
    Return $False
  }
  Return $True
}

# Validate the TimeStamp formatting
#
# Caller: ValidateMessage

Function IsValidDateTime([String]$MessageString)
{
  $IsValid = $False
  If ($MessageString -Match &quot;(?&lt;=\&gt;)\w{3}\s\s?\d{1,2}\s(\d\d:){2}\d\d(?=\s)&quot;)
  {
    $Date = New-Object DateTime
    ForEach ($Format in @(&quot;MMM  d hh:mm:ss&quot;, &quot;MMM dd hh:mm:ss&quot;))
    {
      $Date = New-Object DateTime
      $IsValid = [DateTime]::TryParseExact(
        $Matches[0],
        $Format,
        [Globalization.CultureInfo]::InvariantCulture,
        [Globalization.DateTimeStyles]::AssumeUniversal,
        [Ref]$Date)
      If ($IsValid) { Return $True }
    }
  }
  Return $False
}

# Create a new DateTime String
#
# Caller: ValidateMessage

Function NewDateTimeString
{
  $Date = (Get-Date).ToUniversalTime()
  If ($Date.Day -lt 10)
  {
    Return $Date.ToString(&quot;MMM  d HH:mm:ss&quot;)
  }
  Return $Date.ToString(&quot;MMM dd HH:mm:ss&quot;)
}

# Attempt to lookup the HostName if an IP value was passed.
# [Net.Dns]::GetHostEntry fails to return if a Forward Lookup record
# does not exist. NsLookup as a simple alternative.
#
# Caller: ValidateMessage

Function GetHostName([String]$HostName)
{
  If (!$EnableHostNameLookup) { Return $HostName }
  If ([Net.IPAddress]::TryParse($HostName, [Ref]$Null))
  {
    $Temp = (nslookup -q=ptr $HostName | ?{ $_ -Like &quot;*name = *&quot; })
    $Temp = $Temp -Replace &quot;.*name = &quot;
    If ($Temp -ne [String]::Empty) { $HostName = $Temp }
  }
  If ($EnableHostNamesOnly)
  {
    Return $HostName.Split(&quot;.&quot;)[0]
  }
  Return $HostName
}

# Returns a Byte Array representation of the original message.
# If the length is greater than 1024 Bytes the array is truncated
# as stipulated under RFC 3164.
#
# Caller: ValidateMessage

Function EncodeMessage([String]$MessageString)
{
  $Message = [Text.Encoding]::ASCII.GetBytes($MessageString)
  If ($Message.Length -gt 1024)
  {
    Return $Message[0..1023]
  }
  Return $Message
}

# Maintain a per-host log file in the $LogFolder
# Script does not clean up old log files
#
# Caller: ValidateMessage

Function WriteToLog([String]$MessageString, [String]$HostName)
{
  # Simple time based roll-over check
  If ((Get-Date).Day -ne $Day)
  {
    $Day = (Get-Date).Day
    $DateStamp = (Get-Date).ToString(&quot;yyyy.MM.dd&quot;)
  }

  $LogFile = &quot;$LogFolder\$HostName-$DateStamp.log&quot;
  $MessageString &gt;&gt; $LogFile
}

# Start the server

Start-SysLog
</pre>


<p>Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2010/02/17/dhcp-discovery/' rel='bookmark' title='Permanent Link: DHCP Discovery'>DHCP Discovery</a> <small>A PowerShell script to send a DHCP Discover request and...</small></li>
<li><a href='http://www.indented.co.uk/index.php/2010/01/23/powershell-subnet-math/' rel='bookmark' title='Permanent Link: IPv4 subnet math with PowerShell'>IPv4 subnet math with PowerShell</a> <small>Written to complement the VbScript version of this post. This...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2009/12/01/syslog-in-powershell/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Get-DsAcl</title>
		<link>http://www.indented.co.uk/index.php/2009/10/02/get-dsacl/</link>
		<comments>http://www.indented.co.uk/index.php/2009/10/02/get-dsacl/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 08:33:31 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[acl]]></category>

		<guid isPermaLink="false">http://www.highorbit.co.uk/?p=1199</guid>
		<description><![CDATA[The goal of this PowerShell function is to create a report of permissions assigned to objects in Active Directory in much the same way as DsRevoke. The names for extended rights and object types are read from the schema allowing the script to display friendly names. Properties Property Description Name The name of the Object; [...]


Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2010/01/22/changing-the-primary-group-with-powershell/' rel='bookmark' title='Permanent Link: Changing the Primary Group with PowerShell'>Changing the Primary Group with PowerShell</a> <small>Exactly as the title says, an example of how to...</small></li>
<li><a href='http://www.indented.co.uk/index.php/2009/08/27/accept-or-reject-messages-from/' rel='bookmark' title='Permanent Link: Accept or reject messages from'>Accept or reject messages from</a> <small>This function reads delivery restrictions from objects in Active Directory....</small></li>
<li><a href='http://www.indented.co.uk/index.php/2009/08/27/building-ldap-filters-for-date-based-attributes/' rel='bookmark' title='Permanent Link: Building LDAP filters for date based attributes'>Building LDAP filters for date based attributes</a> <small>Active Directory contains a number of attributes which hold date...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>The goal of this PowerShell function is to create a report of permissions assigned to objects in Active Directory in much the same way as DsRevoke.<br />
<span id="more-1199"></span><br />
The names for extended rights and object types are read from the schema allowing the script to display friendly names.</p>
<h3>Properties</h3>
<table>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
<tr>
<td>Name</td>
<td>The name of the Object; by default this will be an OU, but I made this configurable (see examples).</td>
</tr>
<tr>
<td>DN</td>
<td>The DN of the Object; equivalent to Object (DsRevoke)</td>
</tr>
<tr>
<td>ObjectClass</td>
<td>Object class</td>
</tr>
<tr>
<td>SecurityPrincipal</td>
<td>The User or Group (or Computer) the Access Control Entry is for; used as the search using DsRevoke</td>
</tr>
<tr>
<td>AccessType</td>
<td>Allow or Deny; equivalent to ACE Type</td>
</tr>
<tr>
<td>Permissions</td>
<td>Same as Permissions list in DsRevoke</td>
</tr>
<tr>
<td>AppliesTo</td>
<td>What the ACE applies to; equivalent to &#8220;ACE inherited by all child objects&#8221; entry</td>
</tr>
<tr>
<td>AppliesToObjectType</td>
<td>The object class the ACE applies to; equivalent to &#8220;ACE inherited by all child objects of Class &#8230;&#8221;</td>
</tr>
<tr>
<td>AppliesToProperty</td>
<td>The specific property or Property Set an ACE applies to, or the Extended Right an ACE grants (if defined)</td>
</tr>
<tr>
<td>Inherited</td>
<td>True if the Access Control Entry was inherited. Only applies with -Inherited switch.</td>
</tr>
</table>
<h3>Usage examples</h3>
<p>Standard output (reporting on organizational units in the current domain):</p>
<pre class="brush: powershell;">
Get-DsAcl
</pre>
<p>Format Table:</p>
<pre class="brush: powershell;">
Get-DsAcl | Format-Table
</pre>
<p>Store in a variable:</p>
<pre class="brush: powershell;">
ACLs = Get-DsAcl
</pre>
<p>Export to CSV:</p>
<pre class="brush: powershell;">
Get-DsAcl | Export-CSV &quot;Rights.csv&quot;
</pre>
<p>Reporting on User objects:</p>
<pre class="brush: powershell;">
Get-DsAcl -ObjectType &quot;user&quot;
</pre>
<p>Reporting on a sub-OU:</p>
<pre class="brush: powershell;">
Get-DsAcl &quot;OU=Test,DC=domain,DC=com&quot;
# Or
Get-DsAcl -SearchRoot &quot;OU=Test,DC=domain,DC=com&quot;
</pre>
<p>Reporting on contacts in a sub-OU:</p>
<pre class="brush: powershell;">
Get-DsAcl &quot;OU=Test,DC=domain,DC=com&quot; -ObjectType &quot;contact&quot;
</pre>
<p>Using a custom LDAP filter:</p>
<pre class="brush: powershell;">
Get-DsAcl -LdapFilter &quot;(objectClass=*)&quot;
</pre>
<p>Including Inherited entries:</p>
<pre class="brush: powershell;">
Get-DsAcl -LdapFilter &quot;(name=Chris Dent)&quot; -Inherited | Format-Table
</pre>
<h3>Get-DsAcl</h3>
<pre class="brush: powershell;">
Function Get-DSACL {
  # Function to list permissions assigned to objects in Active Directory
  # This function reports on organizationalUnits within the domain by default.

  Param(
    $SearchRoot = ([ADSI]&quot;LDAP://RootDSE&quot;).Get(&quot;defaultNamingContext&quot;),
    $ObjectType = &quot;organizationalUnit&quot;,
    $LdapFilter = &quot;(&amp;(objectClass=$ObjectType)(objectCategory=$ObjectType))&quot;,
    [Switch]$Inherited = $False
  )

  # Set the output field separator (default is &quot; &quot;)
  $OFS = &quot;\&quot;

  # Connect to RootDSE
  $RootDSE = [ADSI]&quot;LDAP://RootDSE&quot;
  # Connect to the Schema
  $Schema = [ADSI]&quot;LDAP://$($RootDSE.Get('schemaNamingContext'))&quot;
  # Connect to the Extended Rights container
  $Configuration = $RootDSE.Get(&quot;configurationNamingContext&quot;)
  $ExtendedRights = [ADSI]&quot;LDAP://CN=Extended-Rights,$Configuration&quot;

  # Find objects based on $SearchRoot and $ObjectType
  $Searcher = New-Object DirectoryServices.DirectorySearcher(`
    [ADSI]&quot;LDAP://$SearchRoot&quot;, `
    $LdapFilter)

  $Searcher.FindAll() | %{
    $Object = $_.GetDirectoryEntry()

    # Retrieve all Access Control Entries from the AD Object
    $ACL = $Object.PsBase.ObjectSecurity.GetAccessRules(`
      $True, `
      $Inherited, `
      [Security.Principal.NTAccount])

    # Get interesting values
    $ACL | Select-Object @{n='Name';e={ $Object.Get(&quot;name&quot;) }}, `
      @{n='DN';e={ $Object.Get(&quot;distinguishedName&quot;) }}, `
      @{n='ObjectClass';e={ $Object.Class }}, `
      @{n='SecurityPrincipal';e={ $_.IdentityReference.ToString() }}, `
      @{n='AccessType';e={ $_.AccessControlType }}, `
      @{n='Permissions';e={ $_.ActiveDirectoryRights }}, `
      @{n='AppliesTo';e={
        #
        # Change the values for InheritanceType to friendly names
        #
        Switch ($_.InheritanceType) {
          &quot;None&quot;            { &quot;This object only&quot; }
          &quot;Descendents&quot;     { &quot;All child objects&quot; }
          &quot;SelfAndChildren&quot; { &quot;This object and one level Of child objects&quot; }
          &quot;Children&quot;        { &quot;One level of child objects&quot; }
          &quot;All&quot;             { &quot;This object and all child objects&quot; }
        } }}, `
      @{n='AppliesToObjectType';e={
        If ($_.InheritedObjectType.ToString() -NotMatch &quot;0{8}.*&quot;) {
          #
          # Search for the Object Type in the Schema
          #
          $LdapFilter = `
            &quot;(SchemaIDGUID=\$($_.InheritedObjectType.ToByteArray() | `
            %{ '{0:X2}' -f $_ }))&quot;
          $Result = (New-Object DirectoryServices.DirectorySearcher(`
            $Schema, $LdapFilter)).FindOne()
          $Result.Properties[&quot;ldapdisplayname&quot;]
        } Else { &quot;All&quot; } }}, `
      @{n='AppliesToProperty';e={
        If ($_.ObjectType.ToString() -NotMatch &quot;0{8}.*&quot;) {
          #
          # Search for a possible Extended-Right or Property Set
          #
          $LdapFilter = &quot;(rightsGuid=$($_.ObjectType.ToString()))&quot;
          $Result = (New-Object DirectoryServices.DirectorySearcher(`
            $ExtendedRights, $LdapFilter)).FindOne()
          If ($Result) {
            $Result.Properties[&quot;displayname&quot;]
          } Else {
            #
            # Search for the attribute name in the Schema
            #
            $LdapFilter = &quot;(SchemaIDGUID=\$($_.ObjectType.ToByteArray() | `
              %{ '{0:X2}' -f $_ }))&quot;
            $Result = (New-Object DirectoryServices.DirectorySearcher(`
              $Schema, $LdapFilter)).FindOne()
            $Result.Properties[&quot;ldapdisplayname&quot;]
          }
        } Else { &quot;All&quot; } }}, `
      @{n='Inherited';e={ $_.IsInherited }}
  }
}
</pre>


<p>Related posts:<ol><li><a href='http://www.indented.co.uk/index.php/2010/01/22/changing-the-primary-group-with-powershell/' rel='bookmark' title='Permanent Link: Changing the Primary Group with PowerShell'>Changing the Primary Group with PowerShell</a> <small>Exactly as the title says, an example of how to...</small></li>
<li><a href='http://www.indented.co.uk/index.php/2009/08/27/accept-or-reject-messages-from/' rel='bookmark' title='Permanent Link: Accept or reject messages from'>Accept or reject messages from</a> <small>This function reads delivery restrictions from objects in Active Directory....</small></li>
<li><a href='http://www.indented.co.uk/index.php/2009/08/27/building-ldap-filters-for-date-based-attributes/' rel='bookmark' title='Permanent Link: Building LDAP filters for date based attributes'>Building LDAP filters for date based attributes</a> <small>Active Directory contains a number of attributes which hold date...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2009/10/02/get-dsacl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
