Receiving error when using Move-ADObject to an organizational unit - powershell

Trying to move a user to a different ou but I'm receiving an error. I tried looking online for solutions but no dice
$user1 = Read-Host "Terminated User: "
Move-ADObject -Identity $user1.distinguishedName -TargetPath "OU=DisabledAccounts,DC=meme,DC=com"
The Error I am receiving is:
Move-ADObject : Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again.

As Lotpings explains, you need to first get the user object from AD by means of the (string) value that was entered using the Read-Host cmdlet.
Make sure you ask for the SamAccountName of the user, because that is what you will need to find the AD user object.
Import-Module ActiveDirectory
$accountName = Read-Host "Enter the SamAccountName of the terminated user: "
# find the user object using the SamAccountName entered
# Get-ADUser takes a DistinghuishedName, a GUID, a SID or SamAccountName as Identity parameter
$user = Get-ADUser -Identity $accountName
if ($user) {
# Move-ADObject takes a DistinghuishedName or GUID as Identity parameter
Move-ADObject -Identity $user.DistinguishedName -TargetPath "OU=DisabledAccounts,DC=nfii,DC=com"
# you can also pipe the object through:
# $user | Move-ADObject -TargetPath "OU=DisabledAccounts,DC=nfii,DC=com"
}
else {
Write-Warning "User with SamAccountName '$accountName' not found."
}

Related

Updating Active Directory Field from Csv

Giving myself a fun little project today I thought, but now it's grown into an issue and the solution eludes me. I have a massive .Csv file with all our employees sAMAccountName and telephoneNumber attributes. I would like to update all of the telephone numbers in our active directory. I was poking around some of my old scripts, taking parts and pieces that would work for this my first iteration got me too here.
$Users = Import-Csv -Path C:\Results\EmployeeExtsTest.csv
ForEach ($User in $Users) {
$User = $User.sAMAccountName
$telephoneNumber = $User.telephoneNumber
Get-ADUser -Identity $User | Set-ADUser -telephoneNumber $telephoneNumber
}
That's when I discovered that PowerShell doesn't have a -telephoneNumber attribute. So I did some digging and then arrived here.
$Users = Import-Csv -Path C:\Results\EmployeeExtsTest.csv
ForEach ($User in $Users) {
$User = $User.sAMAccountName
$telephoneNumber = $User.telephoneNumber
Get-ADUser -Identity $User | Set-ADUser -Add #{telephoneNumber=$telephoneNumber}
}
I tested it out with my user at first and I keep getting the following.
Set-ADUser : Cannot validate argument on parameter 'Add'. The argument is null or an element of the argument collection contains a null value.
At line:6 char:50
+ ... -Identity $User | Set-ADUser -Add #{telephoneNumber=$telephoneNumber}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Set-ADUser], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.SetADUser
I know that it's reading my .Csv correctly because I can call it just fine. It outputs the following.
sAMAccountName telephoneNumber
-------------- ---------------
zgroven 1121
I know this solution "should" be easy but it's completely escaping me!
To expand on #PaulWain answer. Active Directory Users and Computers displays Telephone Number, the AD Attribute is telephoneNumber, but Set-ADUser oddly uses the parameter OfficePhone for setting it. Another quirk due to OfficePhone being a "special" field, when clearing with Set-ADUser you actually have to use telephoneNumber as the field. e.g.:
$Users = Import-Csv -Path C:\Results\EmployeeExtsTest.csv
ForEach ($UserEntry in $Users) {
$User = Get-ADUser -Filter "samAccountName -like '$($UserEntry.sAMAccountName)'" -Properties *
#Check to see if the user exists
if($User)
{
#Check to see if the Office Phone number has been cleared in CSV
if ([string]::IsNullOrEmpty($UserEntry.telephoneNumber))
{
#Clear the user's OfficePhone (telephoneNumber) in Active Directory
Set-ADUser -Identity $User -Clear telephoneNumber
}
else
{
#Update the user in Active Directory
Set-ADUser -Identity $User -OfficePhone $UserEntry.telephoneNumber
}
}
else
{
Write-Host "User $($UserEntry.sAMAccountName) does not exist in Active Directory"
}
}
One thing I add to my script is to use the -Filter parameter on my Get-ADUser that way I can verify the user exists without Get-ADUser throwing an error. See my answer for more information "Determine If Users Are In Active Directory With PowerShell":
The other method is to modify all of the properties all at once, and then use the Set-ADUser -Instance parameter to set them all at once (note: OfficePhone/telephoneNumber are special and have to be cleared manually like the above code, other fields can be manually cleared/set blank):
$Users = Import-Csv -Path C:\Results\EmployeeExtsTest.csv
ForEach ($UserEntry in $Users) {
$User = Get-ADUser -Filter "samAccountName -like '$($UserEntry.sAMAccountName)'" -Properties *
#Check to see if the user exists
if($User)
{
#Check to see if the Office Phone number has been cleared in CSV
if ([string]::IsNullOrEmpty($UserEntry.telephoneNumber))
{
#Clear the user's OfficePhone (telephoneNumber) in Active Directory
Set-ADUser -Identity $User -Clear telephoneNumber
}
else
{
#Modify Local instance of the user's properties
$User.OfficePhone = $UserEntry.telephoneNumber
}
#Modify Local instance of other user's properties
$User.GivenName = $UserEntry.GivenName
$User.Surname = $UserEntry.Surname
#..... etc.....
#Update the user in Active Directory
Set-ADUser -Instance $User
}
else
{
Write-Host "User $($UserEntry.sAMAccountName) does not exist in Active Directory"
}
}
I believe that you are being misled by what is displayed and what the actual name of the property is, due to behind-the-scenes aliasing.
Try using this instead:
set-aduser $user -OfficePhone $telephoneNumber
The final script that got me through this is here
$Users = Import-Csv -Path C:\Results\EmployeeExts.csv
ForEach ($U in $Users) {
$User = $U.sAMAccountName
$telephoneNumber = $U.telephoneNumber
Set-ADUser $User -OfficePhone $telephoneNumber
}
Because I work for a school district I will be adding on more to this in the future to look for employees that are missing. As it stands now this script just updated nearly 1000 AD accounts perfectly (aside from the missing employees that have left). I want to thank all of you for helping in giving me pieces of this answer. You've made me better at my job.
Special thanks to #PaulWain and #HAL9256

