Fail a Scheduled Task When PS Script Fails - powershell

I run a PowerShell script using Task Scheduler and my issue is that when that script fails, the scheduled Task does not fail and therefore I do not get notified.
So when I run this script on PowerShell:
Add-PsSnapIn VeeamPSSnapIn
$Job = Get-VBRJOB -name "Whatever"
Start-VBRJOB -job $Job
I get the following exception:
However, when I run it using a scheduled task, the task does not fail.
How can I get it to fail when the script fails?
Reason I want it to fail is because when it fails, I get notified by Email. If you have any other way of doing it, like logging an event that can trigger the alert, this would be good too.
I'm using Windows Server 2008 R2.
Thanks,

Do you try to put you code into a try/catch statement ?
try
{
Add-PsSnapIn VeeamPSSnapIn
$Job = Get-VBRJOB -name "Whatever"
Start-VBRJOB -job $Job
$returnCode = 0
}
catch
{
$message = $_.exception.message
$returnCode = 1
}
return $returnCode
In my case I directly send email from the script with the message.

I ended up doing this
Add-PsSnapIn VeeamPSSnapIn
$Job = Get-VBRJOB -name "Type the job name here"
$error.clear() #To make sure I'm checking next statement only
Start-VBRJOB -job $Job
if ($error.count -gt 0)
{
Write-EventLog –LogName Application –Source “My Company” –EntryType Error –EventID 1 –Message “Whatever Message You Want"
}
Then I used Task Scheduler to send Emails when Error 1 from source "My Company" is logged.
Note: You need to create the events source "My Company" using this command on PowerShell:
New-EventLog –LogName Application –Source “My Company”
Hope this helps someone.
Ahmad

Related

Powershell wait-job gives error one or more jobs are blocked waiting for user interaction

I have below command, $a have 20 URLs:
$a = #('http://10.10.10.101/Login.aspx',
'http://10.10.10.101/user/customers')
$startFulltime = (Get-Date)
foreach($a1 in $a){
start-job -ArgumentList $a1 -ScriptBlock{
param($a1)
Invoke-WebRequest $a1 -Method post -DisableKeepAlive -UseBasicParsing
-ArgumentList $a1
}}
Get-Job | Wait-Job
Getting Below Errors:
Wait-Job : The Wait-Job cmdlet cannot finish working, because one or more jobs are blocked waiting for user interaction. Process interactive job
output by using the Receive-Job cmdlet, and then try again.
At line:13 char:11
+ Get-Job | Wait-Job
+ ~~~~~~~~
+ CategoryInfo : Deadlock detected: (System.Manageme...n.PSRemotingJob:PSRemotingJob) [Wait-Job], ArgumentException
+ FullyQualifiedErrorId : BlockedJobsDeadlockWithWaitJob,Microsoft.PowerShell.Commands.WaitJobCommand
Reference Link : input objects in powershell jobs
Please help me to resolve error, thanks In Advance!!
The only obvious problem with your code - which may be a posting artifact - is that there's a second, extraneous -ArgumentList $a1 inside your Start-Job script block - but that would cause a different error, though potentially preempted by the one you're getting.
It sounds like one of your jobs unexpectedly prompts for user input, as implied by the error message.
Use of Receive-Job, as suggested in the error message, will bring interactive prompts to the foreground, allowing you to see and respond to them.
This should help you diagnose which job causes the problem and why; here's a simplified example:
# Start a job with a command that asks the user for interactive input
# (which isn't a good idea).
$job = Start-Job { Read-Host 'Enter something' }
# !! Error, because the job is waiting for interactive user input.
$job | Wait-Job
# OK - Receive-Job "foregrounds" the Read-Host prompt.
# Once you respond to it, the job finishes
# (and is automatically removed here, thanks to -Wait -AutoRemoveJob).
$job | Receive-Job -Wait -AutoRemoveJob

How do you log the results of remotely invoked commands on the system running the PowerShell session?

