1
votes

excuse me for my rusty understanding of programming, hoping someone could take a glance at this and see where my mistake is. I'm having issues trying to mass reset passwords within a test 2008 R2 domain using Powershell. I imported the AD module into Powershell. I have a .csv file containing the sAMAccountName (ADUC usernames) and I import that into powershell by assigning object $UserFile = "c:\2019StudentsB115.csv". Then I am using a foreach loop to go through and reset the passwords on each account but this is where it always seems to fail.

I tried adding the password to the .csv file as a 2nd column and that didn't work. Then I removed the 2nd column and removed the corresponding code for the passwords. I tried using ConvertTo-SecureString to give the generic password "Qwerty10" to all of these accounts. These accounts are all getting 1 generic password and I do not want the user to have to reset it upon first login. I thought I could use a foreach loop to easily do this but I get errors no matter what I do.

The code I've tried is as follows:

Attempt 1: Endless loop of error "Cannot bind argument to String because it is null"


foreach ($Account in $Resetpassword) {
    $Account.sAMAccountName
    $Account.Password
        Set-ADAccountPassword -Identity $Account.sAMAccountName -NewPassword (ConvertTo-SecureString $Account.Password -AsPlainText "Qwerty10" -force) -Reset
}

Attempt 2: Error "Cannot validate argument on parameter 'Identity'. The argument is null." lime:3 char:40

$UserFile = "c:\2019StudentsB115.csv"


foreach ($Account in $Resetpassword) {
    $Account.sAMAccountName
        Set-ADAccountPassword -Identity $Account.sAMAccountName -NewPassword (ConvertTo-SecureString "Qwerty19" -AsPlainText -force) -Reset
}

I thought maybe it was my syntax using Set-AdAccountPassword but then I tried this and it worked fine: Set-AdAccountPassword -Identity "math1-1" -NewPassword (ConvertTo-SecureString -AsPlainText "Qwerty10" -force)

I'm passing the identity Math1-1 and the password Qwerty10 as a new password to this cmdlet and it works, so why can't I pass this using the .csv file? Any tips or pointers would be appreciated. I have about 20 tabs open from Googling this and nothing is really helping. I reviewed the syntax for Get/set ADAddcount and ConvertTo-SecureString but that isn't really helping me figure out how to assign objects from this .csv file.

Alex

I tried running:

foreach ($Account in $Resetpassword) {
        Set-ADAccountPassword  $Account -NewPassword (ConvertTo-SecureString -AsPlainText "Qwerty19" -force) -Reset
}

Results of 1 of the accounts:

Set-ADAccountPassword : Cannot bind parameter 'Identity'. Cannot convert the "@{sAMAccountName=math5-3}" value of type "System.Management.Automation.PSCustomObject" to type "Microsoft.ActiveDirectory.Management.ADAccount". At line:2 char:30 + Set-ADAccountPassword <<<< $Account -NewPassword (ConvertTo-SecureString -AsPlainText "Qwerty19" -force) -Re set + CategoryInfo : InvalidArgument: (:) [Set-ADAccountPassword], ParameterBindingException + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.ActiveDirectory.Management.Commands.SetADAccoun tPassword

1
Your foreach loop contains $account.SamAccountName . Does this bring back the username you're expecting to see? Identity eq $null means that's the missing bitGraham Jordan
If your CSV contains just account names, drop ...Samaccount name and just use $account. like foreach ( $account in $resetpasswords ) { Set-adAccountPassword $account -NewPassword (ConvertTo-SecureString -AsPlainText "Qwerty10" -force) -Reset }Graham Jordan
Thank you for that suggestion, I tried it out. Once I removed the SamAccountName parts it gave a new error but seems to now be going through the .csv file. The error is "Cannot bind parameter "Identity". Cannot convert the "@(sAMAccountName=USERNAME)" value of type "System.Management.Automation.PSCustomObject" To type "Microsoft.ActiveDirectory.Management.Commands.SetADAccountPassword" If I read this error right I can't convert the AD username to the custom object that I have created in this script?Alexandra McFarland
I was also thinking maybe I am not properly using the -Identity in Set-AdAccountPasswordAlexandra McFarland
God knows. Any chance you can edit your post to include the results of this? $resetpassword[1]. Feel free to change anything identifiable, it's the variable names I'm looking for.Graham Jordan

1 Answers

1
votes

Example 1 (CSV File Contains Header SamAccountName):

Let's assume that 2019StudentsB115.csv contains the following:

SamAccountName
Math9-9
Math1-1
User3

The following code should work:

$Accounts = Import-Csv "c:\2019StudentsB115.csv"
foreach ($Account in $Accounts) {
    Set-ADAccountPassword -Identity $Account.SamAccountName -NewPassword (ConvertTo-SecureString "Qwerty19" -AsPlainText -force) -Reset
}

Example 2 (CSV File Contains No Headers):

If your CSV file does not contain headers and you do not want to use headers, then do not use Import-Csv. Get-Content works well for a text file with single values on each line. Let's assume 2019StudentsB115.csv contains the following:

Math9-9
Math1-1
User3

Here the CSV file contains no header. Now we can skip using Import-Csv for simplistic purposes. The code becomes the following and notice how the .SamAccountName property is no longer needed.

$Accounts = Get-Content "c:\2019StudentsB115.csv"
foreach ($Account in $Accounts) {
    Set-ADAccountPassword -Identity $Account -NewPassword (ConvertTo-SecureString "Qwerty19" -AsPlainText -force) -Reset
}

Explanation:

If you have a file that you read with Import-Csv, it will assume the very first row contains headers rather than values. The exception to this is if you use the -Header switch, which will automatically create a headers for you and consider the file contents to be all values.

When Import-Csv is used, the resulting object is an array of objects where each object contains a property for each header. In PowerShell to retrieve the value of a single property, you need to access that property directly. One such way is to use the syntax object.property. If you access the property from an object array, it will return the value of that property for every object in the array. That's where the foreach loop helps because it will iterate over every object in the array. In my example, $Accounts is the object array. $Account is the current iterated object, which has the property SamAccountName because of how the CSV file is constructed. The good thing about Import-Csv is that you can have many columns and headers in your file and you can choose to ignore or select ones that are useful.