Last active
December 16, 2015 01:30
-
-
Save josheinstein/5355916 to your computer and use it in GitHub Desktop.
Create temporary rules in Outlook by naming them with " (Until date)" or " (Until date time)" and then run this script at periodic intervals to disable those rules when they expire.
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
| ############################################################################## | |
| #.SYNOPSIS | |
| # Scans your Outlook rules (Outlook must be running) and disables any rules | |
| # whose name matches a specific pattern such as: | |
| # Move Stuff (Until 4/10/2013 5:00 PM) | |
| # Ignore Stuff (Until 4/11/2013) | |
| # | |
| #.DESCRIPTION | |
| # | |
| # To create temporary rules in Outlook, just create rules as you would | |
| # normally, but name them such that they end in " (Until date)" or | |
| # " Until (date time)". | |
| # | |
| # The script should be run using the Windows Task scheduler or some other | |
| # mechanism that will periodically run it so that rules will be disabled when | |
| # they are set to expire. | |
| ############################################################################## | |
| [CmdletBinding(DefaultParameterSetName='Run', SupportsShouldProcess=$true)] | |
| param( | |
| # When this switch is present, Outlook will be started if it is not | |
| # already running. Otherwise the script will return an error if | |
| # Outlook is not running. | |
| [Parameter(ParameterSetName='Run')] | |
| [Switch]$Force, | |
| # When this switch is present, the job will be scheduled with Windows | |
| # Task Scheduler to run hourly at 5 minutes past the hour. | |
| # Note that no precautions are taken to prevent multiple jobs being | |
| # scheduled so that's on you. | |
| [Parameter(ParameterSetName='Schedule')] | |
| [Switch]$Schedule | |
| ) | |
| ############################################################################## | |
| # PRIVATE FUNCTIONS | |
| # Get a running COM object from the running object table | |
| function Get-ComObject([String]$ComObject, [Switch]$Force) { | |
| try { | |
| [System.Runtime.InteropServices.Marshal]::GetActiveObject($ComObject) | |
| } | |
| catch [System.Management.Automation.MethodInvocationException] { | |
| if ( $Force ) { New-Object -ComObject $ComObject } | |
| else { Write-Error "An active object of type $ComObject is not available." } | |
| } | |
| } | |
| # Decrement (or zero out if -Force) the reference count of the RCW | |
| function Release-ComObject([Object[]]$Object, [Switch]$Force) { | |
| foreach ($O in $Object) { | |
| if ($O -eq $Null) { continue; } | |
| [Int32]$Remaining = 0 | |
| do { | |
| $Remaining = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($O) | |
| } while ($Force -and $Remaining -gt 0) | |
| Write-Verbose "Release COM Object: $Remaining remaining" | |
| } | |
| } | |
| # Pulls off the expiration date from the name of a rule and stores | |
| # it as an extended property on the Rule object | |
| filter ParseExpirationDate { | |
| $Expires = $Null | |
| if ($_.Name -match " \(Until (.*)\)$") { | |
| try { | |
| $Expires = [DateTime]::Parse($Matches[1]) | |
| } | |
| catch { | |
| Write-Warning "Couldn't parse $($Matches[1]) as a date. Skipping." | |
| } | |
| } | |
| if ($Expires) { | |
| Add-Member NoteProperty Expires $Expires -InputObject:$_ -PassThru | |
| } | |
| } | |
| # END FUNCTIONS | |
| ############################################################################## | |
| switch ($PSCmdlet.ParameterSetName) { | |
| # Scheduling mode registers with Windows Task Schedule to | |
| # run every hour at 5 minutes past the hour | |
| 'Schedule' { | |
| Import-Module PSScheduledJob | |
| $JobArgs = @{ | |
| Name = Split-Path $MyInvocation.MyCommand.Path -Leaf | |
| FilePath = $MyInvocation.MyCommand.Path | |
| Trigger = @( | |
| @{Frequency='Daily'; At='12:05 AM'; RepetitionInterval='01:00:00'; RepetitionDuration='1.00:00:00'} | |
| ) | |
| } | |
| Register-ScheduledJob @JobArgs | |
| } | |
| # Run mode runs the script on demand | |
| # This is the default mode if the -Schedule switch is not provided | |
| 'Run' { | |
| # Reserve these in scope so we can safely release | |
| # them later without trouncing on a higher scope | |
| $Outlook = $Null | |
| $OutlookSession = $Null | |
| $OutlookStore = $Null | |
| $OutlookRules = $Null | |
| try { | |
| # Any of these could fail because, well... Outlook. Yeah. | |
| # So the finally block will take care of releasing whatever | |
| # was acquired. | |
| $Outlook = Get-ComObject Outlook.Application -Force:$Force | |
| $OutlookSession = $Outlook.Session | |
| $OutlookStore = $OutlookSession.DefaultStore | |
| $OutlookRules = $OutlookStore.GetRules() | |
| $NeedsSave = $False | |
| $OutlookRules | | |
| ParseExpirationDate | | |
| Where { $_.Enabled } | | |
| Where { $_.Expires -lt [DateTime]::Now } | | |
| ForEach { | |
| # If the -WhatIf switch was used, this will return | |
| # false after writing a message to the host | |
| if ($PSCmdlet.ShouldProcess($_.Name)) { | |
| $_.Enabled = $False | |
| $NeedsSave = $True | |
| Write-Host "Disabled expired rule: $($_.Name)" | |
| } | |
| } | |
| if ($NeedsSave) { | |
| $OutlookRules.Save() | |
| } | |
| } | |
| finally { | |
| # Zeroes out the reference count of the runtime-callable wrappers | |
| Release-ComObject -Force ( | |
| $OutlookRules, | |
| $OutlookStore, | |
| $OutlookSession, | |
| $Outlook | |
| ) | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment