This question already has an answer here:
Powershell Active Directory DisplayName
(1 answer)
Closed 2 years ago.
Hello everyone I am currently learning PowerShell, and I have script were I can create a Active Directory User, And I am trying to combine the first name and last name (firstname.lastname) and set it where it says $logonname so the user will not have to input that information. Is there some type of command used to achieve that ?
import-module activedirectory
#Define variable
$OU ="OU=mine,DC=mine,DC=mine"
$firstname = Read-Host 'Enter New Users First Name'
$lastname = Read-Host 'Enter New Users Last Name'
$logonname = Read-Host 'Enter New Users Windows Logon Name'
$EmailAddress = "$logonname#mine.com"
$Description = Read-Host 'Job Title?'
$Landline = Read-Host 'Enter the Users Landline Phone (if applicable)'
$Mobile = Read-Host 'Mobile Phone? (If Applicable)'
$Password = Read-Host 'Please enter a secure password'
New-ADUser -Name "$firstname $lastname" -EmailAddress $EmailAddress -DisplayName "$firstname $lastname" -SamAccountName $logonname -Title $Description -UserPrincipalName "$logonname#mine.com" -GivenName $firstname -Surname $lastname -Description $Description -OfficePhone $Landline -MobilePhone $Mobile
Write-Host 'Setting Account Details...'
Write-Host 'Setting Password...'
Set-ADAccountPassword -Identity $logonname -NewPassword (ConvertTo-SecureString -AsPlainText "$Password" -Force)
Set-ADUser -Identity $logonname -PasswordNeverExpires $true
Write-Host 'Setting Home Directory to \\networklocation\Home'
Set-ADUser -Identity $logonname -HomeDirectory \\networklocation\home -HomeDrive H
Write-Host 'Enabling Account in Active Directory..
**NOTE**
The Account Will Take 30 Seconds To Enable, It Is Safe To Close The Script As Long as you See the "DONE" Prompt.'
Enable-ADAccount -Identity $logonname
Write-Host 'Done'
If you want to update your script so that $logonname is using the values from $firstname and $lastname then you can do that in a couple different ways.
I also see in the comments that you want a . in between.
This is how I would do it:
$logonname = "$firstname.$lastname";
As a side note, I personally don't have experience with AD, however, allowing the user to type in whatever they want, and then using that info could lead to problems.
What if the user types symbols that are not allowed in a username or in an email address?
If you are the only one using this script and you're just writing it to make your job easier, then that's probably fine. But I would be wary of allowing others to run it.
What happens if any one of these commands which depend on the previous command, fails?
I realize you said you're learning. So this is a good opportunity to learn about error handling, checking your inputs and verifying they are valid, etc.
Related
I am automating the creation of user accounts in our Windows AD. I am trying to copy the permissions from one account to another,(like you would if you right click and copied a user inside of the "Active Directory Users and Computers" application) but when using the cmdlet 'New AD-User' and passing in a variable to the 'instance' parameter, it does nothing different than if I do not pass the variable at all.
This is what I am using to obtain the $userInstance variable:
$userInstance = Get-ADUser -Identity $department User
This is the code I am using to create a new user:
New-ADUser `
-SamAccountName $userName `
-UserPrincipalName "$userName#123.COM" `
-Name "$firstName $lastName" `
-GivenName $firstName `
-Surname $lastName `
-Enabled $true `
-DisplayName "$firstName $lastName" `
-City $city `
-PostalCode $zip `
-Company $company `
-State $state `
-EmailAddress $email `
-Department $department `
-Instance $userInstance `
-AccountPassword (ConvertTo-SecureString "1234" -AsPlainText -Force)
When I run this command, it does the same exact thing as if I ran this command without the instance parameter.
New-ADUser `
-SamAccountName $userName `
-UserPrincipalName "$userName#123.COM" `
-Name "$firstName $lastName" `
-GivenName $firstName `
-Surname $lastName `
-Enabled $true `
-DisplayName "$firstName $lastName" `
-City $city `
-PostalCode $zip `
-Company $company `
-State $state `
-EmailAddress $email `
-Department $department `
-AccountPassword (ConvertTo-SecureString "1234" -AsPlainText -Force)
Am I missing something? I do not understand what the 'instance' parameter is supposed to be doing if it only copies certain attributes that are easily obtainable(state, company, city). Is there something out there that actually copies a template account or do I need to write a loop that goes through every single attribute, permission, and group in the template account that provides some sort of meaning to my organization and assign them manually?
What exactly do you mean by "permission"?
Permissions on resources are set based on the objectSid of a user. Since this is unique to every user you can never "copy" them (and related permissions) to a new user.
Group memberships are stored on groups not on users. The memberOf attribute is just a "backLink" so this won't be copied neither.
Group membership needs to be added in a separate step, e.g. by using
Add-ADGroupMember
cmdlet in PowerShell...
"Permissions" might not have been the word I was looking for necessarily. I wanted to create the user and assign them the same groups and directory location as a previous User. I was able to add group membership to my new users by using the method stated by #Oliver Hauck earlier
Add-ADGroupMember
This aided me in my findings, but what I desired was to not have to write long, repetitive switch code for each new employee type, along with their groups, we could onboard. In hopes that someone sees this and doesn't feel intrigued in writing super long, boring switch code, I wanted to share how I achieved this if it helps anyone else in the future. I still obtained the $userInstance variable in the same way, but adding the -Property parameter defined to MemberOf
$userInstance = Get-ADUser -Identity $department User -Properties MemberOf
I then used the $userInstance variable to obtain the properties I needed from it (Groups to copy, Directory Path)
//Obtains the Path from the copied User, without their common name (CN) attached
$path = $userInstance.DistinguishedName.split(",",2)[-1]
I still created the new user with the same command as above but added the -Path parameter to assign the directory path to the New-ADUser cmd
New-ADUser `
-SamAccountName $userName `
-UserPrincipalName "$userName#123.COM" `
-Name "$firstName $lastName" `
-GivenName $firstName `
-Surname $lastName `
-Enabled $true `
-DisplayName "$firstName $lastName" `
-City $city `
-PostalCode $zip `
-Company $company `
-State $state `
-Path $path `
-EmailAddress $email `
-Department $department `
-AccountPassword (ConvertTo-SecureString "1234" -AsPlainText -Force)
And here is how I obtained and assigned the Group Membership to the New User
//Obtains the groups to be copied from the existing User
$refGroups = $userInstance.MemberOf
//Adds AD Group Membership to User
$refGroups | Add-ADGroupMember -Members $userName
I need to migrate from AD Windows2003Forest to AD 2016. I have below script to create users in bulk. My requirement is to map the same SID of older AD to new AD. For example in older AD SID='xyz' then it should be the same in newAD too as SID='xyz'
I am having all the users data along with SID in CSV format & am using below PowerShell script which is somehow not working. As of advice or suggestions.
powershell code snippent:
#Enter a path to your import CSV file
$ADUsers = Import-csv C:\scripts\newusers.csv
foreach ($User in $ADUsers)
{
$Username = $User.username
$Password = $User.password
$Firstname = $User.firstname
$Lastname = $User.lastname
$Department = $User.department
$OU = $User.ou
$sid = $User.sid
$UserPrincipalName = $User.UserPrincipalName
$DistinguishedName = $User.DistinguishedName
#Check if the user account already exists in AD
if (Get-ADUser -F {SamAccountName -eq $Username})
{
#If user does exist, output a warning message
Write-Warning "A user account $Username has already exist in Active Directory."
}
else
{
#If a user does not exist then create a new user account
#Account will be created in the OU listed in the $OU variable in the CSV file; don’t forget to change the domain name in the"-UserPrincipalName" variable
New-ADUser `
-SamAccountName $Username `
-UserPrincipalName $UserPrincipalName `
-Name "$Firstname $Lastname" `
-GivenName $Firstname `
-Surname $Lastname `
-Enabled $True `
-ChangePasswordAtLogon $True `
-DisplayName "$Lastname, $Firstname" `
-Department $Department `
-DistinguishedName $DistinguishedName `
-SID $sid `
-Path $OU `
-AccountPassword (convertto-securestring $Password -AsPlainText -Force)
}
}
You won't be able to assign a SID as that's generated by the domain controller based on a RID. If trying to migrate to a new forest then you'll need to perform a proper AD migration. The old SIDs will be copied onto the migrated users' SID history attributes to allow permissions based on the old SID to still work.
If you simply want to upgrade to a newer version of AD then you're better off joining a newer domain controller to your existing Active Directory forest / domain. The forest functional level mush be 2003 or higher.
As a side note, I'd recommend then getting rid of the 2003 servers as soon as possible as these are no longer supported by Microsoft.
I am working on a Power Shell script that will create bulk users in Active Directory. As stated in a previous post, I'm fairly new to Power Shell and want to be safe before I go live with anything. Below is the script, some of it borrowed. It will be reading data from the .csv noted in the Import-CSV cmdlet. Ideally, this would create the user and define the user's full name, first name, last name, username, SAM name, e-mail, title, description and manager. It would also set a password.
I would love any feedback on how the below script looks. Please let me know if you have any questions or need any additional information.
Import-Module activedirectory
$ADUsers = Import-CSV C:\scripts\hourlyimport.csv
foreach ($User in $ADUsers)
{
#read user data from each field in each row and assign the data to a variable as below
$Username = $User.username
$Firstname = $User.firstname
$Lastname = $User.lastname
$Password = $User.password
$OU = $User.ou
$Title = $User.title
$Manager = $User.manager
#check to see if the user already exists in AD
if (Get-ADUser -F {SamAccountName -eq $Username})
{
#if user does exist, give a warning
Write-Warning "A user account with username $Username already exist in Active Directory. Say wha?!?"
}
else
{
#if user does not exist then proceed to create the new user account
#account will be created in the OU provided by the $OU variable read from the CSV file
New-ADUser `
-SamAccountName $Username `
-UserPrincipalName "$Username#thredup.com" `
-Email "$Username#thredup.com" `
-Name "$Firstname $Lastname" `
-GivenName $Firstname `
-Surname $Lastname `
-Enabled $True `
-DisplayName "$Lastname, $Firstname" `
-Path $OU `
-Description "$Title" `
-Title "$Title" `
-Manager "$Manager" `
-AccountPassword (convertto-securestring $Password -AsPlainText -Force)
}
}
Looks pretty good to me. You are somewhat inconsistent with the use of ", for example you don't need to write -Title "$Title", you can leave away the " in this case.
You could probably do some fancy optimization with splatting here, reducing the assignments, but since it is a quite unknown feature among many readers I wouldn't go for it here.
One thing I'm missing is error handling. With the default settings, your script will print out errors when something goes wrong, but continue the loop. Is this intended? It is often good practice to state your intention explicitly by setting $ErrorActionPreference at the start of your script.
I'm trying to build a script that will take a CSV with the fields
firstname, lastname, password
and create a user in AD in a specific OU with that info. I've done a bunch of googling, and this is what I've come up with (from this blog):
Import-Csv .\userImport.csv | ForEach-Object {
New-ADUser
-Name $_.DisplayName
-UserPrincipalName $_.UserPrincipalName
-SamAccountName $_.Username
-FirstName $_.FirstName
-DisplayName $_.DisplayName
-LastName $_.Lastname
-Path $_.Path
-AccountPassword (ConvertTo-SecureString $_.Password -AsPlainText -force)
-Enabled $True
-PasswordNeverExpires $True
-PassThru
}
I have a few questions:
I want to specify the OU in my command, instead of having it be in the CSV. Can I just change it to:
-Path OU=MyOU,DC=Domain,DC=Local
What is the -PassThru line for?
Is the -AccountPassword line correct? I got that from a blog that suggested this is the right way to take a password and set it as my AD user's password.
Do I need the PrincipalName, SamAccountName and DisplayName all as separate fields? This can be as minimal as possible, at least for now.
Any tips or changes you would make? This is my first time doing a script like this so I'm willing to learn.
Yes, you can specify parameters whichever way you like, they don't need to come from the input file.
-PassThru makes New-ADUser echo the created user object. By default the cmdlet doesn't return anything.
Yes, the -AccountPassword argument is correct, provided the password field from the CSV contains the plaintext password.
You don't necessarily have to have a separate CSV field for each parameter argument if you can construct an argument from existing field values. For instance, you most likely can create values like DisplayName or SamAccountName from first and last name, e.g. like this:
-SamAccountName ($_.firstname.Substring(0,1) + $_.lastname).ToLower()
-DisplayName ('{0} {1}' -f $_.firstname, $_.lastname)
You also don't need to specify every argument. For instance, the UPN (User Principal Name) will automatically be generated when omitted, and the display name will default to the name.
You can't wrap the lines like you have. PowerShell can't read your mind and won't know that you intend to continue the statement in the next line unless you tell it that or the statement is obviously incomplete. Use backticks to escape the linebreaks. Also, the parameters for first and last name are -GivenName and -Surname, not -FirstName and -LastName.
$csv = '.\userImport.csv'
$ou = 'OU=MyOU,DC=Domain,DC=Local'
Import-Csv $csv | ForEach-Object {
$name = '{0} {1}' -f $_.firstname, $_.lastname
$acct = ($_.firstname.Substring(0,1) + $_.lastname).ToLower()
$pw = ConvertTo-SecureString $_.password -AsPlainText -Force
New-ADUser -Name $name `
-SamAccountName $acct `
-GivenName $_.firstname `
-Surname $_.lastname `
-Path $ou `
-AccountPassword $pw `
-Enabled $true `
-PasswordNeverExpires $true `
-PassThru
}
OU - If you want them all in the same OU, you can hard code it (remember the quotes)
-Path "OU=MyOU,DC=Domain,DC=Local"
-PassThru
The -PassThru parameter lets you request output from cmdlets that return no output by default. (The PassThru Parameter: Gimme Output)
i.e. Instead of New-ADUser just executing and then returning you to the next line, it will actually print out the new user created info to the prompt.
Yes the -AccountPassword takes a SecureString as the argument. The command ConvertTo-SecureString converts a plain text string to a SecureString, which then can be passed to the -AccountPassword parameter
You don't need -UserPrincipalName. You do need -SamAccountName. -DisplayName can be changed to:
-DisplayName "$($_.FirstName) $($_.Lastname)"
This is a pretty standard script for mass producing accounts, so it is pretty good the way it is. The only change I would look at is -PasswordNeverExpires $True You typically only really set the Password Never Expires on Service accounts, so if you are creating plain old user accounts, you wouldn't need it.
I was wondering if it was possible to change the OU (organizational unit) of a user in ActiveDirectory using PowerShell. I have a script that should update many of the fields. I am using the Set-ADUser command to update, but I can't seem to find a flag that will allow me to update the OU. Below is the the Set-ADUser command I am using currently. The variables are set earlier in the script and shouldn't be relevant to the question.
set-ADUser -identity $samName -GivenName $firstName -Surname $lastName -Department $department -Description $description -Manager $manager -AccountExpirationDate $acctExp -Organization $org
I also have a script that creates users. That script allows me to set the OU. That leads me to believe that I could change the OU after creation. Below is the command I use to create the user. Again, the variables are set earlier in the script.
New-ADUser -Name $dName -SamAccountName $sam -GivenName $firstName -Surname $lastName -Path $OU -AccountPassword $passwd -ChangePasswordAtLogon $true -Department $department -Description $description -Manager $manager -Organization $org
If there is a flag for the Set-ADUser command that would be great, otherwise, any help is appreciated. Thanks.
You can use the move-adobject:
Move-ADObject 'CN=myuser,CN=Users,DC=mydomain,DC=com' -TargetPath 'OU=mynewou,DC=mydomain,DC=com'
or
Get-ADUser $name| Move-ADObject -TargetPath 'OU=mynewou,DC=mydomain,DC=com'