Como posso desativar uma tarefa agendada usando o Powershell?

8

Eu tenho um aplicativo Web que é executado no Windows Server 2008 R2, que possui um grande número de tarefas agendadas que cuidam de todo o material de back-end. Quando faço uma implantação de software que toca o banco de dados, preciso desativar todas as tarefas agendadas. Atualmente, tenho uma longa lista de verificação que preciso percorrer manualmente, desativando cada tarefa agendada à medida que for avançando - certamente esse é um trabalho pronto para a automação no Powershell.

Infelizmente, a documentação do Powershell parece bastante tímida sobre como desabilitar uma tarefa agendada existente (e, é claro, reativá-la assim que a liberação for concluída com êxito). Posso obter uma lista de tarefas prontas, em execução ou desabilitadas, mas o que vem a seguir?

David Keaveny
fonte

Respostas:

14

Você pode usar os objetos de script do Agendador de tarefas baseados em COM :

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

Para habilitar a tarefa novamente:

$MyTask.Enabled = $true

O procedimento acima só funcionará se o shell estiver elevado e você for um administrador local no servidor. Você pode criar seu próprio cmdlet com o acima:

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
fonte
2
Nota: isso parece não funcionar para tarefas criadas com at.exe. (Exemplo:) AT 09:00 /every:SUNDAY shutdown.exe /r /f /d p:4:1 /c "Reboot via SchTask (AT Job)". O erro que você receberá é 0x80041327; A tarefa possui propriedades que não são compatíveis com as versões anteriores do Windows
Signal15:
5

Se você está apenas tentando interromper TODAS as tarefas, pode ser mais fácil interromper o serviço Agendador de Tarefas. O módulo ScheduledTasks não está disponível até o Windows Server 2012, portanto, gerenciar tarefas não é tão simples quanto parar e iniciar um serviço:

Stop-Service Schedule
Start-Service Schedule

Se isso não funcionar, o schtasks.exe ainda pode ser usado no PowerShell para gerenciar tarefas individuais:

schtasks.exe /CHANGE /TN "My Task" /DISABLE
schtasks.exe /CHANGE /TN "My Task" /ENABLE
Tim Ferrill
fonte
1
A partir de 2008 / Vista, o próprio Windows usa fortemente o Agendador de Tarefas para uma ampla variedade de tarefas do sistema. Dependendo da duração, interromper o serviço Agendador de tarefas pode não ser uma ótima idéia (embora seja fácil).
Mathias R. Jessen
Certo. O caso de uso fornecido foi para desabilitar as tarefas durante a manutenção, para que pudesse ser uma opção viável. Também deu a segunda opção, caso isso não atendesse à necessidade.
precisa
3

Mesmo uma maneira melhor de você não precisar especificar os nomes das tarefas:

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

Isto é perfeito! Funciona melhor do que Get-ScheduledTask desde que eu estou em um ambiente misto de 2008/2012. Adicionei algumas linhas para consultar o AD e chamar esse comando em um grupo de computadores. Meu objetivo era desativar a tarefa do "Gerenciador do Servidor" sempre que um usuário faz login. Presto! tudo se foi!

$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
fonte
0

Olhe para esta função

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 exemplo, você pode desativar todas as tarefas na pasta "\ mysql" chamando Control-Tasks -FolderPath "\mysql" -Disable -Recursive

Esses trechos de código vêm de Como desabilitar / habilitar a tarefa agendada em lote pelo PowerShell , você pode baixar o arquivo de amostra completo lá.

Eric
fonte
0

isso funcionou para mim

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