使用 PowerShell 将班次连接到 UKG Pro Workforce Management

概述

使用适用于 UKG Pro Workforce Management 的 Microsoft Teams 排班连接器将 Microsoft Teams 中的排班应用与 UKG Pro Workforce Management (UKG Pro WFM) 集成。 一线员工可以在 UKG Pro WFM中从班次中无缝查看和管理他们的日程安排。

本文介绍如何使用 PowerShell 设置和配置连接器,以将 Shifts 与 UKG Pro WFM集成。

若要设置连接,请运行 PowerShell 脚本。 该脚本配置连接器、应用同步设置、创建连接,并将 UKG Pro WFM 实例 (也称为) WFM实例映射到 Teams 中的团队。 同步设置确定在排班中启用的功能,以及 UKG Pro WFM 和排班之间同步的计划信息。 映射定义 Teams 中WFM实例与团队之间的同步关系。 可以映射到现有团队和新团队。

我们提供两个脚本。 可以使用任一脚本,具体取决于是要映射到现有团队还是创建要映射到的新团队。

可以设置多个连接,每个连接具有不同的同步设置。 例如,如果你的组织具有多个具有不同计划要求的位置,请为每个位置创建具有唯一同步设置的连接。 请记住,WFM 实例只能在任何给定时间映射到一个团队。 如果实例已映射到团队,则无法将其映射到另一个团队。

将 UKG Pro WFM 作为记录系统,一线员工可以有效地管理其设备上的排班计划和可用性。 一线经理可以继续使用 UKG Pro WFM来设置计划。

注意

还可以使用Microsoft 365 管理中心中的排班连接器向导将排班连接到 UKG Pro WFM。

开始之前

先决条件

花点时间查看 UKG Pro Workforce Management Teams 排班连接器的先决条件和要求中的信息并完成所有先决条件和配置任务。

在按照本文中的步骤操作之前,请确保完成所有任务。

使用 PowerShell 管理连接器的管理员角色

你必须是 Microsoft 365 全局管理员或排班连接器管理员才能完成本文中的步骤。

Shifts 连接器管理员角色是在 Microsoft Entra ID 中创建并分配给用户的自定义角色。 角色的名称必须是“Shifts 连接器管理员”。 角色不需要具有任何特定权限,不过,创建该角色时必须至少设置一个权限。 该服务依赖于用户上角色的存在,而不是其权限。

若要了解详细信息,请参阅在 Microsoft Entra ID 中创建和分配自定义角色向用户分配Microsoft Entra角色。 请记住,创建角色并将其应用到用户最多可能需要 24 小时。

设置环境

  1. 安装 Powershell 版本 7 或更新。 有关分步指南,请参阅在 Windows 上安装 PowerShell

  2. 以管理员模式运行 Powershell。

  3. 安装 Microsoft Graph PowerShell 模块。

    Install-Module Microsoft.Graph
    Import-Module Microsoft.Graph
    

    验证其版本是否为 1.6.1 或更高版本。

    Get-InstalledModule Microsoft.Graph 
    
  4. 安装 Teams 预览版 PowerShell 模块。

    Install-Module -Name MicrosoftTeams -AllowPrerelease -Force
    Import-Module MicrosoftTeams 
    

    验证它是否至少为版本 4.7.0 并包含 Shifts 连接器 cmdlet。

    Get-Command -Module MicrosoftTeams -Name *teamsshiftsconnection* 
    
  5. 将 PowerShell 设置为在运行脚本时出错时退出。

    $ErrorActionPreference = "Stop" 
    
  6. 启用脚本以在 Windows 中运行。

    Set-ExecutionPolicy bypass 
    

连接到 Teams

运行以下命令以连接到 Microsoft Teams。

Connect-MicrosoftTeams

出现提示时,请使用管理员凭据登录。 现在你已设置完成,可以运行本文中的脚本和排班连接器 cmdlet 了。

确定要映射的团队

注意

