使用 PowerShell 将排班连接到 Blue Yonder Workforce Management

概述

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

本文介绍如何使用 PowerShell 设置和配置连接器,以将排班与 Blue Yonder WFM 集成。

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

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

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

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

注意

还可以在 Microsoft 365 管理中心中使用排班连接器向导将排班连接到 Blue Yonder WFM。

开始之前

先决条件

在开始之前,请确保满足以下所有先决条件:

  • 你有 Blue Yonder WFM版本 2020.3、2021.1 或 2021.2。

    注意

    如果有 Blue Yonder WFM 2020.3 或 2021.1,请应用 2020.3.0.4 或 2021.1.0.3 修补程序。 此修补程序修复了用户在 Shifts 中收到持久性错误消息的问题。 它还修复了用户在排班中无法更新空闲状态的问题。

  • 你知道 Blue Yonder WFM服务帐户名称、密码和服务 URL:

    • 联合身份验证 URL
    • Cookie 身份验证 URL
    • 员工自助服务 URL
    • 零售 Web API URL
    • 网站管理器 API URL
    • 管理 API URL

    如果没有所有这些信息,请联系 Blue Yonder 支持。 Blue Yonder 帐户由 Blue Yonder 企业管理员在根企业级别创建。 它必须具有 API 访问权限、客户端管理员、应用商店管理器和辅助角色访问权限。 创建连接需要帐户和密码。

  • 已在 Blue Yonder WFM 环境中启用联合 SSO 身份验证。 请联系 Blue Yonder 支持部门,确保已启用联合 SSO。 他们将需要以下信息:

    • federatedSSOValidationService: https://wfmconnector.teams.microsoft.com/api/v1/fedauth/{tenantId}/6A51B888-FF44-4FEA-82E1-839401E9CD74/authorize 其中 {tenantId} 是 tenantId
    • proxyHeader:X-MS-AuthToken
  • Teams 中至少设置了一个团队。

  • 你添加了一个常规帐户,我们称之为 Microsoft 365 系统帐户,作为要映射的所有团队的团队所有者。

    在 Microsoft 365 管理中心中创建此帐户,并为其分配 Microsoft 365 许可证。 然后,将帐户添加为要映射的所有团队的团队所有者。 从 Blue Yonder WFM 同步排班更改时,排班连接器将使用此帐户。 建议专门为此目的创建一个帐户,不要使用个人用户帐户。

使用 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

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

Connect-MicrosoftTeams

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

确定要映射的团队

注意

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

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

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

注意

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

运行脚本

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

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

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

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

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

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

    注意

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

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

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

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

管理连接

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

使用Microsoft 365 管理中心

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

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

使用 PowerShell

可以使用 PowerShell 查看错误报告、更改连接设置、禁用同步等。 如需获取分步指南,请参阅使用 PowerShell 管理与 Blue Yonder 劳动力的排班连接

脚本

设置连接并创建新团队

#Map WFM sites 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 (comment out if not implemented for preview)
Write-Output "Listing connector types available"
$BlueYonderId = "6A51B888-FF44-4FEA-82E1-839401E9CD74"
$connectors = Get-CsTeamsShiftsConnectionConnector
Write-Output $connectors

#Prompt for entering of WFM username and password
$WfmUserName = Read-Host -Prompt 'Input your Blue Yonder account username'
$WfmPwd = Read-Host -Prompt 'Input your Blue Yonder 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'
$adminApiUrl = Read-Host -Prompt 'Input admin api url'
$cookieAuthUrl = Read-Host -Prompt 'Input cookie authorization url'
$essApiUrl = Read-Host -Prompt 'Input ess api url'
$federatedAuthUrl = Read-Host -Prompt 'Input federated authorization url'
$retailWebApiUrl = Read-Host -Prompt 'Input retail web api url'
$siteManagerUrl = Read-Host -Prompt 'Input site manager url'

$testResult = Test-CsTeamsShiftsConnectionValidate `
	-Name $ConnectionName `
	-ConnectorId $BlueYonderId `
    -ConnectorSpecificSettings (New-Object Microsoft.Teams.ConfigAPI.Cmdlets.Generated.Models.ConnectorSpecificBlueYonderSettingsRequest `
        -Property @{
            AdminApiUrl = $adminApiUrl
            SiteManagerUrl = $siteManagerUrl
            EssApiUrl = $essApiUrl
            RetailWebApiUrl = $retailWebApiUrl
            CookieAuthUrl = $cookieAuthUrl
            FederatedAuthUrl = $federatedAuthUrl
            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 $BlueYonderId `
    -ConnectorSpecificSettings (New-Object Microsoft.Teams.ConfigAPI.Cmdlets.Generated.Models.ConnectorSpecificBlueYonderSettingsRequest `
		-Property @{
			AdminApiUrl = $adminApiUrl
			SiteManagerUrl = $siteManagerUrl
			EssApiUrl = $essApiUrl
			RetailWebApiUrl = $retailWebApiUrl
			CookieAuthUrl = $cookieAuthUrl
			FederatedAuthUrl = $federatedAuthUrl
			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" }
	}
}
$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 `
	-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 sites to existing teams script
Write-Output "Map WFM sites to existing 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 (comment out if not implemented for preview)
Write-Output "Listing connector types available"
$BlueYonderId = "6A51B888-FF44-4FEA-82E1-839401E9CD74"
$connectors = Get-CsTeamsShiftsConnectionConnector
Write-Output $connectors

#Prompt for entering of WFM username and password
$WfmUserName = Read-Host -Prompt 'Input your Blue Yonder account username'
$WfmPwd = Read-Host -Prompt 'Input your Blue Yonder 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'
$adminApiUrl = Read-Host -Prompt 'Input admin api url'
$cookieAuthUrl = Read-Host -Prompt 'Input cookie authorization url'
$essApiUrl = Read-Host -Prompt 'Input ess api url'
$federatedAuthUrl = Read-Host -Prompt 'Input federated authorization url'
$retailWebApiUrl = Read-Host -Prompt 'Input retail web api url'
$siteManagerUrl = Read-Host -Prompt 'Input site manager url'

$testResult = Test-CsTeamsShiftsConnectionValidate `
	-Name $ConnectionName `
	-ConnectorId $BlueYonderId `
	-ConnectorSpecificSettings (New-Object Microsoft.Teams.ConfigAPI.Cmdlets.Generated.Models.ConnectorSpecificBlueYonderSettingsRequest `
		-Property @{
			AdminApiUrl = $adminApiUrl
			SiteManagerUrl = $siteManagerUrl
			EssApiUrl = $essApiUrl
			RetailWebApiUrl = $retailWebApiUrl
			CookieAuthUrl = $cookieAuthUrl
			FederatedAuthUrl = $federatedAuthUrl
			LoginUserName = $WfmUserName
			LoginPwd = $plainPwd
		})
		
if ($NULL -ne $testResult.Code) {
	Write-Output $testResult
	throw "Validation failed, conflict found"
}
Write-Host "Test complete, no conflicts found"

#Create a connection
Write-Output "Creating a connection"
$ConnectionResponse = New-CsTeamsShiftsConnection `
    -Name $ConnectionName `
    -ConnectorId $BlueYonderId `
    -ConnectorSpecificSettings (New-Object Microsoft.Teams.ConfigAPI.Cmdlets.Generated.Models.ConnectorSpecificBlueYonderSettingsRequest `
		-Property @{
			AdminApiUrl = $adminApiUrl
			SiteManagerUrl = $siteManagerUrl
			EssApiUrl = $essApiUrl
			RetailWebApiUrl = $retailWebApiUrl
			CookieAuthUrl = $cookieAuthUrl
			FederatedAuthUrl = $federatedAuthUrl
			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" }
	}
}
$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 `
	-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

错误报告