Bulk change password of users in AD through powershell - powershell

I am trying to change password of multiple users in my AD through powershell script which I have written. In my AD, I have added an attribute called tempPassword which takes unicode string, which contains random generated password for all users. I want to write this tempPassword attribute as the user password. For this, my powershell script is:
$users = Get-ADUser -properties * -Filter *
foreach($user in $users)
{
$password = $user.tempPassword
$secure_string_pwd = convertto-securestring -String $password -asplaintext -force
Set-ADAccountPassword -Identity $user -NewPassword $secure_string_pwd
}
When i execute this script, I get the following error:
ConvertTo-SecureString : Cannot convert 'Microsoft.ActiveDirectory.Management.ADPropertyValueCollection' to the type 'S
ystem.String' required by parameter 'String'. Specified method is not supported.
The passwords contain numbers, lower and upper case characters and are all of length 8.
What may be the reason for this error?

I don't know how tempPassword is defined in AD. However from what you receive, it means you get a collection of elements.
Try this:
$password = $user.tempPassword[0]

Related

Creating a simple script to import user's first name , create local account and and password

I'm looking to create a simple powershell script that will import the user's first name from file, prompt to create a new password and loop on error when the password doesn't meet the password requirement based on the "ErrorVariable" if possible. If not, please advise.
# import user firstname from file
$firstname = $(Get-Content "C:\tmp\local\firstname.txt")
# prompt user for new password
$password = Read-Host "Hello, $firstname!! Please change your local admin account password. (Requirements: At least 8-characters, 1-Cap Letter, 1-Number) " -AsSecureString -Erroraction silentlycontinue -ErrorVariable PasswordError
# create new password
$password = $password
Get-LocalUser -Name "$firstname" | Set-LocalUser -Password $password -Erroraction silentlycontinue -ErrorVariable PasswordError
If ($PasswordError)
{
"Unable to update the password. The new password does not meet the length or complexity."
}
If (-Not $PasswordError)
{
"Password updated successfully!!"
See script above.........
Think you could simply use try/catch - e.g.:
try {
Set-LocalUser -Name $firstname -Password $password -Erroraction:stop
write-host "Password updated successfully!!"
}
Catch {
write-error $_
}
If the operation succeeded you will get "Password updated successfully!!", otherwise it returns the error.

Find Row in CSV

I'm trying to reset passwords from a set username and password CSV. I have tried using the for-each method and it passes through all of the list rather than just one. Ideally I want it to ask for the username and then reset the password based on the username being entered.
The CSV is as follows
Daniel,Apples
Ben,Bannanas
Harry,Pears
Peter,Grapes
The code is very messy, but any input would be very much appreiciated. I've tried a few different ways and just can't get it to play ball!
Do I need to remove the For-Each element, basically I want it to ask me for a username and when I type it, it resets the password that is given for that username. As all are given a default password.
$Spreadsheet = Import-CSV "C:\Desktop\Password Reset\Passwords.csv"
$username = $User.'Username'
$password = $User.'Password'
ForEach($User in $Spreadsheet) {
$resetusername = Read-Host "Who's Password would you like to reset"
Set-ADAccountPassword $User.UserName -reset -NewPassword (Convertto-Securestring -asplaintext $($User.Password) -force)
Write-Host "Password reset to $password for $username"
}
Thank you very much in advance! :)
The idiomatic approach would be to filter the list of CSV records using Where-Object:
$Spreadsheet = Import-CSV "C:\Desktop\Password Reset\Passwords.csv" -Header Username,Password
$resetUsername = Read-Host "Who's Password would you like to reset"
$targetUser = $Spreadsheet |Where-Object Username -eq $resetUsername
if($targetUser){
Set-ADAccountPassword $targetUser.Username -Reset -NewPassword (Convertto-Securestring -AsPlainText $targetUser.Password -Force)
Write-Host "Password reset to $($targetUser.Password) for $($targetUser.Username)"
}
else {
Write-Host "User '$resetUsername' could not be found in spreadsheet!"
}

Updating Office 365 attributes and creating new accounts using Powershell

I'm working on a powershell script that will do the following:
Will log into our O365 instance
Read the CSV file and update the users attributes (such as department and title)
If the user isn't found, create a new one with those attributes.
If i comment out the New-AzureADUser section it will work fine and update the users that are found, but when i do call New-AzureADUser i get the following error.
New-AzureADUser : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'DisplayName'. Specified method is not supported.
I understand the meaning behind the error in that it wants a string, not an object but i'm a little unsure on next steps.
# Connect to AzureAD
Connect-AzureAD
# Get CSV content
$CSVrecords = Import-Csv bra_o365_import1.csv -Delimiter ","
#CSV contains UserPrincipalName,Department,DisplayName,FirstName,LastName,Title
# Loop trough CSV records
foreach ($CSVrecord in $CSVrecords) {
$upn = $CSVrecord.UserPrincipalName
$user = Get-AzureADUser -Filter "userPrincipalName eq '$upn'"
if ($user) {
try{
$user | Set-AzureADUser -Department $CSVrecord.Department -JobTitle $CSVrecord.Title
} catch {
Write-Warning "$upn user found, but FAILED to update."
}
}
else {
New-AzureADUser -DisplayName $CSVrecords.DisplayName -UserPrincipalName $CSVrecords.UserPrincipalName -AccountEnabled $true -Department $CSVrecord.Department -JobTitle $CSVrecord.Title
Write-Host $CSVrecords.DisplayName
}
}

using secure password with multiple users without prompt

I am trying to have my password secured and stored in a file so that I don't need to enter each time when I run the script.
First step, I ran the following, entered the password which got stored into E:\cred.txt file. The txt file now contains an encrypted password.
(Get-Credential).Password | ConvertFrom-SecureString | Out-File "E:\cred.txt"
Secondly, I ran the below Script:
$File = "E:\cred.txt"
$User = "jason#domain.com"
#### I have two different user accounts, one for admin and other for operator,
#### however both user accounts use same password.
$adminuser = $User
$operator = $User -replace "#domain.com"
#### I would need to read $File to get only the password
$pass = New-Object -TypeName System.Management.Automation.PSCredential `
-ArgumentList (Get-Content $File | ConvertTo-SecureString)
$adminuser
$operator
$pass
Output:
jason#domain.com
jason
UserName Password
-------- --------
From the output, it seems New-Object refers to both UserName and Password. And when I try to connect to systems, it fails with Authentication error. Since I already have two different usernames hard coded within the script, how should I get only the password stored in $pass? or is it possible to include all usernames ($User, $adminuser, $operator) into the cred.txt file?
Try this:
#saving credentials
Get-Credential | Export-CliXml -Path c:\credential.xml
#importing credentials to a variable
$Credential = Import-CliXml -Path c:\credential.xml
Or this:
#you could then write it to a file or, i say its a better approach to a registry key
$SecurePassword = ConvertTo-SecureString -String 'P#ssw0rd' -AsPlainText -Force | ConvertFrom-SecureString
#now you are taking it back as a secure string
$RegistrySecureString = $SecurePassword | ConvertTo-SecureString
#you can aslo see the password
$UserName = "NULL"
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $RegistrySecureString
$Password = $Credentials.GetNetworkCredential().Password
#P#ssw0rd

Add proxyAddresses to Active Directory users when created in PowerShell

I am trying to add users in Active Directory. Those users need to have proxyAddresses. My problem is that those proxyAddresses are multiples and stored in an array.
I try :
$proxyAddresses = #("address1#test.com", "address2#test.com", "address3#test.com")
$userInstance = new-object Microsoft.ActiveDirectory.Management.ADUser
$userInstance.ProxyAddresses = $proxyAddresses
New-ADUser test -Instance $userInstance
And I get this error :
Invalid type 'System.Management.Automation.PSObject'. Parameter name: proxyAddresses
I would like to add this proxyAddresses array to the attribute proxyAddresses of my AD user but it don't seem to be possible.
Any idea how this could be done?
Anything wrong with using Set-ADUser?
$username = '...'
$proxyAddresses = 'address1#example.com', 'address2#example.com', 'address3#example.com'
New-ADUser -Name $username
Set-ADUser -Identity $username -Add #{
'proxyAddresses' = $proxyAddresses | % { "smtp:$_" }
}
I just had this same issue and I was pretty sure I was passing in a string array (that's how it was declared).
Problem was just before I sent my string array into AD I was passing it to "Sort-Object -Unique" - which unbeknownst to me was changing either the type or something that made the cmdlet unhappy.
Just FYI...Sort-Object can burn you in these circumstances.
So, in my testing of this. I made Get-ProxyAddresses at https://gist.github.com/PsychoData/dd475c27f7db5ce982cd6160c74ee1d0
function Get-ProxyAddresses
{
Param(
[Parameter(Mandatory=$true)]
[string[]]$username,
[string[]]$domains = 'domain.com'
)
#Strip off any leading # signs people may have provided. We'll add these later
$domains = $domains.Replace('#','')
$ProxyAddresses = New-Object System.Collections.ArrayList
foreach ($uname in $username) {
foreach ($domain in $domains ) {
if ($ProxyAddresses.Count -lt 1) {
$ProxyAddresses.Add( "SMTP:$uname#$domain" ) | Out-Null
} else {
$ProxyAddresses.Add( "smtp:$uname#$domain" ) | Out-Null
}
}
}
return $ProxyAddresses
}
It just returns as a collection. Pretty kludgy, but works for what I need. It also assumes the first username and first domain are the "primary"
I combined that with #ansgar's answer and tried just -OtherAttributes on New-Aduser
$proxyAddresses = Get-ProxyAddress -username 'john.smith', 'james.smith' -domains 'domain.com','domain.net'
New-ADUser -Name $username
-OtherAttributes #{
'proxyAddresses'= $proxyAddresses
}
Works perfectly and added the proxyAddresses for me right at creation, without having to have a separate set action afterwards.
If you are Going to do separate actions, I would recommend to use -Server, like below, so that you don't run into talking to two different DCs by accident (and you also know that the New-ADUser is finished and already there, you don't have to wait for replication)
#I like making it all in one command, above, but this should work fine too.
$ADServer = (Get-ADDomainController).name
New-ADUser -Server $ADServer -name $Username
Set-ADUSer -Server $ADServer -Identity $username -Add #{
'proxyAddresses' = $proxyAddresses | % { "smtp:$_" }
}