PowerShell を使用して Blue Yonder WFM とのシフトを管理する

概要

Blue Yonder 用の Microsoft Teams Shifts コネクタを使用して、Microsoft Teams の Shifts アプリを Blue Yonder 従業員管理(Blue Yonder WFM) と統合します。 現場担当者は、シフト内から Blue Yonder WFMでスケジュールをシームレスに表示および管理できます。

Microsoft 365 管理センターまたは PowerShellShifts コネクタ ウィザードを使用して接続を設定できます。 接続を設定したら、 Shifts コネクタ PowerShell コマンドレットを使用して接続を管理できます。

この記事では、次に示す操作の方法を説明します。

この記事では、ウィザードまたは PowerShell を使用して、Blue Yonder WFMへの接続が既に設定されていることを前提としています。

注:

Microsoft 365 管理センターで接続を管理することもできます。 たとえば、正常性状態をチェックし、ウィザードにアクセスして接続設定を変更できます。 詳細については、「Microsoft 365 管理センターを使用して Blue Yonder Workforce Managementへの Shifts 接続を管理する」を参照してください。

はじめに

この記事の手順を完了するには、Microsoft 365 グローバル管理者または Shifts コネクタ管理者である必要があります。

Shifts コネクタ管理者ロールは、Microsoft Entra ID で作成し、ユーザーに割り当てるカスタム ロールです。 ロールの名前は、"シフト コネクタ管理者" である必要があります。 ロールには特定のアクセス許可が必要ありませんが、作成時に少なくとも 1 つのアクセス許可を設定する必要があります。 このサービスは、アクセス許可ではなく、ユーザーに対するロールの存在に依存します。

詳細については、「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 Preview PowerShell モジュールをインストールします。

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

    バージョン 4.7.0 以上で、Shifts コネクタ コマンドレットが含まれていることを確認します。

    Get-Command -Module MicrosoftTeams -Name *teamsshiftsconnection* 
    
  5. スクリプトの実行時にエラーが発生した場合は、PowerShell を終了するように設定します。

    $ErrorActionPreference = "Stop" 
    
  6. Windows で実行するスクリプトを有効にします。

    Set-ExecutionPolicy bypass 
    
  1. Teams に接続

    Connect-MicrosoftTeams
    

    メッセージが表示されたら、管理者の資格情報を使用してサイン インします。 これで、この記事のスクリプトと Shifts コネクタ コマンドレットを実行するように設定しました。

接続セットアップの状態を確認する

メールで受信した操作 ID を使用して設定した接続の状態をチェックするには、次の手順に従います。

  1. 環境を設定します (まだ設定していない場合)。

  2. 次のコマンドを実行します。 このコマンドは、接続のチーム マッピングの全体的な状態を示します。

    Get-CsTeamsShiftsConnectionOperation -OperationId <YourOperationId>
    

詳細については、「Get-CsTeamsShiftsConnectionOperation」を参照してください。

接続のエラー レポートを表示する

接続のエラーの詳細を示すレポートを実行できます。 レポートには、成功と失敗したチームとユーザーのマッピングが一覧表示されます。 また、接続に関連付けられているアカウントに関連するすべての問題に関する情報も提供されます。

  1. 環境を設定します (まだ設定していない場合)。

  2. 接続のエラー レポートの一覧を取得します。

    Get-CsTeamsShiftsConnectionErrorReport -ConnectorInstanceId <ConnectorInstanceId>
    
  3. 特定のエラー レポートを表示するには、次のコマンドを実行します。

    Get-CsTeamsShiftsConnectionErrorReport -ErrorReportId <ErrorReportId>
    

詳細については、「Get-CsTeamsShiftsConnectionErrorReport」を参照してください。

注:

エラー メッセージの完全な一覧については、この記事 の後半の「エラー メッセージの一覧 」を参照してください。

接続エラーを解決する

ユーザー マッピング エラー

WFM インスタンス内の 1 人以上のユーザーが Teams のマップされたチームのメンバーでない場合、ユーザー マッピング エラーが発生する可能性があります。 この問題を解決するには、マップされたチームのユーザーが、WFM インスタンス内のユーザーと一致していることを確認します。