Powershell Active Directory Scripting - Bulk disable with change of display name

I am looking for assistance in creating/completing a Powershell script that grabs a user's samAccountName from a .csv file, disables that user in a specific domain, e.g. "foo.bar", and then prepends their AD display name with a single character. This is a bulk disable script, and it has to add that single character to the front/beginning of their display name.
What I have so far is:
Import-Module ActiveDirectory
$Server = read-host "Enter Domain to query/domain controller"
Import-Csv "C:\Temp\samAccountNames.csv" | ForEach-Object {
$samAccountName = $_."samAccountName"
Get-ADUser -Server $Server -Identity $samAccountName | Disable-ADAccount
}
Now, what I need to do is to prepend the display name with the '#' character.
(e.g. "Doe, John" becomes "#Doe, John")
You need to check if the user can be found at all first, then update the displayname and disable the account
Import-Module ActiveDirectory
$characterToPrepend = '#' # the character you want to prepend the DisplayName with
$Server = Read-Host "Enter Domain to query/domain controller"
Import-Csv "C:\Temp\samAccountNames.csv" | ForEach-Object {
$ADUser = Get-ADUser -Server $Server -Filter "SamAccountName -eq '$($_.samAccountName)'" -Properties DisplayName -ErrorAction SilentlyContinue
if ($ADUser) {
# test if the user is not already disabled
if (!$ADUser.Enabled) {
Write-Host "User '$($_.samAccountName)' is already disabled"
}
else {
$newDisplayName = $characterToPrepend + $ADUser.DisplayName
# set the new displayname and disable the user
$ADUser | Set-ADUser -DisplayName $newDisplayName -Enabled $false
}
}
else {
Write-Warning "User '$($_.samAccountName)' does not exist"
}
}
I'm using -Filter to get the user rather than the -Identity parameter because the latter will throw an exception when a user with that SamAccountName could not be found

Move-ADObject to same OU as another user

Im creating new user from clone user so far have everything in place except I cant get the new user to be moved to the same OU as my clone user, we have over 250 OU's so editing Script for move-ADObject each time is not Ideal as some staff new to powershell I can get the Clone user OU as Vairable but when running Script keep getting access denied Im on test lab and the domain administrator/Owner so should have all permissions have chhecked the opjects in ADUC and both are unticket for accidental deletion.
$user = Get-ADUser -Identity "User1"
$User2 = "OUTEST"
$userOU = ($user.DistinguishedName -split "=",3)[-1]
Write-Host $userOU # only to view output
$oupath = Get-aduser $User2
$x = $user.DistinguishedName
Move-ADObject -Identity $x -TargetPath $userOU #Move new user to Accounts OU
Output and error:-
Move-ADObject : Access is denied
At line:11 char:1
+ Move-ADObject -Identity $x -TargetPath $userOU
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (CN=test1 user,O...an,DC=gov,DC=uk:ADObject) [Move-ADObject], UnauthorizedAccessException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.UnauthorizedAccessException,Microsoft.ActiveDirectory.Management.Commands.MoveADObject
As commented, your code tries to move a user ($user) to the same OU it is already in. It never uses $User2 ..
Try
# get the OU from the first user (the OU to move the other user into)
$OU = ((Get-ADUser -Identity 'User1').DistinguishedName -split '(?<!\\),', 2)[-1]
# next, get the user object of the user you want to move
$User2 = Get-ADUser -Identity 'User2'
# now move user2 to the OU where user1 is in
$User2 | Move-ADObject -TargetPath $OU
You may have to add parameter -Credential to the Move-ADObject call where you can give it credentials of an admin user that is allowed to move user objects.
The easiest way to get such a credential object is by using
$cred = Get-Credential -Message 'Please enter credentials'
Regex details for the split:
(?<! Assert that it is impossible to match the regex below with the match ending at this position (negative lookbehind)
\\ Match the character “\” literally
)
, Match the character “,” literally

