Планирование запуска сценария PowerShell каждые 20 минут - PullRequest
0 голосов
/ 08 мая 2020

Я пишу сценарий для проверки почты и хочу, чтобы он проверял непрочитанную почту каждые 20 или 30 минут, как я могу запланировать выполнение этой задачи каждые 30 минут с помощью PowerShell.

Ответы [ 2 ]

0 голосов
/ 08 мая 2020

Вы не указали версию PowerShell или операционную систему, в которой хотите проверять электронную почту.

Для Windows:

Планировщик заданий в Windows имеет так много проблем, что я не знаю, с чего начать.

К сожалению, вы можете легко запланировать задачу, которая будет повторяться каждые 20-30 минут. Вы должны запланировать ежедневную задачу на 00:00, 00:30, 01:00 и т. Д. c. в цикле, так что в вашем планировщике будет 48 или 72 запланированных задачи. ?

Если мы говорим о Windows на ноутбуках, ноутбуках даже на настольных ПК с резервным ИБП, вы не можете полагаться на планировщик задач. Задачи не выполняются по расписанию, потому что мешает управление батареей.

Другая проблема заключается в том, что каждые 20-30 минут на экране на короткое время появляется всплывающее окно PowerShell. Вы можете подавить это, зарегистрировав задачу как системная служба => под учетной записью системной службы. Другой подход - запустить PowerShell в CMD и передать скрипт, который должен быть выполнен. Это не вариант, если у вас нет прав администратора.

