Created
July 13, 2026 14:20
-
-
Save supermarsx/6626450819e37a791151df7e8ef476b0 to your computer and use it in GitHub Desktop.
Registers a Windows Scheduled Task for Update-ExchangeCertificate.ps1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #requires -Version 5.1 | |
| #requires -RunAsAdministrator | |
| <# | |
| .SYNOPSIS | |
| Registers a Windows Scheduled Task for Update-ExchangeCertificate.ps1. | |
| .DESCRIPTION | |
| Run this once from an elevated Windows PowerShell prompt. You will be asked | |
| for the credential under which the task should run. Use a dedicated domain | |
| account that is a local administrator on the Exchange server and has the | |
| necessary Exchange RBAC permissions. | |
| The task checks daily. The update script is idempotent and only changes | |
| configuration when a newer certificate or connector drift is detected. | |
| #> | |
| [CmdletBinding()] | |
| param( | |
| [Parameter(Mandatory = $true)] | |
| [string]$ScriptPath, | |
| [Parameter(Mandatory = $true)] | |
| [string]$TargetFqdn, | |
| [string]$Server = $env:COMPUTERNAME, | |
| [string]$TaskName = 'Exchange Certificate Auto Update', | |
| [datetime]$DailyAt = [datetime]::Today.AddHours(3).AddMinutes(15), | |
| [switch]$RestartAffectedServices, | |
| [switch]$RemoveExpiredMatchingCertificates | |
| ) | |
| $resolvedScript = (Resolve-Path -LiteralPath $ScriptPath).Path | |
| $credential = Get-Credential -Message 'Credential for the Exchange certificate scheduled task' | |
| $arguments = New-Object System.Collections.Generic.List[string] | |
| $arguments.Add('-NoProfile') | Out-Null | |
| $arguments.Add('-NonInteractive') | Out-Null | |
| $arguments.Add('-ExecutionPolicy Bypass') | Out-Null | |
| $arguments.Add(('-File "{0}"' -f $resolvedScript)) | Out-Null | |
| $arguments.Add(('-TargetFqdn "{0}"' -f $TargetFqdn)) | Out-Null | |
| $arguments.Add(('-Server "{0}"' -f $Server)) | Out-Null | |
| $arguments.Add('-AllowReplaceInternalTransportCertificate') | Out-Null | |
| if ($RestartAffectedServices) { | |
| $arguments.Add('-RestartAffectedServices') | Out-Null | |
| } | |
| if ($RemoveExpiredMatchingCertificates) { | |
| $arguments.Add('-RemoveExpiredMatchingCertificates') | Out-Null | |
| } | |
| $action = New-ScheduledTaskAction ` | |
| -Execute "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" ` | |
| -Argument ($arguments -join ' ') | |
| $trigger = New-ScheduledTaskTrigger -Daily -At $DailyAt | |
| $settings = New-ScheduledTaskSettingsSet ` | |
| -StartWhenAvailable ` | |
| -RunOnlyIfNetworkAvailable ` | |
| -MultipleInstances IgnoreNew ` | |
| -ExecutionTimeLimit (New-TimeSpan -Hours 1) ` | |
| -RestartCount 3 ` | |
| -RestartInterval (New-TimeSpan -Minutes 15) | |
| $principal = New-ScheduledTaskPrincipal ` | |
| -UserId $credential.UserName ` | |
| -LogonType Password ` | |
| -RunLevel Highest | |
| $task = New-ScheduledTask ` | |
| -Action $action ` | |
| -Trigger $trigger ` | |
| -Settings $settings ` | |
| -Principal $principal ` | |
| -Description ("Select and apply the newest valid Exchange certificate for {0}." -f $TargetFqdn) | |
| $passwordPointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($credential.Password) | |
| try { | |
| $plainPassword = [Runtime.InteropServices.Marshal]::PtrToStringBSTR($passwordPointer) | |
| Register-ScheduledTask ` | |
| -TaskName $TaskName ` | |
| -InputObject $task ` | |
| -User $credential.UserName ` | |
| -Password $plainPassword ` | |
| -Force | Out-Null | |
| } | |
| finally { | |
| if ($passwordPointer -ne [IntPtr]::Zero) { | |
| [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($passwordPointer) | |
| } | |
| $plainPassword = $null | |
| } | |
| Write-Host ("Scheduled task registered: {0}" -f $TaskName) -ForegroundColor Green | |
| Write-Host ("Runs daily at: {0}" -f $DailyAt) | |
| Write-Host ("Script: {0}" -f $resolvedScript) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment