Compare commits

...

5 Commits

Author SHA1 Message Date
8045198d05 support for multi-day time off, day shift replacement bug fix 2025-10-16 16:40:53 +02:00
c7620a60ea oprava duplicitní směny po nalezení náhradníka, oprava zkrácení směny den po RLCZ maintenanci 2025-10-15 13:22:57 +02:00
Jonatan Rek
c988f637a1 Fixes 2025-10-14 19:27:51 +02:00
Jonatan Rek
d5ab85739d Clean Up 2025-10-14 18:44:09 +02:00
Jonatan Rek
1a7ba16c85 My take on shift Problem 2025-10-14 18:42:07 +02:00
2 changed files with 564 additions and 230 deletions

View File

@@ -1,18 +1,19 @@
param( param(
[switch]$debug, [switch]$debug,
[switch]$clear [switch]$clear,
[switch]$noplan
) )
if ($debug) { if ($debug) {
$script:debug = $debug $script:debug = $debug
} }
if($noplan) {
$script:noplan = $noplan
}
$teamsName = "IT Support & Delivery" $teamsName = "IT Support & Delivery"
$scheduleGroupName = "IT SUPPORT" $scheduleGroupName = "IT SUPPORT"
# App Registration details & Tenant ID
$ClientId = "6cb76bbf-f253-4551-87a8-5e1f49d8ace3" $ClientId = "6cb76bbf-f253-4551-87a8-5e1f49d8ace3"
$ClientSecret = "IQg8Q~JTBTDbrHyjKMc.KMSETtQoKWvUhnCr1aY1" $ClientSecret = "IQg8Q~JTBTDbrHyjKMc.KMSETtQoKWvUhnCr1aY1"
$tenantid = "e81b4a31-e8ad-4df6-aa30-3bdcc1da2cdd" $tenantid = "e81b4a31-e8ad-4df6-aa30-3bdcc1da2cdd"
@@ -31,7 +32,6 @@ function Write-Debug {
} }
} }
#Naplánování konkrétní směny
function Set-Shift { function Set-Shift {
param( param(
[string]$userId, [string]$userId,
@@ -55,19 +55,34 @@ function Set-Shift {
} }
} }
#$headers = @{ if($script:noplan -eq $false) {
# "MS-APP-ACTS-AS" = $userIdAdmin $newShift = New-MgTeamScheduleShift -TeamId $teamID -BodyParameter $params -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin }
# "Prefer" = "no-notification" Write-Debug("{0} {1}: setting {2}'s shift - {3} {4}-{5}" -f $dayDate, $dayDate.DayOfWeek, $mail, $shiftName, $StartDate, $EndDate)
#} }
else {
Write-Debug("{0} {1}: Not setting {2}'s shift - {3} {4}-{5} - running with -noplan" -f $dayDate, $dayDate.DayOfWeek, $mail, $shiftName, $StartDate, $EndDate)
$newshift = 0
}
$newShift = New-MgTeamScheduleShift -TeamId $teamID -BodyParameter $params -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin }
#Write-Debug ("SCHEDULING: {0} {1} - {2}" -f $newShift.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm"), $newShift.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm"), $newShift.SharedShift.Notes)
#("SCHEDULING: {0} {1} - {2}" -f $newShift.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm"), $newShift.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm"), $newShift.SharedShift.Notes) | Add-Content -Path $logPath
Write-Debug("{0} {1}: {2} {3} {4} {5}" -f $dayDate, $dayDate.DayOfWeek, $mail, $shiftName, $StartDate, $EndDate)
#$newShift = 0
return $newShift return $newShift
} }
function Remove-Shift {
param(
[PSCustomObject]$shift,
[string]$teamID
)
if($script:noplan -eq $false) {
Write-Debug("{0} {1}: removing {2}'s shift - {2} {3}-{4}" -f $dayDate, $dayDate.DayOfWeek, $futureds_email, $shift.Notes, $shift.StartDateTime, $shift.EndDateTime)
Remove-MgTeamScheduleShift -ShiftId $shift.id -TeamId $teamID
}
else {
Write-Debug("{0} {1}: Not removing {2}'s shift - {2} {3}-{4} - running with -noplan" -f $dayDate, $dayDate.DayOfWeek, $futureds_email, $shift.Notes, $shift.StartDateTime, $shift.EndDateTime)
}
}
function Invoke-HasTimeOff { function Invoke-HasTimeOff {
param( param(
[string]$UID, [string]$UID,
@@ -77,7 +92,7 @@ function Invoke-HasTimeOff {
foreach ($toff in $timeoff) { foreach ($toff in $timeoff) {
if($toff.UserId -eq $UID) { if($toff.UserId -eq $UID) {
Write-Debug("{0} {1}: {2} has time off at this time" -f $dayDate, $dayDate.DayOfWeek, $mail) Write-Debug("{0} {1}: {2} has time off" -f $dayDate, $dayDate.DayOfWeek, $mail)
return $true return $true
break break
} }
@@ -93,7 +108,7 @@ function Invoke-HasShift {
foreach ($shift in $shifts) { foreach ($shift in $shifts) {
if($shift.UserId -eq $UID) { if($shift.UserId -eq $UID) {
Write-Debug("{0} {1}: {2} has a shift at this time" -f $dayDate, $dayDate.DayOfWeek, $mail) Write-Debug("{0} {1}: {2} has a shift already - {3} {4}-{5}" -f $dayDate, $dayDate.DayOfWeek, $mail, $shift.SharedShift.Notes, $shift.SharedShift.StartDateTime, $shift.SharedShift.EndDateTime)
return $true return $true
break break
} }
@@ -111,7 +126,7 @@ function Invoke-HasShiftorTimeOff {
foreach ($shift in $shifts) { foreach ($shift in $shifts) {
if($shift.UserId -eq $UID) { if($shift.UserId -eq $UID) {
Write-Debug("{0} {1}: {2} has a shift or time off at this time" -f $dayDate, $dayDate.DayOfWeek, $mail) Write-Debug("{0} {1}: {2} has a shift already - {3} {4}-{5}" -f $dayDate, $dayDate.DayOfWeek, $mail, $shift.SharedShift.Notes, $shift.SharedShift.StartDateTime, $shift.SharedShift.EndDateTime)
return $true return $true
break break
} }
@@ -119,7 +134,7 @@ function Invoke-HasShiftorTimeOff {
foreach ($toff in $timeoff) { foreach ($toff in $timeoff) {
if($toff.UserId -eq $UID) { if($toff.UserId -eq $UID) {
Write-Debug("{0} {1}: {2} has a shift or time off at this time" -f $dayDate, $dayDate.DayOfWeek, $mail) Write-Debug("{0} {1}: {2} has time off" -f $dayDate, $dayDate.DayOfWeek, $mail)
return $true return $true
break break
} }
@@ -127,8 +142,6 @@ function Invoke-HasShiftorTimeOff {
return $false return $false
} }
#Microsoft auth
$body = @{ $body = @{
grant_type = "client_credentials" grant_type = "client_credentials"
resource = "https://graph.microsoft.com" resource = "https://graph.microsoft.com"
@@ -143,14 +156,10 @@ $token = $response.access_token
Import-Module Microsoft.Graph.Teams Import-Module Microsoft.Graph.Teams
Connect-MgGraph -AccessToken $($token | ConvertTo-SecureString -AsPlainText -Force) >> $null Connect-MgGraph -AccessToken $($token | ConvertTo-SecureString -AsPlainText -Force) >> $null
# Dnešní datum a plán směn # ---| SCHEDULE |---
#$today = (Get-Date).Date
#$today = $today_old.AddYears(2)
$today = Get-Date -Day 1 -Month 2 -Year 2027 -Hour 9 -Minute 00 -Second 00 -Millisecond 00
$schedule = Get-Content -Path "./config.json" -Raw | ConvertFrom-Json $schedule = Get-Content -Path "./config.json" -Raw | ConvertFrom-Json
# ---| ALL MEMBERS SPECIFIED IN THE SCHEDULE |---
$allemails = $schedule.PSObject.Properties | ForEach-Object { $allemails = $schedule.PSObject.Properties | ForEach-Object {
if ($_.Name -in @("monday", "tuesday", "wednesday", "thursday", "friday")) { if ($_.Name -in @("monday", "tuesday", "wednesday", "thursday", "friday")) {
$_.Value.PSObject.Properties | ForEach-Object { $_.Value.PSObject.Properties | ForEach-Object {
@@ -163,155 +172,183 @@ $allemails = $schedule.PSObject.Properties | ForEach-Object {
} }
} | Select-Object -Unique } | Select-Object -Unique
#Časové rozmezí plánování # --------------------------- | DATE SETTINGS | ---------------------------
#$Monday = $today.AddDays(1 - $today.DayOfWeek.value__) # ---| Today's date |---
#$Friday = $Monday.AddDays(4) $today = (Get-Date).Date
$daysahead = 5
# ---| Specific date |---
#$today = Get-Date -Day 27 -Month 10 -Year 2025 -Hour 9 -Minute 00 -Second 00 -Millisecond 00
$daysahead = 14 #How many days ahead to plan
$timeoff_past_look = -7 #How many days to look into the past for the start of a multi-day time off
# ---| Time span |---
$startSpanDate = Get-Date -Day $today.Day -Month $today.Month -Year $today.Year -Hour 9 -Minute 00 -Second 00 -Millisecond 00 $startSpanDate = Get-Date -Day $today.Day -Month $today.Month -Year $today.Year -Hour 9 -Minute 00 -Second 00 -Millisecond 00
$endSpanDate = Get-Date -Day $startSpanDate.AddDays($daysahead).Day -Month $startSpanDate.AddDays($daysahead).Month -Year $startSpanDate.AddDays($daysahead).Year -Hour 17 -Minute 00 -Second 00 -Millisecond 00 $endSpanDate = Get-Date -Day $startSpanDate.AddDays($daysahead).Day -Month $startSpanDate.AddDays($daysahead).Month -Year $startSpanDate.AddDays($daysahead).Year -Hour 17 -Minute 00 -Second 00 -Millisecond 00
#RLCZ maintenance # --------------------------- | RLCZ MAINTENANCE SETTINGS | ---------------------------
$rlcz_mtnc_email = "jiri.kotlan@itego.cz" $rlcz_mtnc_email = "jiri.kotlan@itego.cz"
$rlcz_shift_reduction = -3 $rlcz_shift_reduction = -3 #How many hours does the next day shift get reduced by
# --------------------------- | MAIN SCRIPT | ---------------------------
# SKRIPT
try { try {
$team = Get-MgTeam -Property "id,displayName" | Where-Object -property displayName -value $teamsName -eq $team = Get-MgTeam -Property "id,displayName" | Where-Object -property displayName -value $teamsName -eq
$group = Get-MgTeamScheduleSchedulingGroup -TeamId $team.id -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } | Where-Object -property displayName -value $scheduleGroupName -eq $group = Get-MgTeamScheduleSchedulingGroup -TeamId $team.id -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } | Where-Object -property displayName -value $scheduleGroupName -eq
$allshifts = [object[]] (Get-MgTeamScheduleShift -TeamId $team.id -Filter "SharedShift/StartDateTime ge $($startSpanDate.toString('yyyy-MM-ddT00:00:00Z'))" -All -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin }) $allshifts = [object[]] (Get-MgTeamScheduleShift -TeamId $team.id -Filter "SharedShift/StartDateTime ge $($startSpanDate.toString('yyyy-MM-ddT00:00:00Z'))" -All -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin })
$timeoff_all = [object[]] (Get-MgTeamScheduleTimeOff -TeamId $team.id -Filter "SharedTimeOff/StartDateTime ge $($startSpanDate.toString('yyyy-MM-ddT00:00:00Z'))" -All -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } | Select-Object -Property *,@{name="Date";expression={$_.SharedTimeOff.StartDateTime.AddHours(1).Date}}) $timeoff_all = [object[]] (Get-MgTeamScheduleTimeOff -TeamId $team.id -Filter "SharedTimeOff/StartDateTime ge $($startSpanDate.AddDays($timeoff_past_look).toString('yyyy-MM-ddT00:00:00Z'))" -All -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } | Select-Object -Property *,@{name="Date";expression={$_.SharedTimeOff.StartDateTime.AddHours(1).Date}})
#return # ---| SHIFT CLEARING with -clear |---
if ($clear) {
#$timeoff_today = $timeoff_all | Where-Object -Property Date -eq -Value $(Get-Date -Day 20 -Month 1 -Year 2027).Date foreach ($shift in $allshifts) {
if($shift.SharedShift.Notes -ne "RLCZ") {
Remove-Shift -shift $shift -teamID $team.Id
}
}
return
}
#if ($clear) {
# foreach ($shift in $allshifts) {
# Remove-MgTeamSchedu#leShift -TeamId $team.id -ShiftId $shift.id
# }
#
# return
# }
#Procházíme dny v časovém rozmezí
$timeSpan = New-TimeSpan -Start $startSpanDate -End $endSpanDate $timeSpan = New-TimeSpan -Start $startSpanDate -End $endSpanDate
Write-Debug("Planning from {0} to {1}" -f $startSpanDate, $endSpanDate) Write-Debug("Planning from {0} to {1}" -f $startSpanDate, $endSpanDate)
# ---| DAY LOOP |---
for ($dayNumber = 0; $dayNumber -lt $timespan.Days; $dayNumber++) { for ($dayNumber = 0; $dayNumber -lt $timespan.Days; $dayNumber++) {
$dayDate = $today.AddDays($dayNumber); $dayDate = $today.AddDays($dayNumber);
#Pokud jde o pracovní den, jinak se jde ihned na další den # ---| WEEKEND CHECK |---
if ($dayDate.DayOfWeek -notin @("Saturday", "Sunday")) { if($dayDate.DayOfWeek -in @("Saturday", "Sunday")) {
#Inicializace dne Write-Debug("{0} {1}: skipping weekend day" -f $dayDate, $dayDate.DayOfWeek)
continue
}
# ---| NEW DAY INIT |---
$ds_shift_inplace = $false
$ho_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ho'
$ds_email = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ds'
$os_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'os'
$ns_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ns'
# ---| TIME SYNC |---
$dateStart = $(get-date -Day $dayDate.Day -Month $dayDate.Month -Year $dayDate.Year -Hour 9 -Minute 00 -Second 00).AddHours(-1)
$dateEnd = $(get-date -Day $dayDate.Day -Month $dayDate.Month -Year $dayDate.Year -Hour 17 -Minute 00 -Second 00).AddHours(-1)
if (($dayDate.IsDaylightSavingTime()) -eq $true) {
$dateStart = $dateStart.AddHours(-1)
$dateEnd = $dateEnd.AddHours(-1)
}
$dayEnd = Get-Date -Day $dayDate.Day -Month $dayDate.Month -Year $dayDate.Year -Hour 23 -Minute 00 -Second 0
$dayStart = $dayEnd.AddDays(-1)
# ---| TODAY'S SHIFTS AND TIME OFF |---
$shifts_today = [Object[]] $allshifts | Where-Object -Filter {
$_.schedulingGroupId -eq $group.Id -and $_.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.ToString("yyyy-MM-dd HH:mm") -and $_.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.ToString("yyyy-MM-dd HH:mm")
}
$timeoff_today = [Object[]] $timeoff_all | Where-Object {
$_.SharedTimeOff.StartDateTime.Date -le $dayStart.Date -and
$_.SharedTimeOff.EndDateTime.Date -ge $dayEnd.Date
}
$manual_dayshifts = [Object[]] $shifts_today | Where-Object -Filter { ($_.SharedShift.Notes -eq "Home Office - Denní směna") -or ($_.SharedShift.Notes -eq "Office - Denní směna") }
if ($null -eq $manual_dayshifts) {
$ds_shift_inplace = $false $ds_shift_inplace = $false
Write-Debug("{0} {1}: day shift not yet set" -f $dayDate, $dayDate.DayOfWeek)
}
else {
$ds_shift_inplace = $true
Write-Debug("{0} {1}: day shift set already" -f $dayDate, $dayDate.DayOfWeek)
}
#Množina emailů pro tento den v týdnu co mají mít home office # ---| TEAM MEMBER LOOP |---
$ho_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ho' foreach($email in $allemails) {
$userId = $(Get-MgUser -Filter "UserPrincipalName eq '$email' or proxyAddresses/any(c:c eq 'smtp:$email')").Id
#Email a ID toho kdo má mít tento den denní směnu # ---| DAY SHIFT CHECK |---
$ds_email = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ds' if($ds_shift_inplace -eq $false) {
if($email -eq $ds_email) {
Write-Debug("{0} {1}: checking {2} for day shift availability..." -f $dayDate, $dayDate.DayOfWeek, $email)
#Emaily těch co jsou on-site u zákazníka # ---| IF DAY SHIFT CAN BE ASSIGNED TO THE PROPER MEMEBER |---
$os_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'os' if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) {
# ---| HOME-OFFICE DAY SHIFT |---
#Emaily těch co nemají mít dnes žádnou směnu if ($email -in $ho_emails) {
$ns_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ns' $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $email
$allshifts += [Object[]] $newshift
#Upravení času $ds_shift_inplace = $true
$dateStart = $(get-date -Day $dayDate.Day -Month $dayDate.Month -Year $dayDate.Year -Hour 9 -Minute 00 -Second 00).AddHours(-1) continue
$dateEnd = $(get-date -Day $dayDate.Day -Month $dayDate.Month -Year $dayDate.Year -Hour 17 -Minute 00 -Second 00).AddHours(-1)
if (($dayDate.IsDaylightSavingTime()) -eq $true) {
$dateStart = $dateStart.AddHours(-1)
$dateEnd = $dateEnd.AddHours(-1)
}
$shifts_today = [Object[]] $allshifts | Where-Object -Filter {
$_.schedulingGroupId -eq $group.Id -and $_.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.ToString("yyyy-MM-dd HH:mm") -and $_.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.ToString("yyyy-MM-dd HH:mm")
}
$timeoff_today = [Object[]] $timeoff_all | Where-Object -Filter {
($_.SharedTimeOff.StartDateTime.Date -eq $dateStart.Date -or $_.SharedTimeOff.EndDateTime.Date -eq $dateEnd.Date)
}
# Tohle jsou všechny způsoby co jsem zkoušel, nikdy to nematchne, nikdy to nevidí dovolenou
#$timeoff_today = [Object[]] $timeoff_all | Where-Object -Filter { $_.schedulingGroupId -eq $group.Id -and $_.SharedTimeOff.StartDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.AddDays(1).ToString("yyyy-MM-dd HH:mm") -and $_.SharedTimeOff.EndDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.AddDays(-1).ToString("yyyy-MM-dd HH:mm") }
#$timeoff_today = [Object[]] $timeoff_all | Where-Object { $_.schedulingGroupId -eq $group.Id -and $_.SharedTimeOff.StartDateTime -lt $dateEnd -and $_.SharedTimeOff.EndDateTime -gt $dateStart }
#$timeoff_today = $timeoff_all | Where-Object { $_.schedulingGroupId -eq $group.Id -and ([datetime]$_.SharedTimeOff.StartDateTime) -lt $dayEnd -and ([datetime]$_.SharedTimeOff.EndDateTime) -gt $dayStart }
#$timeoff_today = [Object[]] $timeoff_all | Where-Object -Filter { $_.schedulingGroupId -eq $group.Id -and $_.SharedTimeOff.StartDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.ToString("yyyy-MM-ddT00:00:00Z") -and $_.SharedTimeOff.EndDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.AddDays(1).ToString("yyyy-MM-ddT00:00:00Z") }
#$timeoff_today = [Object[]] $timeoff_all | Where-Object -Filter { $_.schedulingGroupId -eq $group.Id -and $_.SharedTimeOff.StartDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.ToString("yyyy-MM-ddT00:00:00Z") -and $_.SharedTimeOff.EndDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.ToString("yyyy-MM-ddT00:00:00Z") }
#Pokus o naplnění množiny manuálně daných denních směn pro tento den
$manual_dayshifts = [Object[]] $shifts_today | Where-Object -Filter { ($_.SharedShift.Notes -eq "Home Office - Denní směna") -or ($_.SharedShift.Notes -eq "Office - Denní směna") }
if ($null -eq $manual_dayshifts) {
$ds_shift_inplace = $false
Write-Debug("{0} {1}: day shift not set" -f $dayDate, $dayDate.DayOfWeek)
foreach($shift in $manual_dayshifts) {
Write-Debug("{0}: {1}-{2}"-f $shift.SharedShift.Notes, $shift.SharedShift.StartDateTime, $shift.SharedShift.EndDateTime)
}
}
else {
$ds_shift_inplace = $true
Write-Debug("{0} {1}: day shift set already" -f $dayDate, $dayDate.DayOfWeek)
foreach($shift in $manual_dayshifts) {
Write-Debug("{0}: {1}-{2}"-f $shift.SharedShift.Notes, $shift.SharedShift.StartDateTime, $shift.SharedShift.EndDateTime)
}
}
foreach($email in $allemails) {
$userId = $(Get-MgUser -Filter "UserPrincipalName eq '$email' or proxyAddresses/any(c:c eq 'smtp:$email')").Id
if($ds_shift_inplace -eq $false) {
if($email -eq $ds_email) {
Write-Debug("{0} {1}: checking {2} for day shift availability..." -f $dayDate, $dayDate.DayOfWeek, $email)
foreach($toff in $timeoff_today) {
if($toff.UserId -eq $userId) {
Write-Debug("{0}: {1} {2}" -f $email, $toff.SharedTimeOff.StartDateTime, $toff.SharedTimeOff.EndDateTime)
}
}
if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) {
if ($email -in $ho_emails) {
$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $email
$allshifts += [Object[]] $newshift
$ds_shift_inplace = $true
continue
}
else {
$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $email
$allshifts += [Object[]] $newShift
$ds_shift_inplace = $true
continue
}
} }
# ---| OFFICE DAY SHIFT |---
else { else {
#Budeme hledat ve zbývajících dnech zvoleného rozsahu $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $email
Write-Debug("{0} {1}: looking ahead for a day shift replacement" -f $dayDate, $dayDate.DayOfWeek) $allshifts += [Object[]] $newShift
$remainingdays = $timespan.Days - $dayNumber $ds_shift_inplace = $true
for ($daysahead = 1; $daysahead -lt $remainingdays; $daysahead++) { continue
$futureday = $dayDate.AddDays($daysahead) }
#Pokud jsme narazili na pracovní den... }
if ($futureday.DayOfWeek -notin @("Saturday", "Sunday")) {
#...jdeme se podívat kdo má mít denní směnu # ---| DAY SHIFT REPLACEMENT CHECK |---
$futureds_email = $schedule.($futureday.DayOfWeek.ToString().ToLower()).'ds' else {
Write-Debug(">>> {0} {1}: {2} has it on that day" -f $futureday, $futureday.DayOfWeek, $futureds_email) Write-Debug("{0} {1}: looking ahead for a day shift replacement" -f $dayDate, $dayDate.DayOfWeek)
$futureds_id = $(Get-MgUser -Filter "UserPrincipalName eq '$futureds_email' or proxyAddresses/any(c:c eq 'smtp:$futureds_email')").Id $remainingdays = $timespan.Days - $dayNumber
#Má další na řadě nastavenou na dnešek směnu? Pokud ne tak má denní a hledání ukončujeme, jinak se jde na další den
if((Invoke-HasTimeOff -UID $futureds_id -timeoff $timeoff_today -mail $futureds_email) -eq $false -and ($futureds_email -notin $os_emails) -and ($futureds_email -notin $ns_emails)) { # ---| FUTURE DAYS LOOP |---
Write-Debug(">>> {0} {1}: {2} doesn't have time off, on site or no-shift on {3} {4}" -f $futureday, $futureday.DayOfWeek, $futureds_email, $dayDate, $dayDate.DayOfWeek) for ($daysahead = 1; $daysahead -lt $remainingdays; $daysahead++) {
if((Invoke-HasShift -UID $futureds_id -shifts $shifts_today -mail $futureds_email) -eq $false) { $futureday = $dayDate.AddDays($daysahead)
Write-Debug(">>> {0} {1}: {2} ID: {3} doesn't have a shift on {4} {5}" -f $futureday, $futureday.DayOfWeek, $futureds_email, $futureds_id, $dayDate, $dayDate.DayOfWeek)
# ---| WEEKEND CHECK |---
if ($futureday.DayOfWeek -in @("Saturday", "Sunday")) {
Write-Debug(">>> {0} {1}: skipping weekend day" -f $futureday, $futureday.DayOfWeek, $futureds_email)
continue
}
# ---| NEXT IN LINE FOR THE DAY-SHIFT |---
$futureds_email = $schedule.($futureday.DayOfWeek.ToString().ToLower()).'ds'
$futureds_id = $(Get-MgUser -Filter "UserPrincipalName eq '$futureds_email' or proxyAddresses/any(c:c eq 'smtp:$futureds_email')").Id
Write-Debug(">>> {0} {1}: {2} has it on that day" -f $futureday, $futureday.DayOfWeek, $futureds_email)
# ---| THE NEXT IN LINE FOR THE DAY-SHIFT DOESN'T HAVE TIME OFF, NO-SHIFT OR ON-SITE |---
if((Invoke-HasTimeOff -UID $futureds_id -timeoff $timeoff_today -mail $futureds_email) -eq $false -and ($futureds_email -notin $os_emails) -and ($futureds_email -notin $ns_emails)) {
# ---| NEXT IN LINE DOESN'T HAVE A SHIFT ALREADY |---
if((Invoke-HasShift -UID $futureds_id -shifts $shifts_today -mail $futureds_email) -eq $false) {
# ---| HOME-OFFICE DAY SHIFT |---
if($futureds_email -in $ho_emails) {
$newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Home Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email
$allshifts += [Object[]] $newshift
$ds_shift_inplace = $true
break
}
# ---| OFFICE DAY SHIFT |---
else {
$newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email
$allshifts += [Object[]] $newShift
$ds_shift_inplace = $true
break
}
}
# ---| NEXT IN LINE HAS A SHIFT ALREADY |---
else {
# ---| LOOKING FOR THE SHIFT |---
foreach ($shift in $shifts_today) {
if($shift.UserId -eq $futureds_id) {
# ---| REMOVE THE SHIFT |---
Remove-Shift -shift $shift -teamID $team.Id
# ---| HOME-OFFICE DAY SHIFT |---
if($futureds_email -in $ho_emails) { if($futureds_email -in $ho_emails) {
$newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Home Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email $newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Home Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email
$allshifts += [Object[]] $newshift $allshifts += [Object[]] $newshift
$ds_shift_inplace = $true $ds_shift_inplace = $true
break break
} }
# ---| OFFICE DAY SHIFT |---
else { else {
$newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email $newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email
$allshifts += [Object[]] $newShift $allshifts += [Object[]] $newShift
@@ -319,112 +356,99 @@ try {
break break
} }
} }
else {
Write-Debug(">>> {0} {1}: {2} has a shift on {3} {4}" -f $futureday, $futureday.DayOfWeek, $futureds_email, $dayDate, $dayDate.DayOfWeek)
foreach ($shift in $shifts_today) {
if($shift.UserId -eq $futureds_id) {
Write-Debug(">>> {0} {1}: removing shift {2} {3} {4} for {5}" -f $futureday, $futureday.DayOfWeek, $shift.Notes, $shift.StartDateTime, $shift.EndDateTime, $futureds_email)
Remove-MgTeamScheduleShift -ShiftId $shift.id -TeamId $team.Id
if($futureds_email -in $ho_emails) {
$newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Home Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email
$allshifts += [Object[]] $newshift
$ds_shift_inplace = $true
break
}
else {
$newshift = Set-Shift -userId $futureds_id -groupID $group.id -shiftName "Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $futureds_email
$allshifts += [Object[]] $newShift
$ds_shift_inplace = $true
break
}
}
}
}
}
else {
foreach($timeoff in $timeoff_today) {
if($timeoff.UserId -eq $futureds_id) {
Write-Debug(">>> {0} {1}: {2} has a shift on {3} {4} - {5} {6} {7}" -f $futureday, $futureday.DayOfWeek, $futureds_email, $dayDate, $dayDate.DayOfWeek, $timeoff.SharedTimeOff.Notes, $timeoff.SharedTimeOff.StartDateTime, $timeoff.SharedTimeOff.EndDateTime)
}
}
if($futureds_email -in $os_emails) {
Write-Debug(">>> {0} {1}: {2} is on the on-site list {3} {4}" -f $futureday, $futureday.DayOfWeek, $futureds_email, $dayDate, $dayDate.DayOfWeek)
}
if($futureds_email -in $ns_emails) {
Write-Debug(">>> {0} {1}: {2} is on the no-shift list {3} {4}" -f $futureday, $futureday.DayOfWeek, $futureds_email, $dayDate, $dayDate.DayOfWeek)
}
} }
} }
} }
# ---| IF THE DAY SHIFT IS SET, BREAK OUT OF THE FUTURE DAYS LOOP |---
if($ds_shift_inplace -eq $true) {
break
}
# ---| MOVE ON TO THE NEXT FUTURE DAY IF NO CONDITION IS MET |---
continue continue
} }
} }
} }
}
# ---| END OF THE DAY SHIFT CHECK SECTION |---
if($email -in $os_emails) { # ---| UPDATE COLLECTION OF SHIFTS TODAY |---
if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) { $shifts_today = [Object[]] $allshifts | Where-Object -Filter {
$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "On-site" -StartDate $dateStart -EndDate $dateEnd -color "gray" -teamID $team.id -mail $email $_.schedulingGroupId -eq $group.Id -and $_.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.ToString("yyyy-MM-dd HH:mm") -and $_.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.ToString("yyyy-MM-dd HH:mm")
$allshifts += [Object[]] $newshift }
continue
}
}
if($email -in $ns_emails) {
continue
}
if($email -eq $rlcz_mtnc_email) {
if ($dayDate.DayOfWeek -eq "Thursday") {
$yesterday = $dayDate.AddDays(-1)
$rlcz_shifts = [Object[]] $allshifts | Where-Object -Filter { $_.schedulingGroupId -eq $group.Id -and $_.SharedShift.Notes -eq "RLCZ" -and ($_.SharedShift.StartDateTime.Date -eq $yesterday.Date -or $_.SharedShift.EndDateTime.Date -eq $yesterday.Date) }
if (Invoke-HasShift -UID $userId -shifts $rlcz_shifts -mail $email) {
if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_toda -mail $email) -eq $false) {
if($email -in $ho_emails) {
$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home office" -StartDate $dateStart -EndDate $dateEnd.AddHours($rlcz_shift_reduction) -color "pink" -teamID $team.id -mail $email
$allshifts += [Object[]] $newshift
continue
}
else {
$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office" -StartDate $dateStart -EndDate $dateEnd.AddHours($rlcz_shift_reduction) -color "blue" -teamID $team.id -mail $email
$allshifts += [Object[]] $newshift
continue
}
}
}
}
}
if($email -in $ho_emails) {
if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) {
$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home office" -StartDate $dateStart -EndDate $dateEnd -color "pink" -teamID $team.id -mail $email
$allshifts += [Object[]] $newshift
continue
}
}
# ---| ON-SITE SHIFT CHECK |---
if($email -in $os_emails) {
if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) { if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) {
$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office" -StartDate $dateStart -EndDate $dateEnd -color "blue" -teamID $team.id -mail $email $newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "On-site" -StartDate $dateStart -EndDate $dateEnd -color "gray" -teamID $team.id -mail $email
$allshifts += [Object[]] $newshift $allshifts += [Object[]] $newshift
continue continue
} }
} }
# ---| NO-SHIFT CHECK |---
if($email -in $ns_emails) {
Write-Debug("{0} {1}: {2} has no-shift defined for today" -f $dayDate, $dayDate.DayOfWeek, $email)
continue
}
# ---| RLCZ MAINTENANCE CHECK |---
if($email -eq $rlcz_mtnc_email) {
if ($dayDate.DayOfWeek -eq "Thursday") {
$yesterday = $dayDate.AddDays(-1)
$rlcz_shifts = [Object[]] $allshifts | Where-Object -Filter { $_.schedulingGroupId -eq $group.Id -and $_.SharedShift.Notes -eq "RLCZ" -and ($_.SharedShift.StartDateTime.Date -eq $yesterday.Date -or $_.SharedShift.EndDateTime.Date -eq $yesterday.Date) }
if (Invoke-HasShift -UID $userId -shifts $rlcz_shifts -mail $email) {
if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) {
if($email -in $ho_emails) {
$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home office" -StartDate $dateStart -EndDate $dateEnd.AddHours($rlcz_shift_reduction) -color "pink" -teamID $team.id -mail $email
$allshifts += [Object[]] $newshift
continue
}
else {
$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office" -StartDate $dateStart -EndDate $dateEnd.AddHours($rlcz_shift_reduction) -color "blue" -teamID $team.id -mail $email
$allshifts += [Object[]] $newshift
continue
}
}
}
}
}
# ---| HOME-OFFICE CHECK |---
if($email -in $ho_emails) {
if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) {
$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home office" -StartDate $dateStart -EndDate $dateEnd -color "pink" -teamID $team.id -mail $email
$allshifts += [Object[]] $newshift
continue
}
}
# ---| OFFICE DEFAULT |---
if((Invoke-HasShiftorTimeOff -UID $userId -shifts $shifts_today -timeoff $timeoff_today -mail $email) -eq $false) {
$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office" -StartDate $dateStart -EndDate $dateEnd -color "blue" -teamID $team.id -mail $email
$allshifts += [Object[]] $newshift
continue
}
} }
} }
$params = @{ # ---| SCHEDULE SHARING |---
notifyTeam = $false if($script:noplan -eq $false) {
startDateTime = [System.DateTime]::Parse($startSpanDate.ToString("yyyy-MM-dd'T'HH:mm:ssZ"))
endDateTime = [System.DateTime]::Parse($endSpanDate.ToString("yyyy-MM-dd'T'HH:mm:ssZ")) $params = @{
notifyTeam = $false
startDateTime = [System.DateTime]::Parse($startSpanDate.ToString("yyyy-MM-dd'T'HH:mm:ssZ"))
endDateTime = [System.DateTime]::Parse($endSpanDate.ToString("yyyy-MM-dd'T'HH:mm:ssZ"))
}
Invoke-MgShareTeamSchedule -TeamId $team.Id -BodyParameter $params -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin }
("SHARING: {0}" -f $scheduleGroupName) | Add-Content -Path $logPath
}
else {
Write-Debug("Schedule not shared because of -noplan")
} }
Invoke-MgShareTeamSchedule -TeamId $team.Id -BodyParameter $params -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin }
("SHARING: {0}" -f $scheduleGroupName) | Add-Content -Path $logPath
} }
catch { catch {
$_ $_

310
shifts_copy.ps1 Normal file
View File

@@ -0,0 +1,310 @@
param(
[switch]$debug,
[switch]$clear
)
if ($debug) {
$script:debug = $debug
}
$teamsName = "IT Support & Delivery"
$scheduleGroupName = "IT SUPPORT"
# App Registration details & Tenant ID
$ClientId = "6cb76bbf-f253-4551-87a8-5e1f49d8ace3"
$ClientSecret = "IQg8Q~JTBTDbrHyjKMc.KMSETtQoKWvUhnCr1aY1"
$tenantid = "e81b4a31-e8ad-4df6-aa30-3bdcc1da2cdd"
$userIdAdmin = "747bd624-5cd7-4ae0-952f-5dc374e07a5e"
$logPath = (".\log_{0}.log" -f (Get-Date).toString("yyyy_MM_dd"))
function Write-Debug {
param(
[string]$message
)
if ($script:debug) {
Write-Host $message
}
else {
$message | Add-Content $logPath
}
}
#Naplánování konkrétní směny
function Set-Shift {
param(
[string]$userId,
[string]$groupID,
[string]$shiftName,
[System.DateTime]$StartDate,
[System.DateTime]$EndDate,
[string]$color,
[string]$teamID,
[string]$mail
)
$params = @{
UserId = $userId
schedulingGroupId = $groupID
sharedShift = @{
notes = ($shiftName)
startDateTime = [System.DateTime]::Parse($StartDate.ToString("yyyy-MM-dd'T'HH:mm:ssZ"))
endDateTime = [System.DateTime]::Parse($EndDate.ToString("yyyy-MM-dd'T'HH:mm:ssZ"))
theme = $color
}
}
#$headers = @{
# "MS-APP-ACTS-AS" = $userIdAdmin
# "Prefer" = "no-notification"
#}
$newShift = New-MgTeamScheduleShift -TeamId $teamID -BodyParameter $params -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin }
#Write-Debug ("SCHEDULING: {0} {1} - {2}" -f $newShift.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm"), $newShift.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm"), $newShift.SharedShift.Notes)
#("SCHEDULING: {0} {1} - {2}" -f $newShift.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm"), $newShift.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm"), $newShift.SharedShift.Notes) | Add-Content -Path $logPath
Write-Debug ("{0} {1}: {2} {3} {4} {5}" -f $dayDate, $dayDate.DayOfWeek, $mail, $shiftName, $StartDate, $EndDate)
#$newShift = 0
return $newShift
}
function Invoke-HasTimeOff {
param(
[string]$UID,
[PSCustomObject]$timeoff,
[string]$mail
)
foreach ($toff in $timeoff) {
if ($toff.UserId -eq $UID) {
Write-Debug ("{0} {1}: {2} has time off at this time" -f $dayDate, $dayDate.DayOfWeek, $mail)
return $true
break
}
}
return $false
}
function Invoke-HasShift {
param(
[string]$UID,
[PSCustomObject]$shifts,
[string]$mail
)
foreach ($shift in $shifts) {
if ($shift.UserId -eq $UID) {
Write-Debug ("{0} {1}: {2} has a shift at this time" -f $dayDate, $dayDate.DayOfWeek, $mail)
return $true
break
}
}
return $false
}
function Invoke-HasShiftorTimeOff {
param(
[string]$UID,
[PSCustomObject]$shifts,
[PSCustomObject]$timeoff,
[string]$mail
)
foreach ($shift in $shifts) {
if ($shift.UserId -eq $UID) {
Write-Debug ("{0} {1}: {2} has a shift or time off at this time" -f $dayDate, $dayDate.DayOfWeek, $mail)
return $true
break
}
}
foreach ($toff in $timeoff) {
if ($toff.UserId -eq $UID) {
Write-Debug ("{0} {1}: {2} has a shift or time off at this time" -f $dayDate, $dayDate.DayOfWeek, $mail)
return $true
break
}
}
return $false
}
#Microsoft auth
$body = @{
grant_type = "client_credentials"
resource = "https://graph.microsoft.com"
client_id = $ClientId
client_secret = $ClientSecret
}
$authUri = "https://login.microsoftonline.com/$tenantid/oauth2/token"
$response = Invoke-RestMethod $authUri -Method 'POST' -Body $body
$token = $response.access_token
Import-Module Microsoft.Graph.Teams
Connect-MgGraph -AccessToken $($token | ConvertTo-SecureString -AsPlainText -Force) >> $null
# Dnešní datum a plán směn
#$today = (Get-Date).Date
#$today = $today_old.AddYears(2)
$today = (Get-Date -Day 14 -Month 10 -Year 2025).Date
$schedule = Get-Content -Path "./config.json" -Raw | ConvertFrom-Json
$allemails = $schedule.PSObject.Properties | ForEach-Object {
if ($_.Name -in @("monday", "tuesday", "wednesday", "thursday", "friday")) {
$_.Value.PSObject.Properties | ForEach-Object {
if ($_.Name -in @("ds", "ho", "os", "ns")) {
$_.Value | ForEach-Object {
$_
}
}
}
}
} | Select-Object -Unique
#Časové rozmezí plánování
$daysahead = 5
$startSpanDate = Get-Date -Day $today.Day -Month $today.Month -Year $today.Year -Hour 9 -Minute 00 -Second 00 -Millisecond 00
$endSpanDate = Get-Date -Day $startSpanDate.AddDays($daysahead).Day -Month $startSpanDate.AddDays($daysahead).Month -Year $startSpanDate.AddDays($daysahead).Year -Hour 17 -Minute 00 -Second 00 -Millisecond 00
#RLCZ maintenance
$rlcz_mtnc_email = "jiri.kotlan@itego.cz"
$rlcz_shift_reduction = -3
# SKRIPT
try {
$team = Get-MgTeam -Property "id,displayName" | Where-Object -property displayName -value $teamsName -eq
$group = Get-MgTeamScheduleSchedulingGroup -TeamId $team.id -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } | Where-Object -property displayName -value $scheduleGroupName -eq
$allshifts = [object[]] (Get-MgTeamScheduleShift -TeamId $team.id -Filter "SharedShift/StartDateTime ge $($startSpanDate.toString('yyyy-MM-ddT00:00:00Z'))" -All -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin })
$timeoff_all = [object[]] (Get-MgTeamScheduleTimeOff -TeamId $team.id -Filter "SharedTimeOff/StartDateTime ge $($startSpanDate.toString('yyyy-MM-ddT00:00:00Z'))" -All -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin } | Select-Object -Property *, @{name = "Date"; expression = { $_.SharedTimeOff.StartDateTime.AddHours(1).Date } })
#Procházíme dny v časovém rozmezí
$timeSpan = New-TimeSpan -Start $startSpanDate -End $endSpanDate
Write-Debug ("Planning from {0} to {1}" -f $startSpanDate, $endSpanDate)
for ($dayNumber = 0; $dayNumber -lt $timespan.Days; $dayNumber++) {
$dayDate = $today.AddDays($dayNumber);
#Pokud jde o pracovní den, jinak se jde ihned na další den
if ($dayDate.DayOfWeek -in @("Saturday", "Sunday")) {
Write-Debug ("is weekend {0}" -f $dayDate)
continue
}
#Množina emailů pro tento den v týdnu co mají mít home office
$ho_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ho'
#Email a ID toho kdo má mít tento den denní směnu
$ds_email = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ds'
#Emaily těch co jsou on-site u zákazníka
$os_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'os'
#Emaily těch co nemají mít dnes žádnou směnu
$ns_emails = $schedule.($dayDate.DayOfWeek.ToString().ToLower()).'ns'
#Upravení času
$dateStart = $(get-date -Day $dayDate.Day -Month $dayDate.Month -Year $dayDate.Year -Hour 9 -Minute 00 -Second 00).AddHours(-1)
$dateEnd = $(get-date -Day $dayDate.Day -Month $dayDate.Month -Year $dayDate.Year -Hour 17 -Minute 00 -Second 00).AddHours(-1)
if (($dayDate.IsDaylightSavingTime()) -eq $true) {
$dateStart = $dateStart.AddHours(-1)
$dateEnd = $dateEnd.AddHours(-1)
}
$shifts_today = [Object[]] $allshifts | Where-Object -Filter {
$_.schedulingGroupId -eq $group.Id -and $_.SharedShift.StartDateTime.ToString("yyyy-MM-dd HH:mm") -ge $dateStart.ToString("yyyy-MM-dd HH:mm") -and $_.SharedShift.EndDateTime.ToString("yyyy-MM-dd HH:mm") -le $dateEnd.ToString("yyyy-MM-dd HH:mm")
}
$timeoff_today = [Object[]] $timeoff_all | Where-Object -Filter {
($_.SharedTimeOff.StartDateTime.Date -eq $dateStart.Date -or $_.SharedTimeOff.EndDateTime.Date -eq $dateEnd.Date)
}
Write-Debug ("Shifts {0}, TimeOff: {1}" -f $shifts_today.length, $timeoff_today.length)
$ds_covered = $false;
$userEmailToIdHashtable = @{}
$userEmailNotAvailable = @()
foreach ($email in $allemails) {
$userId = $(Get-MgUser -Filter "UserPrincipalName eq '$email' or proxyAddresses/any(c:c eq 'smtp:$email')").Id
$userEmailToIdHashtable[$email] = $userId
if ($userId -in $shifts_today.UserId) {
$userEmailNotAvailable += $email
Write-Debug ("{0} has Manual Shift" -f $email)
continue;
}
if ($userId -in $timeoff_today.UserId) {
$userEmailNotAvailable += $email
Write-Debug ("{0} has TimeOff" -f $email)
continue;
}
#NoShift
if ($email -in $ns_emails) {
$userEmailNotAvailable += $email
Write-Debug ("{0} has NULL Shift " -f $email)
continue
}
#OnSite
if ($email -in $os_emails) {
Write-Debug ("{0} has On Site " -f $email)
#$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "On-site" -StartDate $dateStart -EndDate $dateEnd -color "gray" -teamID $team.id -mail $os_email
#$allshifts += [Object[]] $newshift
continue
}
#Dení Směna
if ($email -eq $ds_email -and $email -in $ho_emails) {
Write-Debug ("{0} has Denní HO" -f $email)
#$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Home Office - Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $ds_email
#$allshifts += [Object[]] $newshift
$ds_covered = $true;
continue
}
elseif ($email -eq $ds_email) {
Write-Debug ("{0} has Denní" -f $email)
#$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Denní směna" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $ds_email
#$allshifts += [Object[]] $newshift
$ds_covered = $true;
continue
}
}
$timeoff_today = [Object[]] $timeoff_all | Where-Object -Filter {
($_.SharedTimeOff.StartDateTime.Date -eq $dateStart.Date -or $_.SharedTimeOff.EndDateTime.Date -eq $dateEnd.Date)
}
foreach ($email in ($allemails | Where-Object -Filter {$_ -notin $userEmailNotAvailable} | Where-Object -Filter {$userEmailToIdHashtable[$_] -notin $timeoff_today.UserId})) {
if (($ds_covered -eq $false)) {
$ds_covered = $true;
Write-Debug ("{0} has backup Denní" -f $email)
#$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $ds_email
#$allshifts += [Object[]] $newshift
continue
}
Write-Debug ("{0} has Office" -f $email)
#$newshift = Set-Shift -userId $userId -groupID $group.id -shiftName "Office" -StartDate $dateStart -EndDate $dateEnd -color "purple" -teamID $team.id -mail $ds_email
#$allshifts += [Object[]] $newshift
}
}
$params = @{
notifyTeam = $false
startDateTime = [System.DateTime]::Parse($startSpanDate.ToString("yyyy-MM-dd'T'HH:mm:ssZ"))
endDateTime = [System.DateTime]::Parse($endSpanDate.ToString("yyyy-MM-dd'T'HH:mm:ssZ"))
}
Invoke-MgShareTeamSchedule -TeamId $team.Id -BodyParameter $params -Headers @{ "MS-APP-ACTS-AS" = $userIdAdmin }
("SHARING: {0}" -f $scheduleGroupName) | Add-Content -Path $logPath
}
catch {
$_
break;
}