<?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! &#187; Active Directory</title>
	<atom:link href="http://www.indented.co.uk/index.php/tag/active-directory/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.indented.co.uk</link>
	<description></description>
	<lastBuildDate>Mon, 17 Oct 2011 19:03:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<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. No related posts. Related posts brought to you by Yet Another Related Posts Plugin.
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>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>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>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>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. No related posts. Related posts brought to you by Yet Another Related Posts Plugin.
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>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; title: ; notranslate">
# 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 = $OldGroup.Get(&quot;primaryGroupToken&quot;)

$NewGroup = [ADSI]&quot;LDAP://CN=Domain Guests,CN=Users,$DomainNC&quot;
$NewGroup.GetInfoEx(@(&quot;primaryGroupToken&quot;), 0)
$NewGroupToken = $NewGroup.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>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>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>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; [...]
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>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; title: ; notranslate">
Get-DsAcl
</pre>
<p>Format Table:</p>
<pre class="brush: powershell; title: ; notranslate">
Get-DsAcl | Format-Table
</pre>
<p>Store in a variable:</p>
<pre class="brush: powershell; title: ; notranslate">
ACLs = Get-DsAcl
</pre>
<p>Export to CSV:</p>
<pre class="brush: powershell; title: ; notranslate">
Get-DsAcl | Export-CSV &quot;Rights.csv&quot;
</pre>
<p>Reporting on User objects:</p>
<pre class="brush: powershell; title: ; notranslate">
Get-DsAcl -ObjectType &quot;user&quot;
</pre>
<p>Reporting on a sub-OU:</p>
<pre class="brush: powershell; title: ; notranslate">
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; title: ; notranslate">
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; title: ; notranslate">
Get-DsAcl -LdapFilter &quot;(objectClass=*)&quot;
</pre>
<p>Including Inherited entries:</p>
<pre class="brush: powershell; title: ; notranslate">
Get-DsAcl -LdapFilter &quot;(name=Chris Dent)&quot; -Inherited | Format-Table
</pre>
<h3>Get-DsAcl</h3>
<pre class="brush: powershell; title: ; notranslate">
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>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>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>
		<item>
		<title>Accept or reject messages from</title>
		<link>http://www.indented.co.uk/index.php/2009/08/27/accept-or-reject-messages-from/</link>
		<comments>http://www.indented.co.uk/index.php/2009/08/27/accept-or-reject-messages-from/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 15:28:47 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[Exchange]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.highorbit.co.uk/?p=1170</guid>
		<description><![CDATA[This function reads delivery restrictions from objects in Active Directory. By default it looks at Groups. As the same information can be returned using Get-DistributionGroup or Get-Mailbox using Exchange 2007; this function is aimed at Exchange 2003. No related posts. Related posts brought to you by Yet Another Related Posts Plugin.
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>This function reads delivery restrictions from objects in Active Directory. By default it looks at Groups. As the same information can be returned using Get-DistributionGroup or Get-Mailbox using Exchange 2007; this function is aimed at Exchange 2003.<br />
<span id="more-1170"></span></p>
<pre class="brush: powershell; title: ; notranslate">
Function Get-SendToPermissions {
  Param(
    [String]$Identity,
    [String]$SearchRoot = $Null,
    [String]$LDAPFilter = &quot;(objectCategory=group)&quot;,
    [Switch]$GC
  )

  If ($GC) { $Port = &quot;GC&quot; } else { $Port = &quot;LDAP&quot; }
  If ($SearchRoot) { $SearchRoot = [ADSI]&quot;$Port://$SearchRoot&quot; }

  $Properties = @(&quot;name&quot;, &quot;distinguishedName&quot;, &quot;dLMemSubmitPerms&quot;, `
    &quot;dLMemRejectPerms&quot;, &quot;authOrig&quot;, &quot;unauthOrig&quot;, &quot;msExchRequireAuthToSendTo&quot;)

  $Searcher = New-Object `
    DirectoryServices.DirectorySearcher($SearchRoot, $LDAPFilter)
  $Searcher.PageSize = 1000
  $Searcher.PropertiesToLoad.AddRange($Properties)

  $Searcher.FindAll() | %{
    $_ | Select-Object `
      @{n='Name';e={ $_.Properties['name'] }}, `
      @{n='DN';e={ $_.Properties['distinguishedname'] }}, `
      @{n='RequireAuthToSendTo';e={
        If ($_.Properties['msexchrequireauthtosendto']) {
          $True
        } Else {
          $False
        } }}, `
      @{n='AcceptFromMembersOfGroup';e={ $_.Properties['dlmemsubmitperms'] }}, `
      @{n='RejectFromMembersOfGroup';e={ $_.Properties['dlmemrejectperms'] }}, `
      @{n='AcceptFromUsers';e={ $_.Properties['authorig'] }}, `
      @{n='RejectFromUsers';e={ $_.Properties['unauthorig'] }}
  }
End Function
</pre>
<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2009/08/27/accept-or-reject-messages-from/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building LDAP filters for date based attributes</title>
		<link>http://www.indented.co.uk/index.php/2009/08/27/building-ldap-filters-for-date-based-attributes/</link>
		<comments>http://www.indented.co.uk/index.php/2009/08/27/building-ldap-filters-for-date-based-attributes/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 10:33:34 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[VbScript]]></category>
		<category><![CDATA[LDAP]]></category>

		<guid isPermaLink="false">http://www.highorbit.co.uk/?p=1154</guid>
		<description><![CDATA[Active Directory contains a number of attributes which hold date information. This article shows how to generate LDAP Filters for these attributes in both VbScript and PowerShell. Date attributes This LDAP Filter format can be used for the following attributes: createTimeStamp dsCorePropagationData expirationTime modifyTimeStamp whenChanged whenCreated VbScript This will produce a filter like &#8220;(whenCreated>=20090826110816.0Z)&#8221;. Accuracy [...]
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Active Directory contains a number of attributes which hold date information. This article shows how to generate LDAP Filters for these attributes in both VbScript and PowerShell.<br />
<span id="more-1154"></span></p>
<h3>Date attributes</h3>
<p>This LDAP Filter format can be used for the following attributes:</p>
<ul>
<li>createTimeStamp</li>
<li>dsCorePropagationData</li>
<li>expirationTime</li>
<li>modifyTimeStamp</li>
<li>whenChanged</li>
<li>whenCreated</li>
</ul>
<h4>VbScript</h4>
<pre class="brush: vb; title: ; notranslate">
' The date the filter is supposed to find
dtmDate = Now() - 1

arrDateParts = Array(&quot;yyyy&quot;, &quot;m&quot;, &quot;d&quot;, &quot;h&quot;, &quot;n&quot;, &quot;s&quot;)

For Each strInterval in arrDateParts
  intDatePart = DatePart(strInterval, dtmDate)
  If intDatePart &lt; 10 Then
    strDateTime = strDateTime &amp; &quot;0&quot; &amp; intDatePart
  Else
    strDateTime = strDateTime &amp; intDatePart
  End If
Next
strDateTime = strDateTime &amp; &quot;.0Z&quot;

' WhenCreated is after strDateTime. i.e. objects created since strDateTime.
WScript.Echo &quot;(whenCreated&gt;=&quot; &amp; strDateTime &amp; &quot;)&quot;
</pre>
<p>This will produce a filter like &#8220;(whenCreated>=20090826110816.0Z)&#8221;. Accuracy is based on the source date, using Date() instead of Now() would result in accuracy to a day (e.g. &#8220;(whenCreated>=20090826000000.0Z)&#8221;).</p>
<h4>PowerShell</h4>
<pre class="brush: powershell; title: ; notranslate">
# Convert yesterday to a Universal date-time string
$DateString = (Get-Date).AddDays(-1).ToString(&quot;u&quot;) -Replace &quot;-|:|\s&quot;
$DateString = $DateString -Replace &quot;Z&quot;, &quot;.0Z&quot;

Write-Host &quot;(whenCreated&gt;=$DateString)&quot;
</pre>
<p>As with the VbScript version this returns a string accurate to seconds. Accuracy can be modified by using (Get-Date).Date.AddDays(-1).</p>
<h3>Interger8 attributes</h3>
<p>An Interger8 date is represented by the number of 100-nanosecond intervals since the Microsoft epoch (01/01/1601 00:00:00). This format applies to the following attributes:</p>
<ul>
<li>accountExpires</li>
<li>badPasswordTime</li>
<li>lastLogon</li>
<li>lastLogonTimeStamp</li>
<li>lockoutTime</li>
<li>pwdLastSet</li>
</ul>
<p>Note that lastLogoff also uses this format but the value for the attribute is not maintained by Active Directory.</p>
<h4>VbScript</h4>
<pre class="brush: vb; title: ; notranslate">
' The number of days to remove from the current date
Const DAYS_TO_REMOVE = 1

dblInt8 = CDbl(DateDiff(&quot;s&quot;, CDate(&quot;01/01/1601 00:00:00&quot;), Now - DAYS_TO_REMOVE))
' Earlier than the current date. i.e. Passwords set before the generated date
WScript.Echo &quot;(&amp;(pwdLastSet&lt;=&quot; &amp; CStr(dblInt8) &amp; &quot;0000000)(!pwdLastSet=0))&quot;
</pre>
<p>This produces a filter like &#8220;(&#038;(pwdLastSet<=128957595350000000)(!pwdLastSet=0))". As with the previous filter this is accurate to seconds, that can be modified by changing the source date in the same way as before.</p>
<h4>PowerShell</h4>
<pre class="brush: powershell; title: ; notranslate">
$DaysToRemove = 1
$Int8Date = [Math]::Round(( `
  New-TimeSpan $(Get-Date(&quot;01/01/1601 00:00:00&quot;)) `
  ((Get-Date).AddDays(-$DaysToRemove))).TotalSeconds, 0)

$Int8Date = &quot;$($Int8Date.ToString())0000000&quot;

$LdapFilter = &quot;(&amp;(pwdLastSet&lt;=$Int8Date)(!pwdLastSet=0))&quot;
</pre>
<h3>accountExpires</h3>
<p>Certain attributes, such as accountExpires, have default values that can make filtering using a date string difficult.</p>
<p>The following LDAP filter can be used to return all accounts that are set to expire.</p>
<pre class="brush: powershell; title: ; notranslate">
&quot;(accountExpires&lt;=9223372032559810000)(!accountExpires=0))&quot;
</pre>
<p>Where 9223372032559810000 is the default attribute value in most cases, and 0 is the default in the rest.</p>
<p>accountExpires exhibits inconsistent behaviour depending on how it is accessed. If using iADSUser.AccountExpirationDate an account that does not expire is denoted by the date &#8220;01/01/1970 00:00:00&#8243;. This epoch date differs from the epoch used with the underlying attribute, &#8220;01/01/1601 00:00:00&#8243;.</p>
<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2009/08/27/building-ldap-filters-for-date-based-attributes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Listing Trusts</title>
		<link>http://www.indented.co.uk/index.php/2009/08/27/listing-trusts/</link>
		<comments>http://www.indented.co.uk/index.php/2009/08/27/listing-trusts/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 10:01:11 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[VbScript]]></category>
		<category><![CDATA[Trust]]></category>

		<guid isPermaLink="false">http://www.highorbit.co.uk/?p=1144</guid>
		<description><![CDATA[A script to enumerate trust information from an Active Directory forest. Usage example In the past I have used the script above to monitor trust settings across a forest. The following script uses the trust information to build a text file storing trust configuration sends an e-mail if that configuration changes. No related posts. Related [...]
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>A script to enumerate trust information from an Active Directory forest.<br />
<span id="more-1144"></span></p>
<pre class="brush: vb; title: ; notranslate">
Const ADS_SCOPE_SUBTREE = 2

' Trust Type
' http://msdn.microsoft.com/en-us/library/cc223771(PROT.10).aspx
Dim objTrustTypes
Set objTrustTypes = CreateObject(&quot;Scripting.Dictionary&quot;)
objTrustTypes.Add 4, &quot;DCE&quot;
objTrustTypes.Add 3, &quot;MIT&quot;
objTrustTypes.Add 2, &quot;UpLevel&quot;
objTrustTypes.Add 1, &quot;DownLevel&quot;

' Trust Attributes
' http://msdn.microsoft.com/en-us/library/cc223779(PROT.10).aspx
Dim objTrustAttributes
Set objTrustAttributes = CreateObject(&quot;Scripting.Dictionary&quot;)
objTrustAttributes.Add 128, &quot;UsesRC4Encryption&quot;
objTrustAttributes.Add 64, &quot;TreatAsExternal&quot;
objTrustAttributes.Add 32, &quot;WithinForest&quot;
objTrustAttributes.Add 16, &quot;CrossOrganisation&quot;
objTrustAttributes.Add 8, &quot;ForestTransitive&quot;
objTrustAttributes.Add 4, &quot;QuarantinedDomain&quot;
objTrustAttributes.Add 2, &quot;UpLevelOnly&quot;
objTrustAttributes.Add 1, &quot;NonTransitive&quot;

' Trust Direction
' http://msdn.microsoft.com/en-us/library/cc223768(PROT.10).aspx
Dim objTrustDirection
Set objTrustDirection = CreateObject(&quot;Scripting.Dictionary&quot;)
objTrustDirection.Add 3, &quot;BiDirectional&quot;
objTrustDirection.Add 2, &quot;Outbound&quot;
objTrustDirection.Add 1, &quot;Inbound&quot;
objTrustDirection.Add 0, &quot;Disabled&quot;

Dim objConnection : Set objConnection = CreateObject(&quot;ADODB.Connection&quot;)
objConnection.Provider = &quot;ADsDSOObject&quot;
objConnection.Open &quot;Active Directory Provider&quot;

Dim objCommand : Set objCommand = CreateObject(&quot;ADODB.Command&quot;)
objCommand.ActiveConnection = objConnection

Dim objRootDSE : Set objRootDSE = GetObject(&quot;LDAP://RootDSE&quot;)
objCommand.CommandText = &quot;SELECT distinguishedName, name, trustType, &quot; &amp; _
  &quot;trustAttributes, trustDirection, trustPartner, whenCreated &quot; &amp; _
  &quot;FROM 'GC://&quot; &amp; objRootDSE.Get(&quot;rootDomainNamingContext&quot;) &amp; _
  &quot;' WHERE objectClass='trustedDomain'&quot;

objCommand.Properties(&quot;Page Size&quot;) = 1000
objCommand.Properties(&quot;Timeout&quot;) = 600
objCommand.Properties(&quot;Searchscope&quot;) = ADS_SCOPE_SUBTREE
objCommand.Properties(&quot;Cache Results&quot;) = False

Dim objRecordSet : Set objRecordSet = objCommand.Execute

While Not objRecordSet.EOF
  WScript.Echo &quot;Trusted Domain: &quot; &amp; objRecordSet.Fields(&quot;name&quot;).Value
  WScript.Echo &quot;Trust Type: &quot; &amp; _
    objTrustTypes(objRecordSet.Fields(&quot;trustType&quot;).Value)

  Dim dblFlag
  Dim strFlags : strFlags = &quot;&quot;
  For Each dblFlag in objTrustAttributes
    If objRecordSet.Fields(&quot;trustAttributes&quot;).Value And dblFlag Then
      strFlags = strFlags &amp; objTrustAttributes(dblFlag) &amp; &quot; &quot;
    End If
  Next
  WScript.Echo &quot;Trust Attributes: &quot; &amp; strFlags

  WScript.Echo &quot;Trust Direction: &quot; &amp; _
    objTrustDirection(objRecordSet.Fields(&quot;trustDirection&quot;).Value)
  WScript.Echo &quot;Trust Partner: &quot; &amp; objRecordSet.Fields(&quot;trustPartner&quot;).Value
  WScript.Echo &quot;Distinguished Name: &quot; &amp; _
    objRecordSet.Fields(&quot;distinguishedName&quot;).Value
  WScript.Echo &quot;Created: &quot; &amp; objRecordSet.Fields(&quot;whenCreated&quot;).Value

  objRecordSet.MoveNext
Wend

objConnection.Close
</pre>
<h3>Usage example</h3>
<p>In the past I have used the script above to monitor trust settings across a forest. The following script uses the trust information to build a text file storing trust configuration sends an e-mail if that configuration changes.</p>
<pre class="brush: vb; title: ; notranslate">
Option Explicit

' Script to get trusts, compare with stored configuration and notify if changed

Sub ShowUsage
  Dim strUsage
  strUsage = &quot;Usage:&quot; &amp; vbCrLf &amp; vbCrLf &amp; _
    WScript.ScriptName &amp; _
    &quot; /Command:[Update | Notify] [/MailServer:&lt;serverName&gt;] &quot; &amp; _
    &quot;[/Recipient:&lt;address&gt;]&quot; &amp; vbCrLf &amp; vbCrLf &amp; _
    &quot;Arguments:&quot; &amp; vbCrLf &amp; vbCrLf &amp; _
    &quot;    Command      Update - Updates the contents of the text &quot; &amp; _
    &quot;file with data from the global catalog&quot; &amp; vbCrLf &amp; _
    &quot;                 Notify - Notifies the recipient using mailserver &quot; &amp; _
    &quot;if the trust data changes&quot; &amp; vbCrLf &amp; _
    &quot;    MailServer   Server used to send mail. Default: localhost&quot; &amp; vbCrLf &amp; _
    &quot;    Recipient    Email address of person or group to notify&quot; &amp; vbCrLf

  WScript.Echo strUsage
  WScript.Quit
End Sub

Function GetTrusts
  ' Returns a Scripting.Dictionary object containing details of the Trust
  ' Format:
  ' Key: DistinguishedName
  ' Data: Array(
  '           Trusted Domain,
  '           Type,
  '           Attributes,
  '           Direction,
  '           Partner,
  '           Created,
  '           Changed )

  Const ADS_SCOPE_SUBTREE = 2

  ' Trust Type
  ' http://msdn.microsoft.com/en-us/library/cc223771(PROT.10).aspx
  Dim objTrustTypes
  Set objTrustTypes = CreateObject(&quot;Scripting.Dictionary&quot;)
  objTrustTypes.Add 4, &quot;DCE&quot;
  objTrustTypes.Add 3, &quot;MIT&quot;
  objTrustTypes.Add 2, &quot;UpLevel&quot;
  objTrustTypes.Add 1, &quot;DownLevel&quot;

  ' Trust Attributes
  ' http://msdn.microsoft.com/en-us/library/cc223779(PROT.10).aspx
  Dim objTrustAttributes
  Set objTrustAttributes = CreateObject(&quot;Scripting.Dictionary&quot;)
  objTrustAttributes.Add 128, &quot;UsesRC4Encryption&quot;
  objTrustAttributes.Add 64, &quot;TreatAsExternal&quot;
  objTrustAttributes.Add 32, &quot;WithinForest&quot;
  objTrustAttributes.Add 16, &quot;CrossOrganisation&quot;
  objTrustAttributes.Add 8, &quot;ForestTransitive&quot;
  objTrustAttributes.Add 4, &quot;QuarantinedDomain&quot;
  objTrustAttributes.Add 2, &quot;UpLevelOnly&quot;
  objTrustAttributes.Add 1, &quot;NonTransitive&quot;

  ' Trust Direction
  ' http://msdn.microsoft.com/en-us/library/cc223768(PROT.10).aspx
  Dim objTrustDirection
  Set objTrustDirection = CreateObject(&quot;Scripting.Dictionary&quot;)
  objTrustDirection.Add 3, &quot;BiDirectional&quot;
  objTrustDirection.Add 2, &quot;Outbound&quot;
  objTrustDirection.Add 1, &quot;Inbound&quot;
  objTrustDirection.Add 0, &quot;Disabled&quot;

  Dim objConnection : Set objConnection = CreateObject(&quot;ADODB.Connection&quot;)
  objConnection.Provider = &quot;ADsDSOObject&quot;
  objConnection.Open &quot;Active Directory Provider&quot;

  Dim objCommand : Set objCommand = CreateObject(&quot;ADODB.Command&quot;)
  objCommand.ActiveConnection = objConnection

  Dim objRootDSE : Set objRootDSE = GetObject(&quot;LDAP://RootDSE&quot;)
  objCommand.CommandText = &quot;SELECT distinguishedName, name, &quot; &amp; _
    &quot;trustType, trustAttributes, trustDirection, trustPartner, &quot; &amp; _
    &quot;whenCreated, whenChanged &quot; &amp; _
    &quot;FROM 'GC://&quot; &amp; objRootDSE.Get(&quot;rootDomainNamingContext&quot;) &amp; _
    &quot;' WHERE objectClass='trustedDomain'&quot;

  objCommand.Properties(&quot;Page Size&quot;) = 1000
  objCommand.Properties(&quot;Timeout&quot;) = 600
  objCommand.Properties(&quot;Searchscope&quot;) = ADS_SCOPE_SUBTREE
  objCommand.Properties(&quot;Cache Results&quot;) = False

  Dim objRecordSet : Set objRecordSet = objCommand.Execute

  Dim objTrusts : Set objTrusts = CreateObject(&quot;Scripting.Dictionary&quot;)

  While Not objRecordSet.EOF
    Dim dblFlag
    Dim strAttributes : strAttributes = &quot;&quot;
    For Each dblFlag in objTrustAttributes
      If objRecordSet.Fields(&quot;trustAttributes&quot;).Value And dblFlag Then
        strAttributes = strAttributes &amp; objTrustAttributes(dblFlag) &amp; &quot; &quot;
      End If
    Next

    objTrusts.Add objRecordSet.Fields(&quot;distinguishedName&quot;).Valuem, Array( _
      objRecordSet.Fields(&quot;name&quot;).Value, _
      objTrustTypes(objRecordSet.Fields(&quot;trustType&quot;).Value), _
      strAttributes, _
      objTrustDirection(objRecordSet.Fields(&quot;trustDirection&quot;).Value), _
      objRecordSet.Fields(&quot;trustPartner&quot;).Value, _
      objRecordSet.Fields(&quot;whenCreated&quot;).Value, _
      objRecordSet.Fields(&quot;whenChanged&quot;).Value)

    objRecordSet.MoveNext
  Wend

  objConnection.Close

  Set objRecordSet = Nothing
  Set objCommand = Nothing
  Set objConnection = Nothing

  Set GetTrusts = objTrusts
End Function

Sub SendMail(strRecipient, strBody, strMailServer)

  Set objMail = CreateObject(&quot;CDO.Message&quot;)
  objMail.Subject = &quot;Trust monitor&quot;

  objMail.From = strRecipient
  objMail.To = strRecipient

  objMail.TextBody = strBody

  objMail.Configuration.Fields.Item _
    (&quot;http://schemas.microsoft.com/cdo/configuration/sendusing&quot;) = 2
  objMail.Configuration.Fields.Item _
    (&quot;http://schemas.microsoft.com/cdo/configuration/smtpserver&quot;) = _
    strMailServer
  objMail.Configuration.Fields.Item _
    (&quot;http://schemas.microsoft.com/cdo/configuration/smtpserverport&quot;) = 25

  objMail.Configuration.Fields.Update
  objMail.Send
End Sub

'
' Main Code
'

Dim objFileSystem
Set objFileSystem = CreateObject(&quot;Scripting.FileSystemObject&quot;)
Dim objFile

Dim objTrusts : Set objTrusts = GetTrusts

If LCase(WScript.Arguments.Named(&quot;command&quot;)) = &quot;update&quot; Then
  Set objFile = objFileSystem.OpenTextFile(&quot;Trusts.txt&quot;, 2, True, 0)

  Dim strDN
  For Each strDN in objTrusts
    objFile.WriteLine strDN &amp; vbTab &amp; Join(objTrusts(strDN), vbTab)
  Next

ElseIf LCase(WScript.Arguments.Named(&quot;command&quot;)) = &quot;notify&quot; Then

  strRecipient = WScript.Arguments.Named(&quot;recipient&quot;)

  If strRecipient = &quot;&quot; Then
    WScript.Echo &quot;ERROR: No recipient defined&quot;
    ShowUsage
  End If

  strMailServer = WScript.Arguments.Named(&quot;mailserver&quot;)

  If strMailServer = &quot;&quot; Then
    strMailServer = &quot;localhost&quot;
  End If

  If objFileSystem.FileExists(&quot;Trusts.txt&quot;) Then
    Set objFile = objFileSystem.OpenTextFile(&quot;Trusts.txt&quot;, 1, False, 0)

    Dim objTrustsInFile
    Set objTrustsInFile = CreateObject(&quot;Scripting.Dictionary&quot;)

    Dim arrTrustData()
    Do While Not objFile.AtEndOfStream
      Dim arrTrustInFile : arrTrustInFile = Split(objFile.ReadLine, vbTab)

      ReDim arrTrustData(0)
      Dim i
      For i = 1 to UBound(arrTrustInFile)
        ReDim Preserve arrTrustData(i - 1)
        arrTrustData(i - 1) = arrTrustInFile(i)
      Next

      objTrustsInFile.Add arrTrustInFile(0), arrTrustData
    Loop
  End If

  Dim strTrust

  ' Comparison - Check for new Trusts

  Dim objNewTrusts : Set objNewTrusts = CreateObject(&quot;Scripting.Dictionary&quot;)

  For Each strTrust in objTrusts
    If Not objTrustsInFile.Exists(strTrust) Then
      objNewTrusts.Add strTrust, objTrusts(strTrust)
    End If
  Next

  ' Comparison - Check for removed Trusts

  Dim objRemovedTrusts
  Set objRemovedTrusts = CreateObject(&quot;Scripting.Dictionary&quot;)

  For Each strTrust in objTrustsInFile
    If Not objTrusts.Exists(strTrust) Then
      objRemovedTrusts.Add strTrust, objTrustsInFile(strTrust)
    End If
  Next

  ' Data: Array(
  '           Trusted Domain,
  '           Type,
  '           Attributes,
  '           Direction,
  '           Partner,
  '           Created,
  '           Changed )

  Dim strMessageBody
  Dim booNotify : booNotify = False
  If objNewTrusts.Count &gt; 0 Then
    booNotify = True
    strMessageBody = &quot;New Trusts:&quot; &amp; vbCrLf &amp; vbCrLf
    For Each strTrust in objNewTrusts
      strMessageBody = strMessageBody &amp; &quot;DN: &quot; &amp; strTrust &amp; vbCrLf &amp; _
        &quot;Trusted Domain: &quot; &amp; objNewTrusts(strTrust)(0) &amp; vbCrLf &amp; _
        &quot;Type: &quot; &amp; objNewTrusts(strTrust)(1) &amp; vbCrLf &amp; _
        &quot;Attributes: &quot; &amp; objNewTrusts(strTrust)(2) &amp; vbCrLf &amp; _
        &quot;Direction: &quot; &amp; objNewTrusts(strTrust)(3) &amp; vbCrLf &amp; _
        &quot;Partner: &quot; &amp; objNewTrusts(strTrust)(4) &amp; vbCrLf &amp; _
        &quot;Created: &quot; &amp; objNewTrusts(strTrust)(5) &amp; vbCrLf &amp; _
        &quot;Changed: &quot; &amp; objNewTrusts(strTrust)(6) &amp; vbCrLf &amp; vbCrLf
    Next
  End If
  If objRemovedTrusts.Count &gt; 0 Then
    booNotify = True
    For Each strTrust in objRemovedTrusts
      strMessageBody = strMessageBody &amp; &quot;DN: &quot; &amp; strTrust &amp; vbCrLf &amp; _
        &quot;Trusted Domain: &quot; &amp; objRemovedTrusts(strTrust)(0) &amp; vbCrLf &amp; _
        &quot;Type: &quot; &amp; objRemovedTrusts(strTrust)(1) &amp; vbCrLf &amp; _
        &quot;Attributes: &quot; &amp; objRemovedTrusts(strTrust)(2) &amp; vbCrLf &amp; _
        &quot;Direction: &quot; &amp; objRemovedTrusts(strTrust)(3) &amp; vbCrLf &amp; _
        &quot;Partner: &quot; &amp; objRemovedTrusts(strTrust)(4) &amp; vbCrLf &amp; _
        &quot;Created: &quot; &amp; objRemovedTrusts(strTrust)(5) &amp; vbCrLf &amp; _
        &quot;Changed: &quot; &amp; objRemovedTrusts(strTrust)(6) &amp; vbCrLf &amp; vbCrLf
    Next
  End If
  If booNotify = True Then
    strMessageBody = strMessageBody &amp; _
      &quot;If these trusts are correct please run &quot; &amp; _
      WScript.ScriptName &amp; &quot; /Command:Update&quot;

    SendMail strRecipient, strMessageBody, strMailServer
  End If
Else

  ShowUsage

End If
</pre>
<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2009/08/27/listing-trusts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mapping the DNSRecord attribute</title>
		<link>http://www.indented.co.uk/index.php/2009/06/18/mapping-the-dnsrecord-attribute/</link>
		<comments>http://www.indented.co.uk/index.php/2009/06/18/mapping-the-dnsrecord-attribute/#comments</comments>
		<pubDate>Thu, 18 Jun 2009 10:44:16 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[Microsoft DNS]]></category>
		<category><![CDATA[dnsRecord]]></category>

		<guid isPermaLink="false">http://www.highorbit.co.uk/?p=1097</guid>
		<description><![CDATA[Microsoft DNS is able to store records in Active Directory when running on a Domain Controller. The information is stored in a Binary Large Object (BLOB) called DNSRecord. No official maps for that attribute appear to have been published. The information below is a result of reverse engineering the contents of the attribute. Michael Smith [...]
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Microsoft DNS is able to store records in Active Directory when running on a Domain Controller. The information is stored in a Binary Large Object (BLOB) called DNSRecord. No official maps for that attribute appear to have been published. The information below is a result of reverse engineering the contents of the attribute.</p>
<p>Michael Smith has a very pretty PowerShell script which uses the structures below, and a few more, to convert the DnsRecord attribute into a human readable format on his blog, <a href='http://theessentialexchange.com/blogs/michael/archive/2009/12/22/getting-the-contents-of-an-active-directory-integrated-dns-zone-version-2.aspx'>Michael&#8217;s meanderings&#8230;</a>.</p>
<p><i>Update 02/02/2010: In December 2009, Microsoft released a (not entirely accurate) protocol specification including details of dnsRecord and dnsProperty: <a href='http://download.microsoft.com/download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-DNSP%5D.pdf'>MS-DNSP.pdf</a></i><br />
<span id="more-1097"></span></p>
<h3>About the mapped structure</h3>
<p>The map created below for DNSRecord is incomplete, the remaining values seem to defy testing. While the map below is probably accurate I reserve the right to be wrong. Despite that, the structures can be used to manually construct or decode DNSRecords via LDAP rather than using the GUI, dnscmd or WMI. <i>Edit: The map is now complete</i>.</p>
<h3>About DNSRecord</h3>
<p>The dnsRecord attribute appears on dnsNode objects. The dnsRecord attribute is multi-valued. This means that each node can contain more than one record. This is most obvious for the node representing &#8220;same as parent folder&#8221; which will hold the NS records and SOA records as a minimum.</p>
<h3>Structures: DNSRecord</h3>
<p>The DNSRecord attribute is composed of the fields described in the table below.</p>
<table>
<tr>
<th class="tableleft">Field Name</th>
<th class="tableleft">Length (Bytes)</th>
<th class="tableleft">Format</th>
<th class="tableright">Description</th>
</tr>
<tr>
<td class="tableleft">RData Length</td>
<td class="tableleft">2</td>
<td class="tableleft">Little Endian</td>
<td class="tableright">Length of the Record Data block</td>
</tr>
<tr>
<td class="tableleft">Type</td>
<td class="tableleft">2</td>
<td class="tableleft">Little Endian</td>
<td class="tableright">Record type. Matches published type values on <a href="http://www.iana.org/assignments/dns-parameters">IANA</a></td>
</tr>
<tr>
<td class="tableleft">Unknown (1)</td>
<td class="tableleft">4</td>
<td class="tableleft">N/A</td>
<td class="tableright">Predictable, but unknown.</td>
</tr>
<tr>
<td class="tableleft">UpdatedAtSerial</td>
<td class="tableleft">4</td>
<td class="tableleft">Little Endian</td>
<td class="tableright">Changes to match the serial number in the SOA whenever the record is modified</td>
</tr>
<tr>
<td class="tableleft">TTL</td>
<td class="tableleft">4</td>
<td class="tableleft">Big Endian</td>
<td class="tableright">Time To Live value for the record</td>
</tr>
<tr>
<td class="tableleft">Unknown (2)</td>
<td class="tableleft">4</td>
<td class="tableleft">N/A</td>
<td class="tableright">Always 0</td>
</tr>
<tr>
<td class="tableleft">TimeStamp</td>
<td class="tableleft">4</td>
<td class="tableleft">Little Endian</td>
<td class="tableright">TimeStamp in hours from 01/01/1601 00:00:00</td>
</tr>
<tr>
<td class="tableleft">RData</td>
<td class="tableleft">Variable</td>
<td class="tableleft">Variable</td>
<td class="tableright">The record data, formatting described below</td>
</tr>
</table>
<p>These values produce the following binary array.</p>
<pre class="brush: plain; title: ; notranslate">
                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                 RDATA LENGTH                  |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TYPE                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                  UNKNOWN (1)                  |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                 UPDATEDATSERIAL               |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TTL                      |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                  UNKNOWN (2)                  |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                   TIMESTAMP                   |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
    /                     RDATA                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</pre>
<p>Unknown 1 is a difficult value to interpret. It may contain several separate fields, however as none appear easy to decipher they were left as a single block in the map. Testing shows that &#8220;unknown 1&#8243; has the following values:</p>
<pre class="brush: plain; title: ; notranslate">
                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |           5           |     AdvRecordType     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |           0           |           0           |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</pre>
<p><i>Edit: The structure of Unknown 1 is as follows.</i></p>
<pre class="brush: plain; title: ; notranslate">
                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |        VERSION        |     AdvRecordType     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     FLAGS                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</pre>
<p>Modifying the first byte to any (decimal) value other than 5 will cause the record to vanish from the DNS system. It will remain in the directory, but appears to render it useless. <i>Edit: 5 is the Version number and is a static value.</i></p>
<p>The second byte, termed AdvRecordType, appears to have a number of possible values. Experimentation shows that Root Hints have the value set to decimal 8, out-of-zone records (normally Glue for NS Records) have 128, delegations within a zone have 130 and everything else has 240. A larger data set than I have available is required to draw conclusions other than those.</p>
<p><i>Edit: The values for AdvRecordType, referred to as Rank in the documentation above are represented by this Enumeration.</i></p>
<pre class="brush: csharp; title: ; notranslate">
public enum RankFlag : uint
{
  // The record came from the cache.
  CacheBit = 1,
  // The record is a preconfigured root hint.
  RootHint = 8,
  // This value is not used.
  OutsideGlue = 32,
  // The record was cached from the additional section of a
  // nonauthoritative response.
  CacheNAAdditional = 49,
  // The record was cached from the authority section of a
  // nonauthoritative response.
  CacheNAAuthority = 65,
  // The record was cached from the additional section of an
  // authoritative response.
  CacheAAdditional = 81,
  // The record was cached from the answer section of a
  // nonauthoritative response.
  CacheNAAnswer = 97,
  // The record was cached from the authority section of an
  // authoritative response.
  CacheAAuthority = 113,
  // The record is a glue record in an authoritative zone.
  Glue = 128,
  // The record is a delegation (type NS) record in an
  // authoritative zone.
  NSGlue = 130,
  // The record was cached from the answer section of an
  // authoritative response.
  CacheAAnswer = 193,
  // The record comes from an authoritative zone.
  Zone = 240
 }
</pre>
<p>The final two bytes appear to be set to 0 in all instances. <i>Edit: Referred to as Flags, the value must be 0.</i></p>
<p><i>Edit: Unknown 2 is reserved for future use and should be set to 0 in all cases.</i></p>
<h3>Structures: RDATA</h3>
<p>Each of the structures below is a minimal representation of the record data, the structures show single-label names. In each case the &#8220;Label Length&#8221; and &#8220;Data&#8221; structures repeat where multiple labels are used, this also applies to &#8220;Responsible Person&#8221; in the SOA record.</p>
<h4>A</h4>
<p>The RDATA block for the A record is a static 4 byte (32 bit) field. Each byte represents an octet in the IP address.</p>
<pre class="brush: plain; title: ; notranslate">
                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     DATA                      |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</pre>
<h4>CNAME and NS</h4>
<pre class="brush: plain; title: ; notranslate">
                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |         LENGTH        |   NUMBER OF LABELS    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |      LABEL LENGTH     |                       |
    |--+--+--+--+--+--+--+--+                       |
    /                     DATA                      /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</pre>
<h4>MX</h4>
<pre class="brush: plain; title: ; notranslate">
                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    PRIORITY                   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |         LENGTH        |   NUMBER OF LABELS    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |      LABEL LENGTH     |                       |
    |--+--+--+--+--+--+--+--+                       |
    /                     DATA                      /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</pre>
<h4>SOA</h4>
<pre class="brush: plain; title: ; notranslate">
                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     SERIAL                    |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    REFRESH                    |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     RETRY                     |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    EXPIRE                     |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                  MINIMUM TTL                  |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |         LENGTH        |   NUMBER OF LABELS    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |      LABEL LENGTH     |                       |
    +--+--+--+--+--+--+--+--+                       |
    /                     DATA                      /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |         LENGTH        |   NUMBER OF LABELS    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |      LABEL LENGTH     |                       |
    |--+--+--+--+--+--+--+--+                       |
    /               RESPONSIBLE PERSON              /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</pre>
<h4>SRV</h4>
<pre class="brush: plain; title: ; notranslate">
                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    PRIORITY                   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     WEIGHT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      PORT                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |         LENGTH        |   NUMBER OF LABELS    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |      LABEL LENGTH     |                       |
    |--+--+--+--+--+--+--+--+                       |
    /                     DATA                      /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</pre>
<h4>TXT</h4>
<pre class="brush: plain; title: ; notranslate">
                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |      LENGTH           |                       |
    |--+--+--+--+--+--+--+--+                       |
    /                     DATA                      /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</pre>
<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2009/06/18/mapping-the-dnsrecord-attribute/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Get-MailboxStatistics for Exchange 2003</title>
		<link>http://www.indented.co.uk/index.php/2009/01/22/exchange-2003-get-mailboxstatistics/</link>
		<comments>http://www.indented.co.uk/index.php/2009/01/22/exchange-2003-get-mailboxstatistics/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 17:35:54 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[Exchange]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[DirectorySearcher]]></category>
		<category><![CDATA[wmi]]></category>

		<guid isPermaLink="false">http://www.highorbit.co.uk/?p=871</guid>
		<description><![CDATA[Using PowerShell to create a version of Get-MailboxStatistics for Exchange 2003. Get-MailboxStatistics returns a set of information about a mailbox for Exchange 2007. It is possible to retrieve roughly the same information using WMI for Exchange 2003. The differences The following table notes the differences in property names between Exchange 2003 and Exchange 2007. Exchange [...]
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Using PowerShell to create a version of Get-MailboxStatistics for Exchange 2003.<br />
<span id="more-871"></span><br />
Get-MailboxStatistics returns a set of information about a mailbox for Exchange 2007. It is possible to retrieve roughly the same information using WMI for Exchange 2003.</p>
<h3>The differences</h3>
<p>The following table notes the differences in property names between Exchange 2003 and Exchange 2007.</p>
<table>
<tr>
<th>Exchange 2007</th>
<th>Exchange 2003</th>
</tr>
<tr>
<td>AssociatedItemCount</td>
<td>AssocContentCount</td>
</tr>
<tr>
<td>DeletedItemCount</td>
<td><i>Not available</i></td>
</tr>
<tr>
<td>DisconnectDate</td>
<td>DateDiscoveredAbsentInDS</td>
</tr>
<tr>
<td>DisplayName</td>
<td>MailboxDisplayName</td>
</tr>
<tr>
<td>ItemCount</td>
<td>TotalItems</td>
</tr>
<tr>
<td>ObjectClass</td>
<td>Can be assumed to be Mailbox</td>
</tr>
<tr>
<td>StorageLimitStatus</td>
<td>StorageLimitInfo</td>
</tr>
<tr>
<td>TotalDeletedItemSize</td>
<td>DeletedMessageSizeExtended</td>
</tr>
<tr>
<td>TotalItemSize</td>
<td>Size</td>
</tr>
<tr>
<td>Database</td>
<td>Composed of Server, Storage Group and Store</td>
</tr>
<tr>
<td>DatabaseName</td>
<td>StoreName</td>
</tr>
<tr>
<td>Identity</td>
<td>MailboxGuid (repeat of above included for pipeline)</td>
</tr>
<tr>
<td>IsValid</td>
<td><i>Not available</i></td>
</tr>
<tr>
<td>OriginatingServer</td>
<td>Same as ServerName</td>
</tr>
</table>
<p>In addition to these the MailboxGuid attribute is formatted slightly differently. The MailboxGuid is enclosed in curly braces, {}, these are stripped in the code (or added when a search is being performed using a GUID)</p>
<p>No formatting is applied to the output. The output from this function can be made to look like the Exchange 2007 version of Get-MailboxStatistics by using Format-Table.</p>
<pre class="brush: powershell; title: ; notranslate">
Get-2003MailboxStatistics | Format-Table MailboxDisplayName, TotalItems, `
  StorageLimitStatus, LastLogonTime
</pre>
<p>This is the code for the function, it is not as flexible as the Exchange 2007 version with regard to pipelines, but it should accept simple input and work in much the same way otherwise.</p>
<h3>Usage examples</h3>
<pre class="brush: powershell; title: ; notranslate">
# With a Mailbox Display Name
Get-2003MailboxStatistics &quot;Chris Dent&quot;
# With a Legacy Exchange DN (&quot;-Identity&quot; itself is optional)
Get-2003MailboxStatistics -Identity &quot;/O=SomeOrg/OU=AdminGroup/CN=RECIPIENTS/CN=Someone&quot;
# For a single Mailbox Database
Get-2003MailboxStatistics -Database &quot;Mailbox Database&quot;
# For a different server
Get-2003MailboxStatistics -Server &quot;ExchangeServer02&quot;
</pre>
<h3>Get-MailboxStatistics for Exchange 2003</h3>
<pre class="brush: powershell; title: ; notranslate">
Function Get-2003MailboxStatistics {
  Param(
     [String]$Identity = &quot;&quot;,
     [String]$Server = $Env:ComputerName,
     [String]$Database = &quot;&quot;
  )

  $Filter = &quot;ServerName='$Server'&quot;
  if ($Database -ne &quot;&quot; ) {
    $Filter = &quot;$Filter AND StoreName='$Database'&quot;
  }
  if ($Identity -ne &quot;&quot;) {
    $Filter = &quot;$Filter AND (MailboxGuid='{$Identity}' OR LegacyDN='$Identity'&quot;
    $Filter = &quot;$Filter OR MailboxDisplayName='$Identity')&quot;
  }

  Get-WMIObject -ComputerName $Server `
    -Namespace &quot;root/MicrosoftExchangeV2&quot; -Class &quot;Exchange_Mailbox&quot; `
    -Filter $Filter | `
  Select-Object `
    AssocContentCount, `
    @{n='DateDiscoveredAbsentInDs';e={
      If ($_.DateDiscoveredAbsentInDs -ne $Null) {
        [Management.ManagementDateTimeConverter]::ToDateTime(`
          $_.DateDiscoveredAbsentInDs)
      }} }, `
    MailboxDisplayName, TotalItems, LastLoggedOnUserAccount, `
    @{n='LastLogonTime';e={ if ($_.LastLogonTime -ne $Null) { `
      [Management.ManagementDateTimeConverter]::ToDateTime($_.LastLogonTime)}}
    }, `
    @{n='LastLogoffTime';e={ if ($_.LastLogoffTime -ne $Null) { `
      [Management.ManagementDateTimeConverter]::ToDateTime($_.LastLogoffTime)}}
    }, `
    LegacyDN, `
    @{n='MailboxGuid';e={
      ([String]$_.MailboxGuid).ToLower() -Replace &quot;\{|\}&quot; }}, `
    @{n='ObjectClass';e={ &quot;Mailbox&quot; }}, `
    @{n='StorageLimitStatus';e={ `
      Switch ($_.StorageLimitInfo) {
        1 { &quot;BelowLimit&quot; }
        2 { &quot;IssueWarning&quot; }
        4 { &quot;ProhibitSend&quot; }
        8 { &quot;NoChecking&quot; }
        16 { &quot;MailboxDisabled&quot; } }} }, `
    DeletedMessageSize, Size, `
    @{n='Database';e={
      &quot;$($_.ServerName)\$($_.StorageGroupName)\$($_.StoreName)&quot; }}, `
    ServerName, StorageGroupName, StoreName, `
    @{n='Identity';e={ ([String]$_.MailboxGuid).ToLower() -Replace &quot;\{|\}&quot; }}
}
</pre>
<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2009/01/22/exchange-2003-get-mailboxstatistics/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Setting desktop wallpaper</title>
		<link>http://www.indented.co.uk/index.php/2008/12/23/setting-desktop-wallpaper/</link>
		<comments>http://www.indented.co.uk/index.php/2008/12/23/setting-desktop-wallpaper/#comments</comments>
		<pubDate>Tue, 23 Dec 2008 13:27:50 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[VbScript]]></category>
		<category><![CDATA[group policy]]></category>
		<category><![CDATA[vbs]]></category>

		<guid isPermaLink="false">http://www.highorbit.co.uk/?p=671</guid>
		<description><![CDATA[Group Policy will, by default, only set the desktop wallpaper using Active Desktop. It is also possible to set the wallpaper using the logon script, or using a custom Group Policy template. Custom Group Policy Template The first thing to note about the custom policy is that it is an Unmanaged Policy. That means that [...]
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Group Policy will, by default, only set the desktop wallpaper using Active Desktop. It is also possible to set the wallpaper using the logon script, or using a custom Group Policy template.<br />
<span id="more-671"></span></p>
<h3>Custom Group Policy Template</h3>
<p>The first thing to note about the custom policy is that it is an Unmanaged Policy. That means that any setting change will not revert if the policy is set to Disabled or Not Configured. The setting would have to be manually reversed or removed.</p>
<p>The second thing to note is that Unmanaged Policies are not displayed by default. After adding this template select the Administrative Templates folder under User Configuration, then View and Filtering. Remove the tick from &#8220;Show only policy settings that can be fully managed&#8221;. The policy will appear with a red icon instead of the regular blue icon.</p>
<p>This is a template that can be used to set the wallpaper on a client. It must be saved as a Administrative Template (.adm) file and manually added into a policy.</p>
<pre class="brush: plain; title: ; notranslate">
CLASS USER

CATEGORY &quot;Desktop&quot;
  CATEGORY &quot;Custom Policies&quot;

    KEYNAME &quot;Control Panel\Desktop&quot;

    POLICY &quot;Desktop Wallpaper&quot;

      EXPLAIN !!ExplainText

      PART !!WallpaperPathText EDITTEXT REQUIRED
        VALUENAME &quot;Wallpaper&quot;
      END PART

      PART !!WallpaperStyleText DROPDOWNLIST
        VALUENAME &quot;WallpaperStyle&quot;

        ITEMLIST
          NAME &quot;Centre&quot; VALUE NUMERIC 0 DEFAULT
          NAME &quot;Stretch&quot; VALUE NUMERIC 2
        END ITEMLIST
      END PART

      PART !!TileWallpaperText DROPDOWNLIST
        VALUENAME &quot;TileWallpaper&quot;

        ITEMLIST
          NAME &quot;No&quot; VALUE NUMERIC 0 DEFAULT
          NAME &quot;Yes&quot; VALUE NUMERIC 1
        END ITEMLIST
      END PART

    END POLICY

  END CATEGORY
END CATEGORY

[Strings]
ExplainText=&quot;Specifies the desktop background (wallpaper) displayed on all users' desktops.\n\nThe wallpaper image must be in bitmap (bmp) format.\n\nTo use this setting, type the fully qualified path and name of the file that stores the wallpaper image. You can type a local path, such as C:\Windows\web\wallpaper\home.bmp or a UNC path, such as \\Server\Share\Corp.bmp. If the specified file is not available when the user logs on, no wallpaper is displayed. You can also use this setting to specify that the wallpaper image be centered, tiled, or stretched.\n\nTo set wallpaper to Centre Tile must be disabled. To set wallpaper to Tiled both Centre and Tiled must be selected.&quot;
WallpaperPathText=&quot;Full UNC or path to Bitmap (bmp) file:&quot;
WallpaperStyleText=&quot;Centre or Stretch Wallpaper:&quot;
TileWallpaperText=&quot;Tile Wallpaper (if centre is selected):&quot;
</pre>
<h3>VbScript</h3>
<p>Alternatively, the same registry entries can be set using VbScript. This has the potential to be more flexible depending on the environment. It will run under a standard user, no need to grant extra rights on the PC.</p>
<pre class="brush: vb; title: ; notranslate">
Option Explicit

' Network and local locations for the wallpaper file.
' Must be BMP for the screen refresh to work
Const WALLPAPER_SOURCE = &quot;\\server01\netlogon\Wallpaper.bmp&quot;

Sub SetWallpaper
  ' Copies and sets the client wallpaper

  Const REG_HKCU = &amp;H80000001

  Dim objShell, objFileSystem, objFile, objRegistry
  Dim strWallpaperDestination, strKeyPath, strCommand

  ' Get the current user profile so we can copy the wallpaper there.
  Set objShell = CreateObject(&quot;WScript.Shell&quot;)
  strWallpaperDestination = objShell.ExpandEnvironmentStrings(&quot;%USERPROFILE%&quot;)

  ' Get the wallpaper file from the source
  Set objFileSystem = CreateObject(&quot;Scripting.FileSystemObject&quot;)
  Set objFile = objFileSystem.GetFile(WALLPAPER_SOURCE)

  ' Update the destination path to include the file name
  strWallpaperDestination = strWallpaperDestination &amp; &quot;\&quot; &amp; objFile.Name
  objFile.Copy strWallpaperDestination, True
  Set objFileSystem = Nothing

  ' Connect to the Registry on the local machine
  Set objRegistry = GetObject(&quot;winmgmts:\\.\root\default:StdRegProv&quot;)

  ' Set the values for the Wallpaper
  strKeyPath = &quot;Control Panel\Desktop&quot;
  objRegistry.SetStringValue REG_HKCU, strKeyPath, &quot;Wallpaper&quot;, _
    strWallpaperDestination

  ' Set the Position to Stretch
  objRegistry.SetStringValue REG_HKCU, strKeyPath, &quot;TileWallpaper&quot;, &quot;0&quot;
  objRegistry.SetStringValue REG_HKCU, strKeyPath, &quot;WallpaperStyle&quot;, &quot;2&quot;
  Set objRegistry = Nothing

  ' Update the system settings (refresh)
  strCommand = &quot;RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters&quot;
  objShell.Run strCommand, 1, True
  Set objShell = Nothing
End Sub

SetWallpaper
</pre>
<h3>Random wallpaper with VbScript</h3>
<p>I once had to deploy one of a selection of wallpapers to client computers on a network. It had to change (or at least attempt to change) each time the user logged on. This snippet uses the Randomize function in VbScript to generate a random number and pick a random file.</p>
<pre class="brush: vb; title: ; notranslate">
Option Explicit

Sub SetWallpaper
  ' Copies and sets the client wallpaper

  Const REG_HKCU = &amp;H80000001

  Dim objShell, objFileSystem, objFile, objRegistry
  Dim strWallpaperSource, strWallpaperDestination, strKeyPath, strCommand

  ' Get the current user profile so we can copy the wallpaper there.
  Set objShell = CreateObject(&quot;WScript.Shell&quot;)
  strWallpaperDestination = objShell.ExpandEnvironmentStrings(&quot;%USERPROFILE%&quot;)

  ' Get the source path
  strWallpaperSource = RandomizeWallpaper

  ' Get the wallpaper file from the source
  Set objFileSystem = CreateObject(&quot;Scripting.FileSystemObject&quot;)
  Set objFile = objFileSystem.GetFile(strWallpaperSource)

  ' Update the destination path to include the file name
  strWallpaperDestination = strWallpaperDestination &amp; &quot;\&quot; &amp; objFile.Name
  objFile.Copy strWallpaperDestination, True
  Set objFileSystem = Nothing

  ' Connect to the Registry on the local machine
  Set objRegistry = GetObject(&quot;winmgmts:\\.\root\default:StdRegProv&quot;)

  ' Set the values for the Wallpaper
  strKeyPath = &quot;Control Panel\Desktop&quot;
  objRegistry.SetStringValue REG_HKCU, strKeyPath, &quot;Wallpaper&quot;, strWallpaperDestination

  ' Set the Position to Stretch
  objRegistry.SetStringValue REG_HKCU, strKeyPath, &quot;TileWallpaper&quot;, &quot;0&quot;
  objRegistry.SetStringValue REG_HKCU, strKeyPath, &quot;WallpaperStyle&quot;, &quot;2&quot;
  Set objRegistry = Nothing

  ' Update the system settings (refresh)
  strCommand = &quot;RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters&quot;
  objShell.Run strCommand, 1, True
  Set objShell = Nothing
End Sub

Function RandomizeWallpaper
  Dim objShell, objFolder, objSubFolder, objFile
  Dim  strLogonServer
  Dim arrWallpaper()
  Dim i

  ' Get the current user profile so we can copy the wallpaper there.
  Set objShell = CreateObject(&quot;WScript.Shell&quot;)
  strLogonServer = objShell.ExpandEnvironmentStrings(&quot;%LOGONSERVER%&quot;)
  Set objShell = Nothing

  Set objFolder = objFileSystem.GetFolder(strLogonServer &amp; &quot;\NetLogon\Wallpaper&quot;)
  i = 0

  ' Get all the files beneath the folder
  For Each objFile in objFolder.Files
    ReDim Preserve arrWallpaper(i)
    arrWallpaper(i) = objFile.Path
    i = i + 1
  Next
  Randomize()

  ' Choose a random file
  i = Int(UBound(arrWallpaper) * Rnd())
  RandomizeWallpaper = arrWallpaper(i)
End Function

SetWallpaper
</pre>
<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2008/12/23/setting-desktop-wallpaper/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Returning the OU for an object in AD</title>
		<link>http://www.indented.co.uk/index.php/2008/12/08/returning-the-ou-for-an-object/</link>
		<comments>http://www.indented.co.uk/index.php/2008/12/08/returning-the-ou-for-an-object/#comments</comments>
		<pubDate>Mon, 08 Dec 2008 11:42:47 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[VbScript]]></category>
		<category><![CDATA[vbs]]></category>

		<guid isPermaLink="false">http://www.highorbit.co.uk/?p=641</guid>
		<description><![CDATA[Occasionally it can be useful to know how to retrieve the parent, or OU holding an object, from Active Directory. Perhaps the easiest way to do this is using the Parent property. VbScript: Getting the OU for a user In VbScript the value returned is a string, to get the name of the OU either [...]
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Occasionally it can be useful to know how to retrieve the parent, or OU holding an object, from Active Directory.<br />
Perhaps the easiest way to do this is using the Parent property.<br />
<span id="more-641"></span></p>
<h3>VbScript: Getting the OU for a user</h3>
<pre class="brush: vb; title: ; notranslate">
Set objUser = GetObject( _
  &quot;LDAP://CN=Chris Dent,OU=Somewhere,DC=internal,DC=highorbit,DC=co,DC=uk&quot;)
strParent = objUser.Parent

WScript.Echo strParent
</pre>
<p>In VbScript the value returned is a string, to get the name of the OU either connect to the object then get the name attribute or parse the name out of the string (Split, or Mid, etc). The example below shows connecting to the parent object and echoing the name.</p>
<pre class="brush: vb; title: ; notranslate">
Set objParent = GetObject(strParent)
WScript.Echo objParent.Get(&quot;name&quot;)
</pre>
<h3>PowerShell: Getting the OU for a user</h3>
<pre class="brush: powershell; title: ; notranslate">
$DN = &quot;CN=Chris Dent,OU=Somewhere,DC=internal,DC=highorbit,DC=co,DC=uk&quot;
$User = [ADSI]&quot;LDAP://$DN&quot;
$Parent = $User.PSBase.Parent
</pre>
<p>PowerShell is a little different, the returned value is a DirectoryEntry, that means we can directly access any other property or attribute without connecting again.</p>
<pre class="brush: powershell; title: ; notranslate">
$DN = &quot;CN=Chris Dent,OU=Somewhere,DC=internal,DC=highorbit,DC=co,DC=uk&quot;
$User = [ADSI]&quot;LDAP://$DN&quot;
$Name = ($User.PSBase.Parent).Name
</pre>
<h3>Example: Getting the OU for all members of a group</h3>
<p>These examples assume that the group path is known, no searches are involved.</p>
<h4>VbScript</h4>
<pre class="brush: vb; title: ; notranslate">
Set objGroup = GetObject( _
  &quot;LDAP://CN=Domain Admins,CN=Users,DC=internal,DC=highorbit,DC=co,DC=uk&quot;)

Set objFileSystem = CreateObject(&quot;Scripting.FileSystemObject&quot;)
Set objFile = objFileSystem.OpenTextFile( _
  objGroup.Get(&quot;name&quot;) &amp; &quot; - Members.txt&quot;, 2, True, 0)

For Each objMember in objGroup.Members
  objFile.WriteLine objMember.Get(&quot;sAMAccountName&quot;) &amp; VbTab &amp; _
    objMember.Get(&quot;cn&quot;) &amp; VbTab &amp; _
    objMember.Parent
Next

Set objFile = Nothing
Set objFileSystem = Nothing

Set objGroup = Nothing
</pre>
<h4>PowerShell</h4>
<p>The note above about Parent returning a DirectoryEntry does not apply if using the Members method in PowerShell. The object returned is a COM Object and will not work in quite the same way. This is the equivalent of the VbScript above.</p>
<pre class="brush: powershell; title: ; notranslate">
$DN = &quot;CN=Domain Admins,CN=Users,DC=internal,DC=highorbit,DC=co,DC=uk&quot;
$Group = [ADSI]&quot;LDAP://$DN&quot;
$Group.PSBase.Invoke(&quot;Members&quot;) `
  | Select-Object `
    @{n=&quot;sAMAccountName&quot;;e={
      $_.GetType().InvokeMember(&quot;sAMAccountName&quot;, &quot;GetProperty&quot;, `
        $Null, $_, $Null)}}, `
    @{n=&quot;CN&quot;;e={
      $_.GetType().InvokeMember(&quot;cn&quot;, &quot;GetProperty&quot;, `
        $Null, $_, $Null)}}, `
    @{n=&quot;Parent&quot;;e={
      $_.GetType().InvokeMember(&quot;parent&quot;, &quot;GetProperty&quot;, `
        $Null, $_, $Null)}}
</pre>
<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.indented.co.uk/index.php/2008/12/08/returning-the-ou-for-an-object/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