如果要将WFM实例映射到现有团队,请完成此步骤。 如果要创建要映射到的新团队,则可以跳过此步骤。

在 Azure 门户中,转到所有组页面,获取组织中团队的 TeamId 列表。

记下要映射的团队的 TeamId。 此脚本将提示你输入此信息。

注意

如果一个或多个团队具有现有计划,则脚本将从这些团队中删除计划。 否则,你将看到重复的班次。

运行脚本

运行以下脚本之一,具体取决于是要创建新团队还是映射到现有团队:

  • 若要设置连接,在 Teams 中创建新团队,并将WFM实例映射到新团队,请运行新的团队脚本
  • 若要设置连接并将WFM实例映射到 Teams 中的现有团队,请运行现有团队脚本

运行脚本时,请按照屏幕上的说明进行操作。 该脚本完成以下操作:

  1. 使用您输入的 UKG Pro WFM 服务帐户凭据和服务 URL 测试并验证与 UKG Pro WFM 的连接。

  2. 应用同步设置。 这些设置包括同步频率 ((以分钟为单位)) ,以及 UKG Pro WFM 和排班之间同步的计划数据。 可以启用由以下方案定义的计划数据:Shift、、SwapRequestOfferShiftRequestUserShiftPreferencesOpenShiftOpenShiftRequestTimeOff、。 TimeOffRequest

    若要了解详细信息,请参阅 New-CsTeamsShiftsConnectionInstance。 若要查看每个参数支持的同步选项列表,请运行 Get-CsTeamsShiftsConnectionConnector

    注意

    该脚本为每个支持的同步选项启用同步。 如果要更改同步设置,可以在设置连接后执行此操作。 若要了解详细信息,请参阅使用 PowerShell 管理与 UKG Pro Workforce Management的排班连接

  3. 将WFM实例映射到 Teams 中的团队。

    • 如果选择运行 新团队脚本 来创建新团队,则映射将基于你创建的新团队。
    • 如果选择运行现有团队脚本来映射现有团队,则映射将基于输入WFM实例 ID 和 TeamId。 如果团队具有现有计划,则脚本会删除所有计划数据。

运行脚本后, “成功” 消息确认连接是否已成功设置。

管理连接

设置连接后,可以在Microsoft 365 管理中心或使用 PowerShell 对其进行管理和更改。

使用Microsoft 365 管理中心

“连接器管理”页列出了你设置的每个连接,以及运行状况和同步间隔详细信息等信息。 还可以访问向导来更改任何连接。 例如,可以更新同步设置和团队映射。

若要了解详细信息,请参阅使用Microsoft 365 管理中心管理与 UKG Pro Workforce Management的排班连接

使用 PowerShell

可以使用 PowerShell 查看错误报告、更改连接设置、禁用同步等。 有关分步指南,请参阅使用 PowerShell 管理与 UKG Pro Workforce Management的排班连接

脚本

设置连接并创建新团队

#Map WFM instances to teams script
Write-Output "Map WFM sites to teams"
Start-Sleep 1

#Ensure Teams module is at least version x
Write-Output "Checking Teams module version"
try {
    Get-InstalledModule -Name "MicrosoftTeams" -MinimumVersion 5.2.0
} catch {
    throw
}

#Connect to MS Graph
Connect-MgGraph -Scopes "User.Read.All","Group.ReadWrite.All"

#List connector types available
Write-Output "Listing connector types available"
$UkgId = "95BF2848-2DDA-4425-B0EE-D62AEED4C0A0"
$connectors = Get-CsTeamsShiftsConnectionConnector
Write-Output $connectors
$Ukg = $connectors | Where-Object {$_.Id -match $UkgId}
if ($NULL -eq $Ukg) {
    throw "UKG Dimensions not currently supported"
}

#Prompt for entering of WFM username and password
$WfmUserName = Read-Host -Prompt 'Input your UKG account username'
$WfmPwd = Read-Host -Prompt 'Input your UKG account password' -AsSecureString
$plainPwd =[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($WfmPwd))

#Test connection settings
Write-Output "Testing connection settings"
$ConnectionName = Read-Host -Prompt 'Input connection name'
$apiUrl = Read-Host -Prompt 'Input connector api url'
$ssoUrl = Read-Host -Prompt 'Input connector sso url'
$clientId = Read-Host -Prompt 'Input connector client id'
$AppKey = Read-Host -Prompt 'Input your app key' -AsSecureString
$plainKey =[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($AppKey))
$ClientSecret = Read-Host -Prompt 'Input your client secret' -AsSecureString
$plainSecret =[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($ClientSecret))

$testResult = Test-CsTeamsShiftsConnectionValidate `
    -Name $ConnectionName `
    -ConnectorId $UkgId `
    -ConnectorSpecificSettings (New-Object Microsoft.Teams.ConfigAPI.Cmdlets.Generated.Models.ConnectorSpecificUkgDimensionsSettingsRequest `
        -Property @{
            apiUrl = $apiUrl
            ssoUrl = $ssoUrl
            appKey = $plainKey
            clientId = $clientId
            clientSecret = $plainSecret
            LoginUserName = $WfmUserName
            LoginPwd = $plainPwd
        })
if ($NULL -ne $testResult.Code) {
    Write-Output $testResult
    throw "Validation failed, conflict found"
}
Write-Output "Test complete, no conflicts found"

#Create a connection
Write-Output "Creating a connection"
$ConnectionResponse = New-CsTeamsShiftsConnection `
    -Name $ConnectionName `
    -ConnectorId $UkgId `
    -ConnectorSpecificSettings (New-Object Microsoft.Teams.ConfigAPI.Cmdlets.Generated.Models.ConnectorSpecificUkgDimensionsSettingsRequest `
        -Property @{
            apiUrl = $apiUrl
            ssoUrl = $ssoUrl
            appKey = $plainKey
            clientId = $clientId
            clientSecret = $plainSecret
            LoginUserName = $WfmUserName
            LoginPwd = $plainPwd
        })

$ConnectionId = $ConnectionResponse.Id
if ($null -ne $ConnectionId){
    Write-Output "Successfully created connection"
} else {
    throw "Connection creation failed"
}

#Create a connection instance
Write-Output "Creating a connection instance"
$designatedActorName = Read-Host -Prompt "Input Microsoft 365 System Account (person@contoso.com)"
$designator = Get-MgUser -UserId $designatedActorName
$teamsUserId = $designator.Id
$syncFreq = Read-Host -Prompt "Input sync frequency in minutes"
$InstanceName = Read-Host -Prompt "Input connection instance name"

#Read sync scenarios for connection instance
function GetSyncScenarioSetting {
    param (
        $SettingName
    )
    $TwoWay = New-Object System.Management.Automation.Host.ChoiceDescription '&TwoWay', 'TwoWay'
    $Disabled = New-Object System.Management.Automation.Host.ChoiceDescription '&Disabled', 'Disabled'
    $FromWfmToShifts = New-Object System.Management.Automation.Host.ChoiceDescription '&FromWfmToShifts', 'FromWfmToShifts'
    $options = [System.Management.Automation.Host.ChoiceDescription[]]($TwoWay, $Disabled, $FromWfmToShifts)
    $result = $host.ui.PromptForChoice("Set sync scenario for $SettingName", "", $options, 0)

    switch ($result)
    {
        0 { return "TwoWay" }
        1 { return "Disabled" }
        2 { return "FromWfmToShifts" }
    }
}
$SyncScenarioOfferShiftRequest = GetSyncScenarioSetting "Offer Shift Request"
$SyncScenarioOpenShift = GetSyncScenarioSetting "Open Shift"
$SyncScenarioOpenShiftRequest = GetSyncScenarioSetting "Open Shift Request"
$SyncScenarioShift = GetSyncScenarioSetting "Shift"
$SyncScenarioSwapRequest = GetSyncScenarioSetting "Swap Request"
$SyncScenarioTimeCard = GetSyncScenarioSetting "Time Card"
$SyncScenarioTimeOff = GetSyncScenarioSetting "Time Off"
$SyncScenarioTimeOffRequest = GetSyncScenarioSetting "Time Off Request"
$SyncScenarioUserShiftPreference = GetSyncScenarioSetting "User Shift Preferences"