マップされていないユーザーの詳細を表示するには、(まだない場合は) 環境を設定 し、次のスクリプトを実行します。

#View sync errors script
Write-Host "View sync errors"
Start-Sleep 1

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

#List connection instances available
Write-Host "Listing connection instances"
$InstanceList = Get-CsTeamsShiftsConnectionInstance
write $InstanceList

#Get an instance
if ($InstanceList.Count -gt 0){
    $InstanceId = Read-Host -Prompt 'Input the instance ID that you want to retrieve user sync results from'
}
else {
    throw "Instance list is empty"
}

#Get a list of the mappings
Write-Host "Listing team mappings"
$mappings = Get-CsTeamsShiftsConnectionTeamMap -ConnectorInstanceId $InstanceId
write $mappings

#For each mapping, retrieve the failed mappings
ForEach ($mapping in $mappings){
    $teamsTeamId = $mapping.TeamId
    $wfmTeamId = $mapping.WfmTeamId
    Write-Host "Failed mapped users in the mapping of ${teamsTeamId} and ${wfmTeamId}:"
    $userSyncResult = Get-CsTeamsShiftsConnectionSyncResult -ConnectorInstanceId $InstanceId -TeamId $teamsTeamId
    Write-Host "Failed AAD users:"
    write $userSyncResult.FailedAadUser
    Write-Host "Failed WFM users:"
    write $userSyncResult.FailedWfmUser
}

アカウント承認エラー

アカウントの承認エラーは、WFM サービス アカウントまたは Microsoft 365 システム アカウントの資格情報が正しくない場合、または必要なアクセス許可がない場合に発生する可能性があります。

接続のWFM サービス アカウントまたは Microsoft 365 システム アカウントの資格情報を変更するには、Set-CsTeamsShiftsConnectionInstance コマンドレットを実行するか、この記事の「接続設定の変更」セクションの PowerShell スクリプトを使用します。

接続設定を変更する

このスクリプトを使用して接続設定を変更します。 変更できる設定には、WFM サービス アカウントとパスワード、Microsoft 365 システム アカウント、チーム マッピング、同期設定が含まれます。

同期設定には、同期頻度 (分単位) と、WFM システムと Shifts の間で同期されるスケジュール データが含まれます。 スケジュール データは、 Get-CsTeamsShiftsConnectionConnectionConnector を実行して表示できる次のパラメーターで定義されています。

  • enabledConnectorScenarios パラメーターは、WFM システムから Shifts に同期されるデータを定義します。 オプションは ShiftSwapRequestUserShiftPreferencesOpenShiftOpenShiftRequestTimeOffTimeOffRequest です。

  • enabledWfiScenarios パラメーターは、Shifts から WFM システムに同期されるデータを定義します。 オプションは SwapRequestOpenShiftRequestTimeOffRequestUserShiftPreferences です。

    注:

    Shifts と WFM システムの間でオープン シフト、オープン シフト要求、スワップ要求、または休暇要求を同期しないことを選択した場合は、Shifts の機能を非表示にするためにもう 1 つの手順を実行する必要があります。 このスクリプトを実行した後は、この記事の後半の「オープン シフトを無効にする、シフト要求を開く、要求をスワップする、および休暇要求を無効にする」セクションの手順に従っていることを確認します。

重要

変更しない設定の場合は、スクリプトからメッセージが表示されたら、元の設定を再入力する必要があります。

環境をセットアップし (まだない場合)、次のスクリプトを実行します。

#Update connector instance and mapping script
Write-Host "Update Connector instance and mapping"
Start-Sleep 1

#Ensure Teams module is at least version x
Write-Host "Checking Teams module version"
try {
    Get-InstalledModule -Name "MicrosoftTeams" -MinimumVersion 4.7.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-Host "Listing connector types available"
$BlueYonderId = "6A51B888-FF44-4FEA-82E1-839401E9CD74"
$connectors = Get-CsTeamsShiftsConnectionConnector
write $connectors
$blueYonder = $connectors | where {$_.Id -match $BlueYonderId}

#List connection instances available
Write-Host "Listing connection instances available"
$InstanceList = Get-CsTeamsShiftsConnectionInstance | where {$_.ConnectorId -match $BlueYonderId}
write $InstanceList

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

#Get the instance ID
$InstanceId = Read-Host -Prompt 'Input the instance ID that you want to update'
$Instance = Get-CsTeamsShiftsConnectionInstance -ConnectorInstanceId $InstanceId
$Etag = $Instance.etag

#Change sync setting
$designatorName = Read-Host -Prompt "Input designated actor's user name"
$designator = Get-MgUser -UserId $designatorName
$teamsUserId = $designator.Id
$UpdatedInstanceName = Read-Host -Prompt 'Input new connection instance name'
$updatedConnectorScenarioString = Read-Host -Prompt 'Input new enabled connector scenarios'
$updatedWfiScenarioString = Read-Host -Prompt 'Input new enabled WFI scenarios'
$Delimiters = ",", ".", ":", ";", " ", "`t"
$updatedConnectorScenario = $updatedConnectorScenarioString -Split {$Delimiters -contains $_}
$updatedConnectorScenario = $updatedConnectorScenario.Trim()
$updatedConnectorScenario = $updatedConnectorScenario.Split('',[System.StringSplitOptions]::RemoveEmptyEntries)
$updatedWfiScenario = $updatedWfiScenarioString -Split {$Delimiters -contains $_}
$updatedWfiScenario = $updatedWfiScenario.Trim()
$updatedWfiScenario = $updatedWfiScenario.Split('', [System.StringSplitOptions]::RemoveEmptyEntries)
$adminApiUrl = $Instance.ConnectorSpecificSettingAdminApiUrl
$cookieAuthUrl = $Instance.ConnectorSpecificSettingCookieAuthUrl
$essApiUrl = $Instance.ConnectorSpecificSettingEssApiUrl
$federatedAuthUrl = $Instance.ConnectorSpecificSettingFederatedAuthUrl
$retailWebApiUrl = $Instance.ConnectorSpecificSettingRetailWebApiUrl
$siteManagerUrl = $Instance.ConnectorSpecificSettingSiteManagerUrl
$syncFreq = Read-Host -Prompt 'Input new sync frequency'

#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
}
}
$UpdatedInstance = Set-CsTeamsShiftsConnectionInstance `
    -ConnectorInstanceId $InstanceId `
    -ConnectorId $BlueYonderId `
    -ConnectorAdminEmail $AdminEmailList `
    -DesignatedActorId $teamsUserId `
    -EnabledConnectorScenario $updatedConnectorScenario `
    -EnabledWfiScenario $updatedWfiScenario `
    -Name $UpdatedInstanceName `
    -SyncFrequencyInMin $syncFreq `
    -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
    }) `
    -IfMatch $Etag
if ($UpdatedInstance.Id -ne $null) {
    Write-Host "Success"
}
else {
    throw "Update instance failed"
}
#Get a list of the mappings
Write-Host "Listing mappings"
$TeamMaps = Get-CsTeamsShiftsConnectionTeamMap -ConnectorInstanceId $InstanceId
write $TeamMaps

#Modify a mapping
#Remove a mapping
Write-Host "Removing a mapping"
$TeamsTeamId = Read-Host -Prompt 'Input the Teams team ID that you want to unlink'
$WfmTeamId = Read-Host -Prompt 'Input the WFM team ID that you want to unlink'
Remove-CsTeamsShiftsConnectionTeamMap -ConnectorInstanceId $InstanceId -TeamId $TeamsTeamId
Write-Host "Success"

#Add a mapping
Write-Host "Adding a mapping"
$TeamsTeamId = Read-Host -Prompt 'Input the Teams team ID that you want to link'
$WfmTeamId = Read-Host -Prompt 'Input the WFM team ID that you want to link'
New-CsTeamsShiftsConnectionTeamMap -ConnectorInstanceId $InstanceId -TeamId $TeamsTeamId -TimeZone "America/Los_Angeles" -WfmTeamId $WfmTeamId
Write-Host "Success"

オープン シフト、オープン シフト要求、スワップ要求、および休暇要求を無効にする

重要

この記事の「接続設定の変更」セクションのスクリプトを使用するか、 Set-CsTeamsShiftsConnectionInstance コマンドレットを使用して、オープン シフト、オープン シフト要求、スワップ要求、または休暇要求を無効にすることを選択した場合にのみ、次の手順に従います。 この手順を完了すると、Shifts で機能が非表示になります。 この 2 番目の手順を実行しないと、Shifts で機能が表示され、使用しようとすると"サポートされていない操作" というエラー メッセージが表示されます。

Shifts で開いているシフト、スワップ要求、および休暇要求を非表示にするには、Graph API スケジュール リソースの種類を使用して、WFM インスタンスにfalseマップしたチームごとに次のパラメーターを に設定します。

  • 開いているシフト: openShiftsEnabled
  • スワップ要求: swapShiftsRequestsEnabled
  • 休暇要求: timeOffRequestsEnabled

Shifts で開いているシフト要求を非表示にするには、Shifts の [設定] に移動し、[シフトを開く] 設定をオフにします。

ある接続からチームのマップを解除し、別の接続にマップする

注:

Microsoft 365 システム アカウントは、両方の接続で同じである必要があります。 そうでない場合は、"この指定されたアクター プロファイルにチーム所有権の特権がありません" というエラー メッセージが表示されます。

ある接続からチームのマップを解除し、別の接続にマップする場合は、次のようにします。

  1. 環境を設定します (まだ設定していない場合)。

  2. 接続のすべてのチーム マッピングの一覧を表示します。

    Get-CsTeamsShiftsConnectionTeamMap -ConnectorInstanceId <ConnectorInstanceId>
    
  3. 接続からチーム マッピングを削除します。

    Remove-CsTeamsShiftsConnectionTeamMap -ConnectorInstanceId <ConnectorInstanceId> -TeamId <TeamId>
    
  4. チームを別の接続にマップします。

    New-CsTeamsShiftsConnectionTeamMap -ConnectorInstanceId <ConnectorInstanceId> -TeamId <TeamId> -WfmTeamId <SiteId> -TimeZone <TimeZone>
    

詳細については、「Get-CsTeamsShiftsConnectionTeamMapRemove-CsTeamsShiftsConnectionTeamMapおよび New-CsTeamsShiftsConnectionTeamMap」を参照してください。

接続の同期を無効にする

このスクリプトを使用して、接続の同期を無効にします。 このスクリプトでは、接続が削除または削除されないことに注意してください。 Shifts と指定した接続のWFM システム間でデータが同期されないように、同期がオフになります。

環境をセットアップし (まだない場合)、次のスクリプトを実行します。

#Disable sync script
Write-Host "Disable sync"
Start-Sleep 1

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

#List connection instances available
$BlueYonderId = "6A51B888-FF44-4FEA-82E1-839401E9CD74"
Write-Host "Listing connection instances"
$InstanceList = Get-CsTeamsShiftsConnectionInstance | where {$_.ConnectorId -match $BlueYonderId}
write $InstanceList

#Get an instance
if ($InstanceList.Count -gt 0){
    $InstanceId = Read-Host -Prompt 'Input the instance ID that you want to disable sync'
    $Instance = Get-CsTeamsShiftsConnectionInstance -ConnectorInstanceId $InstanceId
    $Etag = $Instance.etag
    $InstanceName = $Instance.Name
    $DesignatedActorId = $Instance.designatedActorId
    $adminApiUrl = $Instance.ConnectorSpecificSettingAdminApiUrl
    $cookieAuthUrl = $Instance.ConnectorSpecificSettingCookieAuthUrl
    $essApiUrl = $Instance.ConnectorSpecificSettingEssApiUrl
    $federatedAuthUrl = $Instance.ConnectorSpecificSettingFederatedAuthUrl
    $retailWebApiUrl = $Instance.ConnectorSpecificSettingRetailWebApiUrl
    $siteManagerUrl = $Instance.ConnectorSpecificSettingSiteManagerUrl
    $ConnectorAdminEmail = $Instance.ConnectorAdminEmail
}
else {
    throw "Instance list is empty"
}