"A referral was returned from the server" in powershell when trying to use Remove-ADGroupMember

Intro
I have a script that works without issue for users in the root domain. Basically what it does is it
Imports a csv of users
Grabs their distinguished name
Sees if their distinguished name exists in a list of distinguished names in a group
If their DN is indeed in the group, remove them from the group.
Issue
However, I am running into issues when trying to remove users in a child domain from a group located in the root domain.
The Error
Remove-ADGroupMember : A referral was returned from the server
At U:\powershell\AD\Remove_users_from_group.ps1:16 char:9
+ Remove-ADGroupMember $groupDN -Members $user -Confirm:$false ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (CN=GroupA C=Domain,DC=com:ADGroup) [Remove-ADGroupMember], ADRe
ferralException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8235,Microsoft.ActiveDirectory.Management.Commands.RemoveADGroupMember
Code
$csv = Import-Csv -Path "users.csv" -Header 'Username'
$group = 'GroupA'
$groupDN = Get-ADgroup 'GroupA'| Select -Property DistinguishedName
$incount = 0
$notcount = 0
$members = Get-ADGroupMember $group -Server "domain.com" | Select -Property DistinguishedName
ForEach ($Username in $csv) {
$user = $Username.Username
$user = Get-ADUser $user -Server "child.domain.com" | Select -Property DistinguishedName
if ($members -like $user){
Remove-ADGroupMember $groupDN -Members $user -Confirm:$false -Server 'domain.com'
#Set-ADObject -Identity $groupDN -Remove #{member=$($user)}
write-host "Removed:" $user
$incount++
} Else {$notcount++}
}
Write-host "Task complete"
Write-host "Users removed from" $group ":" $incount
Write-host "Users that were not in" $group ":" $notcount
$prompt = Read-Host -Prompt "Press enter to close"
A referral is returned when a DC cannot do what you want to do, but it knows who you need to talk to do what you need to do. In this case, that means it isn't connecting to the correct domain, but Remove-ADGroupMember isn't capable of following the referral. Since you are not specifying the -Server parameter for Remove-ADGroupMember, it's likely connecting to whatever domain you're logged into. The solution is just to use the -Server parameter to make it talk to the correct domain, just like you were doing with Get-ADGroupMember.
Remove-ADGroupMember $groupDN -Members $user -Confirm:$false -Server "domain.com"
I see another problem with your code: You are using the -Recursive parameter with Get-ADGroupMember, meaning that it will return users who are members of groups, where that group is a member of $group. But then you are using Remove-ADGroupMember to remove the user from the group as if it was a direct member of that group. Remove-ADGroupMember will fail for users that are not direct members.

Powershell script to add users to A/D group from .csv using email address only?

Import-CSV "C:\users\Balbahagw\desktop\test1.csv" |
Foreach-Object {
$aduser = Get-ADUser -Filter { EmailAddress -eq $_.'EmailAddress' }
if( $aduser ) {
Write-Output "Adding user $($aduser.SamAccountName) to groupname"
Add-ADGroupMember -Identity tech-103 -Members $aduser
} else {
Write-Warning "Could not find user in AD with email address $($_.EmailAddress)"
}
}
Script is working now, however it can't find the user in AD with the email address.
You need to first resolve the ADUser object matching that email address, the -Identity parameter won't auto-resolve based on the EmailAddress field of an ADUser. Assuming the EmailAddress property is set appropriately on the user object in AD, and assuming the column name for the email address in your CSV is ExternalEmailAddress, this should work:
Import-CSV "C:\users\user\desktop\test1.csv" | Foreach-Object {
$aduser = Get-ADUser -Filter "EmailAddress -eq '$($_.EmailAddress)'"
if( $aduser ) {
Write-Output "Adding user $($aduser.SamAccountName) to groupname"
Add-ADGroupMember -Identity groupname -Members $aduser
} else {
Write-Warning "Could not find user in AD with email address $($_.EmailAddress)"
}
}
Note that if the ADUser does not have the email address set, you will not be able to match that AD user to an email.
Here are the docs for Add-ADGroupMember, you may want to read up on them for more information: https://learn.microsoft.com/en-us/powershell/module/activedirectory/add-adgroupmember?view=winserver2012-ps&viewFallbackFrom=winserver2012r2-ps
EDIT: Found some strangeness with using brackets and the $PSitem, so I changed it to use a string-based filter.
EDIT 2: Found the cause for why using a variable in a bracket-based -Filter doesn't work (which is how I had originally written this), and in fact is not recommended when scripting: Get-Aduser -Filter will not accept a variable