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.
CodePudding user response:
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)
CodePudding user response:
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
{
$ServerSessions = New-PSSession -ComputerName $server -Credential 'Administrator'
break
}catch [System.UnauthorizedAccessException]
{
Write-Host("Credential is incorrect! Try again")
}
}
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")
}
}