#Remove scenarios in the mapping
Write-Host "Disabling scenarios in the team mapping"
$UpdatedInstanceName = $InstanceName + " - Disabled"
$BlueYonderId = "6A51B888-FF44-4FEA-82E1-839401E9CD74"
$WfmUserName = Read-Host -Prompt 'Input your WFM user name'
$WfmPwd = Read-Host -Prompt 'Input your WFM password' -AsSecureString
$plainPwd =[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($WfmPwd))

$UpdatedInstance = Set-CsTeamsShiftsConnectionInstance `
    -ConnectorInstanceId $InstanceId `
    -ConnectorId $BlueYonderId `
    -ConnectorAdminEmail $ConnectorAdminEmail `
    -DesignatedActorId $DesignatedActorId `
    -EnabledConnectorScenario @() `
    -EnabledWfiScenario @() `
    -Name $UpdatedInstanceName `
    -SyncFrequencyInMin 10 `
    -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
        }) `
    -IfMatch $Etag

if ($UpdatedInstance.Id -ne $null) {
    Write-Host "Success"
}
else {
    throw "Update instance failed"
}

エラー メッセージの一覧

発生する可能性があるエラー メッセージと、それらを解決するのに役立つ情報の一覧を次に示します。

エラーの種類 エラーの詳細 解決方法
従業員管理システムを認証できません。 指定したワークフォース管理システム アカウントの資格情報が無効であるか、このアカウントに必要なアクセス許可がありません。 接続設定でWFMサービス アカウントの資格情報を更新します。 これを行うには、以下のいずれかの操作を実行します。
Graph を認証できません。 認証に失敗しました。 指定されたアクターの有効な資格情報を入力し、必要なアクセス許可を持っていることを確認します。 Microsoft 365 システム アカウント (指定されたアクターとも呼ばれます) がチーム所有者として追加されていることを確認します。
または、接続設定で Microsoft 365 システム アカウントの資格情報を更新します。
一部のユーザーが正しくマップできませんでした 一部のユーザーに対してマッピングが失敗しました: <X> が成功し、 <X> が AAD ユーザーに失敗し、 <X> が失敗した従業員管理システム ユーザー。 マッピングが失敗したユーザーを特定するには、 Get-CsTeamsShiftsConnectionSyncResult コマンドレットまたは この PowerShell スクリプト を使用します。 マップされたチームのユーザーが、WFM インスタンス内のユーザーと一致していることを確認します。
このバッチでチームまたはチームをマップできません。 この指定されたアクター プロファイルには、チームの所有権特権がありません。 Microsoft 365 システム アカウント (指定されたアクターとも呼ばれます) がチーム所有者として追加されていることを確認します。
Microsoft 365 システム アカウントを変更した場合は、そのアカウントをチーム所有者として追加し、そのアカウントを使用するように接続設定を更新します。
このチームは既に既存のコネクタ インスタンスにマップされています。 Remove-CsTeamsShiftsConnectionTeamMap コマンドレットを使用して、既存のコネクタ インスタンスからチームをマップ解除します。 または、新しい接続を作成してチームを再マップします。
このタイムゾーンは無効です。 渡されるタイムゾーンは、tz データベース形式を使用していません。 タイム ゾーンが正しいことを確認し、チームを再マップします。
このコネクタ インスタンスが見つかりません。 チームを既存の接続にマップします。
この AAD チームが見つかりませんでした。 チームが存在することを確認するか、新しいチームを作成します。

Shifts コネクタ コマンドレット

スクリプトで使用されるコマンドレットを含む Shifts コネクタ コマンドレットのヘルプについては、Teams PowerShell コマンドレット リファレンスCsTeamsShiftsConnection を検索してください。 一般的に使用されるコマンドレットへのリンクを次に示します。