3

I have a while($true) loop with a start-sleep -s 60 at the end of it. The purpose is to start an external PowerShell script as a different user which will run through a list of servers, check the event log for changes within the last minute and react accordingly.

Since my while loop (below) is using the -credential flag to run the script as someone else, I'm concerned about errors (e.g. account locked out, expired password, missing file, etc).

I tried an if ($error) statement, and changed the filename of the external script, but I was never alerted. I'm thinking it's because it never stops to re-check itself?

while($true) { 

    # Start the scan
    Start-Process powershell -Credential $credentials -ArgumentList '-noprofile -command & c:\batch\02-Scan.ps1'

    # Sleep 60 seconds
    start-sleep -s 60

}

I suppose I could change my scheduled task to run every minute, but so far this loop seems to have been working great. Just want to introduce error checking while the loop is active.

1
  • 1
    Try my favorite bit of PS arcanum: if(!$?) Commented Feb 11, 2013 at 18:31

2 Answers 2

3

Have you tried try/catch blocks? Wrong credentials is a terminating error, so the rest of the code in the try block won't run after a credentials-error. When you catch it, you can do whatever you want.. Ex.

try { 
    Start-Process powershell -Credential $credentials -ArgumentList '-noprofile -command & c:\batch\02-Scan.ps1'
} catch {
    #Catches terminating exceptions and display it's message
    Write-Error $_.message
}

If you want to catch all errors, add -ErrorAction Stopto the Start-Processline. As said, credentials should be a terminating error, which make the erroraction parameter unnecessary

EDIT Why would you use Start-Process to run a script in the first place? I switched it to Invoke-Command which runs a powershell script remotely. When the scriptfile is missing, you will recieve a NON-terminating error. Because it's a non-terminating error, we need to use the -ErrorAction Stop parameter. To catch the missing-file error and every other error(like credentials), use something like this:

try { Invoke-Command -ScriptBlock { & c:\batch\02-Scan.ps1 } -ErrorAction Stop
} catch {
    if ($_.Exception.GetType().Name -eq "CommandNotFoundException") {
        Write-Error "File is missing"
    } else {
        Write-Error "Something went wrong. Errormessage: $_"
        #or throw it directly:
        #throw $_
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

How would I catch things like missing file or other general errors? I assume a missing file would be a terminating error as well, so it should be caught without the -ErrorAction. I added the try/catch block to my script and changed the file name. I then set it to have it email me a notification. It never sent. I added the Write-Error $_.message and nothing came on-screen either. I'm just trying to debug if this is working.
Update: This does work if the account's password is invalid. How are we also able to catch a missing file? It's not perceiving an error when it's able to start-process powershell without issue. The error occurs in the secondary powershell window.
Thanks for the edit. That makes sense and I feel we're getting somewhere, but one step forward, one step back. Now able to catch the missing file, but adding -Credential $credentials now causes an error and never runs. Fails with a correct or incorrect credential, so I don't think it's getting that far yet. -- Parameter set cannot be resolved using the specified named parameters.
oh, are you running the need to run the script locally? Ahh, sorry. I thought you were going to run it remotely, which you actually should if the servers have Powershell. The problem with running start-process is that the errors are in a different session, and you need to handle them using the script in your command block.
0

Maybe?

while($true) { 

# Start the scan
try{
Start-Process powershell -Credential $credentials -ArgumentList '-noprofile -command & c:\batch\02-Scan.ps1' -ErrorAction Stop
}
  catch {
          send-alert
          break
          }

# Sleep 60 seconds
start-sleep -s 60
}

2 Comments

This works great for catching an invalid credential. Next question: would it also be possible to catch a missing filename? It's not perceiving an error when it's able to start-process powershell without issue.
Does it work better if you use the -file parameter, rather than command?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.