Link to home
Start Free TrialLog in
Avatar of namerg
namergFlag for United States of America

asked on

Adding & Verifying existing AD Users

Hello,
I have the following file: $newpath = C:\scripts\ceridian\05-22-2013_CeridianExport.csv with the following headers: Last Name,      First Name,Job Title,Clock Number
The primary key is the Clock Number
I will compare the users from the csv file against OU=ou,DC=domain,DC=com, if a user does not exist at all according to the clock number, it will be created under $location = "OU=New Users,DC=domain,DC=com"
I am stuck here, it will work but will not verify the existence of the user under OU=ou,DC=domain,DC=com
$exists = Get-ADUser -SearchBase "OU=domain,DC=domain,DC=com" -filter * -LDAPFilter "(sAMAccountName=$sam)"

Open in new window

In other words in my output file spits existing and non existing users from @newpath
I did try the following and nothing
$exists = Get-ADUser -SearchBase "OU=ou,DC=domain,DC=com" -filter * -Properties sAMAccountName,sn,givenName,title,employeeNumber | Where { $_.DistinguishedName -notmatch "OU=VIP" -and $_.DistinguishedName -notmatch "OU=DA"} | Select-Object  sAMAccountName,sn,givenName,title,employeeNumber

Open in new window

CODE:
Import-CSV $newpath | ForEach-Object { 
    $sam = $_."Last Name".ToLower() + $_."First Name".substring(0,1).ToLower()
    $ClockNumber = $_."Clock Number"
    Try   {
$exists = Get-ADUser -SearchBase "OU=upi,DC=upicolo,DC=pvt" -filter * -Properties sAMAccountName,sn,givenName,title,employeeNumber | Where { $_.DistinguishedName -notmatch "OU=VIP" -and $_.DistinguishedName -notmatch "OU=DA"} | Select-Object  sAMAccountName,sn,givenName,title,employeeNumber
      }
    Catch { }
If(!$exists)
    {
      $i++
 $password = Get-RandomPassword
	   $domain = "@domain.com"
       $setpass = ConvertTo-SecureString -AsPlainText $password -force
       Write-Host $_."Last Name" ,  $_."First Name" $setpass
       New-ADUser $sam -AccountPassword $setpass -OtherAttributes @{userPrincipalName=$sam + $domain; givenName=$_."First Name";sn=$_."Last Name"; displayName=$_."Last Name" + ", " + $_."First Name"; title=$_."Job Title"; employeeNumber=$_."Clock Number"}
$dn  = (Get-ADUser $sam).DistinguishedName
Move-ADObject -Identity $dn -TargetPath $location
$newdn = (Get-ADUser $sam).DistinguishedName
$CN = $_."Last Name" + ", " + $_."First Name"
      Rename-ADObject -Identity $newdn -NewName $CN
}
    Else
    {
      $Out = "SKIPPED - ALREADY EXISTS OR ERROR:" + "," + $_."Last Name" + "," + $_."First Name" + "," + $_."Clock Number"
Add-Content -Value $Out -Path $log -Encoding UTF8
 }
  }

Open in new window

Thanks for your help,
Avatar of piattnd
piattnd

You need to establish the search scope:

http://technet.microsoft.com/en-us/library/ee617241.aspx

Particularly:

[-SearchScope {<Base> | <OneLevel> | <Subtree>}]

You need to do "Subtree" so it searches through the entire subtree.

$exists = Get-ADUser -SearchScope Subtree -SearchBase "OU=upi,DC=upicolo,DC=pvt" -filter * -Properties sAMAccountName,sn,givenName,title,employeeNumber | Where { $_.DistinguishedName -notmatch "OU=VIP" -and $_.DistinguishedName -notmatch "OU=DA"} | Select-Object  sAMAccountName,sn,givenName,title,employeeNumber
Avatar of footech
"subtree" is the default search scope so doesn't need to be specified in this case.
If you're just trying to verify if there is a user that already exists in AD with the same samaccountname that you construct in line 2, you can just use the following for line 5:
$exists = Get-ADUser $sam

Open in new window

A samAccountName has to be unique for the entire domain, so limiting your search to a specific OU and it's children could give you unwanted results.  Unless you're certain that the name couldn't possibly occur anywhere else, I wouldn't limit your search like that.
Avatar of namerg

