Zoho Banner September 2011

Archive for the ‘Windows Server 2008’ Category

The other day I was in an environment where I had to find what Certification Authorities (CAs) were in place.  With nobody immediately available to help me out, I stumbled around for bit before I worked out how to find them.

Method 1

Query the membership of the Cert Publishers group.  Cert Publishers is a built-in AD group.  When you create a new CA on a member server or a DC, the computer will be added to the group membership.

cert-publishers.jpg

While it worked for me in terms of identifying the server names the CAs were hosted on, it did not provide me with the CA names themselves.   In any case, I’m not convinced this is wholly reliable method of finding servers that host CAs, because there is always the potential for someone with permissions to manually edit the Cert Publishers group membership.  Also, I’m not sure what happens if someone does an ugly decommissioning of a CA.  Does the membership get cleaned up?  Probably not.

Method 2.

Search Active Directory for objects with an objectClass of certificationAuthority.  These are stored in the Configuration partition under CN=Certification Authorities,CN=Public Key Services,CN=Services,CN=Configuration,<ForestRootDN>.  Here’s an example of how to find them using adfind.exe.

C:\>adfind -b “CN=Certification Authorities,CN=Public Key Services,CN=Services,C
N=Configuration,DC=widget,DC=com” -f (objectclass=certificationAuthority) 1.1

The problem with looking in AD is that it provides you with the name of the CA, but not the server that’s hosting it.  Ok, in my example the server name is part of the CA name, but this may not always be the case.   The server name is probably buried within the cACertificate attribute of the certificationAuthority object, which is unfortunately not human-readable.

Method 3.

Open a command prompt and type certutil – dump.  You will see output similar to that shown below.

 Entry 0: (Local)
  Name:                    `widget-ADLDS1-CA’
  Organizational Unit:     `’
  Organization:            `’
  Locality:                `’
  State:                   `’
  Country/region:          `’
  Config:                  `ADLDS1.widget.com\widget-ADLDS1-CA’
  Exchange Certificate:    `’
  Signature Certificate:   `ADLDS1.widget.com_widget-ADLDS1-CA.crt’
  Description:             `’
  Server:                  `ADLDS1.widget.com’
  Authority:               `widget-ADLDS1-CA’
  Sanitized Name:          `widget-ADLDS1-CA’
  Short Name:              `widget-ADLDS1-CA’
  Sanitized Short Name:    `widget-ADLDS1-CA’
  Flags:                   `13′

Entry 1:
  Name:                    `widget-RWDC1-CA’
  Organizational Unit:     `’
  Organization:            `’
  Locality:                `’
  State:                   `’
  Country/region:          `’
  Config:                  `RWDC1.widget.com\widget-RWDC1-CA’
  Exchange Certificate:    `’
  Signature Certificate:   `’
  Description:             `’
  Server:                  `RWDC1.widget.com’
  Authority:               `widget-RWDC1-CA’
  Sanitized Name:          `widget-RWDC1-CA’
  Short Name:              `widget-RWDC1-CA’
  Sanitized Short Name:    `widget-RWDC1-CA’
  Flags:                   `1′
CertUtil: -dump command completed successfully.

This shows me that I have two CAs and provides me with information about the CA names and what servers they are hosted on.  But what if I wanted to find out what type of CA they are (i.e. Enterprise or Stand Alone and whether it is a root or subordinate CA)?  The certutil.exe tool can help with that too.  Here’s an example using certutil with the -cainfo parameter.

C:\>certutil -cainfo -config RWDC1.widget.com\widget-RWDC1-CA type

CA type: 0 — Enterprise Root CA
    ENUM_ENTERPRISE_ROOTCA — 0
CertUtil: -CAInfo command completed successfully.

This tells me that my CA running on server RWDC1.widget.com is an Enteprise Root CA.

The syntax of the certutil.exe tool takes a bit of getting used to, but otherwise seems to do the job nicely!

Tony

I have recently spent some time working with Xpath queries as part of Event Log filtering in Windows Server 2008.  It’s a great feature, but one limitation I found was that it doesn’t appear possible to use the starts-with() function when querying Event Logs with either the UI or Wevtutil.exe.  Here’s an example.

Let’s say I enabled LDAP logging on a DC and want to filter the Directory Service event log to find all LDAP queries coming from a particular IP address.  The IP address is buried in one of the Data nodes of the Event XML, as shown in red below.