I have a script that loops through a list of my servers, and runs various commands on them.
I am attempting to log the commands and their results for both the computer running the PowerShell script, and the remote computer running the commands.
Right now, I am trying to use the PSLogging module with the Start-Log cmdlet. I am able to log the commands run on the system running the Powershell script, but things run on the remote computer are not showing up.
My code looks like this.
Import-Module -Name "C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PSLogging\2.5.2\PSLogging.psm1"
$Date = Get-Date -Format "MM-dd-yyyy hh-mm tt"
$LogFileOutput = "Output Log"+" $Date"+".log"
$LogFilePlusPath = "\\files\Logs\"+"$LogFileOutput"
Start-Log -LogPath "\\files\Logs\" -LogName "LogFileOutput" -ScriptVersion "1.0"
Servers = #("Server1","Server2")
ForEach ($Server in $Servers)
{
Write-Host "Running script on $Server"
param([string]$Server)
Invoke-Command -Computer $Server -ScriptBlock {
Write-Host "Stopping IIS App Pool on $Server."
c:\windows\system32\inetsrv\appcmd.exe stop apppool "IISAppPool"
Write-Host "Switching Service to manual on $Server and stopping it."
Stop-Service Service -Force
Set-Service Service-StartupType Manual
} -args $Server
}
Write-Host "Script complete at $(Get-Date -Format "hh:mm tt MM/dd/yyyy") Logs available at \\files\Logs"
Stop-Log
The script works, and the services and App pools perform their operation as desired. The results just aren't being logged.
The only thing in the log would be:
Running script on Server1
Running script on Server2
Script complete at 12:20 PM 09/19/2020 Logs available at \files\Logs
Any suggestions on the best way to capture everything?
Thank you!

powershell loop for periodical checking running process

I'm trying to create a PowerShell script (loop) for periodical checking if some other PowerShell script with specific command is running. If not I start it.
This is what I have:
$processInfo = Get-WmiObject Win32_Process -Filter "name = 'powershell.exe'" | select CommandLine | Out-String -width 200
while($true) {
if ($processInfo -NotLike '*specific_path*') {
Write-Host 'process not running'
Start-Process powershell -argument '-f X:\specific_path\other_script.ps1'
}
else { Write-Host 'process is running' }
Start-Sleep -Seconds 60
}
The script correctly detects running or not running process when started. but when situation changes during the script run, it does not detect it.
Also, when script starts, detects that the other script is not running, it starts it correctly but then it does not see it already running and starts it again and again.
So the only problem I have (I believe) is how to get "fresh" data about running processes. Any ideas? Many thanks!

Task Scheduling and Powershell's Start-Job

Currently, I try to run a PowerShell-Script, which starts a few instances with Start-Job -name $jobname -Scriptblock { ... Code ...};
This PowerShell-Script should be executed every 15 minutes in the WIndows Task Schedule. I run this process with highest priviledges, and the Power-Shell-Script starts perfectly - the problem is:
The Code, which is executed by Start-Job doesn't work.
I think the problem is that the "Start-Job" can not work with the task schedule together.
Do you know how to solve that? Are there any settings to configure?
Thank you, SUT
If no any control at the end of script, Powershell will immediately exit once background job is created. So try to add below control code:
$runningJobs = Get-Job -State Running
while($runningJobs.Count -gt 0){
Start-Sleep -Seconds 1
$runningJobs = Get-Job -State Running
}
Write-Host "Done!" -ForegroundColor Red -BackgroundColor Black

Clean session on user interupt

Is there a way to catch when the user interrupt the powershell script.
I need to exit a PSSession.
I have test using a try finally but the finally is not executed when the script is interupted Ctrl+c
try
{
$s = New-PSSession -ComputerName MYCOMPUTER -Credential (Get-Credential -Credential admin )
Invoke-Command -ScriptBlock { Get-EventLog -LogName Application } -Session $s
}
catch [Exception]
{
}
finally
{
echo "Ending the session"
Remove-PSSession $s
}
As far as I know it does not exist a script that is run when PowerShell ends. But you can have a look to System.Management.Automation.PsEngineEvent class which provides the events you can subscribe to with Register-EngineEvent CmdLet.
So run a PowerShell command line and execute :
Register-EngineEvent -SourceIdentifier ([System.Management.Automation.PsEngineEvent]::Exiting) -Action {[console]::Beep()}
Then close the PowerShell Command line (exit or click on the upper right corner) and you will ear something. Be carefull if the PowerShell process is killed (using task manager for example) the event is not fired.