Archive

Archive for the ‘Active Directory’ Category

Powershell and AD Object Recovery (Prologue)

February 25th, 2010 Mark A. Weaver No comments
Rating 3.00 out of 5

I have been toying with an idea for a while since I have been diving deeper into Active Directory stuff with Powershell.

The idea is to develop a full Active Directory object backup and recovery tool. There are several excellent tools available commercially that do this, but with IT staffs and budgets shrinking it is often difficult to justify the cost.

I am sure others have thought about it, maybe dabbled with it, but it seems to me that all of tools and components are available to do this, just that nobody (that I know of) has kind of glued them all together in an easy-to-use interface.

I know many of you may say “Hey, doesn’t Microsoft have an AD Recycle Bin now?”. Well yes, they do…BUT many folks, I believe, are probably still running 2003 AD instances. Regardless of all of that, though, this sounds like a good exercise to at least explore doing a larger-scale “application” using Powershell.

This will also be my first major dive in the Powershell V2.0, so I hope to be discovering new and interesting ways to put these tools together.

From my perspective, I see several main components that will need development:
1. A user Interface. While I have done some of this with “visual” languages and a touch with Powershell, I haven’t done anything very extensive.
2. Interfacing with some type of database solution (probably SQL Server)
3. Access to AD objects without 3rd party utilities. I think this will be fairly straightforward but may end up using the Quest tools.
4. Access to the “delete objects” container in the directory and a means to reanimate those objects. (SDM Software Group has some great cmdlets for doing this which I will probably look at using).
5. General functions for manipulating AD objects (again…pretty easy)

One question keeps coming to mind, though is whether something like this would be useful? I am not entirely sure, but I hope so! To that end, I think the journey may be more worthwhile than the outcome.

Anyway, I hope to be spending more time with (when I *HAVE* spare time) and I hope to chronicle this “journey” here as I go.

If anyone has an opinion on this undertaking or has advice, please let me know.

Stay tuned for updates. Right now I am standing up a small infrastructure at home to support this development effort.

Thanks and Happy Scripting!

— Mark

Powershell and FSMO Roles

November 4th, 2009 Mark A. Weaver No comments
Rating 3.50 out of 5

Okay, this will be a quick and dirty post due to lack of time right now.
This one is kind of a tip, rather than a full-blown script or topic. Basically I was looking to grab which system was the PDC Emulator for my current domain (or NOT my current domain) and so I did some google-ing and finally ended up with these little functions.

All I need to do is pass in the DomainName and it spits out the info. For the FSMO roles, it will return an object and for the DomainMode, just the text is returned.

Hopefully you will find them useful.
That’s it for now…
Happy Scripting..
– Mark

Function get-PDCERole ($DomainName)
  {
   ## Return the PDC Emulator Role Owner for the specified Domain
   $DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain", $DomainName)
   $Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext)
   $PDCE = $Domain.PDCRoleOwner
 
   Return $PDCE  
  }
 
Function get-RIDMasterRole ($DomainName)
  {
   ## Return the RID Master Role Owner for the specified Domain
   $DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain", $DomainName)
   $Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext)
   $RIDMaster = $Domain.RIDRoleOwner
 
   Return $RIDMaster
  } 
 
Function Get-InfMasterRole ($DomainName)
  {
   ## Return the Infrastucture Master role owner for the specified Domain
   $DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain", $DomainName)
   $Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext)
   $InfMaster = $Domain.InfrastructureRoleOwner
 
   Return $InfMaster
 }
 
Function Get-DomainMode ($DomainName)
  {
   ## Return the Domain Mode for the specified Domain
   $DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain", $DomainName)
   $Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext)
   $DomainMode = $Domain.DomainMode
 
   Return $DomainMode
 
  }

Powershell and Unknown User SIDs

October 9th, 2009 Mark A. Weaver No comments
Rating 3.00 out of 5

Once again, my apologies for my lack of posting..

Anyway…

An interesting thing came up at work the other day when one of my fellow administrators asked me if I could resolve an unknown SID he was seeing in some logs to see what the heck it belonged to.

Since I had been telling him that Powershell could do ANYTHING (slight exaggeration, I know)… that it should be able to do this.

Well, it certainly is an interesting notion.

I know that I have run into this in the past where you have file system ACLs set and there are a bunch of SIDs sitting in there that nobody seems to know who they belong to.

While it isn’t THAT important to resolve them since the user account is most likely no longer around, it IS an interesting thought exercise.

After perusing the web looking for others who have done something similar, I feel I had enough to throw something together..

Basically when an Active Directory object (like a user) is “deleted”, it is really just Tombstoned for a period of time and is moved to the hidden container “Deleted Objects” and then removed after like 90 days or so.

Here is my solution to “finding” those objects.

First you will have to know what Domain you want to look at for this object AND you have know the SID you are looking for.

function Resolve-DeletedUserSID($Domain, $UserSID)
{
	## This is kind of a mashup of a few different scripts I found online in some forums.
	## Unfortunately I don't remember who did them.  If it was you, point me to your post and I will
	## give you the credit for your piece.
	## 
	## Returns User information for deleted account with the specified SID and User Domain
 
	$DomainRoot = "LDAP://" + $Domain.trim()
	$DomainDN = ([adsi] ( $DomainRoot )).DistinguishedName
	$adspath = "LDAP://" + $DomainDN
	$root = [system.directoryservices.Directoryentry] $Adspath
	$root.psbase.AuthenticationType = [system.directoryservices.authenticationtypes]::Fastbind
	## We will be looking in the "Deleted Objects" container which is normally hidden, etc.
	## You will need to execute this with an account that has DomainAdmin rights to the domain you are
	## querying.
	$root.psbase.path = "LDAP://cn=Deleted Objects," + $DomainDN
	$search = [system.directoryservices.directorysearcher] $root
	$search.filter = "(&(isDeleted=TRUE)(!(objectClass=computer))(objectclass=user))"
	$search.Tombstone = $true
 
	# If you have more than 1000 users, you must NOT define SizeLimit (we haven't)
	# and PageSize must be less than the default value (of 1000). 
	# I found this a bit strange...but as long as we understand it, I guess it is okay
	$Search.PageSize = 500
 
	# Only look in the top level of the Deleted Objects container.
	$search.SearchScope = [system.directoryservices.searchscope]::OneLevel
	$result = $search.FindAll()
 
	# If the SID isn't found, you will get nothing returned.
	$result | Select-Object @{ Name = "Name" ; Expression = { $_.Properties.Item("Name")[0].split("`n")[0] } }, `
	@{ Name = "SAMAccountName" ; Expression = { $_.Properties.Item("SAMAccountName") } }, `
	@{ Name = "SID" ; Expression = { New-Object System.Security.Principal.SecurityIdentifier($_.Properties.Item("ObjectSID")[0], 0) } }, `
	@{ Name = "WhenChanged" ; Expression = { $_.Properties.Item("WhenChanged") } } `
	| where-Object { $_.SID -ieq $UserSid.Trim() }
}

As always…

Happy Scripting!!!! and let me know if you have questions or problems.

– Mark