#Read admin email list
[psobject[]]$AdminEmailList = @()
while ($true){
    $AdminEmail = Read-Host -Prompt "Enter admin's email to receive error report"
    $AdminEmailList += $AdminEmail
    $title    = 'Adding another email'
    $question = 'Would you like to add another admin email?'
    $choices  = '&Yes', '&No'
    $decision = $Host.UI.PromptForChoice($title, $question, $choices, 1)
    if ($decision -eq 1) {
        break
    }
}
$InstanceResponse = New-CsTeamsShiftsConnectionInstance `
    -ConnectionId $ConnectionId `
    -ConnectorAdminEmail $AdminEmailList `
    -DesignatedActorId $teamsUserId `
    -Name $InstanceName `
    -SyncFrequencyInMin $syncFreq `
    -SyncScenarioOfferShiftRequest $SyncScenarioOfferShiftRequest `
    -SyncScenarioOpenShift $SyncScenarioOpenShift `
    -SyncScenarioOpenShiftRequest $SyncScenarioOpenShiftRequest `
    -SyncScenarioShift $SyncScenarioShift `
    -SyncScenarioSwapRequest $SyncScenarioSwapRequest `
    -SyncScenarioTimeCard $SyncScenarioTimeCard `
    -SyncScenarioTimeOff $SyncScenarioTimeOff `
    -SyncScenarioTimeOffRequest $SyncScenarioTimeOffRequest `
    -SyncScenarioUserShiftPreference $SyncScenarioUserShiftPreference

$InstanceId = $InstanceResponse.id
if ($null -ne $InstanceId){
    Write-Output "Success"
} else {
    throw "Connector instance creation failed"
}

#Keep mapping teams until user stops it
$mappings=@()
while ($true)
{
    #Create a new Teams team with owner set to system account and name set to the site name
    Write-Output "Creating a Teams team"
    $teamsTeamName = Read-Host -Prompt "Input the Teams team name"
    $Team = New-Team -DisplayName $teamsTeamName -Visibility "Public" -Owner $teamsUserId
    Write-Output "Successfully created a team"
    $TeamsTeamId=$Team.GroupId

    #Retrieve the list of wfm locations
    Write-Output "Listing the WFM team sites"
    $WfmTeamIds = Get-CsTeamsShiftsConnectionWfmTeam -ConnectorInstanceId $InstanceId
    Write-Output $WfmTeamIds
    if (($NULL -ne $WfmTeamIds) -and ($WfmTeamIds.Count -gt 0)){
        [System.String]$WfmTeamId = Read-Host -Prompt "Input the ID of WFM team you want to map"
    }
    else {
        throw "The WfmTeamId list is null or empty"
    }

    #Retrieve the list of WFM users and their roles
    Write-Output "Listing WFM users and roles"
    $WFMUsers = Get-CsTeamsShiftsConnectionWfmUser -ConnectorInstanceId $InstanceId -WfmTeamId $WfmTeamId
    Write-Output $WFMUsers

    #Add users to the Team for Shifts
    Write-Output "Adding users to Teams team"
    $currentUser = Read-Host -Prompt "Input the current user's user name or AAD ID"
    Add-TeamUser -GroupId $TeamsTeamId -User $currentUser -Role Owner
    $failedWfmUsers=@()
    foreach ($user in $WFMUsers) {
        try {
        $userEmail = $user.Name + "@" +$domain
        Add-TeamUser -GroupId $TeamsTeamId -User $userEmail
        } catch {
            $failedWfmUsers+=$user
        }
    }
    if($failedWfmUsers.Count -gt 0){
        Write-Output "There are WFM users not existed in Teams tenant:"
        Write-Output $failedWfmUsers
    }

    #Enable scheduling in the group
    $RequestBody = @{
        Enabled = $true
        TimeZone = "America/Los_Angeles"
    }
    $teamUpdateUrl="https://graph.microsoft.com/v1.0/teams/"+$TeamsTeamId+"/schedule"
    Invoke-MgGraphRequest -Uri $teamUpdateUrl -Method PUT -Body $RequestBody

    #Create a mapping of the new team to the instance
    Write-Output "Create a mapping of the new team to the site"
    $TimeZone = Read-Host -Prompt "Input the time zone of team mapping"
    $mapping = @{
        teamId = $TeamsTeamId
        wfmTeamId = $WfmTeamId
        timeZone = $TimeZone
        }
    $mappings += , $mapping

    $title    = 'Connecting another team'
    $question = 'Would you like to connect another team?'
    $choices  = '&Yes', '&No'

    $decision = $Host.UI.PromptForChoice($title, $question, $choices, 1)
    if ($decision -eq 1) {
        break
    }
}
$batchMappingResponse = New-CsTeamsShiftsConnectionBatchTeamMap -ConnectorInstanceId $InstanceId -TeamMapping @($mappings)
if ($null -ne $batchMappingResponse.OperationId){
    "The mapping has begun asynchronously. To query mapping results run Get-CsTeamsShiftsConnectionOperation with the operation Id."
}
else {
    throw "The mapping has failed due to validation errors."
}
Write-Output $batchMappingResponse

