none
Error using Set-MsolUserPassword in powershell RRS feed

  • Question

  • I'm getting a frustrating error and it seems to be something potentially inside the Set-MsolUserPassword powershell module. I've got a CSV file with a UPN and password for users that I want to reset passwords in O365 for. I've got the following code to read through the CSV and then set the password and then email the user:

    Connect-EXOPSSession -UserPrincipalName test.email@email.com
    Connect-MsolService
    
    $userlist = Import-Csv "C:\PassReset.csv"
    
    ForEach ( $line in $userlist ) {
        $user = $line.UPN
        $pass = $line.PASS
        #$user = "test.email@email.com"
        #$pass = "testerson"
        $error = $FALSE
    
        Write-Host "Resetting password for '$user' to '$pass'."   
        Try {
            Set-MsolUserPassword -UserPrincipalName "$user" –NewPassword "$pass" -ForceChangePassword $TRUE -ea STOP
            #"Test change: $user $pass" | Out-File "test.log" -Append
        }
        Catch {
            $error = $TRUE
            $Err = $_.Exception.Message
            $Itm = $_.Exception.ItemName
            "$(Get-Date): Error occurred changing password for user '$user'. New password: '$pass'" | Out-File "passerrors.log" -Append
            "$(Get-Date): Item: $Itm" | Out-File "errors.log" -Append
            "$(Get-Date): Message: $Err`r" | Out-File "errors.log" -Append
        }
        Finally {
            IF(-NOT ($error ) ) {
                "$(Get-Date): Successfully changed password for user: $user" | Out-File "passsuccess.log" -Append
                Send-MailMessage -From no-reply@email.com -To $user -Subject "Subject" -Body "Really long thing with &" -SmtpServer smtp.email.com
            }
        }
    }

    With this code I get the following error:

        At C:\PassReset.ps1:30 char:105
        + ...  -To $user -Subject "Subject" -Body "Really long thing with &" -SmtpS ...
        +                                                                 ~
        The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double quotation marks ("&") to pass it as part of a string.
        
        At C:\PassReset.ps1:30 char:106
        + ... "Subject" -Body "Really long thing with &" -SmtpServer smtp.email.com
        +                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The string is missing the terminator: ".
        
        At C:\PassReset.ps1:15 char:6
        +     Try {
        +         ~ Missing closing '}' in statement block or type definition.
        
        At C:\PassReset.ps1:33 char:2
        + }
        +  ~ The Try statement is missing its Catch or Finally block.
        
        At C:\PassReset.ps1:6 char:32
        + ForEach ( $line in $userlist ) {
        +                                ~ Missing closing '}' in statement block or type definition.
            + CategoryInfo          : ParserError: (:) [], ParseException
            + FullyQualifiedErrorId : AmpersandNotAllowed

    The weird thing is if I comment out the line with the Set-MsolUserPassword for testing it doesn't trigger the error and the email gets sent successfully. It seems there's something with that particular command, which is basically the whole point of the script. I've confirmed I can run the command straight from the prompt, but in the ps1 file it immediately throws this error. Anyone else seen this?

    This feels like I'm missing something very simple...

    Tuesday, November 14, 2017 5:11 PM

Answers

  • Use notepad.  The issue is with your system or tools and not with PowerShell.  The proof is when you paste it, it works.  When in a file it fails.  You have to find out why you are creating bad files.  Perhaps you need to check your system.  The file should be ASCII and not various forms of Unicode.  Notepad++ is notorious fro creating bad files.

    You should also be able to paste my code into ISE and run it then save it and run it.  ISE should create a good file for reference.


    \_(ツ)_/

    • Marked as answer by KPuffer Tuesday, November 14, 2017 9:34 PM
    Tuesday, November 14, 2017 7:28 PM

All replies

  • Please read the error message:

    C:\PassReset.ps1:30 char:105
        + ...  -To $user -Subject "Subject" -Body "Really long thing with &" -SmtpS ...
        +                                                                 ~
        The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double quotation marks ("&") to pass it as part of a string.


    \_(ツ)_/

    Tuesday, November 14, 2017 5:42 PM
  • I understand that, but why when I comment out the Set-MsolUserPassword command does the script work unaltered? I'm confidant that the parameters I'm providing to that command are correctly formatted, but it seems there's an issue with that command. Wrapping the ampersand in double quotes just moves the position and nature of the error message. Also, simply removing the ampersand still gives an error.


    • Edited by KPuffer Tuesday, November 14, 2017 5:48 PM words are hard
    Tuesday, November 14, 2017 5:44 PM
  • #1 = you cannot use $error.  It is a system reserved variable.
    #2 - The following iss the correct way to structure an exception handler

    Connect-EXOPSSession -UserPrincipalName test.email@email.com
    Connect-MsolService
    
    $userlist = Import-Csv "C:\PassReset.csv"
    
    ForEach ($line in $userlist) {
        $user = $line.UPN
        $pass = $line.PASS
    
        Try {
            Write-Host "Resetting password for '$user' to '$pass'."
            Set-MsolUserPassword -UserPrincipalName $user –NewPassword $pass -ForceChangePassword $TRUE -ea STOP
            "$(Get-Date): Successfully changed password for user: $user" | Out-File "passsuccess.log" -Append
            Send-MailMessage -From no-reply@email.com -To $user -Subject "Subject" -Body "Really long thing with &" -SmtpServer smtp.email.com
        } 
        Catch {
            $Err = $_.Exception.Message
            $Itm = $_.Exception.ItemName
            "$(Get-Date): Error occurred changing password for user '$user'. New password: '$pass'" | Out-File "passerrors.log" -Append
            "$(Get-Date): Item: $Itm" | Out-File "errors.log" -Append
            "$(Get-Date): Message: $Err" | Out-File "errors.log" -Append
        }
    }



    \_(ツ)_/


    • Edited by jrv Tuesday, November 14, 2017 5:55 PM
    Tuesday, November 14, 2017 5:54 PM
  • Thanks for the information on the error handling. I do appreciate the your help in bouncing ideas back and forth.

    Still getting the same message though. Again, I can remove the ampersand in the -Body text of the Send-MailMessage command, it gives me a different error saying I have a missing double quote terminator after the -SmtpServer parameter. Literally, if I comment out the Set-MsolUserPassword line (which I believe is formatted correctly according to all documentation that I've read) everything works as expected. This is what leads me to something in that command/module being broken.

    • Edited by KPuffer Tuesday, November 14, 2017 6:05 PM
    Tuesday, November 14, 2017 6:05 PM
  • Did you use my version of the code?  The missing quote is a clue that you are over-quoting.

    Run this version. If you still have an issue then it is likely that your CSV is broken.

    Connect-EXOPSSession -UserPrincipalName test.email@email.com
    Connect-MsolService
    
    $userlist = Import-Csv C:\PassReset.csv
    
    ForEach ($line in $userlist) {
        $user = $line.UPN
        $pass = $line.PASS
    
        Try {
            Set-MsolUserPassword -UserPrincipalName $user –NewPassword $pass -ForceChangePassword $true -ea Stop
            Send-MailMessage -From no-reply@email.com -To $user -Subject Subject -Body 'Really long thing with' -SmtpServer smtp.email.com
        } 
        Catch {
            Throw $_
        }
    }


    \_(ツ)_/


    • Edited by jrv Tuesday, November 14, 2017 6:23 PM
    Tuesday, November 14, 2017 6:22 PM
  • Add the following line to the top of the catch block:

            Write-Host User $pass -Fore green


    \_(ツ)_/

    Tuesday, November 14, 2017 6:26 PM
  • Throws this error:

    At C:\tester.ps1:11 char:57
    + ... alName $user –NewPassword $pass -ForceChangePassword $true -ea Stop
    +                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The string is missing the terminator: ".

    At C:\tester.ps1:10 char:9
    +     Try {
    +         ~
    Missing closing '}' in statement block or type definition.

    At C:\tester.ps1:17 char:2
    + }
    +  ~
    The Try statement is missing its Catch or Finally block.

    At C:\tester.ps1:6 char:30
    + ForEach ($line in $userlist) {
    +                              ~
    Missing closing '}' in statement block or type definition.
        + CategoryInfo          : ParserError: (:) [], ParseException
        + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

    My passwords are complex, so I've also attempted another method where the password is generated within the script. This way the CSV file just contains the UPN:

    Connect-EXOPSSession -UserPrincipalName tester@email.com
    Connect-MsolService
    
    $userlist = Import-Csv "C:\PassReset.csv"
    $userdata = @()
    
    $userlist.UPN | ForEach-Object {
    	#$user = $_
    	$user = "tester@email.com"
    	$objProperties = New-Object PSObject
    	$pass = ""
    	$pass += ([char[]]"ABCDEFGHIJKLMNOPQRSTUVWXYZ" | Get-Random)
    	$pass += $(1..3 | % { [char[]]"abcdefghijklmnopqrstuvwxyz" | Get-Random }) -join ""
    	$pass += $(1..4 | % { [char[]]"0123456789" | Get-Random }) -join ""
    
    	Write-Host "Resetting password for '$user' to '$pass'."
    	
    	Try {
    		Set-MsolUserPassword -UserPrincipalName "$user" –NewPassword "$pass" -ForceChangePassword $TRUE -ea STOP
    		#"Test change: $user $pass" | Out-File "test.log" -Append
    		Add-Member -InputObject $objProperties -MemberType NoteProperty -Name "UPN" -Value $user
    		Add-Member -InputObject $objProperties -MemberType NoteProperty -Name "Pass" -Value $pass
    		$userdata += $objProperties
    		"$(Get-Date): Successfully changed password for user '$user' to '$pass'" | Out-File "passsuccess.log" -Append
    		$body = "Really long string with &"
    		Send-MailMessage -From no-reply@email.com -To $user -Subject "Test Subject" -Body $body -SmtpServer smtp.email.com
    	}
    	Catch {
    		$error = $TRUE
    		$Err = $_.Exception.Message
    		$Itm = $_.Exception.ItemName
    		"$(Get-Date): Error occurred changing password for user '$user'. New password: '$pass'" | Out-File "passerrors.log" -Append
    		"$(Get-Date): Item: $Itm" | Out-File "errors.log" -Append
    		"$(Get-Date): Message: $Err`r" | Out-File "errors.log" -Append
    	}
    }
    $userdata
    $userdata | Export-Csv -Path "C:\PassList.csv" -NoTypeInformation

    I get a similar error:

    At C:\PassReset.ps1:38 char:88
    + ... \PassList.csv" -NoTypeInformation
    +                                                      ~~~~~~~~~~~~~~~~~~~~
    The string is missing the terminator: ".

    At C:\PassReset.ps1:18 char:6
    +     Try {
    +         ~
    Missing closing '}' in statement block or type definition.

    At C:\PassReset.ps1:38 char:108
    + ... \PassList.csv" -NoTypeInformation
    +                                                                          ~
    The Try statement is missing its Catch or Finally block.

    At C:\PassReset.ps1:7 char:32
    + $userlist.UPN | ForEach-Object {
    +                                ~
    Missing closing '}' in statement block or type definition.
        + CategoryInfo          : ParserError: (:) [], ParseException
        + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

    Again, if I simply comment out the Set-MsolUserPassword line and uncomment the following line it runs. It won't even pass the compilation process with the Set-MsolUserPassword even though it passes in Visual Studio Code.


    • Edited by KPuffer Tuesday, November 14, 2017 6:38 PM more details
    Tuesday, November 14, 2017 6:36 PM
  • Please use my code.  It is clear that your CSV is trashed or you PS1 is trashed.  Copy and paste my code at a CLI window and see what happens.


    \_(ツ)_/

    Tuesday, November 14, 2017 6:47 PM
  • Okay, so I've pasted your minimized code into the CLI and it'll run through just fine. Obviously I'm canceling the prompts that come up from O365 as well as changing the path to my CSV file and it seems to run through. If I paste that code into a ps1 file I get the same errors. One thing is that I've got a space in the path of the CSV file, so I'm enclosing it within double quotes.

    At C:\tester.ps1:11 char:57
    + ... alName $user –NewPassword $pass -ForceChangePassword $true -ea Stop
    +                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The string is missing the terminator: ".
    
    At C:\tester.ps1:10 char:9
    +     Try {
    +         ~
    Missing closing '}' in statement block or type definition.
    
    At C:\tester.ps1:17 char:2
    + }
    +  ~
    The Try statement is missing its Catch or Finally block.
    
    At C:\tester.ps1:6 char:30
    + ForEach ($line in $userlist) {
    +                              ~
    Missing closing '}' in statement block or type definition.
        + CategoryInfo          : ParserError: (:) [], ParseException
        + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

    FYI: I've tried both Notepad++ with Window EOL as well as Visual Studio Code to edit the ps1 files.


    • Edited by KPuffer Tuesday, November 14, 2017 7:23 PM added details
    Tuesday, November 14, 2017 7:22 PM
  • Use notepad.  The issue is with your system or tools and not with PowerShell.  The proof is when you paste it, it works.  When in a file it fails.  You have to find out why you are creating bad files.  Perhaps you need to check your system.  The file should be ASCII and not various forms of Unicode.  Notepad++ is notorious fro creating bad files.

    You should also be able to paste my code into ISE and run it then save it and run it.  ISE should create a good file for reference.


    \_(ツ)_/

    • Marked as answer by KPuffer Tuesday, November 14, 2017 9:34 PM
    Tuesday, November 14, 2017 7:28 PM
  • Wow! That was exactly it. Lesson learned. Thank you again for hanging on with me and helping me out.

    Cheers to you mate!!

    Tuesday, November 14, 2017 8:30 PM
  • ??? Notepad++?


    \_(ツ)_/

    Tuesday, November 14, 2017 8:30 PM
  • Yes, that was it. Even though I was even editing it in Visual Studio Code there must have been residual hidden characters that it wasn't removing. Switched to Notepad, made a few changes and then saved and runs like a champ.

    Cheers

    Tuesday, November 14, 2017 8:33 PM
  • You may need to upgrade or re-install VSCode.  I have no issues with it.

    \_(ツ)_/

    Tuesday, November 14, 2017 8:35 PM
  • I am using the most recent version 1.18.0. I installed it as I came across this particular issue to ensure I hadn't missed some silly formatting issue. I'll give it a go at reinstalling and see if that helps.

    Again. Thank you very much for the help. Encoding is something I hadn't even thought of. 

    Tuesday, November 14, 2017 8:38 PM
  • Did you install the PowerShell support in VSCode?


    \_(ツ)_/

    Tuesday, November 14, 2017 10:07 PM
  • I did install that. It prompted me from within Visual Studio Code.
    Tuesday, November 14, 2017 10:10 PM