<Event xmlns=”http://schemas.microsoft.com/win/2004/08/events/event”>

  <System>

    <Provider Name=”Microsoft-Windows-ActiveDirectory_DomainService” Guid=”{0e8478c5-3605-4e8c-8497-1e730c959516}” EventSourceName=”NTDS General” />

    <EventID Qualifiers=”16384″>1644</EventID>

    <Version>0</Version>

    <Level>4</Level>

    <Task>15</Task>

    <Opcode>0</Opcode>

    <Keywords>0×8080000000000000</Keywords>

    <TimeCreated SystemTime=”2009-04-29T20:39:00.886Z” />

    <EventRecordID>339453</EventRecordID>

    <Correlation />

    <Execution ProcessID=”648″ ThreadID=”792″ />

    <Channel>Directory Service</Channel>

    <Computer>DC1.Myco.Com</Computer>

    <Security UserID=”S-1-5-21-854245398-152049171-725345543-4606″ />

  </System>

  <EventData>

    <Data>CN=MyCo Enterprise Issuing CA 1, CN=Public Key Services,CN=Services,CN=Configuration,DC=MyCo,DC=Com</Data>

    <Data> (objectClass=cRLDistributionPoint) </Data>

    <Data>1</Data>

    <Data>1</Data>

    <Data>192.168.40.10:4048</Data>

    <Data>base</Data>

    <Data>deltaRevocationList</Data>

    <Data>

    </Data>

  </EventData>

</Event>

So if I wanted to use Xpath to filter all events in the Directory Service Event Log from that IP address my query would look something like this:

<QueryList>

  <Query Id=”0″ Path=”Directory Service”>

    <Select Path=”Directory Service”>*[System[(Level=4 or Level=0) and (EventID=1644)]] and *[EventData[Data[5]=’192.168.40.10:4048′]]</Select>

  </Query>

</QueryList>

The query works well, but the problem is that the Data node within the XML contains the port number (4048) in addition to the IP address.  I want to find all queries issued from that client, regardless of the port used.  Here’s my attempt to use the starts-with() function to filter the event.

<QueryList>

  <Query Id=”0″ Path=”Directory Service”>

    <Select Path=”Directory Service”>*[System[(Level=4 or Level=0) and (EventID=1644)]] and *[EventData[starts-with(Data[5],’192.168.40.10′)]]</Select>

  </Query>

</QueryList>

This fails with the error “The specified query is invalid“.  Back to the drawing board.  I posted a question to Technet Forums and got some good help from Ivan Ting at Microsoft.  He provided some Javascript that used starts-with() and this worked (after some fun messing around with default namespace issues).  Being something of a Javascript muppet (the antithesis of a Javascript guru), I decided to try my hand at a Powershell version.  Here’s what I came up with.

#####
# Author: Tony Murray
# File name: LDAPEvents.ps1
# Date: 28th April 2009
# Purpose: Extracts LDAP Search information from Directory Service Event
# Log. Requires LDAP logging to be switched on.
#####

# Function to create an object for XML document navigation
# Source: Technet Scriptcenter
function get-xpn ($text)
{
$rdr = [System.IO.StreamReader] $text
$trdr = [system.io.textreader]$rdr
$xpdoc = [System.XML.XPath.XPathDocument] $trdr
$xpdoc.CreateNavigator()
}

# Run Wevtutil.exe to export the Event log to file
# Could use Powershell to do this but it creates odd-looking xml!

$file = “c:\util\dumplog.xml”
& $env:windir\System32\wevtutil qe `”Directory Service` /e:Events | Out-File $file

# Remove the namespace from the xml file. It won’t work if it stays

$findStr = ” xmlns=`’http://schemas.microsoft.com/win/2004/08/events/event`’”
$ReplStr = “”
$newcontent = (Get-Content $file) -replace ($findStr,$ReplStr)
Set-Content $file $newcontent

# Invoke the navigator
$xb = get-xpn $file

# Define the Xpath query we want to use
$query = “//*[ System[(Level=4 or Level=0) and (EventID=1644)] `
and EventData[starts-with(Data[5],’192.168.40.10′)]]”

# Create a CSV file with the output. Each line represents the details
# we want from a single Event.