Remove-TeamUser -GroupId $TeamsTeamId -User $currentUser -Role Owner
Disconnect-MgGraph

设置连接并映射现有团队

#Map WFM instances to existing teams script
Write-Host "Map WFM sites to existing teams"
Start-Sleep 1

#Ensure Teams module is at least version x
Write-Host "Checking Teams module version"
try {
    Get-InstalledModule -Name "MicrosoftTeams" -MinimumVersion 5.2.0
} catch {
    throw
}

#Connect to MS Graph
Connect-MgGraph -Scopes "User.Read.All","Group.ReadWrite.All"

#List connector types available
Write-Output "Listing connector types available"
$UkgId = "95BF2848-2DDA-4425-B0EE-D62AEED4C0A0"
$connectors = Get-CsTeamsShiftsConnectionConnector
Write-Output $connectors
$Ukg = $connectors | Where-Object {$_.Id -match $UkgId}
if ($NULL -eq $Ukg) {
    throw "UKG Dimensions not currently supported"
}

#Prompt for entering of WFM username and password
$WfmUserName = Read-Host -Prompt 'Input your UKG account username'
$WfmPwd = Read-Host -Prompt 'Input your UKG account password' -AsSecureString
$plainPwd =[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($WfmPwd))

#Test connection settings
Write-Output "Testing connection settings"
$ConnectionName = Read-Host -Prompt 'Input connection name'
$apiUrl = Read-Host -Prompt 'Input connector api url'
$ssoUrl = Read-Host -Prompt 'Input connector sso url'
$clientId = Read-Host -Prompt 'Input connector client id'
$AppKey = Read-Host -Prompt 'Input your app key' -AsSecureString
$plainKey =[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($AppKey))
$ClientSecret = Read-Host -Prompt 'Input your client secret' -AsSecureString
$plainSecret =[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($ClientSecret))

$testResult = Test-CsTeamsShiftsConnectionValidate `
    -Name $ConnectionName `
    -ConnectorId $UkgId `
    -ConnectorSpecificSettings (New-Object Microsoft.Teams.ConfigAPI.Cmdlets.Generated.Models.ConnectorSpecificUkgDimensionsSettingsRequest `
        -Property @{
            apiUrl = $apiUrl
            ssoUrl = $ssoUrl
            appKey = $plainKey
            clientId = $clientId
            clientSecret = $plainSecret
            LoginUserName = $WfmUserName
            LoginPwd = $plainPwd
        })
if ($NULL -ne $testResult.Code) {
    Write-Output $testResult
    throw "Validation failed, conflict found"
}
Write-Output "Test complete, no conflicts found"

#Create a connection
Write-Output "Creating a connection"
$ConnectionResponse = New-CsTeamsShiftsConnection `
    -Name $ConnectionName `
    -ConnectorId $UkgId `
    -ConnectorSpecificSettings (New-Object Microsoft.Teams.ConfigAPI.Cmdlets.Generated.Models.ConnectorSpecificUkgDimensionsSettingsRequest `
        -Property @{
            apiUrl = $apiUrl
            ssoUrl = $ssoUrl
            appKey = $plainKey
            clientId = $clientId
            clientSecret = $plainSecret
            LoginUserName = $WfmUserName
            LoginPwd = $plainPwd
        })

$ConnectionId = $ConnectionResponse.Id
if ($null -ne $ConnectionId){
    Write-Output "Successfully created connection"
} else {
    throw "Connection creation failed"
}

#Create a connection instance
Write-Output "Creating a connection instance"
$designatedActorName = Read-Host -Prompt "Input Microsoft 365 System Account (person@contoso.com)"
$designator = Get-MgUser -UserId $designatedActorName
$teamsUserId = $designator.Id
$syncFreq = Read-Host -Prompt "Input sync frequency in minutes"
$InstanceName = Read-Host -Prompt "Input connection instance name"

#Read sync scenarios for connection instance
function GetSyncScenarioSetting {
    param (
        $SettingName
    )
    $TwoWay = New-Object System.Management.Automation.Host.ChoiceDescription '&TwoWay', 'TwoWay'
    $Disabled = New-Object System.Management.Automation.Host.ChoiceDescription '&Disabled', 'Disabled'
    $FromWfmToShifts = New-Object System.Management.Automation.Host.ChoiceDescription '&FromWfmToShifts', 'FromWfmToShifts'
    $options = [System.Management.Automation.Host.ChoiceDescription[]]($TwoWay, $Disabled, $FromWfmToShifts)
    $result = $host.ui.PromptForChoice("Set sync scenario for $SettingName", "", $options, 0)

    switch ($result)
    {
        0 { return "TwoWay" }
        1 { return "Disabled" }
        2 { return "FromWfmToShifts" }
    }
}
$SyncScenarioOfferShiftRequest = GetSyncScenarioSetting "Offer Shift Request"
$SyncScenarioOpenShift = GetSyncScenarioSetting "Open Shift"
$SyncScenarioOpenShiftRequest = GetSyncScenarioSetting "Open Shift Request"
$SyncScenarioShift = GetSyncScenarioSetting "Shift"
$SyncScenarioSwapRequest = GetSyncScenarioSetting "Swap Request"
$SyncScenarioTimeCard = GetSyncScenarioSetting "Time Card"
$SyncScenarioTimeOff = GetSyncScenarioSetting "Time Off"
$SyncScenarioTimeOffRequest = GetSyncScenarioSetting "Time Off Request"
$SyncScenarioUserShiftPreference = GetSyncScenarioSetting "User Shift Preferences"

#Read admin email list
[psobject[]]$AdminEmailList = @()
while ($true){
    $AdminEmail = Read-Host -Prompt "Enter admin's email to receive error report"
    $AdminEmailList += $AdminEmail
    $title    = 'Adding another email'
    $question = 'Would you like to add another admin email?'
    $choices  = '&Yes', '&No'
    $decision = $Host.UI.PromptForChoice($title, $question, $choices, 1)
    if ($decision -eq 1) {
        break
    }
}
$InstanceResponse = New-CsTeamsShiftsConnectionInstance `
    -ConnectionId $ConnectionId `
    -ConnectorAdminEmail $AdminEmailList `
    -DesignatedActorId $teamsUserId `
    -Name $InstanceName `
    -SyncFrequencyInMin $syncFreq `
    -SyncScenarioOfferShiftRequest $SyncScenarioOfferShiftRequest `
    -SyncScenarioOpenShift $SyncScenarioOpenShift `
    -SyncScenarioOpenShiftRequest $SyncScenarioOpenShiftRequest `
    -SyncScenarioShift $SyncScenarioShift `
    -SyncScenarioSwapRequest $SyncScenarioSwapRequest `
    -SyncScenarioTimeCard $SyncScenarioTimeCard `
    -SyncScenarioTimeOff $SyncScenarioTimeOff `
    -SyncScenarioTimeOffRequest $SyncScenarioTimeOffRequest `
    -SyncScenarioUserShiftPreference $SyncScenarioUserShiftPreference