Другая, очень сложная проблема заключается в том, что использование одного из должно включать переключатель ( технически вы не используете 'Не обязательно использовать этот переключатель, но задача выполняется быстрее ) для запланированных задач PowerShell: -NonInteractive переключатель будет активно мешать вам использовать некоторые интерактивные командлеты например, Pause, Read-Host или Get-Credential в вашем скрипте, который вы хотите выполнить. Вы должны разработать свою запланированную задачу в соответствии с инструкцией, которую вы хотите выполнить в сеансе PowerShell.

Не идеальный вариант - это расписание триггера как -Once и настройка этого триггера с повторением:

$frequencyOfCheckInMin = 20
$howManyYearYouWantToCheckForEmails = 5
$params = @{
    Once = $true
    At = (Get-Date)
    RepetitionInterval = (New-TimeSpan -Minutes $frequencyOfCheckInMin)
    RepetitionDuration = (New-TimeSpan -Days ($howManyYearYouWantToCheckForEmails * 365 * $frequencyOfCheckInMin)) 
}
$trigger = New-ScheduledTaskTrigger @params

Недостатки:

  1. Вы должны знать, на сколько времени вы хотите запланировать это.
  2. Учитывайте високосные годы.

Лучшим подходом было бы зарегистрировать одну задачу с помощью сценария PowerShell, который запускается за 30 минут на время регистрации задачи вручную. Ваш сценарий PowerShell будет содержать logi c для проверки электронной почты и обновления триггера запланированной задачи до нового, через 30 минут после выполнения триггера запланированной задачи. Ниже следует код.

# A definition of a general task which takes a script as argument and execute task 
$pathToScript = 'D:\Fortis Backup\Test.ps1'
$ScheduledTaskActionParams = @{
    Execute  = "PowerShell.exe"
    Argument = "-NoLogo -NoProfile -NonInteractive -File `"$pathToScript`""
}
$registerTaskParameters = @{
    Principal = New-ScheduledTaskPrincipal -UserId "$ENV:USERDOMAIN\$ENV:USERNAME"
    Trigger   = New-ScheduledTaskTrigger -Once -At ((Get-Date).AddMinutes(30))
    TaskName  = 'Check email'
    Action    = New-ScheduledTaskAction @ScheduledTaskActionParams
}
Register-ScheduledTask @registerTaskParameters -Force

Ваш сценарий

Get-EmailStatus
$newTrigger = New-ScheduledTaskTrigger -Once -At ((Get-Date).AddMinutes(30))
Set-ScheduledTask -TaskName 'Check email' -Trigger $newTrigger

Преимущества:

  1. Вы можете реализовать logi c для верхней границы или даже пропустить несколько дней .
  2. Вы можете просто включить / выключить эту задачу с помощью других сценариев PowerShell или просто командлетов.

Недостатки:

  1. Вам нужно учитывать переход на летнее время изменения.

Подробнее о триггере здесь .

Для Linux (PowerShell Core):

Это очень просто.

  1. Установите PowerShell Core.
  2. Сделайте свой сценарий с проверкой электронной почты logi c.
  3. Выполнение расписания в CRON, например * / 20 * * * * / root / powershell / 7 / pw sh /root/CheckEmail.ps1

Более надежное решение для Windows Планировщик заданий:

Для решения проблем с помощью неинтерактивных командлетов я разработал эти функции, которые использую в моем частном модуле Swiss Army Knife для различных задач PowerShell.

function Confirm-PowerShellScriptForNonInteractiveMode
{
    [CmdletBinding(PositionalBinding)]
    Param (
        # A path to PS1 file to test
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName,
            ValueFromPipeline,
            Position = 0)]
        [ValidateNotNullOrEmpty()]
        [ValidateScript( { Test-Path $_ })]
        [ValidateScript( { $_ -like '*.ps1' })]
        [System.IO.FileInfo]
        $Path
    )
    Begin
    {
        Write-Information 'Starting to validate script(s)...'
    }
    Process
    {
        $nonInteractiveCmdlets = @('Pause', 'Read-Host', 'Get-Credential')
        $isValid = [System.Boolean]$true
        $content = Get-Content -Path $Path
        foreach ($cmdlet in $nonInteractiveCmdlets)
        {
            Write-Verbose "Script status: $isValid, testing $cmdlet"
            $isValid = $isValid -AND !($content -match "$cmdlet")
        }
        return $isValid
    }
    End
    {
        Write-Information 'All scripts has been validated.'
    }
}

function Register-PowerShellScheduledTask
{
    [CmdletBinding(PositionalBinding)]
    Param (
        # A path to PS1 file to register
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName,
            ValueFromPipeline,
            Position = 0)]
        [ValidateNotNullOrEmpty()]
        [ValidateScript( { Test-Path $_ })]
        [ValidateScript( { $_ -like '*.ps1' })]
        [ValidateScript( { Confirm-PowerShellScriptForNonInteractiveMode $_ })]
        [System.IO.FileInfo]
        $Path,
        [Parameter(
            ValueFromPipeline,
            ValueFromPipelineByPropertyName,
            Position = 1)]
        [ValidateNotNullOrEmpty()]
        [Microsoft.Management.Infrastructure.CimInstance]
        $TaskTrigger = (New-ScheduledTaskTrigger -AtLogOn)
    )
    Begin
    {
        Write-Information 'Starting to register task(s)...'
    }
    Process
    {
        $ScheduledTaskActionParams = @{
            Execute  = "PowerShell.exe"
            Argument = "-NoLogo -NoProfile -NonInteractive -File `"$Path`""
        }
        $registerTaskParameters = @{
            Principal = New-ScheduledTaskPrincipal -UserId "$env:USERDOMAIN\$env:USERNAME"
            Trigger   = $TaskTrigger
            TaskName  = "Run $(Split-Path -Path $Path -Leaf) by PowerShell"
            Action    = New-ScheduledTaskAction @ScheduledTaskActionParams
        }
        Register-ScheduledTask @registerTaskParameters -Force

        Get-ScheduledTask | Write-Verbose
    }
    End
    {
        Write-Information 'Registered task:'
        Get-ScheduledTask -TaskName 'Run * by PowerShell' | Write-Information
    }
}

Использование этих функций:

$trigger = New-ScheduledTaskTrigger -At ((Get-Date).AddSeconds(10))
Register-CustomScheduledTask -Path "C:\temp\test.ps1" -Trigger $trigger
0 голосов
/ 08 мая 2020

Вот пример сценария Powershell, который создает запланированную задачу, которая может запускаться с правами администратора.

передаваемый аргумент -RunLevel Highest заставляет его запускаться от имени администратора, вам может потребоваться указать действительное имя пользователя / пароль, который имеет админ прямо на автомате

$frequencyInMin = 20

$taskAction = New-ScheduledTaskAction -Execute 'Powershell.exe' `
-Argument '-NoProfile -WindowStyle Hidden -command "& {get-eventlog -logname Application -After ((get-date).AddDays(-1)) | Export-Csv -Path c:\temp\logs.csv -Force -NoTypeInformation}"'

$trigger = New-ScheduledTaskTrigger `
    -Once `
    -At (Get-Date) `
    -RepetitionInterval (New-TimeSpan -Minutes $frequencyInMin) `
    -RepetitionDuration (New-TimeSpan -Days (365 * $frequencyInMin))

Register-ScheduledTask -Action $taskAction -Trigger $trigger -TaskName "MyTasks\AppLog" -Description "Daily App Logs" -RunLevel Highest
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...