计划Powershell脚本每20分钟运行一次

问题描述 投票:0回答:2

我正在编写一个脚本来检查邮件,并且我希望它每20或30分钟检查一次未读邮件,如何安排使用Powershell每30分钟运行一次此任务。

powershell
2个回答
0
投票

这是一个示例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

0
投票

您未指定要检查电子邮件的PowerShell或操作系统版本。

对于Windows:

Windows中的任务计划程序有很多问题,我不知道从哪里开始。

[不幸的是,您可以安排一个任务,该任务每20-30分钟便会重复发生一次。您必须将每日任务安排在00:00、00:30、01:00等周期中进行,因此最终将在计划程序中安排48或72个计划任务。 🤔

如果我们谈论的是笔记本电脑,笔记本电脑甚至带UPS备份的台式机上的Windows,则不能依赖任务计划程序。由于电池管理干扰,因此未按计划执行任务。

[另一个问题是,每隔20-30分钟,PowerShell窗口会在您的屏幕上弹出一会儿。您可以通过在系统服务帐户下将任务注册为系统服务=>来抑制此情况。另一种方法是在CMD中运行PowerShell并移交必须执行的脚本。如果您没有管理员权限,则不能选择此选项。

另一个非常棘手的问题是对于计划的PowerShell任务使用必须包括开关从技术上讲,您不必使用此开关,但任务执行得更快)之一:< [the-NonInteractiveswitch将主动阻止您在要执行的脚本中使用某些交互式cmdlet,例如PauseRead-HostGet-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. 考虑leap年。

  • [一种更好的方法

  • 将使用PowerShell脚本注册一个任务,该脚本将在30分钟内手动执行以完成任务注册时间。您的PowerShell脚本将包含一个逻辑,用于在执行计划任务触发器后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. 您可以仅使用其他PowerShell脚本或仅使用cmdlet来打开/关闭此任务。

  • 缺点:

      您必须处理夏令时更改。

  • 有关触发器的详细信息,请查看here

    对于Linux(PowerShell核心):

    非常简单。

      安装PowerShell Core。
  • 使用检查电子邮件的逻辑编写脚本。
  • CRON中的计划执行,例如* / 20 * * * * / root / powershell / 7 / pwsh /root/CheckEmail.ps1
  • Windows任务计划程序的更强大的解决方案:

    为了解决非交互式cmdlet的问题,我设计了这些功能,这些功能已在我的私人瑞士军刀模块中用于各种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

  • © www.soinside.com 2019 - 2024. All rights reserved.