¿Cómo puedo deshabilitar una tarea programada con Powershell?

8

Tengo una aplicación web que se ejecuta en Windows Server 2008 R2, que tiene una gran cantidad de tareas programadas que se encargan de todo el backend. Cuando realizo una implementación de software que toca la base de datos, necesito deshabilitar todas las tareas programadas. Actualmente tengo una larga lista de verificación que necesito revisar manualmente, deshabilitando cada tarea programada a medida que avanzo; seguramente este es un trabajo maduro para la automatización con Powershell.

Desafortunadamente, la documentación de Powershell parece ser bastante tímida sobre cómo deshabilita una tarea programada existente (y, por supuesto, vuelve a habilitarla una vez que la versión se haya completado con éxito). Puedo obtener una lista de tareas listas, en ejecución o deshabilitadas, pero ¿qué sigue?

David Keaveny
fuente

Respuestas:

14

Puede usar los objetos de secuencias de comandos del Programador de tareas basados ​​en COM :

($TaskScheduler = New-Object -ComObject Schedule.Service).Connect("localhost")
$MyTask = $TaskScheduler.GetFolder('\').GetTask("My Task")
$MyTask.Enabled = $false

Para habilitar la tarea nuevamente:

$MyTask.Enabled = $true

Lo anterior solo funcionará si el shell está elevado y usted es un administrador local en el servidor. Puede crear su propio cmdlet con lo anterior:

function Disable-ScheduledTask
{
    param([string]$TaskName,
          [string]$ComputerName = "localhost"
         )

    $TaskScheduler = New-Object -ComObject Schedule.Service
    $TaskScheduler.Connect($ComputerName)
    $TaskRootFolder = $TaskScheduler.GetFolder('\')
    $Task = $TaskRootFolder.GetTask($TaskName)
    if(-not $?)
    {
        Write-Error "Task $TaskName not found on $ComputerName"
        return
    }
    $Task.Enabled = $False
}
Mathias R. Jessen
fuente
2
Nota: esto no parece funcionar para tareas creadas con at.exe. (Ejemplo: AT 09:00 /every:SUNDAY shutdown.exe /r /f /d p:4:1 /c "Reboot via SchTask (AT Job)"). El error que obtendrá es 0x80041327; La tarea tiene propiedades que no son compatibles con versiones anteriores de Windows
Signal15
5

Si solo está tratando de detener TODAS las tareas, puede ser más fácil simplemente detener el servicio del Programador de tareas. El módulo ScheduledTasks no estará disponible hasta Windows Server 2012, por lo que administrar tareas no es tan sencillo como detener e iniciar un servicio:

Stop-Service Schedule
Start-Service Schedule

Si eso no funciona para usted, schtasks.exe aún puede usarse desde PowerShell para administrar tareas individuales:

schtasks.exe /CHANGE /TN "My Task" /DISABLE
schtasks.exe /CHANGE /TN "My Task" /ENABLE
Tim Ferrill
fuente
1
Desde 2008 / Vista en adelante, Windows usa el Programador de tareas en gran medida para una amplia variedad de tareas del sistema. Dependiendo de la duración, detener el servicio del Programador de tareas podría no ser una gran idea (aunque es fácil).
Mathias R. Jessen
Por supuesto. El caso de uso dado fue para deshabilitar las tareas durante el mantenimiento, por lo que podría ser una opción viable. También dio la segunda opción en caso de que no satisficiera la necesidad.
Tim Ferrill
3

Incluso una mejor manera en la que no necesita especificar los nombres de las tareas:

($TaskScheduler = New-Object -ComObject Schedule.Service).Connect("localhost")
$TaskScheduler.GetFolder('\').GetTasks(0) | % {$_.Enabled = $false}
Dimitry
fuente
0

¡Esto es perfecto! Funciona mejor que Get-ScheduledTask ya que estoy en un entorno mixto 2008/2012. Agregué algunas líneas para consultar AD e invocar este comando contra un grupo de computadoras. Mi objetivo era deshabilitar la tarea de abrir "Administrador del servidor" cada vez que un usuario inicia sesión. ¡Presto! todo se fue!

$C=Get-ADComputer -SearchBase 'OU=Computers,dc=domain,dc=com' -Filter * | foreach {$_.name}

Invoke-Command $C {
($TaskScheduler = New-Object -ComObject Schedule.Service).Connect("$C")
$TaskScheduler.GetFolder('\Microsoft\Windows\Folder').GetTasks(0) | % {$_.Enabled = $false}
}
hans57sauc
fuente
0

Mira esta función

Function Control-Tasks
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true)][String]$FolderPath,
        [Parameter(Mandatory=$true, ParameterSetname='EnableTask')][Switch]$Enable,
        [Parameter(Mandatory=$true, ParameterSetname='DisableTask')][Switch]$Disable,
        [Parameter()]$TaskScheduler,
        [Parameter()][Switch]$Recursive
    )

    If ($TaskScheduler -eq $null) {
        $TaskScheduler = New-Object -ComObject Schedule.Service
        $TaskScheduler.Connect("localhost")
    }

    $curFolder = $TaskScheduler.GetFolder($FolderPath)

    $curFolder.GetTasks(1) | ForEach-Object {
        If ($Enable) {
            $_.Enabled = $True
            Write-Host "Enable $($_.Path)"
        }

        If ($Disable) {
            $_.Enabled = $False
            Write-Host "Disable $($_.Path)"
        }
    }

    If ($Recursive) {
        $curFolder.GetFolders(1)  | ForEach-Object {
            If ($Enable) {
                Control-Tasks -FolderPath $_.Path -Enable -TaskScheduler $TaskScheduler -Recursive
            }
            If ($Disable) {
                Control-Tasks -FolderPath $_.Path -Disable -TaskScheduler $TaskScheduler -Recursive
            }
        }
    }

}

Por ejemplo, puede deshabilitar todas las tareas en la carpeta "\ mysql" llamando a Control-Tasks -FolderPath "\mysql" -Disable -Recursive

Estos fragmentos de código provienen de Cómo deshabilitar / habilitar la tarea programada en lote por PowerShell , puede descargar el archivo de muestra completo allí.

Eric
fuente
0

esto funcionó para mí

    Get-ScheduledTask -TaskName "TestJob"  | Stop-ScheduledTask
saad elshazly
fuente