Last active
September 13, 2018 17:21
-
-
Save sytone/2921b6329cd307c1b68c7b3ac424fda6 to your computer and use it in GitHub Desktop.
Fill empty blocks in your outlook calendar for the next week
This file contains 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
param ( | |
[int] $DaysForward = 7, | |
# What hour of the day do you start? | |
[int] $DayStart = 8, | |
# How many hours after that are work hours? | |
[int] $DayLength = 10 | |
) | |
function Get-OutlookCalendar { | |
param ( | |
$StartDate, | |
$EndDate | |
) | |
Add-type -assembly "Microsoft.Office.Interop.Outlook" | out-null | |
$olFolders = "Microsoft.Office.Interop.Outlook.OlDefaultFolders" -as [type] | |
$outlook = new-object -comobject outlook.application | |
$namespace = $outlook.GetNameSpace("MAPI") | |
$folder = $namespace.getDefaultFolder($olFolders::olFolderCalendar) | |
$filter = "[START] >= '$StartDate' and [END]<= '$EndDate'" | |
$folderItems = $folder.items | |
$folderItems.IncludeRecurrences = $true | |
$folderItems.Sort("[Start]") | |
$folderItems = $folderItems.Restrict($filter) | |
$folderItems #| Select-Object -Property Subject, Start, Duration, Location, ResponseStatus, BusyStatus | |
} | |
function BlockOffDay($Start, $End) { | |
"$Start -> $End" | |
$entries = Get-OutlookCalendar -StartDate $Start.ToString("M/d/yyyy") -EndDate $End.ToString("M/d/yyyy") | |
# Clean out the existing work items to allow the calendar to be 'cleaner' | |
foreach ($entry in $entries) { | |
if($entry.Subject -eq "Work") { | |
"Removing $($entry.Subject) - $($entry.Start) - $($entry.End)" | |
$entry.Delete() | |
} | |
} | |
# repopulate the entries. | |
$entries = Get-OutlookCalendar -StartDate $Start.ToString("M/d/yyyy") -EndDate $End.ToString("M/d/yyyy") | |
$freeTime = @() | |
for ($i = 0; $i -lt ($DayLength * 60); $i++) { | |
if (($i % 60) -eq 0) { | |
$currentHour = $DayStart + $i / 60 | |
} | |
$currentSlot = Get-Date -Hour $currentHour -Minute ($i % 60) -Second 00 -Year $Start.Year -Month $Start.Month -Day $Start.Day | |
$booked = $false | |
foreach ($entry in $entries) { | |
$entryEnd = $entry.Start.AddMinutes($entry.Duration) | |
$booked = $currentSlot -ge $entry.Start -and $currentSlot -le $entryEnd | |
if ($booked -and ($entry.ResponseStatus -eq 4 -or $entry.ResponseStatus -eq 5 -or $entry.ResponseStatus -eq 2)) { | |
#"Not Accepted, ignore $($entry.Subject)" | |
} | |
elseif ($booked) { | |
#"Checking $($entry.Subject)" | |
if ($booked) {break} | |
} | |
} | |
if ($booked) { | |
#"$currentSlot - Booked" | |
} | |
else { | |
#"$currentSlot - Free" | |
$freeTime += $currentSlot | |
} | |
} | |
[Math]::Round(($freeTime[150] - $freeTime[149]).TotalMinutes) | |
$bookingBlocks = @() | |
$slotStart = $freeTime[0] | |
for ($i = 1; $i -lt $freeTime.Count; $i++) { | |
#$freeTime[$i] | |
if ([Math]::Round(($freeTime[$i] - $freeTime[$i - 1]).TotalMinutes) -gt 1) { | |
$bookingBlocks += @{Start = $slotStart; End = $freeTime[$i - 1]} | |
"BLOCK: $slotStart -> $($freeTime[$i-1])" | |
$slotStart = $freeTime[$i] | |
} | |
else { | |
#"BLOCK: $slotStart -- $($freeTime[$i]) -- $(($freeTime[$i] - $freeTime[$i-1]).TotalMinutes) -- $i" | |
} | |
} | |
$bookingBlocks += @{Start = $slotStart; End = $freeTime[-1]} | |
"BLOCK: $slotStart -> $($freeTime[-1])" | |
$outlook = new-object -com Outlook.Application | |
$namespace = $outlook.GetNameSpace("MAPI") | |
$olFolders = "Microsoft.Office.Interop.Outlook.OlDefaultFolders" -as [type] | |
$calendar = $namespace.getDefaultFolder($olFolders::olFolderCalendar) | |
foreach ($block in $bookingBlocks) { | |
if ($block.Start -ne $block.End) { | |
$appt = $calendar.Items.Add(1) # == olAppointmentItem | |
$appt.Start = $block.Start | |
$appt.End = $block.End | |
$appt.Subject = "Work" | |
$appt.BusyStatus = 2 | |
$appt.Location = "" | |
$appt.Body = "" | |
$appt.ReminderSet = $false | |
$appt.Categories = "WORK" | |
$appt.Save() | |
} | |
} | |
} | |
for ($i = 0; $i -lt $DaysForward; $i++) { | |
"$(([datetime]::Today).AddDays($i).DayOfWeek) to $(([datetime]::Today).AddDays($i + 1).DayOfWeek)" | |
if(([datetime]::Today).AddDays($i + 1).DayOfWeek -eq [System.DayOfWeek]::Sunday -or ([datetime]::Today).AddDays($i + 1).DayOfWeek -eq [System.DayOfWeek]::Monday) { | |
"Skipping $(([datetime]::Today).AddDays($i + 1).DayOfWeek)" | |
} else { | |
BlockOffDay -Start ([datetime]::Today).AddDays($i) -End ([datetime]::Today).AddDays($i+1) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment