Move AD user based on their employeeID in csv file - powershell

I'm attempting to move AD users to different ou's based on a CSV file of employee numbers. I've searched around and I have found a suggestion and tried this code:
Import-Module ActiveDirectory
$TargetOU = "OU=Math,OU=Students,DC=domain,DC=net"
$IDs = Import-CSV "c:\testids.csv" | Select -ExpandProperty employeeID
Get-ADUser -filter * -Properties employeeID | Where { $IDs -contains $_.employeeID } |
Move-ADObject -TargetPath $TargetOU
My csv file looks like this
employeeID
11111
22222
33333
It runs with no errors. But the users never move. Im running Server 2012R2.
Any suggestions? Am I on the wrong track or completely off in left field?

Try this
Import-Module ActiveDirectory
$TargetOU = "OU=Math,OU=Students,DC=domain,DC=net"
$IDs = Import-CSV "c:\testids.csv" | Select employeeID
$IDs | % { Get-ADUser -Filter { employeeID -eq $_.employeeID } -Property employeeID |
Move-ADObject -TargetPath $TargetOU }
Sorry, I pushed 'Enter' too quickly. This has your CSV saved as the $IDs object before you start. I think your pipes were a little out of order. Let me know if this works, and if it doesn't I'll try again.

Ok, I'm on the bandwagon of I want to be sure your finding the correct users first. Theory being that Move-ADObject is not getting any input.
First I would do this to check the CSV file contents.
Get-Content "c:\testids.csv" | Select -Skip 1 | ForEach-Object{"'$_'"}
Then assuming that is working what is the result of this command?
$IDs | ForEach-Object{Get-ADUser -Filter "employeeID -eq '$_'" -Property employeeID
Update from Comments
I wonder now if you are looking at the wrong AD Attribute. Maybe it should be EmployeeNumber.
$IDs | ForEach-Object{Get-ADUser -Filter "employeeNumber -eq '$_'" -Property employeeNumber
Give that a try and see if that is what you need?
Also should try and verify that you have no white-space or special characters in the actual employeeid
"'$(Get-Aduser accountthathasid -properties employeeid | select -expand employeeid)'"

I'm willing to bet that the whole issue you're running into is that Get-ADUser is returning no user objects.
<Previous answer removed>
Edit: Ok, I give up, this makes no sense. I now can not find my own user by looking for it by EmployeeID. I think there may be some issues searching by employeeID because this returns nothing:
$me = get-aduser $env:USERNAME -Properties EmployeeID
Get-ADUser -filter "EmployeeID -eq '$($me.EmployeeID)'" -Properties EmployeeID
I verified that $me does in fact contain my ADUser object info, including my EmployeeID. I thien tried:
Get-ADUser -filter "UserPrincipalName -eq '$($me.UserPrincipalName)'"
This did work, so I am sure that my format works. At this point, I withdraw and wish you luck.

Related

Trying to input a specific user list for get-aduser

I'm trying to use a list of usernames to perform a simple get-aduser command. It works fine for a single user, but I can't input a file to perform this for a list.
This command works fine for a single user:
get-aduser -identity myusername -properties passwordlastset, passwordneverexpires |
sort name | ft Name, passwordlastset, Passwordneverexpires | out-file c:\PS\Output.txt
This works fine, but rather than use -filter * for all AD or identity pointing to a file, I am completely lost. I have tried doing a get-content and link to a file but I'm just getting into a pickle.
If I have a text file with a list of usernames in, how do I run the above command against that single text file list, rather than all of AD?
As a side query, is there a way that I can perform the above command, but for a specific OU?
If you have a list that isn't an object, either import it to an object or iterate over the values
Try something like:
$Userlist = Get-Content -path 'c:\temp\test.txt'
$Results = $Userlist | ForEach-Object {
Get-aduser -identity $_ -properties passwordlastset, passwordneverexpires
}
$Results | sort name | ft Name, passwordlastset, Passwordneverexpires | out-file c:\PS\Output.txt
This will work as long as you supply valid SamAccountNames in your list
I would do it this way. You can pipe in identity byvalue. You can import the csv later and get objects back.
get-content userlist.txt |
Get-aduser -properties passwordlastset, passwordneverexpires |
sort name |
select Name, passwordlastset, Passwordneverexpires |
export-csv users.csv
# searchbase example
get-aduser -filter 'name -like "j*"' -SearchBase 'OU=People,DC=stackoverflow,DC=com'

Compare LastLoginDate of user from multiple DC's

I got 2 DCs and need to get a list of all my users that haven't logged in for X days. I got a PS script that looks at the user his last logon date on the domain and then filters and export the users that haven't logged on for the X days.
PowerShell script:
$AmountDays = 30
Get-ADUser -Filter * -Properties Enabled, LastLogonDate |
? {
$_.LastLogonDate -ne $null -and
$_.LastLogonDate -lt (Get-Date).AddDays(-$AmountDays)
} |
sort LastLogonDate |
Select Name,LastLogonDate |
Export-Csv C:\temp\LastLogonUser.csv -NoTypeInformation
The problem is my DC's have different LastLogonDates of that same user.
So if I run my script on DC1 for example he thinks the user haven't logged in for over 20 days, but when i run it on DC2 he logged in yesterday.
Is there a way to check the LastLogonDate of the same user from both DC's and take the most recent one, so I can check the result of the compare if the user haven't logged in for X days?
I have edited my code so it uses a foreach loop to go through my DCs and find my users. But I think it stops after he went through the first one. Because if I run a simple code to check if he can find both DCs he views them both. But when I run my code and export the result, it only shows each member ones and not all the LastLogonDates are correct.
New Script:
Import-Module ActiveDirectory
$dcs = Get-ADDomainController -Filter {Name -like "*"}
$AmountDays = 0
foreach($dc in $dcs)
{
Get-ADUser -Filter * -Properties Enabled, LastLogonDate | ? { `
($_.LastLogonDate -NE $NULL -AND $_.LastLogonDate -LT (Get-
Date).AddDays(-$AmountDays)) } |
sort LastLogonDate | Select Name,LastLogonDate |
Export-Csv C:\temp\LastLogonUser.csv -NoTypeInformation
}
I could actually use some help with the question asked as well because I need to modify a report that I make to do a comparison against 16 DC's and 1200 Computer accounts to find the last logon and passwordlastset
This is logic that I have used for a smaller set of data but I don't think it will be efficient with ~20,000 rows of data to find accurate info. It would be slow.
$Users = #(
"User1"
"User2"
)
$DomainControllers = #(
"DC1"
"DC2"
)
Foreach ($User in $Users){
Foreach ($Controller in $DomainControllers){
$Data = Get-ADUser $User -Properties "LastLogonDate" -Server $Controller | Select LastLogonData
}
$Data = $null
}
The LastLogonDate is a DateTime object, try to convert it first to your local time using the ToLocalTime() Method
So try:
Get-ADUser [...] -Properties LastLogonDate |
? { $_.LastLogonDate -and $_.LastLogonDate.ToLocalTime() -lt [datetime]::Now.AddDays(-30)}
Also, Make sure to sync the DC's Clock, To validate it use the Net Time \\YouDcName command
That is what LastLogonTimestamp was invented for, given that a value from 1 or 2 weeks ago is sufficient for your needs. If not you'll have to query all domain controllers and pick the most recent value.
Get-ADDomainController | ForEach-Object {
Get-ADUser -Filter * -Server $_ -Properties Enabled, LastLogonDate | Where-Object {
# ...
} | Select-Object Name, LastLogonDate
} | Group-Object Name | Select-Object Name, #{n='LastLogon';e={
$_.Group |
Sort-Object LastLogonDate |
Select-Object -Last 1 -Expand LastLogonDate
}
I feel your pain.
The lastLogonTimeStamp attribute is replicated to all DC's, but is only updated during logon if the existing value is 14 or more days old.
The lastLogon attribute is updated at every logon, but is not replicated. You'll need to query all DC's to get an accurate lastLogon value for each user.
I (for better or worse) tend to do this...
$stuff = $(net user $env:username /domain | select-string 'Last logon*').ToString()
$label, $login_date = [regex]::split($stuff, '\s{5,}')
$login_date
It's quick and dirty.

How to get AD properties for a list of windows generic accounts?

I have below PowerShell commands, using which I can get the properties for all the users in the AD.
Import-Module ActiveDirectory
$attributes = 'SamAccountName', 'Name', 'Mail', 'PasswordLastSet', 'Enabled',
'PasswordNeverExpires', 'PasswordExpired'
Get-ADUser -Filter * -Properties $attributes | select $attributes
If I want properties for one specific user, I can use below example in a command prompt:
net user /domain testuser
But, how can I get the AD properties for given list of users?
So, far I have tried the below but couldnt achieve yet as it returns only for one user (not sure how to loop):
Import-Module ActiveDirectory
cd AD:
$Users = gc "C:\AD\accounts.txt"
Get-ADUser -Filter '*' -Properties DisplayName, Office |
? { $Users -contains $_.SamAccountName } |
select DisplayName, Office |
Export-Csv -Path "C:\AD\output\UserProp_14072016.csv" -NoTypeInformation
I'm looking for password last set, active or inactive, owner of that account.
Could you please help?
A technique I use for getting an arbitrary list of AD users is to construct an ORed LDAP filter from the text list:
$Users = gc "C:\AD\accounts.txt"
$User_filter = $Users -replace '^','(SamAccountName=' -replace '$',')'
$Filter = "(|$User_filter)"
Get-ADUser -LDAPFilter $Filter -Properties DisplayName,Office
You can try the following:
Import-Module ActiveDirectory
$Users = "Get-Content C:\AD\Accounts.txt"
Get-ADUser -Filter '*' -Properties DisplayName,Office,PasswordLastSet,LastLogonDate |
? {$Users -contains $_.SamAccountName} |
Select DisplayName,Office,PasswordLastSet,LastLogonDate |
Export-CSV -Path "C:\AD\output\UserProp_14072016.csv" -NoTypeInformation
I'm not aware of a specific "Active" property, but you can add the "LastLogonDate" to the Properties to determine when the account was last logged onto.
Additionally, I'm not sure what you're looking for when you are asking for the "Owner" of the account.
Incidentally, for a list of all of the properties available, you can do the following:
Get-ADUser <username> -Properties *
You may be able to find what you're looking for in the list.
Hope that helps.
Get last logon on descending order
Import-Module ActiveDirectory
Get-ADUser -filter * -properties Displayname, LastLogonDate, SamAccountName, office, PasswordLastSet | select-object Displayname, LastLogonDate,office, SamAccountName, PasswordExpired, PasswordLastSet | Sort LastLogonTime -Descending | Export-csv c:\users.csv -NoTypeInformation

Cannot export all users, only one shows up when Importing-CSV File to then Get-ADUser

I've only just started to learn PowerShell but I'm banging my head on the wall with this one. When I Import-CSV a list of users to get the userprincipalname on Get-Aduser with the header SamAccountName, I am able to see all the emails on the console:
ForEach ($user in $allUsers)
{
Get-ADUser $user.samaccountname -Properties userprincipalname | select -Property userprincipalname
}
However, when I try to export them to a csv-file only 1 user comes out. I always have a problem when using a foreach loop for this...
ForEach ($user in $allUsers)
{
Get-ADUser $user.samaccountname -Properties userprincipalname | select -Property userprincipalname | export-csv $path -NoTypeInformation
}
I'm always run into this problem when making my foreach loops. I only ever get or change 1 variable. Why is this? x_X Please help!
And my CSV file has a header of SamAccountName and samaccount names. Without exporting I get good data from this code on the console:
user#test.com
user2#test.com
etc...
You were exporting in each iteration of the loop, which would overwrite the file. I haven't tried it but the changes below should work.
$allUsers | Foreach-Object {
$user = $_
Get-ADUser $user.samaccountname -Properties userprincipalname | select -Property userprincipalname
} | export-csv $path -NoTypeInformation
You must use this syntax vs foreach(x in y) if you want to directly pipeline the results to export-csv

Powershell - CSV - AD Attribute Update

I'm trying to get AD attributes updated with information from my payroll system. I have a good dump of employee information, and can get most things updated, but I'm having some small problems that hopefully someone much better with Powershell than I can assist with.
--- UpdateInfo.ps1 ---
Import-Module ActiveDirectory
$Users=Import-Csv C:\info_update.csv
foreach($u in $Users)
{
Get-ADUser -Filter "employeeID -eq '$($u.employeeID)'" -properties * | set-aduser -replace #{title="$($u.title)";extensionAttribute1="$($u.title)";givenName="$($u.givenName)";initials="$($u.initials)";middleName="$($u.middleName)";sn="$($u.sn)";physicalDeliveryOfficeName="$($u.physicalDeliveryOfficeName)";streetAddress="$($u.streetAddress)";l="$($u.l)";st="$($u.st)";co="$($u.co)";countryCode="$($u.countryCode)";c="$($u.c)";postalCode="$($u.postalCode)";department="$($u.department)"}
}
--- info_update.csv ---
employeeID,givenName,initials,middleName,sn,name,title,physicalDeliveryOfficeName,streetAddress,l,st,co,countryCode,c,postalCode,department,manager
"111","Smith","Q","Quincy","John","Smith, John Q.","Tech II","Springfield, IL","800 E Monroe St.","Springfield","IL","United States","840","US","62701","IT","540"
Two questions:
I can't get the 'name' field to update. I thought that it was because of the space, but the physicaldeliveryofficename has a space, too...and it's working fine.
I need to do a lookup for the manager ID (last column), return the DN of the manager, and use that to update the manager attribute.
If anyone can help, I would greatly appreciate it. I feel like I'm really close, but I'm overlooking something.
Thanks!
---UPDATE---
Thanks to #TheMadTechnician
Here's the final answer.
Import-Module ActiveDirectory
$Users=Import-Csv C:\Job_titles.csv
foreach($u in $Users)
{
$Mgr = Get-ADUser -Filter "employeeID -eq '$($u.manager)'" | Select -ExpandProperty DistinguishedName
Get-ADUser -Filter "employeeID -eq '$($u.employeeID)'" -properties * | set-aduser -replace #{title="$($u.title)";extensionAttribute1="$($u.title)";givenName="$($u.givenName)";displayName="$($u.name)";initials="$($u.initials)";middleName="$($u.middleName)";sn="$($u.sn)";physicalDeliveryOfficeName="$($u.physicalDeliveryOfficeName)";streetAddress="$($u.streetAddress)";l="$($u.l)";st="$($u.st)";co="$($u.co)";countryCode="$($u.countryCode)";c="$($u.c)";postalCode="$($u.postalCode)";department="$($u.department)";manager="$Mgr"} -PassThru | Rename-ADObject -NewName "$($u.name)"
}
So we will use get-aduser and filter on EmployeeID for the manager, and use Select -ExpandProperty for the DistinguishedName property. I also use the -PassThru switch on your Set-ADUser, and pipe it to Rename-ADObject. See how that suits you:
Import-Module ActiveDirectory
$Users=Import-Csv C:\info_update.csv
$Managers = Import-Csv C:\Managers.csv
foreach($u in $Users)
{
$Mgr = Get-ADUser -Filter "employeeID -eq '$($u.manager)'" | Select -ExpandProperty DistinguishedName
Get-ADUser -Filter "employeeID -eq '$($u.employeeID)'" -properties * | set-aduser -replace #{title="$($u.title)";extensionAttribute1="$($u.title)";givenName="$($u.givenName)";initials="$($u.initials)";middleName="$($u.middleName)";sn="$($u.sn)";physicalDeliveryOfficeName="$($u.physicalDeliveryOfficeName)";streetAddress="$($u.streetAddress)";l="$($u.l)";st="$($u.st)";co="$($u.co)";countryCode="$($u.countryCode)";c="$($u.c)";postalCode="$($u.postalCode)";department="$($u.department)";manager="$Mgr"} -PassThru | Rename-ADObject -NewName "$($u.name)"
}
Set-ADUser cannot be used to set Name. See http://technet.microsoft.com/en-us/library/ee617215.aspx
Try using Rename-ADObject:
Rename-ADObject [-Identity] <ADObject> [-NewName] <string>
Source: http://technet.microsoft.com/en-us/library/ee617225.aspx