ASKER

@footech: Thanks, you might say that we have gone through this before but always new quirks come up when i talk to mgmt. You are right at some point that the samAccountName is unique but not in my case. What if a new employee with a first and last are Peter Davis, according to our policy the username is davisp. But, if I have already an AD user with First and Last Patrick Davis, its username can not be davisp, so the unique identifier is the clock number that I pulled from the CSV file.
And, yes my search is limited to that specific OU.
Thanks for your help,
I'm not sure of the point you're trying to make.  Even in your case the samAccountName has to be unique.  By samAccountName I mean the value that is present in AD.  It doesn't matter if you have a string in a variable called "samAccountName" (or in your case "sam").  Outside of AD it is irrelevant.  But since each AD account has to have a unique samAccountName, you're checking for its existence before you try to create the new user.  When checking for its existence, you don't care about other accounts which is why the following would be pointless.
$exists = Get-ADUser -SearchBase "OU=upi,DC=upicolo,DC=pvt" -filter * -Properties sAMAccountName,sn,givenName,title,employeeNumber | Where { $_.DistinguishedName -notmatch "OU=VIP" -and $_.DistinguishedName -notmatch "OU=DA"} | Select-Object  sAMAccountName,sn,givenName,title,employeeNumber
# or even just
$exists = Get-ADUser -SearchBase "OU=upi,DC=upicolo,DC=pvt" -filter *

Open in new window

