-
Notifications
You must be signed in to change notification settings - Fork 0
Scheduling #5
base: master
Are you sure you want to change the base?
Scheduling #5
Changes from 36 commits
725cd6d
cc9aa99
f039cfd
81f64f4
d552fbf
46c9c40
fab6e51
578e22b
a847a4a
edc5f2a
3f404c2
bc74b6a
5d41688
a69c990
f0547a5
037f198
b0e405c
571fd6b
8b6b45c
e23cf15
348656f
72779b9
2a8a388
0762348
4d7d79a
0b4b719
8b4b7be
d15e775
34c3ad9
65097d2
0c9b550
c4baae2
aa64bb4
a4ac580
a8f4c02
4500d18
18ce60f
fabe6dc
fe0c233
43cdf37
19f61c2
f6bc311
ddab937
2fbd59a
0026e2c
d5f28b9
901e4f8
5060e82
2d1b2c7
c6a20ef
37a4b87
85a0560
c13281a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<# | ||
.SYNOPSIS | ||
Returns the days, months, and years of all days between 2 days | ||
.DESCRIPTION | ||
Calculates a timespan between 2 dates, then returns each day between those 2 dates as datetime objects | ||
.EXAMPLE | ||
Get-DaysInRange -StartDate 1/1/2020 -EndDate 30/1/2020 | ||
Mortein marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Returns all days in January 2020 as an array | ||
.INPUTS | ||
Datetime strings | ||
.OUTPUTS | ||
Array of Datetime objects | ||
.NOTES | ||
|
||
#> | ||
|
||
function Get-DaysInRange { | ||
[CmdletBinding()] | ||
param ( | ||
# The Start Date for the array to calculate | ||
[Parameter(Mandatory = $true, ValueFromPipeline = $true)] | ||
[string] | ||
$StartDate, | ||
|
||
# The end date for the array to calculate | ||
[Parameter(Mandatory = $true, ValueFromPipeline = $true)] | ||
[string] | ||
$EndDate | ||
) | ||
|
||
begin { | ||
$Timespan = New-Timespan -Start $StartDate -End $EndDate | ||
$DateArray = @() | ||
Mortein marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
process { | ||
$DateArray += Get-Date $StartDate | ||
Mortein marked this conversation as resolved.
Show resolved
Hide resolved
|
||
$WorkingTime = Get-Date $StartDate | ||
foreach ($_ in 1..$Timespan.Days) { | ||
$WorkingTime = $WorkingTime.AddDays(1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only returns 2nd day and beyond, never the 1st. |
||
$DateArray += $WorkingTime | ||
Blockagle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
end { | ||
return $DateArray | ||
Blockagle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<# | ||
.SYNOPSIS | ||
Returns an appointment object and all dates for that appointment based off its recurrence pattern | ||
.DESCRIPTION | ||
Takes an Outlook Recurring Appointment object. Calculates all possible occurences of the appointment based off of | ||
the Start timestampt, and the Recurrence Pattern. | ||
The Recurrence Pattern defines a RecurrenceType, an integer that specifies if it's a daily, weekly, monthly, nth monthly, | ||
yearly, or nth yearly meeting. | ||
Each Typoe can then contain DayofWeek masks or WeekofMonth masks that confirm what day, days, or week they occur on. | ||
.EXAMPLE | ||
$Appointment | Get-RecurringMeetingDates -EndDate 30/01/2020 | ||
Returns all valid appointment dates for the input recurring appointment object | ||
.INPUTS | ||
Outlook Recurring Appointment | ||
.OUTPUTS | ||
pscustomobject | ||
.NOTES | ||
|
||
#> | ||
function Get-RecurringMeetingDates { | ||
Blockagle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
param ( | ||
# An Outlook appointment item | ||
[Parameter(Mandatory = $true, ValueFromPipeline = $true)] | ||
Blockagle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
[object] | ||
$Appointment, | ||
|
||
# The date to calculate the last occurence of a recurring appointment | ||
[Parameter(Mandatory = $false, ValueFromPipeline = $true)] | ||
$EndDate | ||
) | ||
|
||
$DateArray = Get-DaysinRange -StartDate ($Appointment.Start).ToString() -EndDate (Get-Date $EndDate).ToString() | ||
$Results = @() | ||
|
||
Switch (($Appointment.GetRecurrencePattern()).DayOfWeekMask) { | ||
#CdoMonday/2 - The appointment recurs on Mondays. | ||
2 { | ||
$DayOfWeekMask = $DateArray | Where-Object -Property DayOfWeek -eq 'Monday' | ||
} | ||
#CdoTuesday/4 - The appointment recurs on Tuesdays. | ||
4 { | ||
$DayOfWeekMask = $DateArray | Where-Object -Property DayOfWeek -eq 'Tuesday' | ||
} | ||
#CdoWednesday/8 - The appointment recurs on Wednesdays. | ||
8 { | ||
$DayOfWeekMask = $DateArray | Where-Object -Property DayOfWeek -eq 'Wednesday' | ||
} | ||
#CdoThursday/16 - The appointment recurs on Thursdays. | ||
16 { | ||
$DayOfWeekMask = $DateArray | Where-Object -Property DayOfWeek -eq 'Thursday' | ||
} | ||
#CdoFriday/32 - The appointment recurs on Fridays. | ||
32 { | ||
$DayOfWeekMask = $DateArray | Where-Object -Property DayOfWeek -eq 'Friday' | ||
} | ||
#Meeting that occur on every week day have the value of 62 (2+4+8+16+32) | ||
62 { | ||
$DayOfWeekMask += $DateArray | Where-Object -Property DayOfWeek -NotMatch ^[S*] | ||
} | ||
} | ||
|
||
Switch (($Appointment.GetRecurrencePattern()).RecurrenceType) { | ||
#CdoRecurTypeDaily/0 - Appointments that recur daily | ||
0 { | ||
$Results += $DateArray | Where-Object -Property DayOfWeek -NotMatch ^[S*] | ||
return $Results | ||
} | ||
#CdoRecurTypeWeekly/1 - Appointment recurs weekly (DayOfWeekMask,Interval) | ||
1 { | ||
$AppointmentDates = @() | ||
for ($i = 0; $i -lt ($DayOfWeekMask).Count; $i += (($Appointment.GetRecurrencePattern()).Interval)) { | ||
$AppointmentDates += $DayOfWeekMask[$i] | ||
} | ||
$Results += [PSCustomObject]@{ | ||
Appointment = $Appointment | ||
AppointmentDates = $AppointmentDates | ||
} | ||
} | ||
#CdoRecurTypeMonthly/2 - Appointment recurs monthly (DayOfMonth Interval) | ||
2 { | ||
#Not yet doing anything with these | ||
} | ||
#CdoRecurTypeMonthlyNth/3 - Appointment recurs every Nth month | ||
3 { | ||
#Not yet doing anything with these | ||
} | ||
#CdoRecurTypeYearly/5 - Appointment recurs every year | ||
5 { | ||
#Not yet doing anything with these | ||
} | ||
#CdoRecurTypeYearlyNth/6 - Appointment recurs every Nth year | ||
6 { | ||
#Not yet doing anything with these | ||
} | ||
} | ||
return $results | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<# | ||
.SYNOPSIS | ||
Searches a string for a Zoom Meeting invite URL and returns the first instance found | ||
.DESCRIPTION | ||
Searches a string of text for any Zoom URL's based off the standard Zoom uses. Returns the first line found and splits this incase | ||
there are multiple URLS in 1 line (Common for hyperlink formats) | ||
.INPUTS | ||
String | ||
.OUTPUTS | ||
String | ||
.NOTES | ||
Used to scrape meeting object bodies for Zoom meeting URLs | ||
#> | ||
function Get-ZoomStringFromBody { | ||
[CmdletBinding()] | ||
param ( | ||
# A body of text that will contain a Zoom URL | ||
[Parameter(Mandatory = $true, ValueFromPipeline = $true)] | ||
$Body | ||
) | ||
|
||
begin { | ||
} | ||
|
||
process { | ||
$SplitString = $Body -Split ([Environment]::NewLine) | ||
Foreach ($String in $SplitString) { | ||
if ($String -match "\D{5,6}\/\/\S*\/j\/\d{10,11}\?{1}\S*") { | ||
Blockagle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
$Results = (Select-String -InputObject $String -Pattern "\D{5,6}\/\/\S*\/j\/\d{10,11}\?{1}\S*").Matches.Value | ||
Blockagle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
break | ||
} | ||
elseif ($String -match "\D{5,6}\/\/\S*\/j\/\d{10,11}") { | ||
Blockagle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
$results = (Select-String -InputObject $String -Pattern "\D{5,6}\/\/\S*\/j\/\d{10,11}").Matches.Value | ||
Blockagle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
break | ||
} | ||
else { | ||
$results = $null | ||
} | ||
} | ||
} | ||
|
||
end { | ||
return $results | ||
Blockagle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,100 @@ | ||||||
<# | ||||||
.SYNOPSIS | ||||||
Returns meeting objects from Outlook | ||||||
.DESCRIPTION | ||||||
Creates an Outlook COM application and returns all objects with message class IPM.Appointment from the Calendar Folder from the specified date range. If no date range is specified, all meetings from midnight the previous day, to the current time are returned | ||||||
.EXAMPLE | ||||||
Get-OutlookCalendarAppointments | ||||||
Returns Outlook calendar appointments for the next 48 hours | ||||||
|
||||||
Get-OutlookCalendarAppointments -Start 12/01/2020 -End 21/02/2020 | ||||||
Returns all non-recurring meetings between 12th January and 21st February 2020 | ||||||
|
||||||
.OUTPUTS | ||||||
PSCustomObject | ||||||
.NOTES | ||||||
|
||||||
#> | ||||||
function Get-OutlookCalendarAppointment { | ||||||
|
||||||
[CmdletBinding(DefaultParameterSetName = 'Default')] | ||||||
|
||||||
param ( | ||||||
|
||||||
# The start date for the search | ||||||
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'SearchTime')] | ||||||
$Start, | ||||||
|
||||||
# The end date for the search | ||||||
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'SearchTime')] | ||||||
$End | ||||||
) | ||||||
|
||||||
begin { | ||||||
#Add the required Assembly to PowerShell before processing input | ||||||
Add-Type -assembly "Microsoft.Office.Interop.Outlook" | ||||||
|
||||||
#Defines the DefaultFolderID for the Calendar, and creates our new COM Object | ||||||
$OutlookFolders = 'Microsoft.Office.Interop.Outlook.OlDefaultFolders' -as [type] | ||||||
$Outlook = New-Object -ComObject Outlook.Application | ||||||
$NameSpace = $Outlook.GetNamespace('MAPI') | ||||||
|
||||||
#Empty array to store our results | ||||||
$Meetings = @() | ||||||
$Results = @() | ||||||
if ($PSCmdlet.ParameterSetName -eq 'Default') { | ||||||
$Start = Get-Date | ||||||
$End = $Start.AddDays(2) | ||||||
} | ||||||
} | ||||||
|
||||||
process { | ||||||
$Folder = $NameSpace.getDefaultFolder($OutlookFolders::olFolderCalendar) | ||||||
$RecurringAppointments = $Folder.Items | Where-Object -Property IsRecurring -eq $True | ||||||
if ($null -eq $start) { | ||||||
$Meetings += $Folder.Items | Where-Object -Property Start -gt ((Get-Date -Hour 00 -Minute 00 -Second 00).AddDays(-1)) | ||||||
} | ||||||
else { | ||||||
$Meetings += $Folder.Items | Where-Object -Property Start -gt (Get-Date $Start -Hour 00 -Minute 00 -Second 00) | Where-Object -Property End -lt (Get-Date $End -Hour 00 -Minute 00 -Second 00) | ||||||
} | ||||||
} | ||||||
|
||||||
end { | ||||||
Mortein marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
foreach ($Meeting in $Meetings) { | ||||||
$Results += [PSCustomObject]@{ | ||||||
MeetingTime = $Meeting.Start | ||||||
MeetingSubject = $Meeting.Subject | ||||||
MeetingBody = $Meeting.Body | ||||||
MeetingURL = Get-ZoomStringFromBody $Meeting.Body | ||||||
Recurring = $false | ||||||
} | ||||||
} | ||||||
if ($Null -eq $RecurringAppointments) { | ||||||
return $Results | ||||||
} | ||||||
else { | ||||||
Foreach ($Appointment in $RecurringAppointments) { | ||||||
$AppointmentDates = @() | ||||||
$AppointmentDates += (Get-RecurringMeetingDates -Appointment $Appointment -EndDate (Get-Date $End).ToString()).AppointmentDates | ||||||
foreach ($Date in $AppointmentDates) { | ||||||
if ($Date -gt (Get-Date $Start)) { | ||||||
$Results += [pscustomobject]@{ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
And then grab the section below for the properties of the custom object, add them to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we specify the default display set for the properties of the custom object doing it this way? Lines 95-98 for this block in question. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if you take 95-98 and move it to this Will PowerShell care if you pass an object with default display set, rather than an array of objects with default display set? I have a feeling it'll just merge the objects, as long as the display set is the same. |
||||||
MeetingTime = $Date | ||||||
MeetingSubject = $Appointment.Subject | ||||||
MeetingBody = $Appointment.Body | ||||||
MeetingURL = Get-ZoomStringFromBody $Appointment.Body | ||||||
Recurring = $true | ||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
$defaultProperties = @('MeetingTime', 'MeetingSubject', 'MeetingURL', 'Recurring') | ||||||
$defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet(‘DefaultDisplayPropertySet’, [string[]]$defaultProperties) | ||||||
$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) | ||||||
$Results | Add-Member MemberSet PSStandardMembers $PSStandardMembers | ||||||
|
||||||
return $Results | ||||||
} | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it inclusive or exclusive?
1-3 inclusive returns 1, 2, and 3
1-3 exclusive returns 2