'Powershell Script - Re-Prompt Password Screen If PW is İncorrect
I have a script that will change all local administrator passwords with the below script. Script will prompt password for each server. (all servers have different passwords) I want to re-prompt the credential screen if user enters wrong password but I couldn't handle it.
$servers = Get-Content "C:\Users\Administrator\Desktop\Scripts\TestServers.txt"
foreach($server in $servers)
{
$pingtest = Test-Connection -ComputerName $server -Quiet -Count 1 -ErrorAction SilentlyContinue
if($pingtest)
{
Write-Host($server + " is online")
try
{
$ServerSessions = New-PSSession -ComputerName $server -Credential 'Administrator'
}catch [System.UnauthorizedAccessException]
{
Write-Host("Credential is incorrect! Try again")
$ServerSessions = New-PSSession -ComputerName $server -Credential 'Administrator'
}
Invoke-Command -Session $ServerSessions -ScriptBlock {
# Windows Server Versiyonunu check edip parolayı ona göre set etmek için
Get-ComputerInfo | select WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer
$Password = Read-Host -AsSecureString
$UserAccount = Get-LocalUser -Name "Administrator"
$UserAccount | Set-LocalUser -Password $Password
}
else
{
Write-Host($server + " is offline, nothing to do")
}
}
}
I got this error when running the script:
<IP_Address> is online
New-PSSession : [<IP_Address>] Connecting to remote server <IP_Address> failed with the following error message : Access is denied. For more information, see the
about_Remote_Troubleshooting Help topic.
At line:12 char:31
+ ... rSessions = New-PSSession -ComputerName $server -Credential 'Administ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : AccessDenied,PSSessionOpenFailed
Invoke-Command : Cannot validate argument on parameter 'Session'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At line:22 char:37
+ Invoke-Command -Session $ServerSessions -ScriptBlock {
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Invoke-Command], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.InvokeCommandCommand
else : The term 'else' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path
is correct and try again.
At line:30 char:9
+ else
+ ~~~~
+ CategoryInfo : ObjectNotFound: (else:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Write-Host($server + " is offline, nothing to do")
If I use correct password, the script works fine.
Update
Solution
Below method works but I couldn't be able to handle catch statement with catch [System.UnauthorizedAccessException]. Instead I used catch [Exception]. It is not a good solution but it works fine for me now.
$servers = Get-Content "C:\Users\Administrator\Desktop\Scripts\TestServers.txt"
foreach($server in $servers)
{
$pingtest = Test-Connection -ComputerName $server -Quiet -Count 1 -ErrorAction SilentlyContinue
if($pingtest)
{
Write-Host($server + " is online")
$Creds = Get-Credential 'Administrator'
do{
try
{
$ServerSessions = New-PSSession -ComputerName $server -Credential $Creds -ErrorAction Stop
Write-Host ("$ServerSessions")
}catch [Exception]
{
Write-Host("Credential is incorrect! Try again")
$Creds = Get-Credential 'Administrator'
}
}while(!$ServerSessions)
Invoke-Command -Session $ServerSessions -ScriptBlock {
# Windows Server Versiyonunu check edip parolayı ona göre set etmek için
Get-ComputerInfo | select WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer
$Password = Read-Host -AsSecureString
$UserAccount = Get-LocalUser -Name "Administrator"
$UserAccount | Set-LocalUser -Password $Password
}
}
else {
Write-Host($server + " is offline, nothing to do")
}
}
Solution 1:[1]
Try/catch doesn't work if it is not a stopping error, so add the -ErrorAction Stop parameter to your session, and then wrap that try/catch inside a Do/While loop based on if you have a session or not and get new creds in the Catch part.
$Creds = Get-Credentials 'Administrator'
Do{
try
{
$ServerSessions = New-PSSession -ComputerName $server -Credential $Creds -ErrorAction Stop
}catch [System.UnauthorizedAccessException]
{
Write-Host("Credential is incorrect! Try again")
$Creds = Get-Credentials 'Administrator'
}
}While(!$ServerSessions)
Solution 2:[2]
Your curly braces for the if statement were incorrect. This is why properly indenting your code is of importance.
To retry the authentication, use a while loop that will keep looping until a new session is established. For example:
$servers = Get-Content "C:\Users\Administrator\Desktop\Scripts\TestServers.txt"
foreach($server in $servers)
{
$pingtest = Test-Connection -ComputerName $server -Quiet -Count 1 -ErrorAction SilentlyContinue
if($pingtest)
{
Write-Host "$server is online"
while ($True) {
try
{
$Cred = Get-Credential -UserName 'Administrator'
$ServerSession = New-PSSession -ComputerName $server -Credential $Cred
break
}catch [System.UnauthorizedAccessException]
{
Write-Host "Credential is incorrect! Try again"
}
}
try {
Invoke-Command -Session $ServerSession -ScriptBlock {
# Windows Server Versiyonunu check edip parolay? ona göre set etmek için
Get-ComputerInfo | select WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer
$Password = Read-Host -AsSecureString
$UserAccount = Get-LocalUser -Name "Administrator"
$UserAccount | Set-LocalUser -Password $Password
}
finally {
Remove-PSSession $ServerSession
}
}
else {
Write-Host "$server is offline, nothing to do"
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | TheMadTechnician |
| Solution 2 |