Write-Output $xb.Select($query) | %{[xml] $_.OuterXml} | Select-Object `
@{name = “Date&Time”;Expression = {$_.Event.System.TimeCreated.SystemTime}}, `
@{name = “SearchBase”;Expression = {$_.Event.EventData.Data[0]}}, `
@{name = “Filter”;Expression = {$_.Event.EventData.Data[1]}}, `
@{name = “Visited”;Expression = {$_.Event.EventData.Data[2]}}, `
@{name = “Returned”;Expression = {$_.Event.EventData.Data[3]}}, `
#@{name = “SourceIP”;Expression = {$_.Event.EventData.Data[4]}}, `
@{name = “SearchScope”;Expression = {$_.Event.EventData.Data[5]}} `
| export-csv ds.csv -notype
# Replace the previous line with the following line to change the output format
#ConvertTo-HTML | Out-File “LDAPEvent.html”

Having to write a script is more effort than simply issuing the query from within Eventvwr, but it does have the advantage of allowing you to return only the information you are interested in – and in the format that you want.  Hopefully, my experience will save you a bit of time and effort if you are trying to achieve something similar.

Laura Hunter and Brian Desmond will be doing a webcast discussing and demoing the new Active Directory features in Windows Server 2008 R2 as well as answering AD questions. They have a 90 minute slot and expect to spend ~45-60 minutes on R2 and the remainder taking questions on the presentation and AD in general.  They’d love to see you there. The webcast is hosted by O’Reilly and is free to attend. If you can’t make it, a recording will be available. Here are the details: 

Registration Link –

https://oreillymedia.webex.com/oreillymedia/onstage/g.php?d=662451195&t=a

Date: Friday, April 24, 2009Time: 10am PT, San Francisco
6pm – London | 1pm – New York | Sat, Apr 25th at 3am – Sydney | Sat, Apr 25th at 2am – Tokyo | Sat, Apr 25th at 1am – Beijing | 10:30pm – Mumbai

In my last post, I provided a small batch file to support scheduled IFM dumps of an AD LDS instance.  Afterwards, I realised that batch files are sooo last century and decided to have a crack at the Powershell version.  I’m no Bwandon, but the script below seems to do the trick.

#
# Name: Create_IFM_Dump.ps1
# Author: Tony Murray
# Version: 1.0
# Date: 20/04/2009
# Comment: PowerShell script to create AD LDS IFM
# backup.  To be run nightly as a scheduled task.
#
#########################################################

# Declare variables$IFMDir = “c:\backup\adlds\Instance1″
$IFMName = “adamntds.dit”
$cmd = $env:SystemRoot + “\system32\dsdbutil.exe”
$flags = “`”ac i Instance1`” ifm `”create full c:\backup\adlds\Instance1`” q q”
$date = get-Date -f “yyyymmdd”
$backupfile = $date + “_adamntds.bak”
$DumpIFM = “{0} {1}” -f $cmd,$Flags

# Main

# Create the folder if it doesn’t exist if(test-path -path $IFMDir)
{write-host “The folder” $IFMDir “already exists”}
else
{New-Item $IFMDir -type directory}
# Clear the IFM folder (Dsdbutil needs folder to be empty before writing to it) Remove-Item $IFMDir\*

# Run Dsdbutil.exe to create the IFM dump file Invoke-expression $DumpIFM# Rename the dump file to give the backup a unique name

rename-item $IFMDir”\”$IFMName -newname $backupfile

# End Main

 Tony

Microsoft Technet describes how to back up an AD LDS instance using either Windows Server Backup or Dsdbutil.exe.  Interestingly, the Dsdbutil method leverages the Install From Media (IFM) feature to perform the backup.  Here’s a small batch file that you can use to schedule the backup using the Task Scheduler.

@echo off
rd /s c:\backup\adlds\Instance1\ /q
%windir%\system32\dsdbutil.exe “ac i Instance1″ ifm “create full c:\backup\adlds\Instance1″ q q

Enjoy!

If you’ve spent some time with Vista or Windows Server 2008 you’ll have noticed that there are some fundamental changes to the event viewer.  One of the changes is in the way in which event logs can be filtered.  In addition to the point-and-click filter selection you can now also enter an xpath query by accessing the XML tab (see screenshots below).  This gives you the ability to filter using a much wider range of criteria.  Basically, you can search using anything that is presented in the list of XML values.

event_filtering1.JPG

-

event_filtering2.JPG

The xpath queries take a bit of getting used to and as yet there don’t appear to be many publicly available examples.  Here are a few to get you started. This query searches the Security Event log for 4624 events that include a TargetUsername of “User1″ and corresponding to a logon type of “2″ (interactive). 

<QueryList>
  <Query Id=”0″ Path=”Security”>
    <Select Path=”Security”>*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (EventID=4624)] and EventData[Data[@Name='TargetUserName']=’User1′] and EventData[Data[@Name='LogonType']=’2′]]</Select>
  </Query>
</QueryList>

The query below also looks for 4624 events, but this time for those that include a WorkstationName of “Workstation1″ and a logon type of “3″ (network). 

<QueryList>
  <Query Id=”0″ Path=”Security”>
    <Select Path=”Security”>*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (EventID=4624)] and EventData[Data[@Name='WorkstationName']=’Workstation1′] and EventData[Data[@Name='LogonType']=’3′]]</Select>
  </Query>
</QueryList>

Even though Xpath can appear a little daunting at first it is worth spending a bit of time with as it’s potentially quite powerful.  As with Powershell it is something that is likely to be here to stay.

I really like the snapshot feature of Windows Server 2008 AD and have been using it quite a bit recently.  This week I had my first foray into snapshotting with AD LDS.  Everything is pretty much the same as for AD, the only obvious difference being that you can create the snapshots using either dsdbutil or ntdsutil with AD LDS.  I was somewhat surprised then to see a nasty looking error (see below) when I fired up Dsamain.exe to expose my freshly taken AD LDS snapshot.

C:\>dsamain -dbpath “C:\$SNAP_200904031033_VOLUMEC$\Program Files
\Microsoft ADAM\INSTANCE1\data\adamntds.dit” -ldapport 15005
EVENTLOG (Error): NTDS Database / Internal Processing : 1168
Internal error: An Active Directory Domain Services error has occurred.
Additional DataError value (decimal):
-1507
Error value (hex):
fffffa1d

Internal ID:
20208a9

EVENTLOG (Error): NTDS General / Internal Processing : 1003
Active Directory Domain Services could not be initialized.

The directory service cannot recover from this error.

User Action

Restore the local directory service from backup media.

Additional Data

Error value:
-1507 JET_errColumnNotFound, No such column

EVENTLOG (Informational): NTDS General / Service Control : 1004
Active Directory Domain Services was shut down successfully.

After a few minutes bafflement, I had another look through the Dsamain.exe command line options and saw this:

 -adlds       (optional) open AD/LDS DIT

It turns out the -adlds parameter is optional only in the sense that you don’t (and in fact must not) include it when using Dsamain.exe with AD.  It is mandatory when using AD LDS.

Once I included the -adlds parameter everything fired up normally.   Another case of RTFM for me. :-)

 

You may have heard via the grapevine, or even via the Beta program for that matter, that Windows Server 2008 R2 will ship with an Active Directory Module for Powershell.  Having seen some of the capabilities at the recent MVP Summit, I am very impressed with the work the product team has done in this area. 

Now you may be thinking that Powershell is soooo (Exchange) 2007 – and why have we had to wait so long for AD Cmdlets from Microsoft?  The truth is that, despite having been in the pipeline for some time, the Directory Services product team has had other priorities. 

To give you a head start with Powershell in advance of the R2 release, check out the new Active Directory Powershell Blog.

I’m finding there is a huge gulf between playing with Windows Server 2008 in a lab and working with it in a production environment. The biggest difference for me is that I typically use a built-in Administrator account in the lab environment, but work with an account with delegated permissions in production. This means I encounter…er…challenges with User Account Control (UAC) on a fairly regular basis. I have already blogged about some scenarios in which UAC doesn’t error or fail gracefully here, here and here.

Today’s blog entry is all about the following UAC-related Group Policy setting:

Computer Configuration -> Windows Settings -> Security Settings -> Local Polices -> Security Options -> User Account Control: Run all administrators in Admin Approval Mode

Enabled by default, this setting basically forces all users, including Administrators to run as standard users. Any tasks that need to be run as Administrator have to be launched with elevated privilege. It is a setting that is entirely sensible from a security perspective, but can cause frustration and confusion in certain situations. Here’s an example scenario.

Let’s say you are logged into a Windows Sever 2003 (or Vista) machine with an account that is a member of the local Administrators group. By default the Administrators group has Full Control permissions over files and folders on the machine. With the above-mentioned Group Policy enabled, however, you may not be able to, for example, create new text files by right-clicking within Windows Explorer (unless you have rights to do so through either explicit permissions or through membership of other groups).  For example, when right clicking in the root of C:\ you are only likely to have the ability to create a new folder by default, as shown below.

perm1.jpg

No problem, you might think, my account is a member of the local Administrators group so I’ll just fire up Windows Explorer in elevated mode by right-clicking the icon and choosing “Run as Administrator”. Doing this gives all the appearance of running in elevated mode, but in reality does nothing.

perm2.jpg

So how the heck do you create new text files? Or, for that matter, how do you do all those other things that require elevated privileges that you typically would do from within Windows Explorer in earlier versions of the OS? Well, there may be other methods, but the workaround I found was to open Notepad in elevated mode. Then from within Notepad select File -> Open and this gives you, effectively, an elevated Windows Explorer to work with, as shown below.

perm3.jpg

Another option would be to open a command window using “Run as Administrator” and create the text file from there.  You could then edit and save it using an elevated Notepad session.   Again, a rather clumsy workaround for something that you did without thinking in previous versions of the OS.

 If nothing else, UAC in Windows Server 2008 and Vista forces you to think outside the box. The old ways in which you used to work with the user interface in earlier versions of the OS may no longer apply. I can be deeply frustrating, but I suspect UAC is here to stay because of the security benefits it delivers. We may as well get used to it.

Okay, okay, I realise that I may be labouring the point somewhat.  I’ve already written two blog entries (here and here) about UAC in Windows Server 2008 and this is the third and (probably) last.

When you check DC replication using the repadmin /showreps command from a privileged command window you might see something like this:

SITE1\DC1
DSA Options: IS_GC

Site Options: (none)

DSA object GUID: 0f28ec82-687f-4a16-81fb-bc7dc6b67fa9

DSA invocationID: 498ceb24-0a84-40a9-b8cb-63b1ff9a8ed1

==== INBOUND NEIGHBORS ======================================

DC=MYCO,DC=COM

SITE0\DC2 via RPC

DSA object GUID: 04f70cfc-c73d-4e3c-9c8f-42c3ad146bb2

Last attempt @ 2009-02-04 13:48:49 was successful.

CN=Configuration,DC=MYCO,DC=COM

SITE0\DC2 via RPC

DSA object GUID: 04f70cfc-c73d-4e3c-9c8f-42c3ad146bb2

Last attempt @ 2009-02-04 13:48:49 was successful.

CN=Schema,CN=Configuration,DC=MYCO,DC=COM

SITE0\DC2 via RPC

DSA object GUID: 04f70cfc-c73d-4e3c-9c8f-42c3ad146bb2

Last attempt @ 2009-02-04 13:48:49 was successful.

DC=ForestDnsZones,DC=MYCO,DC=COM

SITE0\DC2 via RPC

DSA object GUID: 04f70cfc-c73d-4e3c-9c8f-42c3ad146bb2

Last attempt @ 2009-02-04 13:48:49 was successful.

DC=DomainDnsZones,DC=MYCO,DC=COM

SITE0\DC2 via RPC

DSA object GUID: 04f70cfc-c73d-4e3c-9c8f-42c3ad146bb2

Last attempt @ 2009-02-04 13:48:49 was successful.

Howerver, when you run the same command from an unprivileged command window, you might see the error shown below.

SITE1\DC1

DSA Options: IS_GC

Site Options: (none)

DSA object GUID: 0f28ec82-687f-4a16-81fb-bc7dc6b67fa9

DSA invocationID: 498ceb24-0a84-40a9-b8cb-63b1ff9a8ed1

==== INBOUND NEIGHBORS ======================================

DC=MYCO,DC=COM

SITE0\DC2 via RPC

DSA object GUID: 04f70cfc-c73d-4e3c-9c8f-42c3ad146bb2

Last attempt @ 2009-02-04 13:48:49 was successful.

CN=Configuration,DC=MYCO,DC=COM

SITE0\DC2 via RPC

DSA object GUID: 04f70cfc-c73d-4e3c-9c8f-42c3ad146bb2

Last attempt @ 2009-02-04 13:48:49 was successful.

CN=Schema,CN=Configuration,DC=MYCO,DC=COM

SITE0\DC2 via RPC

DSA object GUID: 04f70cfc-c73d-4e3c-9c8f-42c3ad146bb2

Last attempt @ 2009-02-04 13:48:49 was successful.

DC=ForestDnsZones,DC=MYCO,DC=COM

SITE0\DC2 via RPC

DSA object GUID: 04f70cfc-c73d-4e3c-9c8f-42c3ad146bb2

Last attempt @ 2009-02-04 13:48:49 was successful.

DC=DomainDnsZones,DC=MYCO,DC=COM

SITE0\DC2 via RPC

DSA object GUID: 04f70cfc-c73d-4e3c-9c8f-42c3ad146bb2

Last attempt @ 2009-02-04 13:48:49 was successful.

DsReplicaGetInfo() failed with status 8453 (0x2105):

Replication access was denied.

DsReplicaGetInfo() failed with status 8453 (0x2105):

Replication access was denied.

Note that the information returned is identical.  The only difference is that you see the errors at the end when running in an unprivileged window.  I believe the errors relate to a missing “Monitor Replication Topology” extended right at the root of each of the directory naming contexts (partitions).

 As with other UAC annoyances, the errors can potentially be confusing.  I guess the moral of the story with Windows Server 2008 is to always be aware of when you need to run commands with full privileges.  In my case it clearly takes some getting used to.  :-)