That would just return any users which exist in the OU (and I'm guessing would always return values).  The code that I posted for line 5 is correct (whether you use the -searchbase parameter is up to you, just be aware of potential for error).

You may want the "Clock number" attribute to be unique in AD, but there's no built-in limitation in AD that restricts that.  Even if the "Clock number" attribute is unique in AD (and I'm not saying it isn't), if you were to perform a search for accounts in AD that had the same clock number as an entry in a CSV, whether you find a match or not doesn't determine whether or not there is an account with the same samAccountName attribute as you've constructed for that CSV entry.  BTW, a command for that could be:
$exists = Get-ADUser -SearchBase "OU=upi,DC=upicolo,DC=pvt" -filter * -Properties employeeNumber | Where { $_.employeeNumber -eq $ClockNumber }

Open in new window


Here's an example.
In AD you have a user account for Patrick Davis.
Samaccountname is "davisp".
Clock number (employeeNumber) is "1001".
In your CSV you have an entry for Peter Davis.
Samaccountname would be "davisp".
Clock number is "1020" (which we'll say doesn't exist in AD).
If you do a search for clock number "1020", you won't find a match.  If you were to then try to create a new user account with the samaccountname you would get an error because it already exists.  So you can see that in this case it doesn't matter whether the clock number exists in AD or not, we just need to check for the samaccountname.  If you wanted to perform a check for whether either condition (matching samaccountname or matching clock number, code below) was true, that would be fine, but you have to do the check for the samaccountname.
$exists = Get-ADUser -SearchBase "OU=upi,DC=upicolo,DC=pvt" -filter * -Properties employeeNumber | Where { $_.employeeNumber -eq $ClockNumber -or $_.sAMAccountName -eq $sam }

Open in new window

Avatar of namerg

ASKER

@footech: in your example about Patrick Davis and Peter Davis, you are correct that it will throw an error because davisp already exist as samaccountname but the other user does not exist because having different clock number, which is another stage of the code that i need to talk to mgmt about it, so i might have to create/add the user davisp2. So..?

Question: How can i make all my questions not becoming public?

Thanks for your help,
"...but the other user does not exist because having different clock number"
  I don't know what you're saying here.

"So..?"
  I don't know what you're asking.

When you start a new question, there is a checkbox to make it private.
What is a Private Question?
 Private means that your question will be marked with the correct exclusion tags so that search engines (Google, Bing, etc.) will not include your question in their search results. Only visitors and members of Experts Exchange will be able to view your question.
Avatar of namerg

ASKER

I think I figured it out with this one
$exists = Get-ADUser -LDAPFilter "(employeeNumber=$ClockNumber)" -SearchScope Subtree -SearchBase "OU=ou,DC=domain,DC=com"

Open in new window

Not sure, if I am not able to express well but that query is doing what I expect I think.

Let's say the CSV file contains
Davis,Patrick, 1234
Davis,Peter,5678

AD on that OU contains:
davisp,Davis,Patrick,1234

So $exists will say 1234 already exist, need to jump the next one, ohh 5678 and query, it looks like 5678 does not exist, let's create the AD user, ohh found a problem davisp already exist, well let's create davisp2...created...next on csv, and so on....
I suppose you could do it that way.  I would prefer to check for the existence of an account with the samaccountname before trying to create the user, but since it will error out if the samaccountname is already in AD, you could use a try/catch statement to check for the error and then perform appropriate action.  However, I think it's cleaner to just check for the samaccountname beforehand.

The example I posted
$exists = Get-ADUser -SearchBase "OU=upi,DC=upicolo,DC=pvt" -filter * -Properties employeeNumber | Where { $_.employeeNumber -eq $ClockNumber }

Open in new window

yours
$exists = Get-ADUser -LDAPFilter "(employeeNumber=$ClockNumber)" -SearchScope Subtree -SearchBase "OU=ou,DC=domain,DC=com"

Open in new window

and another
$exists = Get-ADUser -Filter {employeeNumber -eq $ClockNumber} -SearchBase "OU=ou,DC=domain,DC=com"

Open in new window

should all give the same results.
Avatar of namerg

ASKER

I have the following query:
$existsNewUSers = Get-ADUser -LDAPFilter "(employeeNumber=$ClockNumber)" -SearchScope Subtree -SearchBase "OU=OU - New Users,DC=domain,DC=com"
But, when i do the the following comparison, it goes through...and the value of $existsNewUSers equals to blank. Not sure why is accepting the conditional. :(
If($existsNewUSers -ne "") {
        $FlagExistNewUser = 1
        $FlagExistOU = 0
    }
Avatar of namerg

ASKER

Weird, I installed PrimalScript in order to debug easier, and existsNewUsers = null but somehow If($existsNewUSers -ne "") is going through....
"" and $null are two different things.  You can try
If ($existsNewUsers)
or
If ($existsNewUsers -ne $null)
Avatar of namerg

ASKER

Hmmm, it looks like the -ne $null not working...
In the Debug console, I have:
ExistsNewUsers = null
existsOU = CN=Lastname, FirstName, OU=ADM, OU=Domain,DC=com

Open in new window

$existsUPI = Get-ADUser -LDAPFilter "(employeeNumber=$ClockNumber)" -SearchScope Subtree -SearchBase "OU=OU,DC=domain,DC=com"
      $existsNewUsers = Get-ADUser -LDAPFilter "(employeeNumber=$ClockNumber)" -SearchScope Subtree -SearchBase "OU=New Users,DC=domain,DC=com"

If (($existsOU -eq $null) -and ($existsNewUsers -ne $null)) {
        $FlagExistOU = 0
        $FlagExistNewUser = 1
    }
    Elseif (($existsOU -eq $null) -and ($existsNewUsers -eq $null)) {
    	$FlagExistOU = 0
    	$FlagExistNewUser = 0
    }
    ElseIf (($existsOU -ne $null) -and ($existsNewUsers -ne $null)) {
        $FlagExistNewUser = 1
        $FlagExistOU = 1
    }

Open in new window

I don't know what you're trying to do anymore.  When you started this question you had
$exists = Get-ADUser -SearchBase "OU=upi,DC=upicolo,DC=pvt" -filter * -Properties sAMAccountName,sn,givenName,title,employeeNumber | Where { $_.DistinguishedName -notmatch "OU=VIP" -and $_.DistinguishedName -notmatch "OU=DA"} | Select-Object  sAMAccountName,sn,givenName,title,employeeNumber
If(!$exists)

Open in new window

And then you were modifying the code to define the $exists variable.  You supplied a line of code for this, and I supplied a couple that would give the same results.

Now you've got new variables and a few different conditions.  I have no idea what $existsOU is supposed to be, or what you're trying to do or how you're trying to do it.

I've never used PrimalScript so I can't really advise you on it, and the debug output doesn't really mean anything to me.  I don't think it would be of any help to you if I were to just guess.
Avatar of namerg

ASKER

Ay dios mio....ok...let me roll back and rephrase it.

We have a master file, a csv.

That csv contains existing users from AD and new users that are not in AD yet.
There is an OU called, COMPANY, i called it OU.(my mistake)
And, there is another OU called COMPANY - New Users
So, $existsCOMPANY will query the users that matches the clock number from the master file against users found in the OU=COMPANY,DC=domain,DC=com
$existsCOMPANY = Get-ADUser -LDAPFilter "(employeeNumber=$ClockNumber)" -SearchScope Subtree -SearchBase "OU=COMPANY,DC=domain,DC=com"

Open in new window

And, $existsNewUsers will query the new users created from the master file that were moved into the OU=New Users,DC=domain,DC=com
$existsNewUsers = Get-ADUser -LDAPFilter "(employeeNumber=$ClockNumber)" -SearchScope Subtree -SearchBase "OU=New Users,DC=domain,DC=com"

Open in new window


So,
If the user or users from the master file exists in the COMPANY ou and does not exist in the New - Users OU, not need to create the AD User.
If the user or users from the master file does not exist in the COMPANY ou but exists in the New Users OU, not need to create the AD User.
If the user or users from the master file does not exist in the COMPANY ou and does not exist in the New User OU, need to create the AD User.

Thanks for your help,
OK, that's much clearer.  You should only need one If statement for this.
If (!($existsCOMPANY) -and !($existsNewUsers))
{ #create the user }
Else
{ #do nothing }

Open in new window

Avatar of namerg

ASKER

omg, really, footech...is that easy...?...let me try..
Actually, I think there is one more thing that you will have to add.  For a command like
$a = Get-ADUser someone
If "someone" doesn't exist, Get-ADuser returns an error and $a doesn't get set.  In a loop, this would mean that if the variable was set through one pass of the loop, and then in the next pass Get-ADUser encountered an error, the variable would not be updated so it would still have the value from the last loop, causing problems with any checks.  One way you can deal with this is to remove or clear the variable each time through the loop (the commands Remove-Variable or Clear-Variable).
Avatar of namerg

ASKER

:( but one little thing

If the user or users from the master file exists in the COMPANY ou and does not exist in the New - Users OU, not need to create the AD User and creates a ExistingCOMPANYUsersReport

If the user or users from the master file does not exist in the COMPANY ou but exists in the New Users OU, not need to create the AD User but creates ExistingNewUsersReport

If the user or users from the master file does not exist in the COMPANY ou and does not exist in the New User OU, need to create the AD User and creates New-Users Report.

I do have already the code to creates the report and create the AD users. But, with the if you mentioned..not sure how to approach it.
ASKER CERTIFIED SOLUTION
Avatar of footech
footech
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of namerg

ASKER

I am am back to my same dilemma...on line 6 :(
I import the csv through the following line and pipe it to loop and query AD
Import-Csv $MasterFile | ForEach-Object {

Open in new window

then I have:
$LastName = $_."Last Name" -replace "\s"
$sam = $LastName.ToLower() + $_."First Name".substring(0,1).ToLower()
$ClockNumber = $_."Clock Number"
$existsCOMPANY = Get-ADUser -LDAPFilter "(employeeNumber=$ClockNumber)" -SearchScope Subtree -SearchBase "OU=COMPANY,DC=DOMAIN,DC=COM"
$existsNewUsers = Get-ADUser -LDAPFilter "(employeeNumber=$ClockNumber)" -SearchScope Subtree -SearchBase "OU=COMPANY - New Users,DC=DOMAIN,DC=COM"
If (!($existsCOMPANY) -and !($existsNewUsers)) {
#Create NEW AD USER and Create NEW USERS Report
}
Elseif (!($existsCOMPANY)) {
#Create Existing COMPANY Users Report
}

Open in new window

If i have the scenario where existsCOMPANY has a user that belongs to the master file and COMPANY ou, the second IF is ignored and should not be, what is the opposite of !($existsCOMPANY) ?
Thanks for your help.
Notice the difference between what I posted and yours.
ElseIf (!($existsCOMPANY))
{
  #create ExistingNewUsersReport

vs.
Elseif (!($existsCOMPANY)) {
#Create Existing COMPANY Users Report


The scenario you describe would be handled by the third condition in my code.
Avatar of namerg

ASKER

@footech: I am sorry, you are right. It worked like a charm. Thank you, thank you for your patience.
Now, I am going to delete all AD users from OU=COMPANY - New Users. And, it should create Existing COMPANY Users Report and NewUsers Report