我正在编写一个脚本来检查邮件,并且我希望它每20或30分钟检查一次未读邮件,如何安排使用Powershell每30分钟运行一次此任务。
这是一个示例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
您未指定要检查电子邮件的PowerShell或操作系统版本。
Windows中的任务计划程序有很多问题,我不知道从哪里开始。
[不幸的是,您可以安排一个任务,该任务每20-30分钟便会重复发生一次。您必须将每日任务安排在00:00、00:30、01:00等周期中进行,因此最终将在计划程序中安排48或72个计划任务。 🤔
如果我们谈论的是笔记本电脑,笔记本电脑甚至带UPS备份的台式机上的Windows,则不能依赖任务计划程序。由于电池管理干扰,因此未按计划执行任务。
[另一个问题是,每隔20-30分钟,PowerShell窗口会在您的屏幕上弹出一会儿。您可以通过在系统服务帐户下将任务注册为系统服务=>来抑制此情况。另一种方法是在CMD中运行PowerShell并移交必须执行的脚本。如果您没有管理员权限,则不能选择此选项。
另一个非常棘手的问题是对于计划的PowerShell任务使用必须包括开关(从技术上讲,您不必使用此开关,但任务执行得更快)之一:< [the-NonInteractive
switch将主动阻止您在要执行的脚本中使用某些交互式cmdlet,例如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
缺点是:
您必须知道要安排多长时间。
- 考虑leap年。
[一种更好的方法
# 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
优点:
您可以为上限设置逻辑,甚至跳过几天。
- 您可以仅使用其他PowerShell脚本或仅使用cmdlet来打开/关闭此任务。
对于Linux(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