Error handling of command prompt commands in Powershell

Related searches

My goal is to check, disable and remove Scheduled Tasks on numerous Windows servers using Powershell. Some of the servers are Windows 2008R2, so Get-ScheduledTask is out of question. I have to use schtasks

Here is what I have thus far

$servers = (Get-ADComputer -Server DomainController -Filter 'OperatingSystem -like "*Server*"').DNSHostname

$servers |
    ForEach-Object {
        if (Test-Connection -Count 1 -Quiet -ComputerName  $_) {
            Write-Output "$($_) exists, checking for Scheduled Task"
            Invoke-Command -ComputerName $_ {
                    If((schtasks /query /TN 'SOMETASK')) {
                        Write-Output "Processing removal of scheduled task`n"
                        schtasks /change /TN 'SOMETASK' /DISABLE
                        schtasks /delete /TN 'SOMETASK' /F
                    }
                    else {
                        Write-Output "Scheduled Task does not exist`n"
                    }
            }
        }
    }

This works fine for when SOMETASK exists but when it doesn't, Powershell spits an error, like this:

ERROR: The system cannot find the file specified.
    + CategoryInfo          : NotSpecified: (ERROR: The syst...file specified.:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
    + PSComputerName        : SERVER1

NotSpecified: (:) [], RemoteException
Scheduled Task does not exist

I can circumvent this behavior by setting $ErrorActionPreference to "SilentlyContinue" but this suppresses other errors I may be interested in. I also tried Try, Catch but that still generates the error. I don't think I can add -ErrorHandling argument to an IF statement. Can anyone please lend a helping hand?

Thank you,

Handle PowerShell Errors Like a Boss With These Tips, This is where PowerShell's error handling comes in handy. If you are modifying an existing script, you append it to the end of the cmdlet line. your cmdlet hits a snag, it gives options: Yes, Yes For All, Halt Command, Suspend, or Help. Here are the steps to putting this in place: Set the ErrorAction parameter to Stop for any command that needs Error Handling. This will stop executing the command The command that has an ErrorAction parameter set to value Stop is then wrapped in a Try { } block. When an Error In the Catch { }

Personally I prefer to use the Scheduler ComObject to manage scheduled tasks. You can connect to other servers with it, and search them simply enough to manage their tasks.

$Scheduler = New-Object -ComObject Schedule.Service

$servers = (Get-ADComputer -Server DomainController -Filter 'OperatingSystem -like "*Server*"').DNSHostname

$servers |
    ForEach-Object {
        if (Test-Connection -Count 1 -Quiet -ComputerName  $_) {
            Write-Output "$($_) exists, checking for Scheduled Task"
            $Scheduler.Connect($_)
            $RootFolder = $Scheduler.GetFolder("\")
            $TargetTask = $RootFolder.GetTask('SOMETASK')
            # If the task wasn't found continue to the next server
            If(!$TargetTask){
                Write-Output "Scheduled Task does not exist`n"
                Continue
            }
            Write-Output "Processing removal of scheduled task`n"
            $TargetTask.Enabled = $false
            $RootFolder.DeleteTask('SOMETASK')
        }
    }

PowerShell: Getting Started, It looks like the line property contains the full command we used when Terminating errors in PowerShell mean that the script can no longer� Normally, if you run a Windows PowerShell command and an error occurs, the error record will be appended to the “automatic variable” named $error. When you use the -ErrorVariable parameter in a call to a command, the error is assigned to the variable name that you specify.

This appears like you've way over-complicated execution of this effort.

Why disable and remove vs just remove, as that seems a bit redundant?

All scheduled tasks are nothing but xml files and reg entries, that you can just delete if you don't want the task any longer. Thus, you can use sue Get-ChildItem.

# File system:
(Get-ChildItem -Path "$env:windir\System32\Tasks").FullName

# Results
<#
...
C:\Windows\System32\Tasks\Microsoft
...
C:\Windows\System32\Tasks\MicrosoftEdgeUpdateTaskMachineCore
...
#>

# Registry:
Get-ChildItem -Path 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Schedule\Taskcache\Tasks'
# Results
<#
Name                           Property                                                                                                                             
----                           --------                                                                                                                             
{01C5B377-A7EB-4FF3-9C6C-86852 Path               : \Microsoft\Windows\Management\Provisioning\Logon                                                                
...                                                                                                       
#>

Get-ChildItem -Path 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Schedule\Taskcache\Tree'
# Results
<#
Name                           Property                                                                                                                             
----                           --------                                                                                                                             
Adobe Acrobat Update Task      SD    : {1...
#>

Just select your task by name and delete the file and the regkeys using the normal filesystem cmdlets.

Using Azure CLI with PowerShell: error handling explained, Azure Pipelines has a task for using the Azure CLI, but this only has the options to use the command line (.cmd or .com files), or from bash (.sh). I� This command changes a non-terminating error into a terminating one, so you can handle it. Building a try-catch block Once you have a terminating error or have converted a non-terminating one to a terminating error, you can handle it using PowerShell try-catch block. The generic syntax is:

So you just want to hide the error message from schtasks? One way is to redirect standard error or "2" to $null. This is an example anyone can run as admin. The if statement only works because there's no output to standard out when there's an error. It looks like invoke-command generates a remote exception when something comes over standard error, but it doesn't stop the commands that follow. I don't see a way to try/catch it.

invoke-command localhost { if (schtasks /query /tn 'foo' 2>$null) {
  'yes' } ; 'hi'}

hi

Handling Errors the PowerShell Way, The -ErrorAction common parameter allows you to specify which action to take if a command fails. The available options are: Stop, Continue, SilentlyContinue, Ignore, or Inquire. If you're developing a Windows PowerShell workflow, you can also use the Suspend value. However, advanced functions cannot be suspended. If you press “Yes/Yes to All” then error output will be displayed and “Halt Command/Suspend” will not display an error. Suspend − This value is used in the PowerShell workflow to suspend workflow for investigation purposes and then resume.

Powershell error handling when using DOS command mixed in, My shutdown script using the Shutdown -R command to do a mass reboot of machines. If the Shutdown -R throws a error like "RPC Service� PowerShell: Command Prompt: PowerShell was introduced in the year 2006. cmd was introduced in the year 1981. It can be opened from run by typing PowerShell. It can be opened from run by typing cmd. It can operate with both batch commands and PowerShell cmdlets. It can work only with Batch commands.

Command Prompt commands are equivalent in PowerShell Many common Command Prompt commands such as ipconfig to cd can be executed in PowerShell environment. This is because PowerShell contains "alias" that can execute old commands with the appropriate cmdlet commands, run new cmdelt commands when typing the old command.

If the error cannot be handled, the error is written to the error stream. A Catch block can include commands for tracking the error or for recovering the expected flow of the script. A Catch block can specify which error types it catches. A Try statement can include multiple Catch blocks for different kinds of errors.

Comments
  • Thank you very much! I will definitely try this instead of relying on schtasks.exe. Is this limited to a particular Powershell version?
  • Not that I know of, I've used it on Server 2008R2 and up without issues.
  • You are right, I was disabling the task for no apparent reason. I think the reason was, when you work with GPOs, sometimes, depending on an OS, the task will not delete unless it is disabled (as in not running at a given time). But this is GPOs and most likely have nothing to do with this particular case.