$InstanceId = $InstanceResponse.id
if ($null -ne $InstanceId){
    Write-Output "Success"
} else {
    throw "Connector instance creation failed"
}

#Keep mapping teams until user stops it
$mappings=@()
while ($true)
{
    $TeamsTeamId = Read-Host -Prompt "Input the ID of the Teams team to be mapped"
    #Clear schedule of the Teams team
    Write-Host "Clear schedule of the existing team"

    $entityTypeString = Read-Host -Prompt 'Input the entity types of clear schedule'
    $Delimiters = ",", ".", ":", ";", " ", "`t"
    $entityType = $entityTypeString -Split {$Delimiters -contains $_}
    $entityType = $entityType.Trim()
    $entityType = $entityType.Split('',[System.StringSplitOptions]::RemoveEmptyEntries)
    Remove-CsTeamsShiftsScheduleRecord -TeamId $TeamsTeamId -ClearSchedulingGroup:$True -EntityType $entityType

    #Retrieve the list of wfm locations
    Write-Output "Listing the WFM team sites"
    $WfmTeamIds = Get-CsTeamsShiftsConnectionWfmTeam -ConnectorInstanceId $InstanceId
    Write-Output $WfmTeamIds
    if (($NULL -ne $WfmTeamIds) -and ($WfmTeamIds.Count -gt 0)){
        [System.String]$WfmTeamId = Read-Host -Prompt "Input the ID of WFM team you want to map"
    }
    else {
        throw "The WfmTeamId list is null or empty"
    }

    #Retrieve the list of WFM users and their roles
    Write-Output "Listing WFM users and roles"
    $WFMUsers = Get-CsTeamsShiftsConnectionWfmUser -ConnectorInstanceId $InstanceId -WfmTeamId $WfmTeamId
    Write-Output $WFMUsers

    #Create a mapping of the existing team to the instance
    Write-Host "Create a mapping of the existing team to the site"
    $TimeZone = Read-Host -Prompt "Input the time zone of team mapping"
    $mapping = @{
        teamId = $TeamsTeamId
        wfmTeamId = $WfmTeamId
        timeZone = $TimeZone
        }
    $mappings += , $mapping

    $title    = 'Connecting another team'
    $question = 'Would you like to connect another team?'
    $choices  = '&Yes', '&No'

    $decision = $Host.UI.PromptForChoice($title, $question, $choices, 1)
    if ($decision -eq 1) {
        break
    }
}
$batchMappingResponse = New-CsTeamsShiftsConnectionBatchTeamMap -ConnectorInstanceId $InstanceId -TeamMapping @($mappings)
if ($null -ne $batchMappingResponse.OperationId){
    "The mapping has begun asynchronously. To query mapping results run Get-CsTeamsShiftsConnectionOperation with the operation Id."
}
else {
    throw "The mapping has failed due to validation errors."
}
Write-Output $batchMappingResponse

Disconnect-MgGraph

排班连接器 cmdlet

有关排班连接器 cmdlet(包括脚本中使用的 cmdlet)的帮助,请在 Teams PowerShell cmdlet 参考中搜索 CsTeamsShiftsConnection。 下面是一些常用 cmdlet 的链接,按类别分组:

Connections

WFM系统凭据

支持方案的同步选项

删除计划数据

连接实例

用户映射和成功同步

团队映射

操作 ID

错误报告