├── CHANGELOG.md ├── Install.ps1 ├── Publish.ps1 ├── README.md └── source ├── License.txt ├── WorkdayApi.psd1 ├── WorkdayApi.psm1 ├── en-US └── about_WorkdayApi.help.txt ├── public ├── ConvertFrom-WorkdayWorkerXml.ps1 ├── Get-WorkdayDate.ps1 ├── Get-WorkdayEndpoint.ps1 ├── Get-WorkdayIntegrationEvent.ps1 ├── Get-WorkdayReport.ps1 ├── Get-WorkdayToAdData.ps1 ├── Get-WorkdayWorker.ps1 ├── Get-WorkdayWorkerByIdLookupTable.ps1 ├── Get-WorkdayWorkerDocument.ps1 ├── Get-WorkdayWorkerEmail.ps1 ├── Get-WorkdayWorkerNationalId.ps1 ├── Get-WorkdayWorkerOtherId.ps1 ├── Get-WorkdayWorkerPhone.ps1 ├── Get-WorkdayWorkerPhoto.ps1 ├── Invoke-WorkdayRequest.ps1 ├── Remove-WorkdayConfiguration.ps1 ├── Remove-WorkdayWorkerOtherId.ps1 ├── Save-WorkdayConfiguration.ps1 ├── Set-WorkdayCredential.ps1 ├── Set-WorkdayEndpoint.ps1 ├── Set-WorkdayWorkerDocument.ps1 ├── Set-WorkdayWorkerEmail.ps1 ├── Set-WorkdayWorkerOtherId.ps1 ├── Set-WorkdayWorkerPhone.ps1 ├── Set-WorkdayWorkerPhoto.ps1 ├── Set-WorkdayWorkerUserId.ps1 ├── Start-WorkdayIntegration.ps1 ├── Update-WorkdayWorkerEmail.ps1 ├── Update-WorkdayWorkerOtherId.ps1 └── Update-WorkdayWorkerPhone.ps1 ├── samples ├── Sync_AD_to_Workday.ps1 ├── Sync_Workday_to_AD.ps1 ├── Update-WorkdayWorkerPhotosSince.ps1 └── Update_Email_By_WorkerID.ps1 └── tests ├── Get-WorkdayIntegrationEvent.Tests.ps1 ├── Get-WorkdayToAdData.Tests.ps1 ├── Get-WorkdayWorker.Tests.ps1 ├── Get-WorkdayWorkerEmail.Tests.ps1 ├── Get-WorkdayWorkerNationalId.Tests.ps1 ├── Get-WorkdayWorkerOtherId.Tests.ps1 ├── Get-WorkdayWorkerPhone.Tests.ps1 ├── Get-WorkdayWorkerPhoto.Tests.ps1 ├── Invoke-WorkdayRequest.Tests.ps1 ├── Invoke-WorkdayRequestHelper.psm1 ├── Remove-WorkdayWorkerOtherId.Tests.ps1 ├── Set-WorkdayWorkerDocument.Tests.ps1 ├── Set-WorkdayWorkerEmail.Tests.ps1 ├── Set-WorkdayWorkerOtherId.Tests.ps1 ├── Set-WorkdayWorkerPhone.Tests.ps1 ├── Set-WorkdayWorkerPhoto.Tests.ps1 ├── Set-WorkdayWorkerUserId.Tests.ps1 ├── Start-WorkdayIntegration.Tests.ps1 ├── Update-WorkdayWorkerEmail.Tests.ps1 ├── Update-WorkdayWorkerOtherId.Tests.ps1 └── Update-WorkdayWorkerPhone.Tests.ps1 /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 2.3.3 - 2024-03-18 4 | 5 | * FIX: No error messages returned Invoke-WorkdayRequest. Thank you YuriySamorodov. 6 | * FIX: Allow characters A through Z, not just hex A through F, for Worker ID / EID. Thank you YuriySamorodov. 7 | 8 | ## 2.3.1 - 2023-10-19 9 | 10 | * Added progress meter to Get-WorkdayWorker. 11 | * Removed redunant [ordered] accelerator in Invoke-WorkdayRequest. Thank you mthreer. 12 | * Removed some uses of silent exceptions. 13 | * Implemented some validator recommendations. 14 | 15 | ## 2.3.0 - 2020-05-04 16 | 17 | * Added Get-WorkdayWorkerPhoto for getting worker's photo encoded as Base64. Thanks to skywayskase. 18 | 19 | ## 2.2.9 - 2020-02-25 20 | 21 | * Added Set-WorkdayWorkerUserId for setting Worker's User Id (username). Thanks to skumarkom. 22 | 23 | ## 2.2.7 - 2020-02-15 24 | 25 | * Set-WorkdayWorkerPhone now excepts any DeviceType and UsageType. 26 | 27 | ## 2.2.6 - 2020-02-03 28 | 29 | * Added WID to the terribly named Get-WorkdayWorkerByIdLookupTable and an Active property to Get-WorkdayWorker. 30 | * Removed the confusing and broken Export-WorkdayWorkerDocument and improved Get-WorkdayWorkerDocument. 31 | 32 | ## 2.2.5 - 2019-12-28 33 | 34 | * Fixed Worker Location that before was returning the ID, rather than the value. 35 | 36 | ## 2.2.4 - 2019-12-28 37 | 38 | * Published to the Microsoft Powershell Gallery. 39 | * Improved server level error handling when calling Invoke-WorkdayRequest. 40 | 41 | ## 2.2.3 - 2019-12-27 42 | 43 | * Parameter "-IncludeInactive" now available on all Worker cmdlets. 44 | * Code cleanup and preparation for publishing to the Powershell Gallery. 45 | * Thanks to PHactotum. 46 | 47 | ## 2.2.2 - 2018-12-13 48 | 49 | * Bug fix: Update-WorkdayWorkerOtherId now behaves as expected, when a date is not passed. 50 | 51 | ## 2.2.1 - 2018-11-30 52 | 53 | * Bug fix: When not requesting individual workers, Get-WorkdayWorker was returning the last set of values on each page of Workers, due to not anchoring XML XPath queries with "./" in ConvertFrom-WorkdayWorkerXml. 54 | 55 | ## 2.2.0 - 2018-11-29 56 | 57 | * Get-WorkdayWorker now returns Company, BusinessUnit (Department) and Supervisory (still looking for Sub-Department). 58 | 59 | ## 2.1.3 - 2018-04-13 60 | 61 | * Update_Email_By_WorkerID.ps1 will now also read an input file without a header. 62 | 63 | ## 2.1.2 - 2018-04-13 64 | 65 | * Corrected two Get-WorkdayWorker bugs. 66 | 67 | ## 2.1.1 - 2018-04-10 68 | 69 | * Added Get-WorkdayWorkerByIdLookupTable. 70 | * New sample script Update_Email_By_WorkerID.ps1. 71 | 72 | ## 2.1.0 - 2018-04-09 73 | 74 | * Set-WorkdayWorkerEmail will now update a primary email address, without deleting all non-primary addresses. Use the new switch -Append, with -Secondary, to append multiple non-Primary email addresses. 75 | * Update-* commands (Update-WorkdayWorkerEmail, Update-WorkdayWorkerOtherId, Update-WorkdayWorkerPhone) now output details of the request; such as Worker Type, Id and input values and no longer output XML. 76 | -------------------------------------------------------------------------------- /Install.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param ( 3 | [string]$InstallPath = $( 4 | If (($env:OS -eq 'Windows_NT') -Or ($PSVersionTable.platform -eq 'Win32NT')){ 5 | Join-Path $env:ProgramFiles 'WindowsPowerShell\Modules\WorkdayApi' 6 | }ElseIf(($PSVersionTable.platform -eq 'Unix')){ 7 | Join-Path ~/.local/share/ 'powershell/Modules/WorkdayApi' 8 | }), 9 | [switch]$Force 10 | ) 11 | 12 | $sourceFiles = @( 13 | '.\source\*' 14 | ) 15 | 16 | 17 | if (Test-Path $InstallPath) { 18 | if ($Force) { 19 | Remove-Item -Path $InstallPath\* -Recurse 20 | } else { 21 | Write-Warning "Module already installed at `"$InstallPath`" use -Force to overwrite installation." 22 | return 23 | } 24 | } else { 25 | New-Item -Path $InstallPath -ItemType Directory | Out-Null 26 | } 27 | 28 | Push-Location $PSScriptRoot 29 | 30 | Copy-Item -Path $sourceFiles -Destination $InstallPath -Recurse 31 | 32 | Pop-Location 33 | 34 | Import-Module -Name WorkdayApi -Verbose 35 | -------------------------------------------------------------------------------- /Publish.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsys Script that pulls latest copy of WorkdayAPI, tests it, then publishes it to the Powershell Gallery. 3 | #> 4 | [CmdletBinding()] 5 | param ( 6 | [Parameter(Mandatory=$true)] 7 | [ValidateNotNullOrEmpty()] 8 | [string]$ApiKey, 9 | [string]$ProjectUri = 'https://github.com/treestryder/powershell_module_workdayapi.git', 10 | [string]$Repository = 'PSGallery', 11 | [switch]$WhatIf 12 | ) 13 | #TODO: Make this script multiplatform, possibly borrowing more from here https://github.com/PowerShell/PowerShellGet/blob/development/tools/build.psm1 14 | 15 | $tempPath = [System.IO.Path]::GetTempPath() 16 | $rootPath = './WorkdayAPI' 17 | $sourcePath = './WorkdayAPI/source' 18 | $modulePath = './WorkdayAPI/WorkdayAPI' 19 | try { 20 | Push-Location $tempPath -ErrorAction Stop 21 | 'Git Cloning project to "{0}".' -f $rootPath | Write-Host -ForegroundColor Yellow 22 | git clone $ProjectUri $rootPath | Out-String 23 | if (-not $?) {throw 'Git clone failed.'} 24 | 25 | 'Renaming source folder to make Publish-Module work.' | Write-Host -ForegroundColor Yellow 26 | Move-Item $sourcePath $modulePath -ErrorAction Stop 27 | 28 | 'Testing Module.' | Write-Host -ForegroundColor Yellow 29 | $pesterResult = Invoke-Pester -Script $modulePath -PassThru 30 | if ($pesterResult.FailedCount -gt 0) { throw "Will not publish, as there were $($pesterResult.FailedCount) failed Pester Tests."} 31 | 32 | 'Publishing Module.' | Write-Host -ForegroundColor Yellow 33 | Publish-Module -Path $modulePath -NuGetApiKey $ApiKey -Repository $Repository -WhatIf:$WhatIf -ErrorAction Stop -Verbose 34 | } 35 | catch { 36 | throw 37 | } 38 | finally { 39 | 'Cleaning up.' | Write-Host -ForegroundColor Yellow 40 | Remove-Item $rootPath -Recurse -Force -ErrorAction Stop 41 | Pop-Location -ErrorAction Stop 42 | } 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEPRICATED: Workday SOAP API Powershell Script Module # 2 | 3 | Sorry, this project has been depricated. 4 | 5 | ## Description ## 6 | Provides simple methods for accessing the Workday SOAP API. 7 | 8 | This simple Powershell Module has been written to fulfill my employer's Workday automation needs. I see this as a prototype, while I experiment with the best way to expose the complexities of the Workday API in a Powershell-y way. Thinking that the community might find it helpful and may even wish to comment or contribute, I have hosted the source on GitHub (https://github.com/treestryder/powershell_module_workdayapi). 9 | 10 | 11 | ## Features ## 12 | 13 | * Easy command-line use, after setting default configuration options and securely saving them to the current user's profile. 14 | * Get Worker information for one or all workers. 15 | * Get / Set / Update Worker email. 16 | * Get / Set / Update Worker phone. 17 | * Upload Worker Photos. 18 | * Upload Worker Documents. 19 | * Run reports. 20 | * Trigger Integrations and retreive their status. 21 | * Submit arbitrary API calls. 22 | * A sample script to push A.D. changes to Workday (samples/Push_AD_to_Workday.ps1). 23 | 24 | 25 | ## Examples ## 26 | 27 | Set-WorkdayCredential 28 | Set-WorkdayEndpoint -Endpoint Staffing -Uri 'https://SERVICE.workday.com/ccx/service/TENANT/Staffing/v26.0' 29 | Set-WorkdayEndpoint -Endpoint Human_Resources -Uri 'https://SERVICE.workday.com/ccx/service/TENANT/Human_Resources/v26.0' 30 | Set-WorkdayEndpoint -Endpoint Integrations -Uri 'https://SERVICE.workday.com/ccx/service/TENANT/Integrations/v26.0' 31 | Save-WorkdayConfiguration 32 | 33 | Set-WorkdayWorkerPhone -WorkerId 123 -WorkerType Employee_ID -Number '+1 (234) 987-6543' 34 | 35 | Get-WorkdayWorkerPhone -WorkerId 123 -WorkerType Employee_ID | Format-Table 36 | 37 | UsageType DeviceType Number Extension Primary Public 38 | --------- ---------- ------ --------- ------- ------ 39 | Home Landline 1 (234) 567-8910 False False 40 | Work Landline 1 (234) 987-6543 True False 41 | 42 | 43 | $response = Invoke-WorkdayRequest -Request '' -Uri https://SERVICE.workday.com/ccx/service/TENANT/Human_Resources/v26.0 44 | $response.Xml.Server_TimeStamp 45 | 46 | wd version Server_Timestamp_Data 47 | -- ------- --------------------- 48 | urn:com.workday/bsvc v25.1 2015-12-02T12:18:30.841-08:00 49 | 50 | 51 | Get-Command -Module WorkdayApi | sort Name | Get-Help | Format-Table Name, Synopsis -AutoSize 52 | 53 | Name Synopsis 54 | ---- -------- 55 | Export-WorkdayDocument Exports Workday Documents. 56 | Get-WorkdayDate Gets the current time and date from Workday. 57 | Get-WorkdayEndpoint Gets the default Uri value for all or a particular Endpoint. 58 | Get-WorkdayIntegrationEvent Retrieves the status of a Workday Integration. 59 | Get-WorkdayReport Returns the XML result from any Workday report, based on its URI. 60 | Get-WorkdayWorker Gets Worker information as Workday XML. 61 | Get-WorkdayWorkerDocument Gets Workday Worker Documents. 62 | Get-WorkdayWorkerEmail Returns a Worker's email addresses. 63 | Get-WorkdayWorkerPhone Returns a Worker's phone numbers. 64 | Get-WorkdayWorkerPhoto Returns a worker's photo. 65 | Invoke-WorkdayRequest Sends XML requests to Workday API, with proper authentication and receives XML response. 66 | Remove-WorkdayConfiguration Removes Workday configuration file from the current user's Profile. 67 | Save-WorkdayConfiguration Saves default Workday configuration to a file in the current users Profile. 68 | Set-WorkdayCredential Sets the default Workday API credentials. 69 | Set-WorkdayEndpoint Sets the default Uri value for a particular Endpoint. 70 | Set-WorkdayWorkerDocument Uploads a document to a Worker's records in Workday. 71 | Set-WorkdayWorkerEmail Sets a Worker's email in Workday. 72 | Set-WorkdayWorkerPhone Sets a Worker's phone number in Workday. 73 | Set-WorkdayWorkerPhoto Uploads an image file to Workday and set it as a Worker's photo. 74 | Start-WorkdayIntegration Starts a Workday Integration. 75 | Update-WorkdayWorkerEmail Updates a Worker's email in Workday, only if it is different. 76 | Update-WorkdayWorkerPhone Updates a Worker's phone number in Workday, only if it is different. 77 | 78 | 79 | ## Installation ## 80 | 81 | The only dependency is Powershell version 4. 82 | 83 | This module has been published to the Powershell Gallery at https://www.powershellgallery.com/packages/WorkdayApi/ . 84 | 85 | To install run the following Powershell command: 86 | 87 | Install-Module -Name WorkdayApi 88 | 89 | ## Fine Print ## 90 | Please use with caution. This module could cause baldness, could warp time and space, could kill your puppy or, could do nothing at all. I am sharing what I am using as a starting point for a community developed solution. 91 | 92 | Any and all contributions are more than welcome and appreciated. 93 | -------------------------------------------------------------------------------- /source/License.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Nathan Hartley 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /source/WorkdayApi.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | Description = 'Provides a means to access the Workday SOAP API in a Powershell friendly manner.' 3 | ModuleVersion = '2.3.3' 4 | HelpInfoURI = 'https://github.com/treestryder/powershell_module_workdayapi/wiki' 5 | Author = 'Nathan Hartley' 6 | RootModule = 'WorkdayApi.psm1' 7 | PowerShellVersion = '5.1' 8 | CompatiblePSEditions = @('Desktop', 'Core') 9 | PrivateData = @{ 10 | PSData = @{ 11 | Tags = @('Workday') 12 | LicenseUri = 'https://github.com/treestryder/powershell_module_workdayapi/blob/master/source/License.txt' 13 | ProjectUri = 'https://github.com/treestryder/powershell_module_workdayapi/' 14 | ReleaseNotes = @' 15 | * Added progress meter to Get-WorkdayWorker. 16 | * Removed redunant [ordered] accelerator in Invoke-WorkdayRequest. Thank you mthreer. 17 | * Removed some uses of silent exceptions. 18 | * Implemented some validator recommendations. 19 | 20 | Change log available at: https://github.com/treestryder/powershell_module_workdayapi/blob/master/CHANGELOG.md 21 | '@ 22 | } 23 | } 24 | FunctionsToExport = @( 25 | 'ConvertFrom-WorkdayWorkerXml', 26 | 'Get-WorkdayToAdData', 27 | 'Get-WorkdayReport', 28 | 'Get-WorkdayWorker', 29 | 'Get-WorkdayWorkerByIdLookupTable', 30 | 'Invoke-WorkdayRequest', 31 | 'Remove-WorkdayConfiguration', 32 | 'Get-WorkdayWorkerPhoto', 33 | 'Set-WorkdayWorkerPhoto', 34 | 35 | 'Get-WorkdayEndpoint', 36 | 'Set-WorkdayCredential', 37 | 'Set-WorkdayEndpoint', 38 | 'Save-WorkdayConfiguration', 39 | 40 | 'Get-WorkdayWorkerEmail', 41 | 'Set-WorkdayWorkerEmail', 42 | 'Update-WorkdayWorkerEmail', 43 | 44 | 'Get-WorkdayWorkerDocument', 45 | 'Set-WorkdayWorkerDocument', 46 | 47 | 'Get-WorkdayWorkerNationalId', 48 | 49 | 'Get-WorkdayWorkerOtherId', 50 | 'Remove-WorkdayWorkerOtherId', 51 | 'Set-WorkdayWorkerOtherId', 52 | 'Update-WorkdayWorkerOtherId', 53 | 54 | 'Get-WorkdayWorkerPhone', 55 | 'Set-WorkdayWorkerPhone', 56 | 'Update-WorkdayWorkerPhone', 57 | 58 | 'Start-WorkdayIntegration', 59 | 'Get-WorkdayIntegrationEvent', 60 | 61 | 'Get-WorkdayDate', 62 | 63 | 'Set-WorkdayWorkerUserId' 64 | ) 65 | GUID = 'bd4390dc-a8ad-4bce-8d69-f53ccf8e4163' 66 | } 67 | -------------------------------------------------------------------------------- /source/WorkdayApi.psm1: -------------------------------------------------------------------------------- 1 | param ( 2 | [string]$ConfigurationFile = '~\.WorkdayApi.clixml' 3 | ) 4 | 5 | $WorkdayConfiguration = @{ 6 | Endpoints = @{ 7 | Human_Resources = $null 8 | Integrations = $null 9 | Staffing = $null 10 | } 11 | Credential = $null 12 | } 13 | 14 | ### Change from old configuration name to new name. 15 | $OldWorkdayConfigurationFile = $( 16 | If (($env:OS -eq 'Windows_NT') -Or ($PSVersionTable.platform -eq 'Win32NT')){ 17 | Join-Path $env:LOCALAPPDATA WorkdayConfiguration.clixml 18 | }ElseIf(($PSVersionTable.platform -eq 'Unix')){ 19 | Join-Path ~/.workdayapi/ 'WorkdayConfiguration.clixml' 20 | }) 21 | if (Test-Path $OldWorkdayConfigurationFile) { 22 | Move-Item -Path $OldWorkdayConfigurationFile -Destination $ConfigurationFile 23 | } 24 | 25 | if (Test-Path $ConfigurationFile) { 26 | $WorkdayConfiguration = Import-Clixml $ConfigurationFile 27 | } 28 | 29 | $NM = New-Object System.Xml.XmlNamespaceManager -ArgumentList (New-Object System.Xml.NameTable) 30 | $NM.AddNamespace('wd','urn:com.workday/bsvc') 31 | $NM.AddNamespace('bsvc','urn:com.workday/bsvc') 32 | 33 | Get-ChildItem "$PSScriptRoot/public/*.ps1" | ForEach-Object { . $_ } 34 | 35 | New-Alias -Name Export-WorkdayWorkerDocument -Value Get-WorkdayWorkerDocument 36 | -------------------------------------------------------------------------------- /source/en-US/about_WorkdayApi.help.txt: -------------------------------------------------------------------------------- 1 | # Workday SOAP API Powershell Script Module # 2 | 3 | 4 | ## Description ## 5 | Provides simple methods for accessing the Workday SOAP API. 6 | 7 | This simple Powershell Module has been written to fulfill my employer's Workday automation needs. I see this as a prototype, while I experiment with the best way to expose the complexities of the Workday API in a Powershell-y way. Thinking that the community might find it helpful and may even wish to comment or contribute, I have hosted the source on Bitbucket (https://bitbucket.org/treestryder/powershell_module_workdayapi/). 8 | 9 | 10 | ## Features ## 11 | 12 | * Easy command-line use, after setting default configuration options and securely saving them to the current user's profile. 13 | * Get Worker information for one or all workers. 14 | * Get / Set / Update Worker email. 15 | * Get / Set / Update Worker phone. 16 | * Upload Worker Photos. 17 | * Upload Worker Documents. 18 | * Run reports. 19 | * Trigger Integrations and retreive their status. 20 | * Submit arbitrary API calls. 21 | * A sample script to push A.D. changes to Workday (samples/Push_AD_to_Workday.ps1). 22 | 23 | 24 | ## Examples ## 25 | 26 | Set-WorkdayCredential 27 | Set-WorkdayEndpoint -Endpoint Staffing -Uri 'https://SERVICE.workday.com/ccx/service/TENANT/Staffing/v26.0' 28 | Set-WorkdayEndpoint -Endpoint Human_Resources -Uri 'https://SERVICE.workday.com/ccx/service/TENANT/Human_Resources/v26.0' 29 | Set-WorkdayEndpoint -Endpoint Integrations -Uri 'https://SERVICE.workday.com/ccx/service/TENANT/Integrations/v26.0' 30 | Save-WorkdayConfiguration 31 | 32 | Set-WorkdayWorkerPhone -WorkerId 123 -WorkerType Employee_ID -Number '+1 (234) 987-6543' 33 | 34 | Get-WorkdayWorkerPhone -WorkerId 123 -WorkerType Employee_ID | Format-Table 35 | 36 | UsageType DeviceType Number Extension Primary Public 37 | --------- ---------- ------ --------- ------- ------ 38 | Home Landline 1 (234) 567-8910 False False 39 | Work Landline 1 (234) 987-6543 True False 40 | 41 | 42 | $response = Invoke-WorkdayRequest -Request '' -Uri https://SERVICE.workday.com/ccx/service/TENANT/Human_Resources/v26.0 43 | $response.Xml.Server_TimeStamp 44 | 45 | wd version Server_Timestamp_Data 46 | -- ------- --------------------- 47 | urn:com.workday/bsvc v25.1 2015-12-02T12:18:30.841-08:00 48 | 49 | 50 | Get-Command -Module WorkdayApi | sort Name | Get-Help | Format-Table Name, Synopsis -AutoSize 51 | 52 | Name Synopsis 53 | ---- -------- 54 | Export-WorkdayDocument Exports Workday Documents. 55 | Get-WorkdayDate Gets the current time and date from Workday. 56 | Get-WorkdayEndpoint Gets the default Uri value for all or a particular Endpoint. 57 | Get-WorkdayIntegrationEvent Retrieves the status of a Workday Integration. 58 | Get-WorkdayReport Returns the XML result from any Workday report, based on its URI. 59 | Get-WorkdayWorker Gets Worker information as Workday XML. 60 | Get-WorkdayWorkerDocument Gets Workday Worker Documents. 61 | Get-WorkdayWorkerEmail Returns a Worker's email addresses. 62 | Get-WorkdayWorkerPhone Returns a Worker's phone numbers. 63 | Get-WorkdayWorkerPhoto Returns a worker's photo. 64 | Invoke-WorkdayRequest Sends XML requests to Workday API, with proper authentication and receives XML response. 65 | Remove-WorkdayConfiguration Removes Workday configuration file from the current user's Profile. 66 | Save-WorkdayConfiguration Saves default Workday configuration to a file in the current users Profile. 67 | Set-WorkdayCredential Sets the default Workday API credentials. 68 | Set-WorkdayEndpoint Sets the default Uri value for a particular Endpoint. 69 | Set-WorkdayWorkerDocument Uploads a document to a Worker's records in Workday. 70 | Set-WorkdayWorkerEmail Sets a Worker's email in Workday. 71 | Set-WorkdayWorkerPhone Sets a Worker's phone number in Workday. 72 | Set-WorkdayWorkerPhoto Uploads an image file to Workday and set it as a Worker's photo. 73 | Start-WorkdayIntegration Starts a Workday Integration. 74 | Update-WorkdayWorkerEmail Updates a Worker's email in Workday, only if it is different. 75 | Update-WorkdayWorkerPhone Updates a Worker's phone number in Workday, only if it is different. 76 | Set-WorkdayWorkerUserName Sets the employee/contingent workers login user name. 77 | 78 | 79 | ## Installation ## 80 | 81 | The only dependency is Powershell version 4. 82 | 83 | To install... 84 | 85 | * Download the files. 86 | * Execute the script Install-WorkdayModule.ps1 87 | -------------------------------------------------------------------------------- /source/public/ConvertFrom-WorkdayWorkerXml.ps1: -------------------------------------------------------------------------------- 1 | function ConvertFrom-WorkdayWorkerXml { 2 | <# 3 | .Synopsis 4 | Converts Workday Worker XML into a custom object. 5 | #> 6 | [CmdletBinding()] 7 | [OutputType([pscustomobject])] 8 | Param ( 9 | [Parameter(Mandatory=$true, 10 | ValueFromPipeline=$true, 11 | ValueFromPipelineByPropertyName=$true, 12 | Position=0)] 13 | [xml[]]$Xml 14 | ) 15 | 16 | Begin { 17 | $WorkerObjectTemplate = [pscustomobject][ordered]@{ 18 | WorkerWid = $null 19 | Active = $null 20 | WorkerDescriptor = $null 21 | PreferredName = $null 22 | FirstName = $null 23 | LastName = $null 24 | WorkerType = $null 25 | WorkerId = $null 26 | UserId = $null 27 | NationalId = $null 28 | OtherId = $null 29 | Phone = $null 30 | Email = $null 31 | BusinessTitle = $null 32 | JobProfileName = $null 33 | Location = $null 34 | WorkSpace = $null 35 | WorkerTypeReference = $null 36 | Manager = $null 37 | Company = $null 38 | BusinessUnit = $null 39 | Supervisory = $null 40 | XML = $null 41 | } 42 | $WorkerObjectTemplate.PsObject.TypeNames.Insert(0, "Workday.Worker") 43 | } 44 | 45 | Process { 46 | foreach ($elements in $Xml) { 47 | foreach ($x in $elements.SelectNodes('//wd:Worker', $NM)) { 48 | $o = $WorkerObjectTemplate.PsObject.Copy() 49 | 50 | $referenceId = $x.Worker_Reference.ID | Where-Object {$_.type -ne 'WID'} 51 | 52 | $o.WorkerWid = $x.Worker_Reference.ID | Where-Object {$_.type -eq 'WID'} | Select-Object -ExpandProperty '#text' 53 | $o.WorkerDescriptor = $x.Worker_Descriptor 54 | $o.PreferredName = $x.Worker_Data.Personal_Data.Name_Data.Preferred_Name_Data.Name_Detail_Data.Formatted_Name 55 | $o.FirstName = $x.Worker_Data.Personal_Data.Name_Data.Preferred_Name_Data.Name_Detail_Data.First_Name 56 | $o.LastName = $x.Worker_Data.Personal_Data.Name_Data.Preferred_Name_Data.Name_Detail_Data.Last_Name 57 | $o.WorkerType = $referenceId.type 58 | $o.WorkerId = $referenceId.'#text' 59 | $o.XML = [XML]$x.OuterXml 60 | 61 | $o.Phone = @(Get-WorkdayWorkerPhone -WorkerXml $x.OuterXml) 62 | $o.Email = @(Get-WorkdayWorkerEmail -WorkerXml $x.OuterXml) 63 | $o.NationalId = @(Get-WorkdayWorkerNationalId -WorkerXml $x.OuterXml) 64 | $o.OtherId = @(Get-WorkdayWorkerOtherId -WorkerXml $x.OuterXml) 65 | $o.UserId = $x.Worker_Data.User_ID 66 | 67 | # The methods SelectNodes and SelectSingleNode have access to the entire XML document and require anchoring with "./" to work as expected. 68 | $workerEmploymentData = $x.SelectSingleNode('./wd:Worker_Data/wd:Employment_Data', $NM) 69 | if ($null -ne $workerEmploymentData) { 70 | $o.Active = $workerEmploymentData.Worker_Status_Data.Active -eq '1' 71 | } 72 | $workerJobData = $x.SelectSingleNode('./wd:Worker_Data/wd:Employment_Data/wd:Worker_Job_Data', $NM) 73 | if ($null -ne $workerJobData) { 74 | $o.BusinessTitle = $workerJobData.Position_Data.Business_Title 75 | $o.JobProfileName = $workerJobData.Position_Data.Job_Profile_Summary_Data.Job_Profile_Name 76 | $o.Location = $workerJobData.SelectNodes('./wd:Position_Data/wd:Business_Site_Summary_Data/wd:Name', $NM) | Select-Object -ExpandProperty InnerText -First 1 -ErrorAction SilentlyContinue 77 | $o.WorkSpace = $workerJobData.SelectNodes('./wd:Position_Data/wd:Work_Space__Reference/wd:ID[@wd:type="Location_ID"]', $NM) | Select-Object -ExpandProperty InnerText -First 1 -ErrorAction SilentlyContinue 78 | $o.WorkerTypeReference = $workerJobData.SelectNodes('./wd:Position_Data/wd:Worker_Type_Reference/wd:ID[@wd:type="Employee_Type_ID"]', $NM) | Select-Object -ExpandProperty InnerText -First 1 -ErrorAction SilentlyContinue 79 | $o.Manager = $workerJobData.Position_Data.Manager_as_of_last_detected_manager_change_Reference.ID | 80 | Where-Object {$_.type -ne 'WID'} | 81 | Select-Object @{Name='WorkerType';Expression={$_.type}}, @{Name='WorkerID';Expression={$_.'#text'}} 82 | $o.Company = $workerJobData.SelectNodes('./wd:Position_Organizations_Data/wd:Position_Organization_Data/wd:Organization_Data[wd:Organization_Type_Reference/wd:ID[@wd:type="Organization_Type_ID" and . = "COMPANY"]]', $NM) | Select-Object -ExpandProperty Organization_Name -First 1 -ErrorAction SilentlyContinue 83 | $o.BusinessUnit = $workerJobData.SelectNodes('./wd:Position_Organizations_Data/wd:Position_Organization_Data/wd:Organization_Data[wd:Organization_Type_Reference/wd:ID[@wd:type="Organization_Type_ID" and . = "BUSINESS_UNIT"]]', $NM) | Select-Object -ExpandProperty Organization_Name -First 1 -ErrorAction SilentlyContinue 84 | $o.Supervisory = $workerJobData.SelectNodes('./wd:Position_Organizations_Data/wd:Position_Organization_Data/wd:Organization_Data[wd:Organization_Type_Reference/wd:ID[@wd:type="Organization_Type_ID" and . = "SUPERVISORY"]]', $NM) | Select-Object -ExpandProperty Organization_Name -First 1 -ErrorAction SilentlyContinue 85 | } 86 | 87 | Write-Output $o 88 | } 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /source/public/Get-WorkdayDate.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Gets the current time and date from Workday. 4 | 5 | .DESCRIPTION 6 | Gets the current time and date, as a DateTime object, from Workday. 7 | 8 | .PARAMETER Human_ResourcesUri 9 | Human_Resources Endpoint Uri for the request. If not provided, the value 10 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 11 | 12 | .PARAMETER Username 13 | Username used to authenticate with Workday. If empty, the value stored 14 | using Set-WorkdayCredential will be used. 15 | 16 | .PARAMETER Password 17 | Password used to authenticate with Workday. If empty, the value stored 18 | using Set-WorkdayCredential will be used. 19 | 20 | .EXAMPLE 21 | 22 | Get-WorkdayWorker -WorkerId 123 -IncludePersonal 23 | 24 | #> 25 | function Get-WorkdayDate { 26 | [CmdletBinding()] 27 | param ( 28 | [string]$Human_ResourcesUri, 29 | [string]$Username, 30 | [string]$Password 31 | ) 32 | 33 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = Get-WorkdayEndpoint 'Human_Resources' } 34 | 35 | $request = '' 36 | $response = Invoke-WorkdayRequest -Request $request -Uri $Human_ResourcesUri -Username:$Username -Password:$Password 37 | 38 | if ($response.Success) { 39 | Get-Date $response.Xml.Server_TimeStamp.Server_Timestamp_Data 40 | } 41 | else { 42 | Write-Warning $response.Message 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /source/public/Get-WorkdayEndpoint.ps1: -------------------------------------------------------------------------------- 1 | function Get-WorkdayEndpoint { 2 | <# 3 | .SYNOPSIS 4 | Gets the default Uri value for all or a particular Endpoint. 5 | 6 | .DESCRIPTION 7 | Gets the default Uri value for all or a particular Endpoint. 8 | 9 | .PARAMETER Endpoint 10 | The curent Endpoints used by this module are: 11 | 'Human_Resources', 'Staffing' 12 | 13 | .EXAMPLE 14 | 15 | Get-WorkdayEndpoint -Endpoint Staffing 16 | 17 | Demonstrates how to get a single Endpoint value. 18 | 19 | .EXAMPLE 20 | 21 | Get-WorkdayEndpoint 22 | 23 | Demonstrates how to get all of the Endpoint values. 24 | 25 | #> 26 | 27 | [CmdletBinding()] 28 | param ( 29 | [parameter(Mandatory=$false)] 30 | [ValidateSet('Human_Resources', 'Integrations', 'Staffing')] 31 | [string]$Endpoint 32 | ) 33 | 34 | if ([string]::IsNullOrWhiteSpace($Endpoint)) { 35 | Write-Output $WorkdayConfiguration.Endpoints 36 | } else { 37 | Write-Output $WorkdayConfiguration.Endpoints[$Endpoint] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /source/public/Get-WorkdayIntegrationEvent.ps1: -------------------------------------------------------------------------------- 1 |  2 | function Get-WorkdayIntegrationEvent { 3 | 4 | <# 5 | .SYNOPSIS 6 | Retrieves the status of a Workday Integration. 7 | 8 | .DESCRIPTION 9 | Retrieves the status of a Workday Integration. 10 | 11 | .PARAMETER Wid 12 | The WID of the Integration Event to retrieve. 13 | 14 | .PARAMETER Type 15 | The type of ID that -Id represents. Valid values 16 | are 'WID' or 'Integration_System_ID'. 17 | 18 | .PARAMETER Integrations_ResourcesUri 19 | Integration Endpoint Uri for the request. If not provided, the value 20 | stored with Set-WorkdayEndpoint -Endpoint Integration is tried. 21 | 22 | .PARAMETER Username 23 | Username used to authenticate with Workday. If empty, the value stored 24 | using Set-WorkdayCredential will be used. 25 | 26 | .PARAMETER Password 27 | Password used to authenticate with Workday. If empty, the value stored 28 | using Set-WorkdayCredential will be used. 29 | 30 | .EXAMPLE 31 | Get-WorkdayIntegrationEvent -Wid 0123456789ABCDEF0123456789ABCDEF -Integrations_ResourcesUri 'https://SERVICE.workday.com/ccx/service/TENANT/Integrations/v26.0' 32 | 33 | Name : Integration ESB Invocation (INT123 Integration - 04/13/2016 10:18:57.848 (Completed)) 34 | Start : 4/13/2016 1:18:57 PM 35 | End : 4/13/2016 1:21:21 PM 36 | Message : Integration Completed. 37 | PercentComplete : 100 38 | Xml : #document 39 | 40 | .NOTES 41 | Currently only designed for use when waiting for an Integration to complete and retrieving its status. 42 | Start-WorkdayIntegration -Wait 43 | 44 | TODO: Update request to current specifications. https://community.workday.com/sites/default/files/file-hosting/productionapi/Integrations/v30.0/Launch_Integration.html 45 | 46 | #> 47 | 48 | [CmdletBinding(DefaultParametersetName='Search')] 49 | [OutputType([PSCustomObject])] 50 | param ( 51 | [Parameter(Mandatory = $true, 52 | Position=0)] 53 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 54 | [string]$Wid, 55 | [string]$Username, 56 | [string]$Password, 57 | [string]$Integrations_ResourcesUri 58 | ) 59 | 60 | if ([string]::IsNullOrWhiteSpace($Integrations_ResourcesUri)) { $Integrations_ResourcesUri = $WorkdayConfiguration.Endpoints['Integrations'] } 61 | 62 | $request = [XML]@' 63 | 64 | 65 | 66 | wid 67 | 68 | 69 | 70 | '@ 71 | $request.Get_Integration_Events_Request.Request_References.Integration_Event_Reference.ID.InnerText = $wid 72 | 73 | $response = Invoke-WorkdayRequest -Request $request -Uri $Integrations_ResourcesUri -Username:$Username -Password:$Password 74 | 75 | $output = [pscustomobject][ordered]@{ 76 | Name = $null 77 | Start = $null 78 | End = $null 79 | Message = $null 80 | PercentComplete = $null 81 | Xml = $null 82 | } 83 | 84 | if ($null -eq $response) { 85 | $output.Message = 'ERROR: null response.' 86 | return $output 87 | } 88 | 89 | if ($response.Success -eq $false) { 90 | $output.Status = $response.Message 91 | $output.Xml = $response.Xml 92 | return $output 93 | } 94 | 95 | $output.Name = $response.Xml.Get_Integration_Events_Response.Request_References.Integration_Event_Reference.Descriptor 96 | 97 | $startTime = $response.Xml.Get_Integration_Events_Response.Response_Data.Integration_Event.Integration_Event_Data.Initiated_DateTime 98 | if ([string]::IsNullOrWhiteSpace($startTime) -eq $false) { 99 | $output.Start = Get-Date $startTime 100 | } 101 | 102 | $endTime = $response.Xml.Get_Integration_Events_Response.Response_Data.Integration_Event.Integration_Event_Data.Completed_DateTime 103 | if ([string]::IsNullOrWhiteSpace($endTime) -eq $false) { 104 | $output.End = Get-Date $endTime 105 | } 106 | 107 | $output.Message = $response.Xml.Get_Integration_Events_Response.Response_Data.Integration_Event.Integration_Event_Data.Integration_Response_Message 108 | 109 | $percentComplete = $response.Xml.Get_Integration_Events_Response.Response_Data.Integration_Event.Integration_Event_Data.Percent_Complete 110 | if ([string]::IsNullOrWhiteSpace($percentComplete) -eq $false) { 111 | $output.PercentComplete = ([int]$percentComplete) * 100 112 | } 113 | 114 | $output.Xml = $response.Xml 115 | return $output 116 | 117 | } 118 | -------------------------------------------------------------------------------- /source/public/Get-WorkdayReport.ps1: -------------------------------------------------------------------------------- 1 | function Get-WorkdayReport { 2 | <# 3 | .SYNOPSIS 4 | Returns the XML result from any Workday report, based on its URI. 5 | 6 | .DESCRIPTION 7 | Returns the XML result from any Workday report, based on its URI. 8 | 9 | .PARAMETER Uri 10 | Uri for the report. 11 | 12 | .PARAMETER Username 13 | Username used to authenticate with Workday. If empty, the value stored 14 | using Set-WorkdayCredential will be used. 15 | 16 | .PARAMETER Password 17 | Password used to authenticate with Workday. If empty, the value stored 18 | using Set-WorkdayCredential will be used. 19 | 20 | .NOTES 21 | TODO: Create a parameter that accepts a report name, rather than parsing a Uri. 22 | 23 | #> 24 | 25 | [CmdletBinding()] 26 | [OutputType([XML])] 27 | param ( 28 | [Parameter(Mandatory = $true)] 29 | [ValidateNotNullOrEmpty()] 30 | [string]$Uri, 31 | [string]$Username, 32 | [string]$Password 33 | ) 34 | 35 | if ($Uri -match '\/([a-z0-9-_]+)(\?|$)') { 36 | $reportName = $Matches[1] 37 | } else { 38 | throw "A valid report name was not found in the Uri: $Uri" 39 | } 40 | 41 | $request = @' 42 | 43 | '@ -f $reportName 44 | 45 | Invoke-WorkdayRequest -Request $request -Uri $Uri -Username:$Username -Password:$Password | Write-Output 46 | } -------------------------------------------------------------------------------- /source/public/Get-WorkdayToAdData.ps1: -------------------------------------------------------------------------------- 1 | function Get-WorkdayToAdData { 2 | <# 3 | .SYNOPSIS 4 | Converts Get-WorkdayWorker output into "INT011 WD to AD - DT" format. 5 | .NOTES 6 | This is a first attempt at pulling data which is normally gathered by 7 | an integration called "INT011 WD to AD - DT". Though I suspect this 8 | format is specific to my company, I add this as some may find it 9 | valuable. In fact, some of this should probably be moved 10 | into Get-WorkdayWorker. 11 | #> 12 | [CmdletBinding()] 13 | [OutputType([pscustomobject])] 14 | param ( 15 | [Parameter(Position=0, 16 | ValueFromPipelineByPropertyName=$true, 17 | ParameterSetName='IndividualWorker')] 18 | [ValidatePattern ('^$|^[a-zA-Z0-9\-]{1,32}$')] 19 | [string]$WorkerId, 20 | [Parameter(Position=1, 21 | ValueFromPipelineByPropertyName=$true, 22 | ParameterSetName='IndividualWorker')] 23 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 24 | [string]$WorkerType = 'Employee_ID', 25 | [string]$Human_ResourcesUri, 26 | [string]$Username, 27 | [string]$Password, 28 | [switch]$Force, 29 | # Adds a "Worker" Property containing the full Worker object. 30 | [switch]$PassThru 31 | ) 32 | 33 | begin { 34 | $objectTemplate = 0 | select 'ADD or CHANGE','Employee or Contingent Worker Number','First Name','Last Name','Preferred First Name','Preferred Last Name','User Name','Work Phone','Job Title','Employee or Contingent Worker Type','Worker Type','Worker SubType','Department (LOB)','Sub Department','Location (Building)','Location(Workspace)','Badge Id','Supervisor Name','Supervisor Employee Id','Matrix Manager Name (for Team Members)','Hire Date','Termination Date','Requires Cisco Phone' 35 | 36 | filter ParseWorker { 37 | $w = $_ 38 | if ($w.psobject.TypeNames -contains 'WorkdayResponse') { 39 | Write-Error ('Input object was not of type WorkdayResponse: {0}' -f $w.psobject.TypeNames) 40 | continue 41 | } 42 | 43 | $o = $objectTemplate.psobject.Copy() 44 | if ($PassThru) { 45 | $o = Add-Member -InputObject $o -MemberType NoteProperty -Name Worker -Value $w -PassThru 46 | } 47 | $o.'ADD or CHANGE' = '' 48 | $o.'Employee or Contingent Worker Number' = $w.WorkerId 49 | $o.'First Name' = $w.Xml.Worker.Worker_Data.Personal_Data.Name_Data.Legal_Name_Data.Name_Detail_Data.First_Name 50 | $o.'Last Name' = $w.Xml.Worker.Worker_Data.Personal_Data.Name_Data.Legal_Name_Data.Name_Detail_Data.Last_Name 51 | $o.'Preferred First Name' = $w.FirstName 52 | $o.'Preferred Last Name' = $w.LastName 53 | $o.'User Name' = $w.Xml.Worker.Worker_Data.User_ID 54 | $o.'Work Phone' = $w.Phone | where { $_.UsageType -like 'Work' -and $_.Primary -and $_.Public } | select -ExpandProperty Number -First 1 55 | $o.'Badge ID' = $w.OtherID | where { $_.Type -eq 'Badge_ID' } | select -ExpandProperty Id -First 1 56 | $o.'Job Title' = $w.JobProfileName -replace '^.+?-','' 57 | $o.'Employee or Contingent Worker Type' = $w.Xml.Worker.Worker_Data.Employment_Data.Worker_Job_Data.Position_Data.Worker_Type_Reference.ID | where { $_.type -eq 'Employee_Type_ID' } | select -ExpandProperty '#text' -First 1 58 | $o.'Worker Type' = if ($w.Xml.Worker.Worker_Reference.ID | where { $_.type -eq 'Employee_ID' } ) {'Employee'} else {'Contingent Worker'} 59 | $o.'Worker SubType' = $w.Xml.Worker.Worker_Data.Employment_Data.Worker_Job_Data.Position_Data.Worker_Type_Reference.Descriptor 60 | # Could not find Department. 61 | # 62 | $o.'Department (LOB)' = 'Unimplemented' 63 | # Could not find Subdepartment. 64 | # 65 | $o.'Sub Department' = 'Unimplemented' 66 | $o.'Location (Building)' = $w.Location 67 | $o.'Location(Workspace)' = $w.Workspace 68 | $supervisorDescriptor = $w.Xml.Worker.Worker_Data.Employment_Data.Worker_Job_Data.Position_Data.Manager_as_of_last_detected_manager_change_Reference.Descriptor 69 | $o.'Supervisor Name' = if ($supervisorDescriptor -match '(^.+)\s\(') { 70 | $Matches[1] 71 | } 72 | else { 73 | $supervisorDescriptor 74 | } 75 | $o.'Supervisor Employee Id' = $w.Xml.Worker.Worker_Data.Employment_Data.Worker_Job_Data.Position_Data.Manager_as_of_last_detected_manager_change_Reference.ID | where { $_.type -eq 'Employee_ID' } | select -ExpandProperty '#text' -First 1 76 | # Have not found Matrix Manager. 77 | $o.'Matrix Manager Name (for Team Members)' = $null 78 | $hireDate = $w.Xml.Worker.Worker_Data.Employment_Data.Worker_Status_Data.Hire_Date 79 | $o.'Hire Date' = if ($hireDate.length -ge 10) { $hireDate.Substring(0,10) } 80 | Write-Output $o 81 | } 82 | } 83 | 84 | process { 85 | Get-WorkdayWorker -WorkerId:$WorkerId -WorkerType:$WorkerType -Human_ResourcesUri:$Human_ResourcesUri -Username:$Username -Password:$Password -Force:$Force -IncludePersonal -IncludeWork | 86 | ParseWorker | 87 | Write-Output 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /source/public/Get-WorkdayWorker.ps1: -------------------------------------------------------------------------------- 1 | function Get-WorkdayWorker { 2 | <# 3 | .SYNOPSIS 4 | Gets Worker information as Workday XML. 5 | 6 | .DESCRIPTION 7 | Gets Worker information as Workday XML. 8 | 9 | .PARAMETER WorkerId 10 | The Worker's Id at Workday. 11 | 12 | .PARAMETER WorkerType 13 | The type of ID that the WorkerId represents. Valid values 14 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 15 | 16 | .PARAMETER IncludePersonal 17 | Adds Reference and Personal_Information values to response. 18 | 19 | .PARAMETER IncludeWork 20 | Adds Employment_Information, Compensation, Organizations and Roles 21 | values to the response. 22 | 23 | .PARAMETER Passthru 24 | Outputs Invoke-WorkdayRequest object, rather than a custom Worker object. 25 | 26 | .PARAMETER IncludeInactive 27 | Also returns inactive worker(s). Alias is Force 28 | 29 | .PARAMETER Human_ResourcesUri 30 | Human_Resources Endpoint Uri for the request. If not provided, the value 31 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 32 | 33 | .PARAMETER Username 34 | Username used to authenticate with Workday. If empty, the value stored 35 | using Set-WorkdayCredential will be used. 36 | 37 | .PARAMETER Password 38 | Password used to authenticate with Workday. If empty, the value stored 39 | using Set-WorkdayCredential will be used. 40 | 41 | .EXAMPLE 42 | 43 | Get-WorkdayWorker -WorkerId 123 -IncludePersonal 44 | 45 | #> 46 | 47 | #TODO: Potentially, include inactive users when a specific worker is requestd. 48 | 49 | [CmdletBinding()] 50 | [OutputType([PSCustomObject])] 51 | param ( 52 | [Parameter(Position=0, 53 | ValueFromPipelineByPropertyName=$true, 54 | ParameterSetName='IndividualWorker')] 55 | [ValidatePattern ('^$|^[a-zA-Z0-9\-]{1,32}$')] 56 | [string]$WorkerId, 57 | [Parameter(Position=1, 58 | ValueFromPipelineByPropertyName=$true, 59 | ParameterSetName='IndividualWorker')] 60 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 61 | [string]$WorkerType = 'Employee_ID', 62 | [string]$Human_ResourcesUri, 63 | [string]$Username, 64 | [string]$Password, 65 | [switch]$IncludePersonal, 66 | [switch]$IncludeWork, 67 | [switch]$IncludeDocuments, 68 | [DateTime]$AsOfEntryDateTime = (Get-Date), 69 | # Outputs raw XML, rather than a custom object. 70 | [switch]$Passthru, 71 | [Alias("Force")] 72 | [switch]$IncludeInactive 73 | ) 74 | 75 | begin { 76 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = Get-WorkdayEndpoint 'Human_Resources' } 77 | } 78 | 79 | process { 80 | $request = [xml]@' 81 | 82 | 83 | 84 | ?EmployeeId? 85 | 86 | 87 | 88 | Page 89 | ?DateTime? 90 | 91 | 92 | true 93 | 94 | 95 | true 96 | false 97 | false 98 | false 99 | false 100 | false 101 | false 102 | 103 | 104 | '@ 105 | 106 | $request.Get_Workers_Request.Response_Filter.As_Of_Entry_DateTime = $AsOfEntryDateTime.ToString('o') 107 | 108 | if ([string]::IsNullOrWhiteSpace($WorkerId)) { 109 | $null = $request.Get_Workers_Request.RemoveChild($request.Get_Workers_Request.Request_References) 110 | } else { 111 | $request.Get_Workers_Request.Request_References.Worker_Reference.ID.InnerText = $WorkerId 112 | if ($WorkerType -eq 'Contingent_Worker_ID') { 113 | $request.Get_Workers_Request.Request_References.Worker_Reference.ID.type = 'Contingent_Worker_ID' 114 | } elseif ($WorkerType -eq 'WID') { 115 | $request.Get_Workers_Request.Request_References.Worker_Reference.ID.type = 'WID' 116 | } 117 | } 118 | 119 | # Default = Reference, Personal Data, Employment Data, Compensation Data, Organization Data, and Role Data. 120 | if ($IncludePersonal) { 121 | $request.Get_Workers_Request.Response_Group.Include_Personal_Information = 'true' 122 | } 123 | 124 | if ($IncludeWork) { 125 | $request.Get_Workers_Request.Response_Group.Include_Employment_Information = 'true' 126 | $request.Get_Workers_Request.Response_Group.Include_Compensation = 'true' 127 | $request.Get_Workers_Request.Response_Group.Include_Organizations = 'true' 128 | $request.Get_Workers_Request.Response_Group.Include_Roles = 'true' 129 | } 130 | 131 | if ($IncludeDocuments) { 132 | $request.Get_Workers_Request.Response_Group.Include_Worker_Documents = 'true' 133 | } 134 | 135 | if ($IncludeInactive) { 136 | $request.Get_Workers_Request.Request_Criteria.Exclude_Inactive_Workers = 'false' 137 | } 138 | 139 | $nextPage = 0 140 | $totalPages = 1 141 | $more = $true 142 | while ($more) { 143 | $percentComplete = ($nextPage / $totalPages) * 100 144 | Write-Progress -Activity 'WorkdayAPI Get_Workers_Request' -Status "Page $nextPage of $totalPages" -PercentComplete $percentComplete 145 | $nextPage += 1 146 | $request.Get_Workers_Request.Response_Filter.Page = $nextPage.ToString() 147 | $response = Invoke-WorkdayRequest -Request $request -Uri $Human_ResourcesUri -Username:$Username -Password:$Password 148 | if ($Passthru -or $response.Success -eq $false) { 149 | Write-Output $response 150 | } else { 151 | $response.Xml | ConvertFrom-WorkdayWorkerXml 152 | } 153 | $totalPages = $response.xml.Get_Workers_Response.Response_Results.Total_Pages 154 | $more = $response.Success -and $nextPage -lt $totalPages 155 | } 156 | Write-Progress -Completed -Activity 'WorkdayAPI Get_Workers_Request' 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /source/public/Get-WorkdayWorkerByIdLookupTable.ps1: -------------------------------------------------------------------------------- 1 | function Get-WorkdayWorkerByIdLookupTable { 2 | <# 3 | .SYNOPSIS 4 | Returns a hashtable of Worker Type and IDs, indexed by ID. 5 | 6 | .DESCRIPTION 7 | Returns a hashtable of Worker Type and IDs, indexed by ID. Useful 8 | when the Contingent Worker and Employee ID numbers are unique. 9 | #> 10 | [CmdletBinding()] 11 | param ( 12 | [switch]$IncludeInactive, 13 | [string]$Human_ResourcesUri, 14 | [string]$Username, 15 | [string]$Password 16 | ) 17 | 18 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 19 | 20 | $WorkerByIdLookup = @{} 21 | 22 | Write-Verbose 'Downloading lookup table from Workday.' 23 | Get-WorkdayWorker -IncludeInactive:$IncludeInactive -Human_ResourcesUri $Human_ResourcesUri -Username:$Username -Password:$Password | ForEach-Object { 24 | if (-not $WorkerByIdLookup.ContainsKey($_.WorkerId)) { 25 | $WorkerByIdLookup[$_.WorkerId] = @() 26 | } 27 | $WorkerByIdLookup[$_.WorkerId] += @{ 28 | WorkerType = $_.WorkerType 29 | WorkerId = $_.WorkerId 30 | WorkerWid = $_.WorkerWid 31 | } 32 | } 33 | Write-Output $WorkerByIdLookup 34 | } 35 | -------------------------------------------------------------------------------- /source/public/Get-WorkdayWorkerDocument.ps1: -------------------------------------------------------------------------------- 1 | function Get-WorkdayWorkerDocument { 2 | <# 3 | .SYNOPSIS 4 | Gets Workday Worker Documents. 5 | 6 | .DESCRIPTION 7 | Gets Workday Worker Documents. 8 | 9 | .PARAMETER WorkerId 10 | The Worker's Id at Workday. A Worker ID must be at least 1, up to 32, numbers or hex characters. 11 | 12 | .PARAMETER WorkerType 13 | The type of ID that the WorkerId represents. Valid values 14 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 15 | 16 | .PARAMETER Path 17 | If specified, the files will be saved to this directory path. Otherwise the Base64 is returned with an object that can be saved using its SaveAs method. 18 | 19 | .PARAMETER Human_ResourcesUri 20 | Human_Resources Endpoint Uri for the request. If not provided, the value 21 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 22 | 23 | .PARAMETER Username 24 | Username used to authenticate with Workday. If empty, the value stored 25 | using Set-WorkdayCredential will be used. 26 | 27 | .PARAMETER Password 28 | Password used to authenticate with Workday. If empty, the value stored 29 | using Set-WorkdayCredential will be used. 30 | 31 | .EXAMPLE 32 | 33 | Get-WorkdayWorkerDocument -WorkerId 123 34 | 35 | #> 36 | 37 | [CmdletBinding(DefaultParametersetName='Search')] 38 | [OutputType([PSCustomObject])] 39 | param ( 40 | [Parameter(Mandatory = $true, 41 | Position=0, 42 | ParameterSetName='Search')] 43 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 44 | [string]$WorkerId, 45 | [Parameter(ParameterSetName="Search")] 46 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 47 | [string]$WorkerType = 'Employee_ID', 48 | [Parameter(ParameterSetName="Search")] 49 | [string]$Human_ResourcesUri, 50 | [Parameter(ParameterSetName="Search")] 51 | [string]$Username, 52 | [Parameter(ParameterSetName="Search")] 53 | [string]$Password, 54 | [Parameter(ParameterSetName="NoSearch")] 55 | [xml]$DocumentXml, 56 | [string]$Path 57 | ) 58 | 59 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 60 | 61 | if ($PsCmdlet.ParameterSetName -eq 'Search') { 62 | $response = Get-WorkdayWorker -WorkerId $WorkerId -WorkerType $WorkerType -IncludeInactive -IncludeDocuments -PassThru -Human_ResourcesUri $Human_ResourcesUri -Username:$Username -Password:$Password -ErrorAction Stop 63 | if (-not $response.Success) { throw "Error getting documents using Get-WorkdayWorker: $($response.Message)" } 64 | $DocumentXml = $response.Xml 65 | } 66 | 67 | if ($null -eq $DocumentXml) { 68 | Write-Warning 'Unable to find Document information.' 69 | return 70 | } 71 | 72 | $fileTemplate = [pscustomobject][ordered]@{ 73 | FileName = $null 74 | Category = $null 75 | Base64 = $null 76 | Path = $null 77 | } 78 | 79 | Add-Member -InputObject $fileTemplate -MemberType ScriptMethod -Name SaveAs -Value { 80 | param ( [string]$Path ) 81 | [system.io.file]::WriteAllBytes( $Path, [System.Convert]::FromBase64String( $this.Base64 ) ) 82 | } 83 | 84 | if (-not ([string]::IsNullOrEmpty($Path)) -and -not (Test-Path -Path $Path)) { 85 | New-Item -Path $Path -ItemType Directory | Out-Null 86 | } 87 | 88 | foreach ($doc in $DocumentXml.GetElementsByTagName('wd:Worker_Document_Detail_Data')) { 89 | $o = $fileTemplate.PsObject.Copy() 90 | $categoryXml = $doc.Document_Category_Reference.ID | Where-Object {$_.type -match 'Document_Category__Workday_Owned__ID|Document_Category_ID'} 91 | $o.Category = '{0}/{1}' -f $categoryXml.type, $categoryXml.'#text' 92 | $o.FileName = $doc.Filename 93 | $o.Base64 = $doc.File 94 | 95 | if (-not ([string]::IsNullOrEmpty($Path))) { 96 | $filePath = Join-Path $Path $o.FileName 97 | $o.Path = $filePath 98 | $o.SaveAs($filePath) 99 | } 100 | 101 | Write-Output $o 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /source/public/Get-WorkdayWorkerEmail.ps1: -------------------------------------------------------------------------------- 1 | function Get-WorkdayWorkerEmail { 2 | <# 3 | .SYNOPSIS 4 | Returns a Worker's email addresses. 5 | 6 | .DESCRIPTION 7 | Returns a Worker's email addresses as custom Powershell objects. 8 | 9 | .PARAMETER WorkerId 10 | The Worker's Id at Workday. 11 | 12 | .PARAMETER WorkerType 13 | The type of ID that the WorkerId represents. Valid values 14 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 15 | 16 | .PARAMETER Human_ResourcesUri 17 | Human_Resources Endpoint Uri for the request. If not provided, the value 18 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 19 | 20 | .PARAMETER Username 21 | Username used to authenticate with Workday. If empty, the value stored 22 | using Set-WorkdayCredential will be used. 23 | 24 | .PARAMETER Password 25 | Password used to authenticate with Workday. If empty, the value stored 26 | using Set-WorkdayCredential will be used. 27 | 28 | .EXAMPLE 29 | 30 | Get-WorkdayWorkerEmail -WorkerId 123 31 | 32 | Type Email Primary Public 33 | ---- ----- ------- ------ 34 | Home home@example.com True False 35 | Work work@example.com True True 36 | 37 | #> 38 | 39 | [CmdletBinding(DefaultParametersetName='Search')] 40 | [OutputType([PSCustomObject])] 41 | param ( 42 | [Parameter(Mandatory = $true, 43 | Position=0, 44 | ParameterSetName='Search')] 45 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 46 | [string]$WorkerId, 47 | [Parameter(ParameterSetName="Search")] 48 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 49 | [string]$WorkerType = 'Employee_ID', 50 | [Parameter(ParameterSetName="Search")] 51 | [string]$Human_ResourcesUri, 52 | [Parameter(ParameterSetName="Search")] 53 | [string]$Username, 54 | [Parameter(ParameterSetName="Search")] 55 | [string]$Password, 56 | [Parameter(ParameterSetName="NoSearch")] 57 | [xml]$WorkerXml, 58 | [Alias("Force")] 59 | [switch]$IncludeInactive 60 | 61 | ) 62 | 63 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 64 | 65 | if ($PsCmdlet.ParameterSetName -eq 'Search') { 66 | $response = Get-WorkdayWorker -WorkerId $WorkerId -WorkerType $WorkerType -IncludePersonal -Passthru -Human_ResourcesUri $Human_ResourcesUri -Username:$Username -Password:$Password -IncludeInactive:$IncludeInactive -ErrorAction Stop 67 | $WorkerXml = $response.Xml 68 | } 69 | 70 | if ($null -eq $WorkerXml) { 71 | Write-Warning 'Unable to get Email information, Worker not found.' 72 | return 73 | } 74 | 75 | $numberTemplate = [pscustomobject][ordered]@{ 76 | UsageType = $null 77 | Email = $null 78 | Primary = $null 79 | Public = $null 80 | } 81 | 82 | $WorkerXml.GetElementsByTagName('wd:Email_Address_Data') | ForEach-Object { 83 | $o = $numberTemplate.PsObject.Copy() 84 | $o.UsageType = $_.SelectSingleNode('wd:Usage_Data/wd:Type_Data/wd:Type_Reference/wd:ID[@wd:type="Communication_Usage_Type_ID"]', $NM).InnerText 85 | $o.Email = $_.Email_Address 86 | $o.Primary = [System.Xml.XmlConvert]::ToBoolean( $_.Usage_Data.Type_Data.Primary ) 87 | $o.Public = [System.Xml.XmlConvert]::ToBoolean( $_.Usage_Data.Public ) 88 | Write-Output $o 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /source/public/Get-WorkdayWorkerNationalId.ps1: -------------------------------------------------------------------------------- 1 | function Get-WorkdayWorkerNationalId { 2 | <# 3 | .SYNOPSIS 4 | Returns a Worker's National Id information. 5 | 6 | .DESCRIPTION 7 | Returns a Worker's National Id information as custom Powershell objects. 8 | 9 | .PARAMETER WorkerId 10 | The Worker's Id at Workday. 11 | 12 | .PARAMETER WorkerType 13 | The type of ID that the WorkerId represents. Valid values 14 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 15 | 16 | .PARAMETER Human_ResourcesUri 17 | Human_Resources Endpoint Uri for the request. If not provided, the value 18 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 19 | 20 | .PARAMETER Username 21 | Username used to authenticate with Workday. If empty, the value stored 22 | using Set-WorkdayCredential will be used. 23 | 24 | .PARAMETER Password 25 | Password used to authenticate with Workday. If empty, the value stored 26 | using Set-WorkdayCredential will be used. 27 | 28 | .EXAMPLE 29 | 30 | Get-WorkdayWorkerNationalId -WorkerId 123 31 | 32 | Type Id Descriptor 33 | ---- -- ---------- 34 | USA-SSN 000000000 000-00-0000 (USA-SSN) 35 | 36 | #> 37 | 38 | [CmdletBinding(DefaultParametersetName='Search')] 39 | [OutputType([PSCustomObject])] 40 | param ( 41 | [Parameter(Mandatory = $true, 42 | Position=0, 43 | ParameterSetName='Search')] 44 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 45 | [string]$WorkerId, 46 | [Parameter(ParameterSetName="Search")] 47 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 48 | [string]$WorkerType = 'Employee_ID', 49 | [Parameter(ParameterSetName="Search")] 50 | [string]$Human_ResourcesUri, 51 | [Parameter(ParameterSetName="Search")] 52 | [string]$Username, 53 | [Parameter(ParameterSetName="Search")] 54 | [string]$Password, 55 | [Parameter(ParameterSetName="NoSearch")] 56 | [xml]$WorkerXml, 57 | [Alias("Force")] 58 | [switch]$IncludeInactive 59 | ) 60 | 61 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 62 | 63 | if ($PsCmdlet.ParameterSetName -eq 'Search') { 64 | $response = Get-WorkdayWorker -WorkerId $WorkerId -WorkerType $WorkerType -IncludePersonal -Human_ResourcesUri $Human_ResourcesUri -Username:$Username -Password:$Password -IncludeInactive:$IncludeInactive -ErrorAction Stop 65 | $WorkerXml = $response.Xml 66 | } 67 | 68 | if ($null -eq $WorkerXml) { 69 | Write-Warning 'Unable to get National Id information, Worker not found.' 70 | return 71 | } 72 | 73 | $numberTemplate = [pscustomobject][ordered]@{ 74 | Type = $null 75 | Id = $null 76 | Descriptor = $null 77 | WID = $null 78 | } 79 | 80 | $WorkerXml.GetElementsByTagName('wd:National_ID') | ForEach-Object { 81 | $o = $numberTemplate.PsObject.Copy() 82 | $typeXml = $_.National_ID_Data.ID_Type_Reference.ID | Where-Object {$_.type -eq 'National_ID_Type_Code'} 83 | $o.Type = $typeXml.'#text' 84 | $o.Id = $_.National_ID_Data.ID 85 | $o.Descriptor = $_.National_ID_Reference.Descriptor 86 | $o.WID = $_.National_ID_Reference.ID | Where-Object {$_.type -eq 'WID'} | Select-Object -ExpandProperty '#text' 87 | Write-Output $o 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /source/public/Get-WorkdayWorkerOtherId.ps1: -------------------------------------------------------------------------------- 1 | function Get-WorkdayWorkerOtherId { 2 | <# 3 | .SYNOPSIS 4 | Returns a Worker's Id information. 5 | 6 | .DESCRIPTION 7 | Returns a Worker's Id information as custom Powershell objects. 8 | 9 | .PARAMETER WorkerId 10 | The Worker's Id at Workday. 11 | 12 | .PARAMETER WorkerType 13 | The type of ID that the WorkerId represents. Valid values 14 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 15 | 16 | .PARAMETER Human_ResourcesUri 17 | Human_Resources Endpoint Uri for the request. If not provided, the value 18 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 19 | 20 | .PARAMETER Username 21 | Username used to authenticate with Workday. If empty, the value stored 22 | using Set-WorkdayCredential will be used. 23 | 24 | .PARAMETER Password 25 | Password used to authenticate with Workday. If empty, the value stored 26 | using Set-WorkdayCredential will be used. 27 | 28 | .EXAMPLE 29 | 30 | Get-WorkdayWorkerOtherId -WorkerId 123 31 | 32 | Type Id Descriptor 33 | ---- -- ---------- 34 | Badge_ID 1 Badge ID 35 | 36 | #> 37 | 38 | [CmdletBinding(DefaultParametersetName='Search')] 39 | [OutputType([PSCustomObject])] 40 | param ( 41 | [Parameter(Mandatory = $true, 42 | Position=0, 43 | ParameterSetName='Search')] 44 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 45 | [string]$WorkerId, 46 | [Parameter(ParameterSetName="Search")] 47 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 48 | [string]$WorkerType = 'Employee_ID', 49 | [Parameter(ParameterSetName="Search")] 50 | [string]$Human_ResourcesUri, 51 | [Parameter(ParameterSetName="Search")] 52 | [string]$Username, 53 | [Parameter(ParameterSetName="Search")] 54 | [string]$Password, 55 | [Parameter(ParameterSetName="NoSearch")] 56 | [xml]$WorkerXml, 57 | [Alias("Force")] 58 | [switch]$IncludeInactive 59 | ) 60 | 61 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 62 | 63 | if ($PsCmdlet.ParameterSetName -eq 'Search') { 64 | $response = Get-WorkdayWorker -WorkerId $WorkerId -WorkerType $WorkerType -IncludePersonal -Human_ResourcesUri $Human_ResourcesUri -Username:$Username -Password:$Password -IncludeInactive:$IncludeInactive -ErrorAction Stop 65 | $WorkerXml = $response.Xml 66 | } 67 | 68 | if ($null -eq $WorkerXml) { 69 | Write-Warning 'Unable to get Other Id information, Worker not found.' 70 | return 71 | } 72 | 73 | $numberTemplate = [pscustomobject][ordered]@{ 74 | Type = $null 75 | Id = $null 76 | Descriptor = $null 77 | Issued_Date = $null 78 | Expiration_Date = $null 79 | WID = $null 80 | } 81 | 82 | $WorkerXml.GetElementsByTagName('wd:Custom_ID') | ForEach-Object { 83 | $o = $numberTemplate.PsObject.Copy() 84 | $typeXml = $_.Custom_ID_Data.ID_Type_Reference.ID | Where-Object {$_.type -eq 'Custom_ID_Type_ID'} 85 | $o.Type = '{0}' -f $typeXml.'#text' 86 | $o.Id = $_.Custom_ID_Data.ID 87 | $o.Descriptor = $_.Custom_ID_Data.ID_Type_Reference.Descriptor 88 | $o.Issued_Date = if ($_.Custom_ID_Data.Issued_Date -match '\d\d\d\d-\d\d-\d\d') { Get-Date $_.Custom_ID_Data.Issued_Date } 89 | $o.Expiration_Date = if ($_.Custom_ID_Data.Expiration_Date -match '\d\d\d\d-\d\d-\d\d') { Get-Date $_.Custom_ID_Data.Expiration_Date } 90 | $o.WID = $_.Custom_ID_Shared_Reference.ID | Where-Object {$_.type -eq 'WID'} | Select-Object -ExpandProperty '#text' 91 | Write-Output $o 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /source/public/Get-WorkdayWorkerPhone.ps1: -------------------------------------------------------------------------------- 1 | function Get-WorkdayWorkerPhone { 2 | <# 3 | .SYNOPSIS 4 | Returns a Worker's phone numbers. 5 | 6 | .DESCRIPTION 7 | Returns a Worker's phone numbers as custom Powershell objects. 8 | 9 | .PARAMETER WorkerId 10 | The Worker's Id at Workday. 11 | 12 | .PARAMETER WorkerType 13 | The type of ID that the WorkerId represents. Valid values 14 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 15 | 16 | .PARAMETER Human_ResourcesUri 17 | Human_Resources Endpoint Uri for the request. If not provided, the value 18 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 19 | 20 | .PARAMETER Username 21 | Username used to authenticate with Workday. If empty, the value stored 22 | using Set-WorkdayCredential will be used. 23 | 24 | .PARAMETER Password 25 | Password used to authenticate with Workday. If empty, the value stored 26 | using Set-WorkdayCredential will be used. 27 | 28 | .EXAMPLE 29 | 30 | Get-WorkdayWorkerPhone -WorkerId 123 31 | 32 | Type Number Primary Public 33 | ---- ------ ------- ------ 34 | Home/Cell +1 5551234567 True True 35 | Work/Landline +1 (555) 765-4321 True True 36 | 37 | #> 38 | 39 | [CmdletBinding(DefaultParametersetName='Search')] 40 | [OutputType([PSCustomObject])] 41 | param ( 42 | [Parameter(Mandatory = $true, 43 | Position=0, 44 | ParameterSetName='Search')] 45 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 46 | [string]$WorkerId, 47 | [Parameter(ParameterSetName="Search")] 48 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 49 | [string]$WorkerType = 'Employee_ID', 50 | [Parameter(ParameterSetName='Search')] 51 | [string]$Human_ResourcesUri, 52 | [Parameter(ParameterSetName='Search')] 53 | [string]$Username, 54 | [Parameter(ParameterSetName='Search')] 55 | [string]$Password, 56 | [Parameter(ParameterSetName='NoSearch')] 57 | [xml]$WorkerXml, 58 | [Alias("Force")] 59 | [switch]$IncludeInactive 60 | ) 61 | 62 | if ($PsCmdlet.ParameterSetName -eq 'Search') { 63 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 64 | $response = Get-WorkdayWorker -WorkerId $WorkerId -WorkerType $WorkerType -IncludePersonal -Human_ResourcesUri $Human_ResourcesUri -Username:$Username -Password:$Password -IncludeInactive:$IncludeInactive -ErrorAction Stop 65 | $WorkerXml = $response.Xml 66 | } 67 | 68 | if ($null -eq $WorkerXml) { 69 | Write-Warning 'Worker not found.' 70 | return 71 | } 72 | 73 | $numberTemplate = [pscustomobject][ordered]@{ 74 | UsageType = $null 75 | DeviceType = $null 76 | Number = $null 77 | Extension = $null 78 | Primary = $null 79 | Public = $null 80 | } 81 | 82 | $WorkerXml.GetElementsByTagName('wd:Phone_Data') | ForEach-Object { 83 | $o = $numberTemplate.PsObject.Copy() 84 | $o.UsageType = $_.SelectSingleNode('wd:Usage_Data/wd:Type_Data/wd:Type_Reference/wd:ID[@wd:type="Communication_Usage_Type_ID"]', $NM).InnerText 85 | $o.DeviceType = $_.SelectSingleNode('wd:Phone_Device_Type_Reference/wd:ID[@wd:type="Phone_Device_Type_ID"]', $NM).InnerText 86 | $international = if ($_ | Get-Member 'International_Phone_Code') { $_.International_Phone_Code } 87 | $areaCode = if ($_ | Get-Member 'Area_Code') { $_.Area_Code } 88 | $phoneNumber = if ($_ | Get-Member 'Phone_Number') { $_.Phone_Number } 89 | 90 | $o.Number = '{0} ({1}) {2}' -f $international, $areaCode, $phoneNumber 91 | $o.Extension = if ($_ | Get-Member 'Phone_Extension') { $_.Phone_Extension } 92 | $o.Primary = [System.Xml.XmlConvert]::ToBoolean( $_.Usage_Data.Type_Data.Primary ) 93 | $o.Public = [System.Xml.XmlConvert]::ToBoolean( $_.Usage_Data.Public ) 94 | Write-Output $o 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /source/public/Get-WorkdayWorkerPhoto.ps1: -------------------------------------------------------------------------------- 1 | function Get-WorkdayWorkerPhoto { 2 | <# 3 | .SYNOPSIS 4 | Gets Worker photo encoded as Base64 as Workday XML. 5 | 6 | .DESCRIPTION 7 | Gets Worker photo information as Workday XML with photo bytes encoded as Base64. 8 | 9 | .PARAMETER WorkerId 10 | The Worker's Id at Workday. 11 | 12 | .PARAMETER WorkerType 13 | The type of ID that the WorkerId represents. Valid values 14 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 15 | 16 | .PARAMETER Path 17 | Path to save the photo. If Path is to a directory, the file name from Workday will be appened. 18 | If no Path is specified, a PsCustomObject is returned containing the file name and byte array. 19 | 20 | .PARAMETER Passthru 21 | Outputs Invoke-WorkdayRequest object, rather than a custom Worker object. 22 | If desired, the Base 64 encoded image and file name can be aquired from the XML. 23 | 24 | .PARAMETER Human_ResourcesUri 25 | Human_Resources Endpoint Uri for the request. If not provided, the value 26 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 27 | 28 | .PARAMETER Username 29 | Username used to authenticate with Workday. If empty, the value stored 30 | using Set-WorkdayCredential will be used. 31 | 32 | .PARAMETER Password 33 | Password used to authenticate with Workday. If empty, the value stored 34 | using Set-WorkdayCredential will be used. 35 | 36 | .EXAMPLE 37 | 38 | # Get the Binary Array of a 39 | $BinaryArray = Get-WorkdayWorkerPhoto -WorkerId 123 40 | 41 | .EXAMPLE 42 | # 43 | 44 | 45 | #> 46 | 47 | 48 | [CmdletBinding()] 49 | [OutputType([PSCustomObject])] 50 | param ( 51 | [Parameter(Mandatory=$true, 52 | Position=0, 53 | ValueFromPipelineByPropertyName=$true, 54 | ParameterSetName='IndividualWorker')] 55 | [ValidatePattern ('^$|^[a-zA-Z0-9\-]{1,32}$')] 56 | [string]$WorkerId, 57 | [Parameter(Position=1, 58 | ValueFromPipelineByPropertyName=$true, 59 | ParameterSetName='IndividualWorker')] 60 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 61 | [string]$WorkerType = 'Employee_ID', 62 | [string]$Path, 63 | [switch]$Passthru, 64 | [string]$Human_ResourcesUri, 65 | [string]$Username, 66 | [string]$Password, 67 | [DateTime]$AsOfEntryDateTime = (Get-Date) 68 | ) 69 | 70 | begin { 71 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = Get-WorkdayEndpoint 'Human_Resources' } 72 | } 73 | 74 | process { 75 | $request = [xml]@' 76 | 77 | 78 | 79 | ?EmployeeId? 80 | 81 | 82 | 83 | ?DateTime? 84 | 85 | 86 | '@ 87 | 88 | $request.Get_Worker_Photos_Request.Response_Filter.As_Of_Entry_DateTime = $AsOfEntryDateTime.ToString('o') 89 | 90 | $request.Get_Worker_Photos_Request.Request_References.Worker_Reference.ID.InnerText = $WorkerId 91 | if ($WorkerType -eq 'Contingent_Worker_ID') { 92 | $request.Get_Worker_Photos_Request.Request_References.Worker_Reference.ID.type = 'Contingent_Worker_ID' 93 | } elseif ($WorkerType -eq 'WID') { 94 | $request.Get_Worker_Photos_Request.Request_References.Worker_Reference.ID.type = 'WID' 95 | } 96 | $response = Invoke-WorkdayRequest -Request $request -Uri $Human_ResourcesUri -Username:$Username -Password:$Password 97 | 98 | if ($Passthru) { 99 | Write-Output $response 100 | } 101 | elseif ($response.Success) { 102 | $filename = $response.Xml.Get_Worker_Photos_Response.Response_Data.Worker_Photo.Worker_Photo_Data.Filename 103 | $base64 = $response.Xml.Get_Worker_Photos_Response.Response_Data.Worker_Photo.Worker_Photo_Data.File 104 | $bytes = [System.Convert]::FromBase64String($base64) 105 | 106 | if ([string]::IsNullOrEmpty($Path)) { 107 | $output = [PsCustomObject][Ordered]@{ 108 | Filename = $filename 109 | Bytes = $bytes 110 | } 111 | Write-Output $output 112 | } 113 | else { 114 | if (Test-Path -Path $Path -PathType Container) { 115 | $Path = Join-Path $Path $filename 116 | } 117 | $bytes | Set-Content -Path $Path -Encoding Byte 118 | } 119 | } 120 | else { 121 | throw "Error calling Get_Worker_Photos_Request: $($response.Message)" 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /source/public/Invoke-WorkdayRequest.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-WorkdayRequest { 2 | <# 3 | .SYNOPSIS 4 | Sends XML requests to Workday API, with proper authentication and receives XML response. 5 | 6 | .DESCRIPTION 7 | Sends XML requests to Workday API, with proper authentication and receives XML response. 8 | 9 | Used for all communication to Workday in this module and may be used to send 10 | custom XML requests. 11 | 12 | .PARAMETER Request 13 | The Workday request XML to be sent to Workday. 14 | See https://community.workday.com/custom/developer/API/index.html for more information. 15 | 16 | .PARAMETER Uri 17 | Endpoint Uri for the request. 18 | 19 | .PARAMETER Username 20 | Username used to authenticate with Workday. If empty, the value stored 21 | using Set-WorkdayCredential will be used. 22 | 23 | .PARAMETER Password 24 | Password used to authenticate with Workday. If empty, the value stored 25 | using Set-WorkdayCredential will be used. 26 | 27 | .EXAMPLE 28 | 29 | $response = Invoke-WorkdayRequest -Request '' -Uri https://SERVICE.workday.com/ccx/service/TENANT/Human_Resources/v25.1 30 | 31 | $response.Server_Timestamp 32 | 33 | wd version Server_Timestamp_Data 34 | -- ------- --------------------- 35 | urn:com.workday/bsvc v25.1 2015-12-02T12:18:30.841-08:00 36 | 37 | .INPUTS 38 | Workday XML 39 | 40 | .OUTPUTS 41 | Workday XML 42 | 43 | .NOTES 44 | TODO: Wrap the password and possibly other values in CDATA tags, if the XML setter is not already handling special characters. 45 | 46 | TODO: Better error handling. Right not, when Workday returns an error in the XML, it also sets the HTTP status as 500. 47 | The following exception was thrown, when an invalid username was sent to Workday: 48 | You cannot call a method on a null-valued expression. 49 | At C:\Program Files\WindowsPowerShell\Modules\WorkdayApi\scripts\Invoke-WorkdayRequest.ps1:104 char:3 50 | + $reader = New-Object System.IO.StreamReader -ArgumentList $_. ... 51 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 52 | + CategoryInfo : InvalidOperation: (:) [], RuntimeException 53 | + FullyQualifiedErrorId : InvokeMethodOnNull 54 | 55 | #> 56 | 57 | [CmdletBinding()] 58 | [OutputType([XML])] 59 | param ( 60 | [Parameter(Mandatory = $true)] 61 | [ValidateNotNullOrEmpty()] 62 | [xml]$Request, 63 | [Parameter(Mandatory = $true)] 64 | [ValidateNotNullOrEmpty()] 65 | [string]$Uri, 66 | [string]$Username, 67 | [string]$Password 68 | ) 69 | 70 | if ($WorkdayConfiguration.Credential -is [PSCredential]) { 71 | if ([string]::IsNullOrWhiteSpace($Username)) { $Username = $WorkdayConfiguration.Credential.Username } 72 | if ([string]::IsNullOrWhiteSpace($Password)) { $Password = $WorkdayConfiguration.Credential.GetNetworkCredential().Password } 73 | } 74 | 75 | $WorkdaySoapEnvelope = [xml] @' 76 | 77 | 78 | 79 | 80 | IntegrationUser@Tenant 81 | Password 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | '@ 90 | 91 | $WorkdaySoapEnvelope.Envelope.Header.Security.UsernameToken.Username = $Username 92 | $WorkdaySoapEnvelope.Envelope.Header.Security.UsernameToken.Password.InnerText = $Password 93 | $WorkdaySoapEnvelope.Envelope.Body.InnerXml = $Request.OuterXml 94 | 95 | Write-Debug "Request: $($WorkdaySoapEnvelope.OuterXml)" 96 | $headers= @{ 97 | 'Content-Type' = 'text/xml;charset=UTF-8' 98 | } 99 | 100 | 101 | $o = [pscustomobject]@{ 102 | Success = $false 103 | Message = 'Unknown Error' 104 | Xml = $null 105 | } 106 | $o.psobject.TypeNames.Insert(0, "WorkdayResponse") 107 | 108 | $response = $null 109 | try { 110 | $response = Invoke-RestMethod -Method Post -Uri $Uri -Headers $headers -Body $WorkdaySoapEnvelope -ErrorAction Stop 111 | $o.Xml = [xml]$response.Envelope.Body.InnerXml 112 | $o.Message = '' 113 | $o.Success = $true 114 | } 115 | catch [System.Net.WebException] { 116 | Write-Debug $_ 117 | $o.Success = $false 118 | $o.Message = $_.ToString() 119 | 120 | try { 121 | $respStream = $_.Exception.Response.GetResponseStream() 122 | $respStream.position = 0 123 | $reader = New-Object System.IO.StreamReader($respStream) 124 | $response = $reader.ReadToEnd() 125 | $reader.Close() 126 | $o.Message = $response 127 | $xml = [xml]$response 128 | $o.Xml = [xml]$xml.Envelope.Body.InnerXml 129 | 130 | # Put the first Workday Exception into the Message property. 131 | if ($o.Xml.InnerXml.StartsWith(' 13 | 14 | [CmdletBinding()] 15 | param () 16 | 17 | if (Test-Path -Path $ConfigurationFile) { 18 | Remove-Item -Path $ConfigurationFile 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /source/public/Remove-WorkdayWorkerOtherId.ps1: -------------------------------------------------------------------------------- 1 | function Remove-WorkdayWorkerOtherId { 2 | <# 3 | .SYNOPSIS 4 | Sets the Custom_ID_Type_ID "Badge_ID". 5 | #> 6 | 7 | [CmdletBinding()] 8 | param ( 9 | [Parameter(Mandatory = $true, 10 | Position=0)] 11 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 12 | [string]$WorkerId, 13 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 14 | [string]$WorkerType = 'Employee_ID', 15 | [Parameter(Mandatory = $true)] 16 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 17 | [string]$WID, 18 | [string]$Human_ResourcesUri, 19 | [string]$Username, 20 | [string]$Password 21 | ) 22 | 23 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 24 | 25 | $request = [xml]@' 26 | 27 | 28 | true 29 | true 30 | 31 | Other ID set by Set-WorkdayWorkerOtherId 32 | 33 | 34 | 35 | 36 | 37 | Employee_ID 38 | 39 | 40 | 41 | 42 | wid 43 | 44 | 45 | 46 | 47 | 48 | 49 | '@ 50 | 51 | 52 | $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Worker_Reference.ID.InnerText = $WorkerId 53 | if ($WorkerType -eq 'Contingent_Worker_ID') { 54 | $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Worker_Reference.ID.type = 'Contingent_Worker_ID' 55 | } elseif ($WorkerType -eq 'WID') { 56 | $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Worker_Reference.ID.type = 'WID' 57 | } 58 | 59 | $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Custom_Identification_Data.Custom_ID.Custom_ID_Shared_Reference.ID.InnerText = $WID 60 | 61 | Invoke-WorkdayRequest -Request $request -Uri $Human_ResourcesUri -Username:$Username -Password:$Password | Write-Output 62 | } -------------------------------------------------------------------------------- /source/public/Save-WorkdayConfiguration.ps1: -------------------------------------------------------------------------------- 1 | function Save-WorkdayConfiguration { 2 | <# 3 | .SYNOPSIS 4 | Saves default Workday configuration to a file in the current users Profile. 5 | 6 | .DESCRIPTION 7 | Saves default Workday configuration to a file within the current 8 | users Profile. If it exists, this file is then read, each time the 9 | Workday Module is imported. Allowing settings to persist between 10 | sessions. 11 | 12 | .EXAMPLE 13 | Save-WorkdayConfiguration 14 | 15 | #> 16 | 17 | [CmdletBinding()] 18 | param () 19 | 20 | Export-Clixml -Path $ConfigurationFile -InputObject $WorkdayConfiguration 21 | } 22 | -------------------------------------------------------------------------------- /source/public/Set-WorkdayCredential.ps1: -------------------------------------------------------------------------------- 1 | function Set-WorkdayCredential { 2 | <# 3 | .SYNOPSIS 4 | Sets the default Workday API credentials. 5 | 6 | .DESCRIPTION 7 | Sets the default Workday API credentials. Configuration values can 8 | be securely saved to a user's profile using Save-WorkdayConfiguration. 9 | 10 | .PARAMETER Credential 11 | A standard Powershell Credential object. Optional. 12 | 13 | .EXAMPLE 14 | Set-WorkdayCredential 15 | 16 | This will prompt the user for credentials and save them in memory. 17 | 18 | .EXAMPLE 19 | $cred = Get-Credential -Message 'Custom message...' -UserName 'Custom Username' 20 | Set-WorkdayCredential -Credential $cred 21 | 22 | This demonstrates prompting the user with a custom message and default username. 23 | 24 | #> 25 | 26 | [CmdletBinding()] 27 | param ( 28 | [PSCredential]$Credential = $(Get-Credential -Message 'Enter Workday API credentials.') 29 | ) 30 | 31 | $WorkdayConfiguration.Credential = $Credential 32 | } 33 | 34 | -------------------------------------------------------------------------------- /source/public/Set-WorkdayEndpoint.ps1: -------------------------------------------------------------------------------- 1 | function Set-WorkdayEndpoint { 2 | <# 3 | .SYNOPSIS 4 | Sets the default Uri value for a particular Endpoint. 5 | 6 | .DESCRIPTION 7 | Sets the default Uri value for a particular Endpoint. These values 8 | can be saved to a user's profile using Save-WorkdayConfiguration. 9 | 10 | .PARAMETER Endpoint 11 | The curent Endpoints used by this module are: 12 | 'Human_Resources', 'Staffing' 13 | 14 | .PARAMETER Uri 15 | Uri for this Endpoint. 16 | 17 | .EXAMPLE 18 | 19 | Set-WorkdayEndpoint -Endpoint Staffing -Uri 'https://SERVICE.workday.com/ccx/service/TENANT/Staffing/v26.0' 20 | 21 | Demonstrates how to set a single Endpoint value. 22 | 23 | .EXAMPLE 24 | 25 | ConvertFrom-Csv @' 26 | Endpoint,Uri 27 | Staffing,https://SERVICE.workday.com/ccx/service/TENANT/Staffing/v26.0 28 | Human_Resources,https://SERVICE.workday.com/ccx/service/TENANT/Human_Resources/v26.0 29 | Integrations,https://SERVICE.workday.com/ccx/service/TENANT/Integrations/v26.0 30 | '@ | Set-WorkdayEndpoint 31 | 32 | Demonstrates how it would be possible to import a CSV file to set these values. 33 | This will be more important when there are more Endpoints supported. 34 | 35 | #> 36 | 37 | [CmdletBinding()] 38 | param ( 39 | [parameter(Mandatory=$true, 40 | ValueFromPipelineByPropertyName=$true)] 41 | [ValidateSet('Human_Resources', 'Integrations', 'Staffing')] 42 | [string]$Endpoint, 43 | [parameter(Mandatory=$true, 44 | ValueFromPipelineByPropertyName=$true)] 45 | [string]$Uri 46 | ) 47 | 48 | process { 49 | $WorkdayConfiguration.Endpoints[$Endpoint] = $Uri 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /source/public/Set-WorkdayWorkerDocument.ps1: -------------------------------------------------------------------------------- 1 | function Set-WorkdayWorkerDocument { 2 | <# 3 | .SYNOPSIS 4 | Uploads a document to a Worker's records in Workday. 5 | 6 | .DESCRIPTION 7 | Uploads a document to a Worker's records in Workday. 8 | 9 | .PARAMETER WorkerId 10 | The Worker's Id at Workday. 11 | 12 | .PARAMETER WorkerType 13 | The type of ID that the WorkerId represents. Valid values 14 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 15 | 16 | .PARAMETER Path 17 | The Path to the document file to upload. 18 | 19 | .PARAMETER StaffingUri 20 | Staffing Endpoint Uri for the request. If not provided, the value 21 | stored with Set-WorkdayEndpoint -Endpoint Staffing is used. 22 | 23 | .PARAMETER Username 24 | Username used to authenticate with Workday. If empty, the value stored 25 | using Set-WorkdayCredential will be used. 26 | 27 | .PARAMETER Password 28 | Password used to authenticate with Workday. If empty, the value stored 29 | using Set-WorkdayCredential will be used. 30 | 31 | .EXAMPLE 32 | 33 | Set-WorkdayWorkerDocument -WorkerId 123 -Path Document.pdf 34 | 35 | #> 36 | 37 | [CmdletBinding()] 38 | param ( 39 | [Parameter(Mandatory = $true, 40 | Position=0)] 41 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 42 | [string]$WorkerId, 43 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 44 | [string]$WorkerType = 'Employee_ID', 45 | [Parameter(Mandatory = $true)] 46 | [ValidateScript({Test-Path $_ -PathType Leaf})] 47 | [string]$Path, 48 | [string]$FileName, 49 | [Parameter(Mandatory = $true)] 50 | [ValidateSet('WID', 'Document_Category__Workday_Owned__ID', 'Document_Category_ID')] 51 | [string]$CategoryType, 52 | [Parameter(Mandatory = $true)] 53 | [string]$CategoryId, 54 | [string]$Comment, 55 | [string]$StaffingUri, 56 | [string]$Username, 57 | [string]$Password 58 | ) 59 | 60 | Add-Type -AssemblyName "System.Web" 61 | 62 | if ([string]::IsNullOrWhiteSpace($StaffingUri)) { $StaffingUri = $WorkdayConfiguration.Endpoints['Staffing'] } 63 | 64 | $request = [xml]@' 65 | 66 | 67 | Filename 68 | 69 | 70 | Z2Vybw== 71 | 72 | CategoryId 73 | 74 | 75 | Employee_ID 76 | 77 | ContentType 78 | 79 | 80 | '@ 81 | 82 | $request.Put_Worker_Document_Request.Worker_Document_Data.Worker_Reference.ID.InnerText = $WorkerId 83 | if ($WorkerType -eq 'Contingent_Worker_ID') { 84 | $request.Put_Worker_Document_Request.Worker_Document_Data.Worker_Reference.ID.type = 'Contingent_Worker_ID' 85 | } elseif ($WorkerType -eq 'WID') { 86 | $request.Put_Worker_Document_Request.Worker_Document_Data.Worker_Reference.ID.type = 'WID' 87 | } 88 | 89 | if ([string]::IsNullOrWhiteSpace($FileName)) { 90 | $FileName = [string] (Split-Path -Path $Path -Leaf) 91 | } 92 | $request.Put_Worker_Document_Request.Worker_Document_Data.Filename = $FileName 93 | $request.Put_Worker_Document_Request.Worker_Document_Data.File = [System.Convert]::ToBase64String( [system.io.file]::ReadAllBytes( $Path ) ) 94 | $request.Put_Worker_Document_Request.Worker_Document_Data.Document_Category_Reference.ID.type = $CategoryType 95 | $request.Put_Worker_Document_Request.Worker_Document_Data.Document_Category_Reference.ID.InnerText = $CategoryId 96 | $request.Put_Worker_Document_Request.Worker_Document_Data.Comment = $Comment 97 | $request.Put_Worker_Document_Request.Worker_Document_Data.Content_Type = [System.Web.MimeMapping]::GetMimeMapping( $fileName ) 98 | 99 | Invoke-WorkdayRequest -Request $request -Uri $StaffingUri -Username:$Username -Password:$Password | Write-Output 100 | 101 | } -------------------------------------------------------------------------------- /source/public/Set-WorkdayWorkerEmail.ps1: -------------------------------------------------------------------------------- 1 | function Set-WorkdayWorkerEmail { 2 | <# 3 | .SYNOPSIS 4 | Sets a Worker's email in Workday. 5 | 6 | .DESCRIPTION 7 | Sets a Worker's email in Workday. 8 | 9 | .PARAMETER WorkerId 10 | The Worker's Id at Workday. 11 | 12 | .PARAMETER WorkerType 13 | The type of ID that the WorkerId represents. Valid values 14 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 15 | 16 | .PARAMETER Email 17 | Email address. 18 | 19 | .PARAMETER UsageType 20 | Currently supports HOME and WORK. 21 | 22 | .PARAMETER Secondary 23 | By default, this will set one non-Primary email address of the same UsageType. To set more than one, use the -Append switch. At some point this command may need to allow specifying a specific email WID to update. 24 | 25 | .PARAMETER Append 26 | When used with the Secondary switch, this will add the specified Email as a non-Primary email of the same UsageType. 27 | 28 | .PARAMETER Private 29 | Marks the email as not Public in Workday. 30 | 31 | .PARAMETER Human_ResourcesUri 32 | Human_Resources Endpoint Uri for the request. If not provided, the value 33 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 34 | 35 | .PARAMETER Username 36 | Username used to authenticate with Workday. If empty, the value stored 37 | using Set-WorkdayCredential will be used. 38 | 39 | .PARAMETER Password 40 | Password used to authenticate with Workday. If empty, the value stored 41 | using Set-WorkdayCredential will be used. 42 | 43 | .EXAMPLE 44 | 45 | Set-WorkdayWorkerEmail -WorkerId 123 -WorkEmail worker@example.com 46 | 47 | .NOTES 48 | When setting a primary email, by default, Workday deletes ALL non-primary addresses of the same type. 49 | When using Do_Not_Replace_All="true", Workday will append non-primary addresses, rather than update a current address. 50 | For this behavior, use the -Append switch, with the -Secondary switch. 51 | Otherwise use the -Secondary switch. 52 | 53 | #> 54 | 55 | [CmdletBinding()] 56 | param ( 57 | [Parameter(Mandatory = $true, 58 | Position=0)] 59 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 60 | [string]$WorkerId, 61 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 62 | [string]$WorkerType = 'Employee_ID', 63 | [Parameter(Mandatory = $true)] 64 | [ValidatePattern('^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$')] 65 | [Alias('EmailAddress')] 66 | [string]$Email, 67 | [ValidateSet('HOME','WORK')] 68 | [string]$UsageType = 'WORK', 69 | [switch]$Private, 70 | [switch]$Secondary, 71 | [switch]$Append, 72 | [string]$Human_ResourcesUri, 73 | [string]$Username, 74 | [string]$Password 75 | ) 76 | 77 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 78 | 79 | $request = [xml]@' 80 | 81 | 82 | true 83 | true 84 | 85 | Email set by Set-WorkdayWorkerEmail 86 | 87 | 88 | 89 | 90 | Employee_ID 91 | 92 | Effective_Date 93 | 94 | 95 | Email_Address 96 | 97 | 98 | 99 | WORK 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | '@ 108 | 109 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Reference.ID.InnerText = $WorkerId 110 | if ($WorkerType -eq 'Contingent_Worker_ID') { 111 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Reference.ID.type = 'Contingent_Worker_ID' 112 | } elseif ($WorkerType -eq 'WID') { 113 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Reference.ID.type = 'WID' 114 | } 115 | 116 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Email_Address_Data.Email_Address = $Email 117 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Effective_Date = (Get-Date).ToString( 'yyyy-MM-dd' ) 118 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Email_Address_Data.Usage_Data.Type_Data.Type_Reference.ID.'#text' = $UsageType 119 | 120 | if ($Secondary) { 121 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Email_Address_Data.Usage_Data.Type_Data.Primary = 'false' 122 | if (-not $Append) { 123 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Email_Address_Data.Do_Not_Replace_All = 'false' 124 | } 125 | } 126 | 127 | if ($Private) { 128 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Email_Address_Data.Usage_Data.Public = 'false' 129 | } 130 | 131 | Invoke-WorkdayRequest -Request $request -Uri $Human_ResourcesUri -Username:$Username -Password:$Password | Write-Output 132 | 133 | } -------------------------------------------------------------------------------- /source/public/Set-WorkdayWorkerOtherId.ps1: -------------------------------------------------------------------------------- 1 | function Set-WorkdayWorkerOtherId { 2 | <# 3 | .SYNOPSIS 4 | Sets the Custom_ID_Type_ID "Badge_ID". 5 | #> 6 | 7 | [CmdletBinding()] 8 | param ( 9 | [Parameter(Mandatory = $true, 10 | Position=0)] 11 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 12 | [string]$WorkerId, 13 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 14 | [string]$WorkerType = 'Employee_ID', 15 | [Parameter(Mandatory = $true)] 16 | [ValidateNotNullOrEmpty()] 17 | [string]$Type, 18 | [Parameter(Mandatory = $true)] 19 | [ValidateNotNullOrEmpty()] 20 | [string]$Id, 21 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 22 | $WID, 23 | $IssuedDate, 24 | $ExpirationDate, 25 | [string]$Human_ResourcesUri, 26 | [string]$Username, 27 | [string]$Password 28 | ) 29 | 30 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 31 | 32 | $request = [xml]@' 33 | 34 | 35 | true 36 | true 37 | 38 | Other ID set by Set-WorkdayWorkerOtherId 39 | 40 | 41 | 42 | 43 | 44 | Employee_ID 45 | 46 | 47 | 48 | 49 | string 50 | 51 | Type 52 | 53 | 54 | 55 | 56 | 57 | wid 58 | 59 | 60 | 61 | 62 | 63 | 64 | '@ 65 | 66 | 67 | $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Worker_Reference.ID.InnerText = $WorkerId 68 | if ($WorkerType -eq 'Contingent_Worker_ID') { 69 | $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Worker_Reference.ID.type = 'Contingent_Worker_ID' 70 | } elseif ($WorkerType -eq 'WID') { 71 | $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Worker_Reference.ID.type = 'WID' 72 | } 73 | 74 | $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Custom_Identification_Data.Custom_ID.Custom_ID_Data.ID_Type_Reference.ID.InnerText = $Type 75 | $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Custom_Identification_Data.Custom_ID.Custom_ID_Data.ID = $Id 76 | 77 | # Deal with the potential for blank or invalid incoming or current date values. 78 | if (-not [string]::IsNullOrWhiteSpace($IssuedDate)) { 79 | try { 80 | $d = Get-Date $IssuedDate -ErrorAction Stop 81 | $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Custom_Identification_Data.Custom_ID.Custom_ID_Data.Issued_Date = $d.ToString('o') 82 | } 83 | catch { 84 | throw "Invalid IssuedDate [$IssuedDate]" 85 | } 86 | } 87 | if (-not [string]::IsNullOrWhiteSpace($ExpirationDate)) { 88 | try { 89 | $d = Get-Date $ExpirationDate -ErrorAction Stop 90 | $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Custom_Identification_Data.Custom_ID.Custom_ID_Data.Expiration_Date = $d.ToString('o') 91 | } 92 | catch { 93 | throw "Invalid ExpirationDate [$ExpirationDate]" 94 | } 95 | } 96 | 97 | if ($PSBoundParameters.ContainsKey('WID')) { 98 | $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Custom_Identification_Data.Custom_ID.Custom_ID_Shared_Reference.ID.InnerText = $WID 99 | } 100 | else { 101 | $null = $request.Change_Other_IDs_Request.Change_Other_IDs_Data.Custom_Identification_Data.Custom_ID.RemoveChild($request.Change_Other_IDs_Request.Change_Other_IDs_Data.Custom_Identification_Data.Custom_ID.Custom_ID_Shared_Reference) 102 | } 103 | 104 | Invoke-WorkdayRequest -Request $request -Uri $Human_ResourcesUri -Username:$Username -Password:$Password | Write-Output 105 | } -------------------------------------------------------------------------------- /source/public/Set-WorkdayWorkerPhone.ps1: -------------------------------------------------------------------------------- 1 | function Set-WorkdayWorkerPhone { 2 | <# 3 | .SYNOPSIS 4 | Sets a Worker's phone number in Workday. 5 | 6 | .DESCRIPTION 7 | Sets a Worker's phone number in Workday. 8 | 9 | .PARAMETER WorkerId 10 | The Worker's Id at Workday. 11 | 12 | .PARAMETER WorkerType 13 | The type of ID that the WorkerId represents. Valid values 14 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 15 | 16 | .PARAMETER Number 17 | Sets the Workday primary Work Landline for a Worker. This cmdlet does not 18 | currently support other phone types. Also excepts the alias OfficePhone. 19 | 20 | .PARAMETER Extension 21 | Sets the worker's extension, if included. 22 | 23 | .PARAMETER UsageType 24 | Known usage types: 'HOME' or 'WORK'. 25 | 26 | .PARAMETER DeviceType 27 | Known device types: 'Landline', 'Cell', Mobile, 'WORK' 28 | 29 | .PARAMETER Private 30 | Mark number as private. 31 | 32 | .PARAMETER Secondary 33 | Any non-primary number. There can be multiple non-primary numbers, but only one primary. 34 | 35 | .PARAMETER Human_ResourcesUri 36 | Human_Resources Endpoint Uri for the request. If not provided, the value 37 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 38 | 39 | .PARAMETER Username 40 | Username used to authenticate with Workday. If empty, the value stored 41 | using Set-WorkdayCredential will be used. 42 | 43 | .PARAMETER Password 44 | Password used to authenticate with Workday. If empty, the value stored 45 | using Set-WorkdayCredential will be used. 46 | 47 | .EXAMPLE 48 | 49 | Set-WorkdayWorkerPhone -WorkerId 123 -Number 1234567890 50 | 51 | #> 52 | 53 | [CmdletBinding()] 54 | param ( 55 | [Parameter(Mandatory = $true, 56 | Position=0)] 57 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 58 | [string]$WorkerId, 59 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 60 | [string]$WorkerType = 'Employee_ID', 61 | [Parameter(Mandatory = $true)] 62 | [ValidateNotNullOrEmpty()] 63 | [string]$Number, 64 | [string]$Extension, 65 | [string]$UsageType = 'WORK', 66 | [string]$DeviceType = 'Landline', 67 | [switch]$Private, 68 | [switch]$Secondary, 69 | [string]$Human_ResourcesUri, 70 | [string]$Username, 71 | [string]$Password 72 | ) 73 | 74 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 75 | 76 | 77 | $request = [xml]@' 78 | 79 | 80 | true 81 | true 82 | 83 | Phone number set by Set-WorkdayWorkerPhone 84 | 85 | 86 | 87 | 88 | Employee_ID? 89 | 90 | Effective_Date? 91 | 92 | 93 | 1 94 | ? 95 | ? 96 | ? 97 | 98 | Landline? 99 | 100 | 101 | 102 | 103 | WORK? 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | '@ 112 | 113 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Reference.ID.InnerText = $WorkerId 114 | if ($WorkerType -eq 'Contingent_Worker_ID') { 115 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Reference.ID.type = 'Contingent_Worker_ID' 116 | } elseif ($WorkerType -eq 'WID') { 117 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Reference.ID.type = 'WID' 118 | } 119 | 120 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Effective_Date = (Get-Date).ToString( 'yyyy-MM-dd' ) 121 | 122 | $scrubbedNumber = $Number -replace '[^\d]', '' 123 | if ($scrubbedNumber -notmatch '(?[\d]*?)(?\d{0,3}?)(?\d{0,3}?)(?\d{1,4})$') { 124 | throw "Invalid number: [$Number]" 125 | } 126 | 127 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Phone_Data.Phone_Device_Type_Reference.ID.'#text' = 128 | $DeviceType 129 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Phone_Data.Usage_Data.Type_Data.Type_Reference.ID.'#text' = 130 | $UsageType 131 | 132 | if ($Private) { 133 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Phone_Data.Usage_Data.Public = '0' 134 | } 135 | 136 | if ($Secondary) { 137 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Phone_Data.Usage_Data.Type_Data.Primary = '0' 138 | } 139 | 140 | $country = if ([string]::IsNullOrWhiteSpace($Matches['country'])) {'1'} else { $Matches['country'] } 141 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Phone_Data.International_Phone_Code = 142 | $country 143 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Phone_Data.Area_Code = 144 | $Matches['areacode'] 145 | 146 | $phoneNumber = '' 147 | if ($Matches['prefix'].length -gt 0) { 148 | $phoneNumber = $Matches['prefix'] + '-' 149 | } 150 | $phoneNumber += $Matches['line'] 151 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Phone_Data.Phone_Number = $phoneNumber 152 | 153 | $request.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data.Worker_Contact_Information_Data.Phone_Data.Phone_Extension = 154 | $Extension 155 | 156 | Write-Debug $request.OuterXml 157 | Invoke-WorkdayRequest -Request $request -Uri $Human_ResourcesUri -Username:$Username -Password:$Password | Write-Output 158 | } -------------------------------------------------------------------------------- /source/public/Set-WorkdayWorkerPhoto.ps1: -------------------------------------------------------------------------------- 1 | function Set-WorkdayWorkerPhoto { 2 | <# 3 | .SYNOPSIS 4 | Uploads an image file to Workday and set it as a Worker's photo. 5 | 6 | .DESCRIPTION 7 | Uploads an image file to Workday and set it as a Worker's photo. 8 | 9 | .PARAMETER WorkerId 10 | The Worker's Id at Workday. 11 | 12 | .PARAMETER WorkerType 13 | The type of ID that the WorkerId represents. Valid values 14 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 15 | 16 | .PARAMETER Path 17 | The Path to the image file to upload. 18 | 19 | .PARAMETER Human_ResourcesUri 20 | Human_Resources Endpoint Uri for the request. If not provided, the value 21 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 22 | 23 | .PARAMETER Username 24 | Username used to authenticate with Workday. If empty, the value stored 25 | using Set-WorkdayCredential will be used. 26 | 27 | .PARAMETER Password 28 | Password used to authenticate with Workday. If empty, the value stored 29 | using Set-WorkdayCredential will be used. 30 | 31 | .EXAMPLE 32 | 33 | Set-WorkdayWorkerPhoto -EmpoyeeId 123 -Path Photo.jpg 34 | 35 | #> 36 | 37 | [CmdletBinding()] 38 | param ( 39 | [Parameter(Mandatory = $true, 40 | Position=0)] 41 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 42 | [string]$WorkerId, 43 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 44 | [string]$WorkerType = 'Employee_ID', 45 | [Parameter(Mandatory = $true)] 46 | [ValidateScript({Test-Path $_ -PathType Leaf})] 47 | [ValidateNotNullOrEmpty()] 48 | [string]$Path, 49 | [string]$Human_ResourcesUri, 50 | [string]$Username, 51 | [string]$Password 52 | ) 53 | 54 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 55 | 56 | $request = [xml]@' 57 | 58 | 59 | employeeId 60 | 61 | 62 | filename 63 | base64 64 | 65 | 66 | '@ 67 | 68 | $request.Put_Worker_Photo_Request.Worker_Reference.ID.InnerText = $WorkerId 69 | if ($WorkerType -eq 'Contingent_Worker_ID') { 70 | $request.Put_Worker_Photo_Request.Worker_Reference.ID.type = 'Contingent_Worker_ID' 71 | } elseif ($WorkerType -eq 'WID') { 72 | $request.Put_Worker_Photo_Request.Worker_Reference.ID.type = 'WID' 73 | } 74 | 75 | $request.Put_Worker_Photo_Request.Worker_Photo_Data.File = [System.Convert]::ToBase64String( [system.io.file]::ReadAllBytes( $Path ) ) 76 | $request.Put_Worker_Photo_Request.Worker_Photo_Data.Filename = [string] (Split-Path -Path $Path -Leaf) 77 | 78 | Invoke-WorkdayRequest -Request $request -Uri $Human_ResourcesUri -Username:$Username -Password:$Password | Write-Output 79 | 80 | } -------------------------------------------------------------------------------- /source/public/Set-WorkdayWorkerUserId.ps1: -------------------------------------------------------------------------------- 1 | function Set-WorkdayWorkerUserId { 2 | <# 3 | .SYNOPSIS 4 | Sets a Worker's account user name in Workday. 5 | 6 | .DESCRIPTION 7 | Sets a Worker's user name in Workday. 8 | 9 | .PARAMETER WorkerId 10 | The Worker's Id at Workday. 11 | 12 | .PARAMETER UserId 13 | The Worker UserId to login into Workday. 14 | 15 | .PARAMETER WorkerType 16 | The type of ID that the WorkerId represents. Valid values 17 | are 'Contingent_Worker_ID' and 'Employee_ID'. 18 | 19 | .PARAMETER Human_ResourcesUri 20 | Human_Resources Endpoint Uri for the request. If not provided, the value 21 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 22 | 23 | .PARAMETER Username 24 | Username used to authenticate with Workday. If empty, the value stored 25 | using Set-WorkdayCredential will be used. 26 | 27 | .PARAMETER Password 28 | Password used to authenticate with Workday. If empty, the value stored 29 | using Set-WorkdayCredential will be used. 30 | 31 | .EXAMPLE 32 | 33 | Set-WorkdayWorkerUserId -WorkerId 123 -UserId worker@example.com 34 | 35 | .NOTES 36 | This changes the users login name for Workday 37 | 38 | #> 39 | 40 | [CmdletBinding()] 41 | param ( 42 | [Parameter(Mandatory = $true, 43 | Position=0)] 44 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 45 | [string]$WorkerId, 46 | [Parameter(Mandatory = $true)] 47 | [ValidateNotNullOrEmpty()] 48 | [Alias('')] 49 | [string]$UserId, 50 | [ValidateSet('Contingent_Worker_ID', 'Employee_ID')] 51 | [string]$WorkerType = 'Employee_ID', 52 | [string]$Human_ResourcesUri, 53 | [string]$Username, 54 | [string]$Password 55 | ) 56 | 57 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 58 | 59 | $request = [xml]@' 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | '@ 69 | $employeeref = [xml]@' 70 | 71 | 72 | 73 | 74 | 75 | '@ 76 | $contingentref = [xml]@' 77 | 78 | 79 | 80 | 81 | 82 | '@ 83 | 84 | if ($WorkerType -eq 'Contingent_Worker_ID') { 85 | $contingentref.Contingent_Worker_Reference.Integration_ID_Reference.ID.InnerText = $WorkerId 86 | $request.Workday_Account_for_Worker_Update.Worker_Reference.InnerXml = $contingentref.OuterXml 87 | } 88 | else { 89 | $employeeref.Employee_Reference.Integration_ID_Reference.ID.InnerText = $WorkerId 90 | $request.Workday_Account_for_Worker_Update.Worker_Reference.InnerXml = $employeeref.OuterXml 91 | } 92 | 93 | # Set Workday employee/congingent worker User ID 94 | $request.Workday_Account_for_Worker_Update.Workday_Account_for_Worker_Data.User_Name = $UserId 95 | 96 | Invoke-WorkdayRequest -Request $request -Uri $Human_ResourcesUri -Username:$Username -Password:$Password | Write-Output 97 | 98 | } 99 | -------------------------------------------------------------------------------- /source/public/Start-WorkdayIntegration.ps1: -------------------------------------------------------------------------------- 1 | function Start-WorkdayIntegration { 2 | <# 3 | .SYNOPSIS 4 | Starts a Workday Integration. 5 | 6 | .DESCRIPTION 7 | Starts a Workday Integration and returns the resulting Integration 8 | information as a custom Powershell object. If the -Wait switch is used, 9 | the script will wait for the Integration to complete and return the 10 | Event information. 11 | 12 | .PARAMETER Id 13 | The WID or Integration_System_ID of the Integration to be triggered. 14 | 15 | .PARAMETER Type 16 | The type of ID that -Id represents. Valid values 17 | are 'WID' or 'Integration_System_ID'. 18 | 19 | .PARAMETER Integrations_ResourcesUri 20 | Integration Endpoint Uri for the request. If not provided, the value 21 | stored with Set-WorkdayEndpoint -Endpoint Integration is tried. 22 | 23 | .PARAMETER Username 24 | Username used to authenticate with Workday. If empty, the value stored 25 | using Set-WorkdayCredential will be used. 26 | 27 | .PARAMETER Password 28 | Password used to authenticate with Workday. If empty, the value stored 29 | using Set-WorkdayCredential will be used. 30 | 31 | .PARAMETER Wait 32 | Causes the script to wait for the Integration to complete, then returns 33 | the resulting Event information. 34 | 35 | .PARAMETER UseDefaultCredentials 36 | Sets Invoke_Integration_As_Current_User to 'true'. 37 | 38 | .EXAMPLE 39 | Start-WorkdayIntegration -Id Integration/Id/StartHere -Type Integration_System_ID -Integrations_ResourcesUri 'https://SERVICE.workday.com/ccx/service/TENANT/Integrations/v26.0' 40 | 41 | Name : Integration ESB Invocation (INT123 Integration - 04/13/2016 08:39:02.099 (Processing)) 42 | Start : 4/13/2016 11:39:02 AM 43 | End : 44 | Message : 45 | Xml : #document 46 | 47 | #> 48 | 49 | [CmdletBinding(DefaultParametersetName='Search')] 50 | [OutputType([PSCustomObject])] 51 | param ( 52 | [Parameter(Mandatory = $true, 53 | Position=0)] 54 | [string]$Id, 55 | [ValidateSet('WID', 'Integration_System_ID')] 56 | [string]$Type = 'Integration_System_ID', 57 | [string]$Username, 58 | [string]$Password, 59 | [string]$Integrations_ResourcesUri, 60 | [switch]$Wait, 61 | [switch]$UseDefaultCredentials 62 | ) 63 | 64 | if ([string]::IsNullOrWhiteSpace($Integrations_ResourcesUri)) { $Integrations_ResourcesUri = $WorkdayConfiguration.Endpoints['Integrations'] } 65 | 66 | $request = [XML]@' 67 | 68 | 69 | id 70 | 71 | false 72 | 73 | '@ 74 | 75 | $request.Launch_Integration_Event_Request.Integration_System_Reference.ID.type = $Type 76 | $request.Launch_Integration_Event_Request.Integration_System_Reference.ID.InnerText = $Id 77 | if ($UseDefaultCredentials) { 78 | $request.Launch_Integration_Event_Request.Invoke_Integration_As_Current_User = 'true' 79 | } 80 | 81 | 82 | $response = Invoke-WorkdayRequest -Request $request -Uri $Integrations_ResourcesUri -Username:$Username -Password:$Password 83 | 84 | $output = [pscustomobject][ordered]@{ 85 | Name = $null 86 | Wid = $null 87 | Message = 'Error' 88 | Xml = $null 89 | } 90 | 91 | if ($null -eq $response) { 92 | return $output 93 | } 94 | 95 | if ($response.Success -eq $false) { 96 | $output.Message = $response.Message 97 | $output.Xml = $response.Xml 98 | return $output 99 | } 100 | 101 | $output.Name = $response.Xml.Launch_Integration_Event_Response.Integration_Event.Integration_Event_Reference.Descriptor 102 | $output.Wid = $response.Xml.Launch_Integration_Event_Response.Integration_Event.Integration_Event_Reference.ID | Where-Object {$_.type -eq 'WID'} | Select-Object -ExpandProperty InnerText 103 | $initTime = Get-Date $response.Xml.Launch_Integration_Event_Response.Integration_Event.Integration_Event_Data.Initiated_DateTime 104 | $output.Message = 'Started at {0:g}.' -f $initTime 105 | $output.Xml = $response.Xml 106 | if ($Wait) { 107 | $wie = Get-WorkdayIntegrationEvent -Wid $output.Wid -Integrations_ResourcesUri:$Integrations_ResourcesUri -Username:$Username -Password:$Password 108 | while ($null -eq $wie.End) { 109 | Start-Sleep -Seconds 5 110 | $wie = Get-WorkdayIntegrationEvent -Wid $output.Wid -Integrations_ResourcesUri:$Integrations_ResourcesUri -Username:$Username -Password:$Password 111 | } 112 | return $wie 113 | } 114 | return $output 115 | } 116 | -------------------------------------------------------------------------------- /source/public/Update-WorkdayWorkerEmail.ps1: -------------------------------------------------------------------------------- 1 | function Update-WorkdayWorkerEmail { 2 | <# 3 | .SYNOPSIS 4 | Updates a Worker's email in Workday, only if it is different. 5 | 6 | .DESCRIPTION 7 | Updates a Worker's email in Workday, only if it is different. 8 | Change requests are always recorded in Workday's audit log even when 9 | the email is the same. Unlike Set-WorkdayWorkerEmail, this cmdlet 10 | first checks the current email before requesting a change. 11 | 12 | .PARAMETER WorkerId 13 | The Worker's Id at Workday. 14 | 15 | .PARAMETER WorkerType 16 | The type of ID that the WorkerId represents. Valid values 17 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 18 | 19 | .PARAMETER Email 20 | Sets the Workday primary, public, Work email for a Worker. This cmdlet does not 21 | currently support other email types. Also excepts the alias EmailAddress. 22 | 23 | .PARAMETER Human_ResourcesUri 24 | Human_Resources Endpoint Uri for the request. If not provided, the value 25 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 26 | 27 | .PARAMETER Username 28 | Username used to authenticate with Workday. If empty, the value stored 29 | using Set-WorkdayCredential will be used. 30 | 31 | .PARAMETER Password 32 | Password used to authenticate with Workday. If empty, the value stored 33 | using Set-WorkdayCredential will be used. 34 | 35 | .EXAMPLE 36 | 37 | Update-WorkdayWorkerEmail -WorkerId 123 -Email test@example.com 38 | 39 | .NOTES 40 | The Set-WorkdayWorkerEmail switch -Append is not supported, as the -Secondary 41 | switch assumes there is only one non-primary email address. At some point 42 | it may be nessesary to implement a means to update a specific email WID. 43 | 44 | #> 45 | 46 | [CmdletBinding(DefaultParametersetName='Search')] 47 | param ( 48 | [Parameter(Mandatory = $true, 49 | ParameterSetName="Search", 50 | Position=0)] 51 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 52 | [string]$WorkerId, 53 | [Parameter(ParameterSetName="Search")] 54 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 55 | [string]$WorkerType = 'Employee_ID', 56 | [Parameter(ParameterSetName="Search")] 57 | [string]$Human_ResourcesUri, 58 | [Parameter(ParameterSetName="Search")] 59 | [string]$Username, 60 | [Parameter(ParameterSetName="Search")] 61 | [string]$Password, 62 | [Parameter(Mandatory = $true, 63 | ParameterSetName="NoSearch")] 64 | [xml]$WorkerXml, 65 | [Parameter(Mandatory = $true)] 66 | [Alias('EmailAddress')] 67 | [string]$Email, 68 | [ValidateSet('HOME','WORK')] 69 | [string]$UsageType = 'WORK', 70 | [switch]$Private, 71 | [switch]$Secondary, 72 | [Alias("Force")] 73 | [switch]$IncludeInactive 74 | ) 75 | 76 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 77 | 78 | if ($PsCmdlet.ParameterSetName -eq 'NoSearch') { 79 | $current = Get-WorkdayWorkerEmail -WorkerXml $WorkerXml 80 | $WorkerType = 'WID' 81 | $workerReference = $WorkerXml.GetElementsByTagName('wd:Worker_Reference') | Select-Object -First 1 82 | $WorkerId = $workerReference.ID | Where-Object {$_.type -eq 'WID'} | Select-Object -ExpandProperty InnerText 83 | } else { 84 | $current = Get-WorkdayWorkerEmail -WorkerId $WorkerId -WorkerType $WorkerType -Human_ResourcesUri:$Human_ResourcesUri -Username:$Username -Password:$Password -IncludeInactive:$IncludeInactive 85 | } 86 | 87 | $currentEmail = $current | 88 | Where-Object { 89 | $_.UsageType -eq $UsageType -and 90 | (-not $_.Primary) -eq $Secondary 91 | } | Select-Object -First 1 92 | 93 | $msg = "{0} Current [$($currentEmail.Email)] Proposed [$Email]" 94 | $output = [pscustomobject][ordered]@{ 95 | WorkerId = $WorkerId 96 | WorkerType = $WorkerType 97 | Email = $Email 98 | UsageType = $UsageType 99 | Primary = -not $Secondary 100 | Public = -not $Private 101 | Success = $false 102 | Message = $msg -f 'Failed' 103 | } 104 | if ( 105 | $null -ne $currentEmail -and 106 | $currentEmail.Email -eq $Email -and 107 | $currentEmail.UsageType -eq $UsageType -and 108 | (-not $currentEmail.Primary) -eq $Secondary -and 109 | (-not $currentEmail.Public) -eq $Private 110 | ) { 111 | $output.Message = $msg -f 'Matched' 112 | $output.Success = $true 113 | } else { 114 | $o = Set-WorkdayWorkerEmail -WorkerId $WorkerId -WorkerType $WorkerType -Email $Email -UsageType:$UsageType -Private:$Private -Secondary:$Secondary -Human_ResourcesUri:$Human_ResourcesUri -Username:$Username -Password:$Password 115 | if ($null -ne $o) { 116 | if ($o.Success) { 117 | $output.Success = $true 118 | $output.Message = $msg -f 'Changed' 119 | } 120 | else { 121 | $output.Success = $false 122 | $output.Message = $o.Message 123 | } 124 | } 125 | } 126 | 127 | Write-Verbose $output.Message 128 | Write-Output $output 129 | } 130 | -------------------------------------------------------------------------------- /source/public/Update-WorkdayWorkerOtherId.ps1: -------------------------------------------------------------------------------- 1 | function Update-WorkdayWorkerOtherId { 2 | <# 3 | .SYNOPSIS 4 | Updates a Worker's Other ID data in Workday, only if it is different. 5 | 6 | .DESCRIPTION 7 | Updates a Worker's Other ID data in Workday, only if it is different. 8 | Change requests are always recorded in Workday's audit log even when 9 | the values are the same. Unlike Set-WorkdayWorkerOtherId, this cmdlet 10 | first checks the current value before requesting a change. 11 | 12 | .PARAMETER WorkerId 13 | The Worker's Id at Workday. 14 | 15 | .PARAMETER WorkerType 16 | The type of ID that the WorkerId represents. Valid values 17 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 18 | 19 | .PARAMETER Human_ResourcesUri 20 | Human_Resources Endpoint Uri for the request. If not provided, the value 21 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 22 | 23 | 24 | .PARAMETER Username 25 | Username used to authenticate with Workday. If empty, the value stored 26 | using Set-WorkdayCredential will be used. 27 | 28 | .PARAMETER Password 29 | Password used to authenticate with Workday. If empty, the value stored 30 | using Set-WorkdayCredential will be used. 31 | 32 | #> 33 | 34 | [CmdletBinding()] 35 | param ( 36 | [Parameter(Mandatory = $true, 37 | ParameterSetName="Search", 38 | Position=0)] 39 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 40 | [string]$WorkerId, 41 | [Parameter(ParameterSetName="Search")] 42 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 43 | [string]$WorkerType = 'Employee_ID', 44 | [Parameter(ParameterSetName="Search")] 45 | [string]$Human_ResourcesUri, 46 | [Parameter(ParameterSetName="Search")] 47 | [string]$Username, 48 | [Parameter(ParameterSetName="Search")] 49 | [string]$Password, 50 | [Parameter(Mandatory = $true, 51 | ParameterSetName="NoSearch")] 52 | [xml]$WorkerXml, 53 | [Parameter(Mandatory = $true)] 54 | [ValidateNotNullOrEmpty()] 55 | [string]$Type, 56 | [Parameter(Mandatory = $true)] 57 | [ValidateNotNullOrEmpty()] 58 | [string]$Id, 59 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 60 | $WID, 61 | $IssuedDate, 62 | $ExpirationDate, 63 | [switch]$WhatIf, 64 | [Alias("Force")] 65 | [switch]$IncludeInactive 66 | ) 67 | 68 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 69 | 70 | if ($PsCmdlet.ParameterSetName -eq 'NoSearch') { 71 | $otherIds = Get-WorkdayWorkerOtherId -WorkerXml $WorkerXml 72 | $WorkerType = 'WID' 73 | $workerReference = $WorkerXml.GetElementsByTagName('wd:Worker_Reference') | Select-Object -First 1 74 | $WorkerId = $workerReference.ID | Where-Object {$_.type -eq 'WID'} | Select-Object -ExpandProperty InnerText 75 | } else { 76 | $otherIds = Get-WorkdayWorkerOtherId -WorkerId $WorkerId -WorkerType $WorkerType -Human_ResourcesUri:$Human_ResourcesUri -Username:$Username -Password:$Password -IncludeInactive:$IncludeInactive 77 | } 78 | 79 | Write-Debug "OtherIds: $otherIds" 80 | 81 | $current = $otherIds | Where-Object {$PSBoundParameters.ContainsKey('WID') -and $_.WID -eq $WID} | Select-Object -First 1 82 | # Default to the first of the requsted type. 83 | if ($null -eq $current) { 84 | $current = $otherIds | Where-Object {$_.Type -eq $Type} | Select-Object -First 1 85 | } 86 | 87 | $currentIdDisplay = $null 88 | $issuedCurrentDisplay = $null 89 | $expirationCurrentDisplay = $null 90 | $issuedProposedDisplay = $IssuedDate 91 | $expirationProposedDisplay = $ExpirationDate 92 | # Defaults to not matching. 93 | $idMatched = $false 94 | $issuedDateMatched = $false 95 | $expirationDateMatched = $false 96 | # Throw an error for an invalid date, default to the current value when no date is specified. 97 | if ($null -ne $IssuedDate) { 98 | try { 99 | $d = Get-Date $IssuedDate -ErrorAction Stop 100 | $IssuedDate = $d 101 | $issuedProposedDisplay = $IssuedDate.ToString('g') 102 | } 103 | catch { 104 | throw "Invalid IssuedDate [$IssuedDate]" 105 | } 106 | } 107 | else { 108 | $issuedProposedDisplay = 'current IssuedDate' 109 | } 110 | 111 | if ($null -ne $ExpirationDate) { 112 | try { 113 | $d = Get-Date $ExpirationDate -ErrorAction Stop 114 | $ExpirationDate = $d 115 | $expirationProposedDisplay = $ExpirationDate.ToString('g') 116 | } 117 | catch { 118 | throw "Invalid ExpirationDate [$ExpirationDate]" 119 | } 120 | } 121 | else { 122 | $expirationProposedDisplay = 'current ExpirationDate' 123 | } 124 | 125 | if ($null -ne $current) { 126 | Write-Debug "Current: $current" 127 | $currentIdDisplay = $current.Id 128 | $idMatched = $current.Id -eq $Id 129 | $WID = $current.Wid 130 | $issuedCurrentDisplay = if ($current.Issued_Date -is [DateTime]) { $current.Issued_Date.ToString('g') } 131 | $expirationCurrentDisplay = if ($current.Expiration_Date -is [DateTime]) { $current.Expiration_Date.ToString('g') } 132 | 133 | # Is a date change requested? 134 | if ($IssuedDate -is [datetime]) { 135 | $issuedProposedDisplay = $IssuedDate.ToString('g') 136 | # Is there a date to compare? 137 | if ($current.Issued_Date -is [datetime]) { 138 | # Do the dates match? 139 | $IssuedDateMatched = ($current.Issued_Date - $IssuedDate).Days -eq 0 140 | } 141 | } 142 | else { 143 | $IssuedDateMatched = $true 144 | } 145 | 146 | # Is a date change requested? 147 | if ($ExpirationDate -is [datetime]) { 148 | $expirationProposedDisplay = $ExpirationDate.ToString('g') 149 | # Is there a date to compare? 150 | if ($current.Expiration_Date -is [datetime]) { 151 | # Do the dates match? 152 | $ExpirationDateMatched = ($current.Expiration_Date - $ExpirationDate).Days -eq 0 153 | } 154 | } 155 | else { 156 | $ExpirationDateMatched = $true 157 | } 158 | } 159 | 160 | $msg = '{{0}} Current [{0} valid from {1} to {2}] Proposed [{3} valid from {4} to {5}]' -f $currentIdDisplay, $issuedCurrentDisplay, $expirationCurrentDisplay, $Id, $issuedProposedDisplay, $expirationProposedDisplay 161 | 162 | Write-Debug "idMatched=$idMatched; issuedDateMatched=$issuedDateMatched; expirationDateMatched=$expirationDateMatched" 163 | 164 | $output = [pscustomobject][ordered]@{ 165 | WorkerId = $WorkerId 166 | WorkerType = $WorkerType 167 | Type = $Type 168 | Id = $Id 169 | WID = $WID 170 | IssueDate = $IssuedDate 171 | ExpirationDate = $ExpirationDate 172 | Success = $false 173 | Message = $msg -f 'Failed' 174 | } 175 | 176 | if ( 177 | $idMatched -and 178 | $issuedDateMatched -and 179 | $expirationDateMatched 180 | ) { 181 | $output.Message = $msg -f 'Matched' 182 | $output.Success = $true 183 | } elseif ($WhatIf) { 184 | $output.Success = $true 185 | $output.Message = $msg -f 'Would change' 186 | } else { 187 | $params = @{ 188 | WorkerId = $WorkerId 189 | WorkerType = $WorkerType 190 | Type = $Type 191 | Id = $Id 192 | } 193 | if (-not [string]::IsNullOrWhiteSpace($WID)) { 194 | $params['WID'] = $WID 195 | } 196 | 197 | $o = Set-WorkdayWorkerOtherId @params -Human_ResourcesUri:$Human_ResourcesUri -Username:$Username -Password:$Password -IssuedDate:$IssuedDate -ExpirationDate:$ExpirationDate 198 | if ($null -ne $o) { 199 | if ($o.Success) { 200 | $output.Success = $true 201 | $output.Message = $msg -f 'Changed' 202 | } 203 | else { 204 | $output.Success = $false 205 | $output.Message = $o.Message 206 | } 207 | } 208 | } 209 | 210 | Write-Verbose $output.Message 211 | Write-Output $output 212 | } 213 | -------------------------------------------------------------------------------- /source/public/Update-WorkdayWorkerPhone.ps1: -------------------------------------------------------------------------------- 1 | function Update-WorkdayWorkerPhone { 2 | <# 3 | .SYNOPSIS 4 | Updates a Worker's phone number in Workday, only if it is different. 5 | 6 | .DESCRIPTION 7 | Updates a Worker's phone number in Workday, only if it is different. 8 | Change requests are always recorded in Workday's audit log even when 9 | the number is the same. Unlike Set-WorkdayWorkerPhone, this cmdlet 10 | first checks the current phone number before requesting a change. 11 | 12 | .PARAMETER WorkerId 13 | The Worker's Id at Workday. 14 | 15 | .PARAMETER WorkerType 16 | The type of ID that the WorkerId represents. Valid values 17 | are 'WID', 'Contingent_Worker_ID' and 'Employee_ID'. 18 | 19 | .PARAMETER WorkPhone 20 | Sets the Workday primary Work Landline for a Worker. This cmdlet does not 21 | currently support other phone types. Also excepts the alias OfficePhone. 22 | 23 | .PARAMETER Human_ResourcesUri 24 | Human_Resources Endpoint Uri for the request. If not provided, the value 25 | stored with Set-WorkdayEndpoint -Endpoint Human_Resources is used. 26 | 27 | 28 | .PARAMETER Username 29 | Username used to authenticate with Workday. If empty, the value stored 30 | using Set-WorkdayCredential will be used. 31 | 32 | .PARAMETER Password 33 | Password used to authenticate with Workday. If empty, the value stored 34 | using Set-WorkdayCredential will be used. 35 | 36 | .EXAMPLE 37 | 38 | Update-WorkdayWorkerPhone -WorkerId 123 -Number 1234567890 39 | 40 | #> 41 | 42 | [CmdletBinding()] 43 | param ( 44 | [Parameter(Mandatory = $true, 45 | ParameterSetName="Search", 46 | Position=0)] 47 | [ValidatePattern ('^[a-zA-Z0-9\-]{1,32}$')] 48 | [string]$WorkerId, 49 | [Parameter(ParameterSetName="Search")] 50 | [ValidateSet('WID', 'Contingent_Worker_ID', 'Employee_ID')] 51 | [string]$WorkerType = 'Employee_ID', 52 | [Parameter(ParameterSetName="Search")] 53 | [string]$Human_ResourcesUri, 54 | [Parameter(ParameterSetName="Search")] 55 | [string]$Username, 56 | [Parameter(ParameterSetName="Search")] 57 | [string]$Password, 58 | [Parameter(Mandatory = $true, 59 | ParameterSetName="NoSearch")] 60 | [xml]$WorkerXml, 61 | [Parameter(Mandatory = $true)] 62 | [ValidateNotNullOrEmpty()] 63 | [string]$Number, 64 | [string]$Extension, 65 | [ValidateSet('HOME','WORK')] 66 | [string]$UsageType = 'WORK', 67 | [ValidateSet('Landline','Cell')] 68 | [string]$DeviceType = 'Landline', 69 | [switch]$Private, 70 | [switch]$Secondary, 71 | [Alias("Force")] 72 | [switch]$IncludeInactive 73 | ) 74 | 75 | if ([string]::IsNullOrWhiteSpace($Human_ResourcesUri)) { $Human_ResourcesUri = $WorkdayConfiguration.Endpoints['Human_Resources'] } 76 | 77 | if ($PsCmdlet.ParameterSetName -eq 'NoSearch') { 78 | $current = Get-WorkdayWorkerPhone -WorkerXml $WorkerXml 79 | $WorkerType = 'WID' 80 | $workerReference = $WorkerXml.GetElementsByTagName('wd:Worker_Reference') | Select-Object -First 1 81 | $WorkerId = $workerReference.ID | Where-Object {$_.type -eq 'WID'} | Select-Object -ExpandProperty InnerText 82 | } else { 83 | $current = Get-WorkdayWorkerPhone -WorkerId $WorkerId -WorkerType $WorkerType -Human_ResourcesUri:$Human_ResourcesUri -Username:$Username -Password:$Password -IncludeInactive:$IncludeInactive 84 | } 85 | 86 | function scrub ([string]$PhoneNumber) { $PhoneNumber -replace '[^\d]','' } 87 | 88 | $scrubbedProposedNumber = scrub $Number 89 | $scrubbedProposedExtention = scrub $Extension 90 | $scrubbedCurrentNumber = $null 91 | $scrubbedCurrentExtension = $null 92 | $currentMatch = $current | 93 | Where-Object { 94 | $_.UsageType -eq $UsageType -and 95 | $_.DeviceType -eq $DeviceType -and 96 | (-not $_.Primary) -eq $Secondary 97 | } | Select-Object -First 1 98 | if ($null -ne $currentMatch) { 99 | $scrubbedCurrentNumber = scrub $currentMatch.Number 100 | $scrubbedCurrentExtension = scrub $currentMatch.Extension 101 | } 102 | 103 | $msg = "{0} Current [$scrubbedCurrentNumber] ext [$scrubbedCurrentExtension] Proposed [$scrubbedProposedNumber] ext [$scrubbedProposedExtention]" 104 | $output = [pscustomobject][ordered]@{ 105 | WorkerId = $WorkerId 106 | WorkerType = $WorkerType 107 | Number = $Number 108 | Extension = $Extension 109 | UsageType = $UsageType 110 | DeviceType = $DeviceType 111 | Primary = -not $Secondary 112 | Public = -not $Private 113 | Success = $false 114 | Message = $msg -f 'Failed' 115 | } 116 | if ( 117 | $null -ne $currentMatch -and 118 | $scrubbedCurrentNumber -eq $scrubbedProposedNumber -and 119 | $scrubbedCurrentExtension -eq $scrubbedProposedExtention -and 120 | (-not $currentMatch.Primary) -eq $Secondary -and 121 | (-not $currentMatch.Public) -eq $Private 122 | ) { 123 | $output.Message = $msg -f 'Matched' 124 | $output.Success = $true 125 | } 126 | else { 127 | $params = $PSBoundParameters 128 | $null = $params.Remove('WorkerXml') 129 | $null = $params.Remove('WorkerId') 130 | $null = $params.Remove('WorkerType') 131 | Write-Debug $params 132 | $o = Set-WorkdayWorkerPhone -WorkerId $WorkerId -WorkerType $WorkerType @params 133 | if ($null -ne $o) { 134 | if ($o.Success) { 135 | $output.Success = $true 136 | $output.Message = $msg -f 'Changed' 137 | } 138 | else { 139 | $output.Success = $false 140 | $output.Message = $o.Message 141 | } 142 | } 143 | } 144 | 145 | Write-Verbose $output.Message 146 | Write-Output $output 147 | } 148 | -------------------------------------------------------------------------------- /source/samples/Sync_AD_to_Workday.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Example script to push Active Directory values to Workday, when they differ. 4 | 5 | This version starts with requesting Workers from Workday. 6 | 7 | .Example 8 | .\Sync_AD_to_Workday.ps1 -Path output\results.csv 9 | #> 10 | 11 | # Requires -Module WorkdayApi 12 | 13 | [CmdletBinding()] 14 | param ( 15 | # Path to a Results file. 16 | [string]$Path, 17 | # A special validation to ensure the worker ID matches the value in AD extensionAttribute1. 18 | [switch]$MatchExtensionAttribute1, 19 | # Specifies how many workers to process. Used primarily for testing. 20 | [int]$Limit = 0 21 | ) 22 | Import-Module WorkdayApi 23 | 24 | function Main { 25 | $count = 0 26 | $ldapProperties = 'userPrincipalName', 'mail', 'telephoneNumber', 'mobile','extensionAttribute1' 27 | 28 | Write-Verbose 'Requesting Workday Workers.' 29 | 30 | Get-WorkdayWorker -IncludePersonal | ForEach-Object { 31 | $worker = $_ 32 | $count++ 33 | if ($Limit -gt 0 -and $count -ge $Limit) { return } 34 | $out = $outputTemplate.PsObject.Copy() 35 | $out.Success = $true 36 | $out.WorkerType = $worker.WorkerType 37 | $out.WorkerId = $worker.WorkerId 38 | $out.UserPrincipalName = $worker.UserId 39 | 40 | $adUser = @() 41 | if ($null -ne $worker.UserId) { 42 | $LDAPFilter = '(&(objectCategory=person)(objectClass=user)(userPrincipalName={0}))' -f $worker.UserId 43 | $adUser = @(Get-DsAdUsers -LDAPFilter $LDAPFilter -Properties $ldapProperties) 44 | } 45 | 46 | $adStatus = 'UserPrincipalName [{0}] returned {1} AD User(s).' -f $worker.UserId, $adUser.Count 47 | Write-Verbose ('{0} {1}' -f $worker.WorkerDescriptor, $adStatus) 48 | if ($AdUser.Count -ne 1) { 49 | $out.UserPrincipalName = $adStatus 50 | # It is OK if no AD user is not found. It is not OK if more than one is found. 51 | if ($AdUser.Count -gt 1) { 52 | $out.Success = $false 53 | } 54 | Write-Output $out 55 | continue 56 | } 57 | 58 | # We keep the worker ID in extensionAttribute1. 59 | if ($MatchExtensionAttribute1 -and $worker.WorkerId -ne $AdUser.extensionAttribute1) { 60 | $out.UserPrincipalName = 'Workday WorkerId [{0}] did not match AD ExtensionAttribute1 [{1}] for UserPrincipalName [{2}].' -f $worker.WorkerId, $AdUser.extensionAttribute1, $worker.UserId 61 | $out.Success = $false 62 | Write-Output $out 63 | continue 64 | } 65 | 66 | $email = $adUser.mail | Select-Object -First 1 67 | if ([string]::IsNullOrWhiteSpace($email)) { 68 | $out.WorkEmailStatus = 'No EmailAddress in AD.' 69 | } else { 70 | try { 71 | $response = Update-WorkdayWorkerEmail -WorkerXml $worker.Xml -Email $email -UsageType WORK -ErrorAction Stop 72 | $out.WorkEmailStatus = $response.Message 73 | } 74 | catch { 75 | $out.WorkEmailStatus = "Error: $_" 76 | $out.Success = $false 77 | } 78 | } 79 | 80 | $workPhone = $adUser.telephoneNumber | Select-Object -First 1 81 | $mobileSecondary = $true 82 | if ([string]::IsNullOrWhiteSpace($workPhone)) { 83 | $out.WorkPhoneStatus = 'No OfficePhone in AD.' 84 | $mobileSecondary = $false 85 | } else { 86 | $workPhone = Add-UsCountryCode $workPhone 87 | try { 88 | $response = Update-WorkdayWorkerPhone -WorkerXml $worker.Xml -Number $workPhone -UsageType WORK -DeviceType Landline -ErrorAction Stop 89 | $out.WorkPhoneStatus = $response.Message 90 | } 91 | catch { 92 | $out.WorkPhoneStatus = "Error: $_" 93 | $out.Success = $false 94 | } 95 | } 96 | 97 | $mobilePhone = $adUser.mobile | Select-Object -First 1 98 | if ([string]::IsNullOrWhiteSpace($mobilePhone)) { 99 | $out.MobilePhoneStatus = 'No MobilePhone in AD.' 100 | } else { 101 | $mobilePhone = Add-UsCountryCode $mobilePhone 102 | try { 103 | $response = Update-WorkdayWorkerPhone -WorkerXml $worker.Xml -Number $mobilePhone -UsageType WORK -DeviceType Cell -Secondary:$mobileSecondary -ErrorAction Stop 104 | $out.MobilePhoneStatus = $response.Message 105 | } 106 | catch { 107 | $out.WorkPhoneStatus = "Error: $_" 108 | $out.Success = $false 109 | } 110 | } 111 | 112 | Write-Output $out 113 | } 114 | } 115 | 116 | $outputTemplate = [pscustomobject][ordered]@{ 117 | WorkerType = $null 118 | WorkerId = $null 119 | UserPrincipalName = $null 120 | WorkEmailStatus = $null 121 | WorkPhoneStatus = $null 122 | MobilePhoneStatus = $null 123 | Success = $null 124 | } 125 | 126 | function Add-UsCountryCode { 127 | param ( 128 | [string]$PhoneNumber 129 | ) 130 | $out = $PhoneNumber 131 | $scrubbed = $PhoneNumber -replace '[^\d]','' 132 | if ($scrubbed.Length -eq 10) { 133 | $PhoneNumber = '1' + $PhoneNumber 134 | } 135 | Write-Output $PhoneNumber 136 | } 137 | 138 | function Get-DsAdUsers { 139 | [CmdletBinding()] 140 | [OutputType([System.DirectoryServices.ResultPropertyCollection])] 141 | param ( 142 | [string]$LDAPFilter = '(&(objectCategory=person)(objectClass=user)(!(useraccountcontrol:1.2.840.113556.1.4.803:=2)))', 143 | [string[]]$Properties = @('name','DistinguishedName') 144 | ) 145 | $objDomain = New-Object System.DirectoryServices.DirectoryEntry 146 | $objSearcher = New-Object System.DirectoryServices.DirectorySearcher 147 | $objSearcher.SearchRoot = $objDomain 148 | $objSearcher.PageSize = 1000 149 | $objSearcher.Filter = $LDAPFilter 150 | $objSearcher.SearchScope = "Subtree" 151 | 152 | $Properties | ForEach-Object { 153 | $null = $objSearcher.PropertiesToLoad.Add($_) 154 | } 155 | $outputTemplate = 1 | Select-Object ($Properties + 'LDAPPath') 156 | 157 | foreach ($entry in $objSearcher.FindAll()) { 158 | $output = $outputTemplate.psobject.Copy() 159 | $output.LDAPPath = $entry.Path 160 | foreach ($prop in $Properties) { 161 | $output."$prop" = $entry.Properties[$prop] | Select-Object 162 | } 163 | Write-Output $output 164 | } 165 | } 166 | 167 | if ([string]::IsNullOrWhiteSpace($Path)) { 168 | Main | Write-Output 169 | } 170 | else { 171 | $expandedPath = $Path -f (Get-Date) 172 | Write-Host "Writing results to: $expandedPath" 173 | Main | Export-Csv -Path $expandedPath -NoTypeInformation 174 | } 175 | -------------------------------------------------------------------------------- /source/samples/Sync_Workday_to_AD.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Example script to push Active Directory values to Workday, when they differ. 4 | 5 | This version starts with requesting Workers from Workday. 6 | 7 | .Example 8 | .\Sync_AD_to_Workday.ps1 -Path output\results.csv 9 | 10 | .NOTES 11 | 12 | Properties in AD True Up file: Active Status Employee ID Legal Name - First Name Legal Name - Last Name Worker Type Employee Type Manager ID User Name Business Title Location Work Space from Worker Primary Job Workspace Division SubDivision Cost Center 13 | 14 | Properties used: 15 | Employee ID 16 | Business Title 17 | Location 18 | Division 19 | SubDivision 20 | Workspace 21 | Manager ID 22 | ~Employee Type 23 | 24 | 25 | if ([string]::IsNullOrWhiteSpace($In.'Business Title')) { 26 | $adUser.Title = $null 27 | $adUser.Description = $null 28 | } else { 29 | $Title = $In.'Business Title' -replace '^TM-|^ST-','' 30 | $adUser.Title = $Title 31 | $adUser.Description = $Title 32 | } 33 | $adUser.Office = if ([string]::IsNullOrWhiteSpace($In.'Location')) { $null } else {$In.'Location'} 34 | $adUser.Department = if ([string]::IsNullOrWhiteSpace($In.'Division')) { $null } else {$In.'Division'} 35 | $adUser.extensionattribute4 = if ([string]::IsNullOrWhiteSpace($In.'SubDivision')) { $null } else {$In.'SubDivision'} 36 | $adUser.extensionattribute5 = if ([string]::IsNullOrWhiteSpace($In.'Workspace')) { $null } else {$In.'Workspace'} 37 | $adUser.extensionattribute7 = if ([string]::IsNullOrWhiteSpace($In.'Employee Type')) { $null } else {$In.'Employee Type'.Replace(' ','_')} 38 | 39 | # Get Manager. 40 | $manager = $null 41 | If ([string]::IsNullOrWhiteSpace($In.'Manager ID') -eq $false) { 42 | $manager = try { 43 | Get-ADUser -Filter "ExtensionAttribute1 -eq '$($In.'Manager ID')'" -ErrorAction Stop | 44 | Select-Object -First 1 -ExpandProperty DistinguishedName 45 | } catch {} 46 | } 47 | 48 | 49 | public void CommitChanges (); https://docs.microsoft.com/en-us/dotnet/api/system.directoryservices.directoryentry.commitchanges?view=netframework-4.7.2 50 | 51 | $properties = 'title','description','physicalDeliveryOfficeName','department','extensionattribute4','extensionattribute5','extensionattribute7' 52 | 53 | #> 54 | 55 | # Requires -Module WorkdayApi 56 | 57 | [CmdletBinding()] 58 | param ( 59 | # Path to a Results file. 60 | [string]$Path, 61 | # A special validation to ensure the worker ID matches the value in AD extensionAttribute1. 62 | [switch]$MatchExtensionAttribute1, 63 | # Specifies how many workers to process. Used primarily for testing. 64 | [int]$Limit = 0 65 | ) 66 | Import-Module WorkdayApi 67 | 68 | function Main { 69 | $count = 0 70 | $ldapProperties = 'userPrincipalName', 'mail', 'telephoneNumber', 'mobile','extensionAttribute1' 71 | 72 | Write-Verbose 'Requesting Workday Workers.' 73 | 74 | Get-WorkdayWorker -IncludePersonal | ForEach-Object { 75 | $worker = $_ 76 | $count++ 77 | if ($Limit -gt 0 -and $count -ge $Limit) { return } 78 | $out = $outputTemplate.PsObject.Copy() 79 | $out.Success = $true 80 | $out.WorkerType = $worker.WorkerType 81 | $out.WorkerId = $worker.WorkerId 82 | $out.UserPrincipalName = $worker.UserId 83 | 84 | $adUser = @() 85 | if ($null -ne $worker.UserId) { 86 | $LDAPFilter = '(&(objectCategory=person)(objectClass=user)(userPrincipalName={0}))' -f $worker.UserId 87 | $adUser = @(Get-DsAdUsers -LDAPFilter $LDAPFilter -Properties $ldapProperties) 88 | } 89 | 90 | $adStatus = 'UserPrincipalName [{0}] returned {1} AD User(s).' -f $worker.UserId, $adUser.Count 91 | Write-Verbose ('{0} {1}' -f $worker.WorkerDescriptor, $adStatus) 92 | if ($AdUser.Count -ne 1) { 93 | $out.UserPrincipalName = $adStatus 94 | # It is OK if an AD user is not found. It is not OK if more than one is found. 95 | if ($AdUser.Count -gt 1) { 96 | $out.Success = $false 97 | } 98 | Write-Output $out 99 | continue 100 | } 101 | 102 | # We keep the worker ID in extensionAttribute1. 103 | if ($MatchExtensionAttribute1 -and $worker.WorkerId -ne $AdUser.extensionAttribute1) { 104 | $out.UserPrincipalName = 'Workday WorkerId [{0}] did not match AD ExtensionAttribute1 [{1}] for UserPrincipalName [{2}].' -f $worker.WorkerId, $AdUser.extensionAttribute1, $worker.UserId 105 | $out.Success = $false 106 | Write-Output $out 107 | continue 108 | } 109 | 110 | $email = $adUser.mail | Select-Object -First 1 111 | if ([string]::IsNullOrWhiteSpace($email)) { 112 | $out.WorkEmailStatus = 'No EmailAddress in AD.' 113 | } else { 114 | try { 115 | $response = Update-WorkdayWorkerEmail -WorkerXml $worker.Xml -Email $email -UsageType WORK -ErrorAction Stop 116 | $out.WorkEmailStatus = $response.Message 117 | } 118 | catch { 119 | $out.WorkEmailStatus = "Error: $_" 120 | $out.Success = $false 121 | } 122 | } 123 | 124 | $workPhone = $adUser.telephoneNumber | Select-Object -First 1 125 | $mobileSecondary = $true 126 | if ([string]::IsNullOrWhiteSpace($workPhone)) { 127 | $out.WorkPhoneStatus = 'No OfficePhone in AD.' 128 | $mobileSecondary = $false 129 | } else { 130 | $workPhone = Add-UsCountryCode $workPhone 131 | try { 132 | $response = Update-WorkdayWorkerPhone -WorkerXml $worker.Xml -Number $workPhone -UsageType WORK -DeviceType Landline -ErrorAction Stop 133 | $out.WorkPhoneStatus = $response.Message 134 | } 135 | catch { 136 | $out.WorkPhoneStatus = "Error: $_" 137 | $out.Success = $false 138 | } 139 | } 140 | 141 | $mobilePhone = $adUser.mobile | Select-Object -First 1 142 | if ([string]::IsNullOrWhiteSpace($mobilePhone)) { 143 | $out.MobilePhoneStatus = 'No MobilePhone in AD.' 144 | } else { 145 | $mobilePhone = Add-UsCountryCode $mobilePhone 146 | try { 147 | $response = Update-WorkdayWorkerPhone -WorkerXml $worker.Xml -Number $mobilePhone -UsageType WORK -DeviceType Cell -Secondary:$mobileSecondary -ErrorAction Stop 148 | $out.MobilePhoneStatus = $response.Message 149 | } 150 | catch { 151 | $out.WorkPhoneStatus = "Error: $_" 152 | $out.Success = $false 153 | } 154 | } 155 | 156 | Write-Output $out 157 | } 158 | } 159 | 160 | $outputTemplate = [pscustomobject][ordered]@{ 161 | WorkerType = $null 162 | WorkerId = $null 163 | UserPrincipalName = $null 164 | WorkEmailStatus = $null 165 | WorkPhoneStatus = $null 166 | MobilePhoneStatus = $null 167 | Success = $null 168 | } 169 | 170 | function Add-UsCountryCode { 171 | param ( 172 | [string]$PhoneNumber 173 | ) 174 | $out = $PhoneNumber 175 | $scrubbed = $PhoneNumber -replace '[^\d]','' 176 | if ($scrubbed.Length -eq 10) { 177 | $PhoneNumber = '1' + $PhoneNumber 178 | } 179 | Write-Output $PhoneNumber 180 | } 181 | 182 | function Get-DsAdUsers { 183 | [CmdletBinding()] 184 | [OutputType([System.DirectoryServices.ResultPropertyCollection])] 185 | param ( 186 | [string]$LDAPFilter = '(&(objectCategory=person)(objectClass=user)(!(useraccountcontrol:1.2.840.113556.1.4.803:=2)))', 187 | [string[]]$Properties = @('name','DistinguishedName') 188 | ) 189 | $objDomain = New-Object System.DirectoryServices.DirectoryEntry 190 | $objSearcher = New-Object System.DirectoryServices.DirectorySearcher 191 | $objSearcher.SearchRoot = $objDomain 192 | $objSearcher.PageSize = 1000 193 | $objSearcher.Filter = $LDAPFilter 194 | $objSearcher.SearchScope = "Subtree" 195 | 196 | $Properties | ForEach-Object { 197 | $null = $objSearcher.PropertiesToLoad.Add($_) 198 | } 199 | $outputTemplate = 1 | Select-Object ($Properties + 'LDAPPath') 200 | 201 | foreach ($entry in $objSearcher.FindAll()) { 202 | $output = $outputTemplate.psobject.Copy() 203 | $output.LDAPPath = $entry.Path 204 | foreach ($prop in $Properties) { 205 | $output."$prop" = $entry.Properties[$prop] | Select-Object 206 | } 207 | Write-Output $output 208 | } 209 | } 210 | 211 | if ([string]::IsNullOrWhiteSpace($Path)) { 212 | Main | Write-Output 213 | } 214 | else { 215 | $expandedPath = $Path -f (Get-Date) 216 | Write-Host "Writing results to: $expandedPath" 217 | Main | Export-Csv -Path $expandedPath -NoTypeInformation 218 | } 219 | -------------------------------------------------------------------------------- /source/samples/Update-WorkdayWorkerPhotosSince.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Updates Worker photos, from a directory of specially named JPEG files. 4 | 5 | .PARAMETER Path 6 | Folder with JEPG photos to be pushed to Workday. Named by Worker ID, optionally zero padded. 7 | 01234.jpg 8 | 01235.jpeg 9 | 10 | .PARAMETER ResultsFile 11 | A path to a CSV file of the results. The .Net format token {0} 12 | is expanded with the current date and time. 13 | 14 | .PARAMETER Since 15 | Optional. When specified, only photos newer than this time will be processed. Defaults 16 | to the last time the script successfully ran. 17 | 18 | .PARAMETER All 19 | Use, in place of the Since parameter, to process all photos. 20 | 21 | .EXAMPLE 22 | $parameters = @{ 23 | Path = 'c:\path\to\photos 24 | ResultsFile = 'c:\path\for\results\Update-WorkdayWorkerPhotosSince_{0:yyyy-MM-dd}.csv' 25 | } 26 | 27 | .\samples\Update-WorkdayWorkerPhotosSince.ps1 @parameters 28 | 29 | #> 30 | [CmdletBinding()] 31 | param ( 32 | [Parameter(Mandatory=$true)] 33 | [ValidateScript({Test-Path -Path $_ -PathType Container})] 34 | $Path, 35 | $ResultsFile, 36 | [string]$PersistanceFile = (Join-Path $Path 'Update-WorkdayWorkerPhotosSince.clixml'), 37 | [datetime]$Since = [datetime]::MinValue, 38 | [switch]$All, 39 | [switch]$WhatIf 40 | ) 41 | Set-StrictMode -Version Latest 42 | 43 | function Main { 44 | $activity = "Updating Workday Worker photos from $Path" 45 | 46 | # Unless the Since has a value specified, use the last time this process was ran. 47 | if ( $All -eq $false -and 48 | $Since -eq [datetime]::MinValue -and 49 | ( Test-Path -Path $persistanceFile ) 50 | ) { 51 | $Since = Import-Clixml -Path $persistanceFile 52 | $activity = '{0}, since {1:g}' -f $activity, $Since 53 | } 54 | 55 | Write-Progress -Activity $activity -Status 'Initalization' 56 | Write-Verbose $activity 57 | 58 | 59 | $RunTime = Get-Date 60 | Write-Progress -Activity $activity -Status 'Initalization' -CurrentOperation 'Enumerating files' 61 | $files = @( 62 | Get-ChildItem -Path (Join-Path $Path '*') -Include *.jpg,*.jpeg | 63 | Where-Object {$All -or $_.LastWriteTime -ge $Since} 64 | ) 65 | 66 | if ($files.count -gt 0) { 67 | Write-Progress -Activity $activity -Status 'Initalization' -CurrentOperation 'Downloading and building Worker lookup table.' 68 | $Workers = Get-WorkdayWorkerByIdLookupTable 69 | 70 | $countOfPhotos = 0 71 | foreach ($file in $files) { 72 | $countOfPhotos++ 73 | Write-Progress -Activity $activity -Status "Processing ($countOfPhotos of $(@($files).count))." -CurrentOperation $file -PercentComplete ($countOfPhotos/@($files).count *100) 74 | $output = [PSCustomObject][ordered]@{ 75 | PhotoPath = $file.FullName 76 | WorkerId = '' 77 | WorkerType = '' 78 | Success = $false 79 | Message = '' 80 | } 81 | 82 | if ($file.Name -match '0*(\d+).jpg$') { 83 | $output.WorkerId = $Matches[1] 84 | $worker = $Workers[$output.WorkerId] 85 | 86 | if ($null -eq $worker) { 87 | $output.Success = $false 88 | $output.Message = 'Worker ID not found at Workday.' 89 | } 90 | elseif ($worker.Count -gt 1) { 91 | $output.Success = $false 92 | $unrolledWorkers = ($worker | Foreach-Object {'{0} {1}' -f $_.WorkerType, $_.WorkerId}) -join ', ' 93 | $output.Message = "More than one Workday Worker found by WorkerID: $unrolledWorkers" 94 | } 95 | else { 96 | $output.WorkerType = $worker[0].WorkerType 97 | if ($WhatIf) { 98 | $output.Success = $true 99 | $output.Message = "WhatIf: Set-WorkdayWorkerPhoto -WorkerType '{0}' -WorkerId '{1}' -Path '{2}'" -f $worker[0].WorkerType, $worker[0].WorkerId, $file.FullName 100 | } 101 | else { 102 | try { 103 | $result = Set-WorkdayWorkerPhoto -WorkerType $worker[0].WorkerType -WorkerId $worker[0].WorkerId -Path $file.FullName 104 | $output.Success = $result.Success 105 | $output.Message = $result.Message 106 | } 107 | catch { 108 | $output.Success = $false 109 | $output.message = $_ 110 | } 111 | } 112 | } 113 | } 114 | else { 115 | $output.Success = $false 116 | $output.Message = 'Invalid file name.' 117 | } 118 | Write-Output $output 119 | } 120 | Write-Progress -Activity $activity -Completed -Status 'Completed' 121 | Write-Verbose "Done processing $($files.count) file(s)." 122 | } else { 123 | Write-Verbose 'No new photos to process.' 124 | } 125 | 126 | if (-not $WhatIf) { 127 | # Save when these tasks were last ran, to only process new files next time. 128 | $RunTime | Export-Clixml -Path $persistanceFile 129 | } 130 | } 131 | 132 | function CreateDirectoryIfNeeded { 133 | param ($Path) 134 | $Directory = Split-Path -Parent -Path $Path 135 | if ($null -ne $Directory -and -not (Test-Path $Directory)) { 136 | New-Item -Path $Directory -Type Directory | Out-Null 137 | } 138 | } 139 | 140 | Main | Write-Output -OutVariable Output 141 | 142 | if ($null -ne $ResultsFile -and $Output.Count -gt 0) { 143 | $ResultsFile = $ResultsFile -f (Get-Date) 144 | CreateDirectoryIfNeeded $ResultsFile 145 | $Output | Export-Csv -Path $ResultsFile -NoTypeInformation 146 | Write-Verbose "Result file: $ResultsFile" 147 | } 148 | -------------------------------------------------------------------------------- /source/samples/Update_Email_By_WorkerID.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Updates Worker Email Addresses, given a file with WorkerID and Email. 4 | .DESCRIPTION 5 | Updates Worker Email Addresses, given a file with WorkerID and Email. 6 | 7 | .PARAMETER InputFile 8 | Path to input CSV file. The CSV should look like this (with or without the header): 9 | WorkerID,Email 10 | 1,email1@example.com 11 | 2,email2@example.com 12 | 13 | .PARAMETER ArchiveFile 14 | A path can be specified to move / archive the input file. The .Net format 15 | token {0} is expanded with the current date and time. When not specified, 16 | the input file is left untouched. When a value of 'delete' is given the 17 | input file is deleted. 18 | .PARAMETER ResultsFile 19 | A path to an optional CSV file of the results. The .Net format token {0} 20 | is expanded with the current date and time. 21 | .PARAMETER UsageType 22 | Passed to Update-WorkdayWorkerEmail. Currently supports Work or Home. 23 | .PARAMETER Private 24 | Passed to Update-WorkdayWorkerEmail. 25 | .PARAMETER Secondary 26 | Passed to Update-WorkdayWorkerEmail. 27 | 28 | .EXAMPLE 29 | $parameters = @{ 30 | InputFile = 'Secondary_Work_Emails.csv' # WorkerID,Email 31 | ArchiveFile = 'Secondary_Work_Emails_{0:yyyyMMdd}.csv' 32 | ResultsFile = 'Secondary_Work_Emails_{0:yyyyMMdd}_Results.csv' 33 | UsageType = 'WORK' 34 | Secondary = $true 35 | } 36 | 37 | .\samples\Update_Email_By_WorkerID.ps1 @parameters 38 | 39 | #> 40 | [CmdletBinding()] 41 | param ( 42 | [Parameter(Mandatory=$true)] 43 | [ValidateScript({Test-Path $_})] 44 | $InputFile, 45 | $ArchiveFile, 46 | $ResultsFile, 47 | [ValidateSet('HOME','WORK')] 48 | [string]$UsageType = 'WORK', 49 | [switch]$Private, 50 | [switch]$Secondary 51 | ) 52 | 53 | Write-Verbose "Downloading and building Worker lookup table." 54 | $Workers = Get-WorkdayWorkerByIdLookupTable 55 | 56 | function Main { 57 | 58 | Write-Verbose "Processing input file: $InputFile" 59 | $arguments = @{ 60 | Path = $InputFile 61 | } 62 | 63 | # Add a header argument, if the first line starts with a number. 64 | $firstLine = Get-Content -Path $InputFile -TotalCount 1 65 | if ($firstLine -match '^"?\d') { 66 | $arguments['Header'] = 'WorkerID','Email' 67 | } 68 | 69 | if ($null -eq $ResultsFile) { 70 | Import-Csv @arguments | UpdateEmail 71 | } 72 | else { 73 | $ResultsFile = $ResultsFile -f (Get-Date) 74 | CreateDirectoryIfNeeded $ResultsFile 75 | Import-Csv @arguments | UpdateEmail | Export-Csv -Path $ResultsFile -NoTypeInformation 76 | Write-Verbose "Result file: $ResultsFile" 77 | } 78 | 79 | if ($null -ne $ArchiveFile) { 80 | if ($ArchiveFile -eq 'delete') { 81 | Write-Verbose "Deleting input file." 82 | Remove-Item -Path $InputFile 83 | } 84 | else { 85 | $ArchiveFile = $ArchiveFile -f (Get-Date) 86 | Write-Verbose "Archiving input file to: $ArchiveFile" 87 | CreateDirectoryIfNeeded $ArchiveFile 88 | Move-Item -Path $InputFile -Destination $ArchiveFile -Force 89 | } 90 | } 91 | } 92 | 93 | filter UpdateEmail { 94 | $entry = $_ 95 | $worker = $Workers[$entry.WorkerID] 96 | if ($null -eq $worker) { 97 | $output = GetErrorResponse -WorkerId $entry.WorkerID -Email $entry.Email -Message 'Workday Worker not found by WorkerID.' 98 | Write-Output $output 99 | } 100 | elseif ($worker.Count -gt 1) { 101 | $unrolledWorkers = ($worker | ForEach-Object {'{0} {1}' -f $_.WorkerType, $_.WorkerId}) -join ', ' 102 | $msg = "More than one Workday Worker found by WorkerID: $unrolledWorkers" 103 | $output = GetErrorResponse -WorkerId $entry.WorkerID -Email $entry.Email -Message $msg 104 | Write-Output $output 105 | } 106 | else { 107 | try { 108 | $output = Update-WorkdayWorkerEmail -WorkerType $worker[0].WorkerType -WorkerId $worker[0].WorkerId -Email $entry.Email -UsageType:$UsageType -Private:$Private -Secondary:$Secondary -ErrorAction Stop 109 | Write-Output $output 110 | } 111 | catch { 112 | $msg = 'Update-WorkdayWorkerEmail error: {0}' -f $_ 113 | $output = GetErrorResponse -WorkerId $entry.WorkerID -Email $entry.Email -Message $msg 114 | Write-Output $output 115 | } 116 | } 117 | } 118 | 119 | function GetErrorResponse { 120 | param ( 121 | $WorkerId, 122 | $Email, 123 | $Message 124 | ) 125 | [PSCustomObject][Ordered]@{ 126 | WorkerId = $WorkerId 127 | WorkerType = $null 128 | Email = $Email 129 | UsageType = $UsageType 130 | Primary = -not $Secondary 131 | Public = -not $Private 132 | Success = $false 133 | Message = $Message 134 | } | Write-Output 135 | } 136 | 137 | function CreateDirectoryIfNeeded { 138 | param ($Path) 139 | $Directory = Split-Path -Parent -Path $Path 140 | if (-not (Test-Path $Directory)) { 141 | New-Item -Path $Directory -Type Directory | Out-Null 142 | } 143 | } 144 | 145 | . Main 146 | -------------------------------------------------------------------------------- /source/tests/Get-WorkdayIntegrationEvent.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Get-WorkdayIntegrationEvent { 6 | InModuleScope WorkdayApi { 7 | 8 | # Echo Request 9 | Mock Invoke-WorkdayRequest { 10 | Mock_Invoke-WorkdayRequest_ExampleIntegrationEvent @args 11 | } 12 | 13 | It 'Calls Invoke-WorkdayRequest and returns the proper responses.' { 14 | $response = Get-WorkdayIntegrationEvent -Wid 0123456789ABCDEF0123456789ABCDEF 15 | $response.Name | Should BeExactly 'Test Descriptor' 16 | $response.Start.GetType().Name | Should BeExactly 'DateTime' 17 | $response.End.GetType().Name | Should BeExactly 'DateTime' 18 | $response.Message | Should BeExactly 'Integration Completed.' 19 | $response.PercentComplete | Should BeExactly 100 20 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /source/tests/Get-WorkdayToAdData.Tests.ps1: -------------------------------------------------------------------------------- 1 | <#### Before testing, have to create the mock XML for the test worker. 2 | 3 | 4 | Get-Module WorkdayApi | Remove-Module -Force 5 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 6 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 7 | 8 | Describe Get-WorkdayToAdData { 9 | 10 | InModuleScope WorkdayApi { 11 | 12 | It 'Returns expected worker information.' { 13 | Mock Invoke-WorkdayRequest { 14 | Mock_Invoke-WorkdayRequest_ExampleWorker 15 | } 16 | 17 | $response = @(Get-WorkdayToAdData -WorkerId 1 -WorkerType Employee_ID) 18 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 19 | $response.Count | Should Be 1 20 | $response[0].'ADD or CHANGE' | Should Be 'ADD' 21 | $response[0].'Employee or Contingent Worker Number' | Should Be '' 22 | $response[0].'First Name' | Should Be '' 23 | $response[0].'Last Name' | Should Be '' 24 | $response[0].'Preferred First Name' | Should Be '' 25 | $response[0].'Preferred Last Name' | Should Be '' 26 | $response[0].'User Name' | Should Be '' 27 | $response[0].'Work Phone' | Should Be '' 28 | $response[0].'Badge ID' | Should Be '' 29 | $response[0].'Job Title' | Should Be '' 30 | $response[0].'Employee or Contingent Worker Type' | Should Be '' 31 | $response[0].'Worker Type' | Should Be '' 32 | $response[0].'Worker SubType' | Should Be '' 33 | $response[0].'Department (LOB)' | Should Be 'Unimplemented' 34 | $response[0].'Sub Department' | Should Be 'Unimplemented' 35 | $response[0].'Location (Building)' | Should Be '' 36 | $response[0].'Location(Workspace)' | Should Be '' 37 | $response[0].'Supervisor Name' | Should Be '' 38 | $response[0].'Supervisor Employee Id' | Should Be '' 39 | $response[0].'Matrix Manager Name (for Team Members)' | Should Be '' 40 | $response[0].'Hire Date' | Should Be '' 41 | } 42 | } 43 | } 44 | #> -------------------------------------------------------------------------------- /source/tests/Get-WorkdayWorker.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Get-WorkdayWorker { 6 | InModuleScope WorkdayApi { 7 | 8 | Mock Invoke-WorkdayRequest { 9 | Mock_Invoke-WorkdayRequest_Echo @args 10 | } 11 | 12 | It 'Creates the correct XML for the Workday request.' { 13 | 14 | $expectedResponse = @' 15 | 11truetruefalsefalsefalsefalsefalsefalse 16 | '@ 17 | $response = Get-WorkdayWorker -WorkerId 1 -WorkerType Employee_ID -Passthru 18 | $response.Xml.Get_Workers_Request.Response_Filter.As_Of_Entry_DateTime = '' 19 | $response.Xml.OuterXml | Should BeExactly $expectedResponse 20 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 21 | } 22 | 23 | It 'Returns expected worker information.' { 24 | 25 | Mock Invoke-WorkdayRequest { 26 | Mock_Invoke-WorkdayRequest_ExampleWorker 27 | } 28 | 29 | $response = @(Get-WorkdayWorker -WorkerId 1 -WorkerType Employee_ID -IncludePersonal) 30 | $response.Count | Should Be 1 31 | $response[0].XML -is [XML] | Should Be $true 32 | $response[0].WorkerWid | Should Be '00000000000000000000000000000000' 33 | $response[0].PreferredName | Should Be 'Example Worker' 34 | $response[0].Phone.Count | Should Be 1 35 | $response[0].Email.Count | Should Be 1 36 | @($response[0].NationalId).Count | Should Be 1 37 | @($response[0].OtherId).Count | Should Be 1 38 | $response[0].BusinessUnit | Should Be 'Business Unit Organization Name' 39 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 2 40 | 41 | } 42 | 43 | It 'Excepts the IncludeInactive parameter.' { 44 | $null = Get-WorkdayWorker -WorkerId 1 -WorkerType Employee_ID -IncludeInactive 45 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 3 46 | } 47 | 48 | } 49 | } -------------------------------------------------------------------------------- /source/tests/Get-WorkdayWorkerEmail.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Get-WorkdayWorkerEmail { 6 | InModuleScope WorkdayApi { 7 | 8 | Context Search { 9 | It 'Returns expected email information when provided an EmployeeId.' { 10 | Mock Invoke-WorkdayRequest { 11 | Mock_Invoke-WorkdayRequest_ExampleWorker 12 | } 13 | 14 | $response = @(Get-WorkdayWorkerEmail -WorkerId 1) 15 | $response.Count | Should Be 1 16 | $response[0].UsageType | Should Be 'Work' 17 | $response[0].Email | Should Be 'test@example.com' 18 | $response[0].Primary | Should Be $true 19 | $response[0].Public | Should Be $true 20 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 21 | } 22 | } 23 | 24 | Context NoSearch { 25 | It 'Returns expected email information when provided a Worker XML object.' { 26 | Mock Invoke-WorkdayRequest {} 27 | 28 | $worker = Mock_Invoke-WorkdayRequest_ExampleWorker 29 | $response = @(Get-WorkdayWorkerEmail -WorkerXml $worker.Xml ) 30 | $response.Count | Should Be 1 31 | $response[0].UsageType | Should Be 'Work' 32 | $response[0].Email | Should Be 'test@example.com' 33 | $response[0].Primary | Should Be $true 34 | $response[0].Public | Should Be $true 35 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 0 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /source/tests/Get-WorkdayWorkerNationalId.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Get-WorkdayWorkerNationalId { 6 | InModuleScope WorkdayApi { 7 | 8 | It 'Returns expected ID information.' { 9 | Mock Invoke-WorkdayRequest { 10 | Mock_Invoke-WorkdayRequest_ExampleWorker 11 | } 12 | 13 | $response = @(Get-WorkdayWorkerNationalId -WorkerId 1) 14 | $response.Count | Should Be 1 15 | $response[0].Type | Should Be 'USA-SSN' 16 | $response[0].Id | Should Be '000000000' 17 | $response[0].Descriptor | Should Be '000-00-0000 (USA-SSN)' 18 | $response[0].WID | Should Be '00000000000000000000000000000000' 19 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /source/tests/Get-WorkdayWorkerOtherId.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Get-WorkdayWorkerOtherId { 6 | InModuleScope WorkdayApi { 7 | 8 | It 'Returns expected ID information.' { 9 | Mock Invoke-WorkdayRequest { 10 | Mock_Invoke-WorkdayRequest_ExampleWorker 11 | } 12 | 13 | $response = @(Get-WorkdayWorkerOtherId -WorkerId 1) 14 | $response.Count | Should Be 1 15 | $response[0].Type | Should Be 'Badge_ID' 16 | $response[0].Id | Should Be '1' 17 | $response[0].Descriptor | Should Be 'Badge ID' 18 | $response[0].WID | Should Be '00000000000000000000000000000000' 19 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /source/tests/Get-WorkdayWorkerPhone.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Get-WorkdayWorkerPhone { 6 | InModuleScope WorkdayApi { 7 | 8 | Context Search { 9 | It 'Returns expected phone information when provided an EmployeeId.' { 10 | Mock Invoke-WorkdayRequest { 11 | Mock_Invoke-WorkdayRequest_ExampleWorker 12 | } 13 | 14 | $response = @(Get-WorkdayWorkerPhone -WorkerId 1) 15 | $response.Count | Should Be 1 16 | $response[0].UsageType | Should Be 'Work' 17 | $response[0].DeviceType | Should Be 'Landline' 18 | $response[0].Number | Should Be '1 (517) 123-4567' 19 | $response[0].Extension | Should Be '4321' 20 | $response[0].Primary | Should Be $true 21 | $response[0].Public | Should Be $true 22 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 23 | } 24 | } 25 | 26 | Context NoSearch { 27 | It 'Returns expected Phone information when provided a Worker XML object.' { 28 | Mock Invoke-WorkdayRequest {} 29 | 30 | $worker = Mock_Invoke-WorkdayRequest_ExampleWorker 31 | $response = @(Get-WorkdayWorkerPhone -WorkerXml $worker.Xml ) 32 | $response.Count | Should Be 1 33 | $response[0].UsageType | Should Be 'Work' 34 | $response[0].DeviceType | Should Be 'Landline' 35 | $response[0].Number | Should Be '1 (517) 123-4567' 36 | $response[0].Extension | Should Be '4321' 37 | $response[0].Primary | Should Be $true 38 | $response[0].Public | Should Be $true 39 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 0 40 | } 41 | } 42 | 43 | } 44 | } -------------------------------------------------------------------------------- /source/tests/Get-WorkdayWorkerPhoto.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Get-WorkdayWorkerPhoto { 6 | InModuleScope WorkdayApi { 7 | 8 | # Echo Request 9 | Mock Invoke-WorkdayRequest { 10 | Mock_Invoke-WorkdayRequest_Echo @args 11 | } 12 | 13 | It 'Creates the correct XML for the request.' { 14 | $expectedResponse = @' 15 | 12020-05-05T00:00:00.0000000 16 | '@ -f (Get-Date) 17 | $response = Get-WorkdayWorkerPhoto -WorkerId 1 -AsOfEntryDateTime '2020-05-05' -Passthru 18 | $response.Xml.OuterXml | Should BeExactly $expectedResponse 19 | } 20 | 21 | } 22 | } -------------------------------------------------------------------------------- /source/tests/Invoke-WorkdayRequest.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | 4 | Describe Invoke-WorkdayRequest { 5 | InModuleScope WorkdayApi { 6 | 7 | It 'Returns the time from Workday using the API, when properly configured.' { 8 | $Uri = Get-WorkdayEndpoint -Endpoint Human_Resources 9 | if ($null -eq $Uri) { 10 | Set-TestInconclusive -Message 'The WorkdayAPI does not appear to be properly configured for this live test.' 11 | } 12 | $request = @' 13 | 14 | '@ 15 | $response = Invoke-WorkdayRequest -Request $request -Uri $Uri 16 | $response.Xml -is [XML] | Should Be $true 17 | $response.Xml.Server_Timestamp.Server_Timestamp_Data -match '^\d\d\d\d-\d\d-\d\d' | Should Be $true 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /source/tests/Invoke-WorkdayRequestHelper.psm1: -------------------------------------------------------------------------------- 1 |  2 | 3 | Set-WorkdayEndpoint -Endpoint Staffing -Uri 'https://SERVICE.workday.com/ccx/service/TENANT/Staffing' 4 | Set-WorkdayEndpoint -Endpoint Human_Resources -Uri 'https://SERVICE.workday.com/ccx/service/TENANT/Human_Resources' 5 | Set-WorkdayEndpoint -Endpoint Integrations -Uri 'https://SERVICE.workday.com/ccx/service/TENANT/Integrations' 6 | 7 | 8 | # Echo Request 9 | function Mock_Invoke-WorkdayRequest_Echo { 10 | param ( 11 | $Request 12 | ) 13 | [pscustomobject][ordered]@{ 14 | Success = $true 15 | Message = '' 16 | Xml = [xml]$Request 17 | } 18 | } 19 | 20 | 21 | # Return an error 22 | function Mock_Invoke-WorkdayRequest_ExampleError { 23 | [pscustomobject][ordered]@{ 24 | Success = $false 25 | Message = 'SOAP-ENV:Client.validationError: Workday Request Error Example' 26 | Xml = [xml]@' 27 | 28 | SOAP-ENV:Client.validationError 29 | Workday Request Error Example/bsvc 30 | 31 | 32 | 33 | Workday Request Error Example 34 | 35 | 36 | 37 | 38 | 39 | 40 | '@ 41 | } 42 | } 43 | 44 | 45 | # Return a Good example 46 | function Mock_Invoke-WorkdayRequest_ExampleWorker { 47 | [pscustomobject][ordered]@{ 48 | Success = $true 49 | Message = '' 50 | Xml = [xml]@' 51 | 52 | 53 | 54 | 00000000000000000000000000000000 55 | 1 56 | 57 | 58 | 59 | 1 60 | 1 61 | 0 62 | 0 63 | 0 64 | 0 65 | 66 | 67 | 1 68 | 1 69 | 1 70 | 1 71 | 72 | 73 | 74 | 75 | 00000000000000000000000000000000 76 | 1 77 | 78 | 79 | 1 80 | ExampleWorker@example.com 81 | 82 | 83 | 84 | 85 | 86 | 00000000000000000000000000000000 87 | US 88 | USA 89 | 840 90 | 91 | Example 92 | Middle 93 | Worker 94 | 95 | 96 | 97 | 98 | 99 | 00000000000000000000000000000000 100 | US 101 | USA 102 | 840 103 | 104 | Example 105 | Middle 106 | Worker 107 | 108 | 109 | 110 | 111 | 00000000000000000000000000000000 112 | Male 113 | 114 | 1960-01-01-07:00 115 | 116 | 00000000000000000000000000000000 117 | Married_United_States_of_America 118 | 119 | 2000-01-01-07:00 120 | 121 | 122 | 00000000000000000000000000000000 123 | DISABILITY-6-71 124 | 125 | 0 126 | 0 127 | 0 128 | 129 | 00000000000000000000000000000000 130 | DISABILITY_STATUS_REFERENCE-3-354 131 | 132 | 133 | 134 | e20c9b6394e9107595745c28ac01495c 135 | 00000000000000000000000000000000 136 | 137 | 0 138 | 139 | 00000000000000000000000000000000 140 | Citizen_United_States_of_America 141 | 142 | 143 | 144 | 00000000000000000000000000000000 145 | MILITARY_STATUS-6-14 146 | MILITARY_STATUS-6-14 147 | 148 | 149 | 00000000000000000000000000000000 150 | MILITARY_SERVICE_REFERENCE-3-3343 151 | 152 | 153 | 154 | 155 | 156 | 00000000000000000000000000000000 157 | 158 | 159 | 000000000 160 | 161 | 00000000000000000000000000000000 162 | USA-SSN 163 | 164 | 165 | 00000000000000000000000000000000 166 | US 167 | USA 168 | 840 169 | 170 | 2015-07-28-07:00 171 | 172 | 00000000000000000000000000000000 173 | 2 174 | 175 | 176 | 177 | 00000000000000000000000000000000 178 | NATIONAL_IDENTIFIER_REFERENCE-3-13830 179 | 180 | 181 | 182 | 183 | 00000000000000000000000000000000 184 | 185 | 186 | 1 187 | 188 | 00000000000000000000000000000000 189 | Badge_ID 190 | 191 | 2015-07-31-07:00 192 | 2020-07-30-07:00 193 | 194 | 195 | 00000000000000000000000000000000 196 | CUSTOM_IDENTIFIER_REFERENCE-3-20109 197 | 198 | 199 | 200 | 201 | 202 | 203 | 00000000000000000000000000000000 204 | US 205 | USA 206 | 840 207 | 208 | 2014-10-08T12:24:19.493-07:00 209 | 3510 Capital City Blvd. 210 | Lansing 211 | 212 | 00000000000000000000000000000000 213 | USA-MI 214 | 215 | 48906 216 | 217 | 218 | 219 | 00000000000000000000000000000000 220 | WORK 221 | 222 | 223 | 224 | 225 | 00000000000000000000000000000000 226 | ADDRESS_REFERENCE-6-153 227 | 228 | 229 | 230 | MSR 231 | 1 232 | 517 233 | 123-4567 234 | 4321 235 | 236 | 00000000000000000000000000000000 237 | Landline 238 | 239 | 240 | 241 | 242 | 00000000000000000000000000000000 243 | WORK 244 | 245 | 246 | 247 | 248 | 249 | test@example.com 250 | 251 | 252 | 253 | 1f27f250dfaa4724ab1e1617174281e4 254 | WORK 255 | 256 | 257 | 258 | 259 | 260 | 0 261 | 262 | 263 | 264 | 265 | 266 | 267 | 00000000000000000000000000000000 268 | BUSINESS_UNIT-3-2 269 | 270 | 271 | BUSINESS_UNIT-3-2 272 | Business Unit Organization Name 273 | 274 | 00000000000000000000000000000000 275 | BUSINESS_UNIT 276 | 277 | 278 | 279 | 280 | 00000000000000000000000000000000 281 | Integration_Partner 282 | 283 | 284 | 285 | 00000000000000000000000000000000 286 | 14970 287 | 288 | Assigned 289 | 290 | 291 | 292 | 1 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | '@ 303 | } 304 | } 305 | 306 | function Mock_Invoke-WorkdayRequest_ExampleIntegration { 307 | [pscustomobject][ordered]@{ 308 | Success = $true 309 | Message = '' 310 | Xml = [xml]@' 311 | 312 | 313 | 314 | 00000000000000000000000000000000 315 | INTEGRATION_ESB_INVOCATION-0-00000 316 | 317 | 318 | 319 | 00000000000000000000000000000000 320 | 321 | 2016-04-12T15:22:27.342-07:00 322 | 323 | 324 | 325 | 326 | '@ 327 | } 328 | } 329 | 330 | # Return a Good example 331 | function Mock_Invoke-WorkdayRequest_ExampleIntegrationEvent { 332 | [pscustomobject][ordered]@{ 333 | Success = $true 334 | Message = '' 335 | Xml = [xml]@' 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 2016-04-12T15:22:27.342-07:00 345 | Integration Completed. 346 | 2016-04-12T15:24:38.308-07:00 347 | 1 348 | 349 | 350 | 351 | 352 | '@ 353 | } 354 | } -------------------------------------------------------------------------------- /source/tests/Remove-WorkdayWorkerOtherId.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Remove-WorkdayWorkerOtherId { 6 | InModuleScope WorkdayApi { 7 | 8 | # Echo Request 9 | Mock Invoke-WorkdayRequest { 10 | Mock_Invoke-WorkdayRequest_Echo @args 11 | } 12 | 13 | It 'Creates the correct XML for the Workday request.' { 14 | $expectedResponse = @' 15 | truetrueOther ID set by Set-WorkdayWorkerOtherId100000000000000000000000000000000 16 | '@ 17 | $response = Remove-WorkdayWorkerOtherId -WorkerId 1 -WorkerType WID -WID '00000000000000000000000000000000' -Debug 18 | $response.Xml.OuterXml | Should BeExactly $expectedResponse 19 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 20 | } 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /source/tests/Set-WorkdayWorkerDocument.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Set-WorkdayWorkerDocument { 6 | InModuleScope WorkdayApi { 7 | 8 | Mock Invoke-WorkdayRequest { 9 | Mock_Invoke-WorkdayRequest_Echo @args 10 | } 11 | 12 | $testFilePath = Join-Path $TestDrive 'TestFile.txt' 13 | Set-Content -Value 'Test File' -Path $testFilePath 14 | 15 | It 'Creates the expected request XML.' { 16 | $expectedResponse = @' 17 | DifferentFileName.txtTest CommentVGVzdCBGaWxlDQo=TestId1text/plain 18 | '@ 19 | $arguments = @{ 20 | WorkerId = 1 21 | WorkerType = 'WID' 22 | Path = $testFilePath 23 | FileName = 'DifferentFileName.txt' 24 | CategoryType = 'WID' 25 | CategoryId = 'TestId' 26 | Comment = 'Test Comment' 27 | } 28 | $response = Set-WorkdayWorkerDocument @arguments 29 | 30 | $response.Xml.OuterXml | Should BeExactly $expectedResponse 31 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 32 | 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /source/tests/Set-WorkdayWorkerEmail.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Set-WorkdayWorkerEmail { 6 | InModuleScope WorkdayApi { 7 | 8 | # Echo Request 9 | Mock Invoke-WorkdayRequest { 10 | Mock_Invoke-WorkdayRequest_Echo @args 11 | } 12 | 13 | It 'Creates the correct XML for the Workday request.' { 14 | $expectedResponse = @' 15 | truetrueEmail set by Set-WorkdayWorkerEmail1{0:yyyy-MM-dd}new@example.comWORK 16 | '@ -f (Get-Date) 17 | $response = Set-WorkdayWorkerEmail -WorkerId 1 -WorkerType WID -Email 'new@example.com' -UsageType WORK -Private -Secondary 18 | $response.Xml.OuterXml | Should BeExactly $expectedResponse 19 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 20 | } 21 | 22 | It 'Throws an exception when an invalid email is supplied.' { 23 | { Set-WorkdayWorkerEmail -WorkerId 1 -WorkEmail BadEmail } | Should Throw 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /source/tests/Set-WorkdayWorkerOtherId.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Set-WorkdayWorkerOtherId { 6 | InModuleScope WorkdayApi { 7 | 8 | # Echo Request 9 | Mock Invoke-WorkdayRequest { 10 | Mock_Invoke-WorkdayRequest_Echo @args 11 | } 12 | 13 | It 'Creates the correct XML for the Workday request.' { 14 | $expectedResponse = @' 15 | truetrueOther ID set by Set-WorkdayWorkerOtherId12Badge_ID2001-01-01T00:00:00.00000002002-02-02T00:00:00.000000000000000000000000000000000000000 16 | '@ 17 | $response = Set-WorkdayWorkerOtherId -WorkerId 1 -WorkerType WID -Type 'Badge_ID' -Id 2 -IssuedDate (Get-Date '1/1/2001') -ExpirationDate (Get-Date '2/2/2002') -WID '00000000000000000000000000000000' 18 | $response.Xml.OuterXml | Should BeExactly $expectedResponse 19 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 20 | } 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /source/tests/Set-WorkdayWorkerPhone.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Set-WorkdayWorkerPhone { 6 | InModuleScope WorkdayApi { 7 | 8 | # Echo Request 9 | Mock Invoke-WorkdayRequest { 10 | Mock_Invoke-WorkdayRequest_Echo @args 11 | } 12 | 13 | Context 'Valid Input' { 14 | $response = Set-WorkdayWorkerPhone -WorkerId 1 -Number 12345678901 -Extension 1234 -Private -Secondary 15 | $x = [xml]$response.Xml 16 | $mcid = $x.Maintain_Contact_Information_for_Person_Event_Request.Maintain_Contact_Information_Data 17 | 18 | It 'References the correct worker.' { 19 | $mcid.Worker_Reference.ID.'#text' | Should BeExactly '1' 20 | } 21 | 22 | It 'Effective_Date' { 23 | $mcid.Effective_Date | Should BeExactly (Get-Date).ToString( 'yyyy-MM-dd' ) 24 | } 25 | 26 | It 'International_Phone_Code' { 27 | $mcid.Worker_Contact_Information_Data.Phone_Data.International_Phone_Code | 28 | Should BeExactly '1' 29 | } 30 | 31 | It 'Correct Area_Code' { 32 | $mcid.Worker_Contact_Information_Data.Phone_Data.Area_Code | 33 | Should BeExactly '234' 34 | } 35 | 36 | It 'Phone_Number' { 37 | $mcid.Worker_Contact_Information_Data.Phone_Data.Phone_Number | 38 | Should BeExactly '567-8901' 39 | } 40 | 41 | It 'Phone_Extension' { 42 | $mcid.Worker_Contact_Information_Data.Phone_Data.Phone_Extension | 43 | Should BeExactly '1234' 44 | } 45 | 46 | It 'Communication_Usage_Type_ID' { 47 | $mcid.Worker_Contact_Information_Data.Phone_Data.Usage_Data.Type_Data.Type_Reference.ID.'#text' | 48 | Should BeExactly 'WORK' 49 | } 50 | 51 | It 'Phone_Device_Type_ID' { 52 | $mcid.Worker_Contact_Information_Data.Phone_Data.Phone_Device_Type_Reference.ID.'#text' | 53 | Should BeExactly 'Landline' 54 | } 55 | 56 | It 'Public' { 57 | $mcid.Worker_Contact_Information_Data.Phone_Data.Usage_Data.Public | 58 | Should BeExactly '0' 59 | } 60 | 61 | It 'Primary' { 62 | $mcid.Worker_Contact_Information_Data.Phone_Data.Usage_Data.Type_Data.Primary | 63 | Should BeExactly '0' 64 | } 65 | 66 | } 67 | 68 | <# 69 | $ $mcid.Worker_Contact_Information_Data.Phone_Data.Usage_Data.Type_Data.Type_Reference.ID 70 | 71 | type #text 72 | ---- ----- 73 | Communication_Usage_Type_ID WORK 74 | 75 | 76 | 77 | $ $mcid.Worker_Contact_Information_Data.Phone_Data.Usage_Data.Type_Data.Type_Reference.ID.'#text' 78 | WORK 79 | #> 80 | Context 'Invalid Input' { 81 | It 'Throws an exception when an invalid phone number is supplied.' { 82 | { Set-WorkdayWorkerPhone -WorkerId 1 -Number BadNumber } | Should Throw 'Invalid number: [BadNumber]' 83 | } 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /source/tests/Set-WorkdayWorkerPhoto.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Set-WorkdayWorkerPhoto { 6 | InModuleScope WorkdayApi { 7 | 8 | Mock Invoke-WorkdayRequest { 9 | Mock_Invoke-WorkdayRequest_Echo @args 10 | } 11 | 12 | $testFilePath = Join-Path $TestDrive 'TestFile.txt' 13 | Set-Content -Value 'Test File' -Path $testFilePath 14 | 15 | It 'Creates the expected request XML.' { 16 | $expectedResponse = @' 17 | 1TestFile.txtVGVzdCBGaWxlDQo= 18 | '@ 19 | $arguments = @{ 20 | WorkerId = 1 21 | WorkerType = 'WID' 22 | Path = $testFilePath 23 | } 24 | $response = Set-WorkdayWorkerPhoto @arguments 25 | 26 | $response.Xml.OuterXml | Should BeExactly $expectedResponse 27 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 28 | 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /source/tests/Set-WorkdayWorkerUserId.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Set-WorkdayWorkerUserId { 6 | InModuleScope WorkdayApi { 7 | 8 | # Echo Request 9 | Mock Invoke-WorkdayRequest { 10 | Mock_Invoke-WorkdayRequest_Echo @args 11 | } 12 | 13 | It 'Creates the correct XML for the Workday request for a Contingent Worker.' { 14 | $expectedResponse = @' 15 | 1new@example.com 16 | '@ -f (Get-Date) 17 | $response = Set-WorkdayWorkerUserId -WorkerId 1 -WorkerType Contingent_Worker_ID -UserId 'new@example.com' 18 | $response.Xml.OuterXml | Should BeExactly $expectedResponse 19 | } 20 | 21 | It 'Creates the correct XML for the Workday request for an Employee.' { 22 | $expectedResponse = @' 23 | 1new@example.com 24 | '@ -f (Get-Date) 25 | $response = Set-WorkdayWorkerUserId -WorkerId 1 -WorkerType Employee_ID -UserId 'new@example.com' 26 | $response.Xml.OuterXml | Should BeExactly $expectedResponse 27 | } 28 | 29 | It 'Throws an exception when a blank UserId is supplied.' { 30 | { Set-WorkdayWorkerUserId -WorkerId 1 -UserId '' } | Should Throw 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /source/tests/Start-WorkdayIntegration.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Start-WorkdayIntegration { 6 | InModuleScope WorkdayApi { 7 | 8 | # Echo Request 9 | Mock Invoke-WorkdayRequest { 10 | Mock_Invoke-WorkdayRequest_ExampleIntegration @args 11 | } 12 | 13 | It 'Calls Invoke-WorkdayRequest and returns the proper responses.' { 14 | $response = Start-WorkdayIntegration -Id TestId 15 | $response.Name | Should BeExactly 'Test Descriptor' 16 | $response.Wid | Should BeExactly '00000000000000000000000000000000' 17 | $response.Message | Should BeExactly 'Started at 4/12/2016 6:22 PM.' 18 | Assert-MockCalled Invoke-WorkdayRequest -Exactly 1 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /source/tests/Update-WorkdayWorkerEmail.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | 4 | Describe Update-WorkdayWorkerEmail { 5 | InModuleScope WorkdayApi { 6 | 7 | Mock Get-WorkdayWorkerEmail { 8 | [pscustomobject][ordered]@{ 9 | WorkerWid = $null 10 | WorkerDescriptor = $null 11 | UsageType = 'WORK' 12 | Email = 'test@example.com' 13 | Primary = $true 14 | Public = $true 15 | } 16 | } 17 | 18 | Mock Set-WorkdayWorkerEmail { 19 | [pscustomobject][ordered]@{ 20 | Success = $true 21 | Message = 'Success' 22 | Xml = 'Success' 23 | } 24 | } 25 | 26 | Context DifferentEmail { 27 | It 'Calls Set-WorkdayWorkerEmail when a new email is presented.' { 28 | $response = Update-WorkdayWorkerEmail -WorkerId 1 -Email 'new@example.com' -UsageType WORK 29 | Assert-MockCalled Set-WorkdayWorkerEmail -Exactly 1 30 | } 31 | 32 | It 'Works when passed a Worker XML object.' { 33 | $worker = Mock_Invoke-WorkdayRequest_ExampleWorker 34 | $response = Update-WorkdayWorkerEmail -WorkerXml $worker.Xml -Email 'new@example.com' 35 | Assert-MockCalled Set-WorkdayWorkerEmail -Exactly 2 36 | } 37 | } 38 | 39 | Context SameEmail { 40 | It 'Skips calling Set-WorkdayWorkerEmail when a duplicate email is presented.' { 41 | $response = Update-WorkdayWorkerEmail -WorkerId 1 -Email 'test@example.com' 42 | Assert-MockCalled Set-WorkdayWorkerEmail -Exactly 0 43 | } 44 | } 45 | 46 | } 47 | } -------------------------------------------------------------------------------- /source/tests/Update-WorkdayWorkerOtherId.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Update-WorkdayWorkerOtherId { 6 | 7 | InModuleScope WorkdayApi { 8 | 9 | Mock Get-WorkdayWorkerOtherId { 10 | param ($WorkerId) 11 | if ($WorkerId -eq 0) { return } 12 | [pscustomobject][ordered]@{ 13 | Type = 'Badge_ID' 14 | Id = 1 15 | Descriptor = $null 16 | Issued_Date = Get-Date '2000-01-01' 17 | Expiration_Date = Get-Date '2001-01-01' 18 | WID = '00000000000000000000000000000000' 19 | } 20 | } 21 | 22 | Mock Set-WorkdayWorkerOtherId { 23 | [pscustomobject][ordered]@{ 24 | Success = $true 25 | Message = 'Success' 26 | Xml = 'Success' 27 | } 28 | } 29 | 30 | Context Different { 31 | 32 | It 'Works when passed a Worker XML object.' { 33 | $worker = Mock_Invoke-WorkdayRequest_ExampleWorker 34 | $response = Update-WorkdayWorkerOtherId -WorkerXml $worker.Xml -Type 'Badge_ID' -Id 2 -IssuedDate '1/1/2000' -ExpirationDate '1/1/2001' 35 | Assert-MockCalled Set-WorkdayWorkerOtherId -Exactly 1 36 | } 37 | 38 | It 'Calls Set-WorkdayWorkerOtherId when BadgeId changes.' { 39 | $response = Update-WorkdayWorkerOtherId -WorkerId 1 -Type 'Badge_ID' -Id 2 -IssuedDate '1/1/2000' -ExpirationDate '1/1/2001' 40 | Assert-MockCalled Set-WorkdayWorkerOtherId -Exactly 2 41 | } 42 | 43 | It 'Calls Set-WorkdayWorkerOtherId when Issued_Date changes.' { 44 | $response = Update-WorkdayWorkerOtherId -WorkerId 1 -Type 'Badge_ID' -Id 1 -IssuedDate (Get-Date) -ExpirationDate '1/1/2001' 45 | Assert-MockCalled Set-WorkdayWorkerOtherId -Exactly 3 46 | } 47 | 48 | It 'Calls Set-WorkdayWorkerOtherId when Expiration_Date changes.' { 49 | $response = Update-WorkdayWorkerOtherId -WorkerId 1 -Type 'Badge_ID' -Id 1 -IssuedDate '1/1/2000' -ExpirationDate (Get-Date) 50 | Assert-MockCalled Set-WorkdayWorkerOtherId -Exactly 4 51 | } 52 | 53 | It 'Calls Set-WorkdayWorkerOtherId when there is a new Badge ID.' { 54 | $response = Update-WorkdayWorkerOtherId -WorkerId 0 -Type 'Badge_ID' -Id 1 -IssuedDate '1/1/2000' -ExpirationDate '1/1/2001' 55 | Assert-MockCalled Set-WorkdayWorkerOtherId -Exactly 5 56 | } 57 | 58 | It 'Should default to the current IssueDate value when a date is not passed.' { 59 | $expected = 'Changed Current [1 valid from 1/1/2000 12:00 AM to 1/1/2001 12:00 AM] Proposed [1 valid from current IssuedDate to 1/1/2003 12:00 AM]' 60 | $response = Update-WorkdayWorkerOtherId -WorkerId 1 -Type 'Badge_ID' -Id 1 -ExpirationDate '1/1/2003' 61 | $response.Message | Should Be $expected 62 | Assert-MockCalled Set-WorkdayWorkerOtherId -Exactly 6 63 | } 64 | 65 | It 'Should default to the current Expiration value when a date is not passed.' { 66 | $expected = 'Changed Current [1 valid from 1/1/2000 12:00 AM to 1/1/2001 12:00 AM] Proposed [1 valid from 1/1/2003 12:00 AM to current ExpirationDate]' 67 | $response = Update-WorkdayWorkerOtherId -WorkerId 1 -Type 'Badge_ID' -Id 1 -IssuedDate '1/1/2003' 68 | $response.Message | Should Be $expected 69 | Assert-MockCalled Set-WorkdayWorkerOtherId -Exactly 7 70 | } 71 | 72 | It 'Throws an exception when an invalid IssueDate is passed.' { 73 | {Update-WorkdayWorkerOtherId -WorkerId 1 -Type 'Badge_ID' -Id 1 -IssuedDate 'bad' -ExpirationDate '1/1/2001'} | Should Throw 74 | } 75 | 76 | It 'Throws an exception when an invalid ExpirationDate is passed.' { 77 | {Update-WorkdayWorkerOtherId -WorkerId 1 -Type 'Badge_ID' -Id 1 -IssuedDate '1/1/2000' -ExpirationDate 'bad'} | Should Throw 78 | } 79 | 80 | } 81 | 82 | Context Same { 83 | 84 | It 'Skips calling Set-WorkdayWorkerOtherId when no changes found.' { 85 | $null = Update-WorkdayWorkerOtherId -WorkerId 1 -Type 'Badge_ID' -Id 1 -IssuedDate '1/1/2000' -ExpirationDate '1/1/2001' 86 | Assert-MockCalled Get-WorkdayWorkerOtherId -Exactly 1 87 | Assert-MockCalled Set-WorkdayWorkerOtherId -Exactly 0 88 | } 89 | 90 | It 'Skips calling Set-WorkdayWorkerOtherId when no changes and no dates passed.' { 91 | $null = Update-WorkdayWorkerOtherId -WorkerId 1 -Type 'Badge_ID' -Id 1 92 | Assert-MockCalled Get-WorkdayWorkerOtherId -Exactly 2 93 | Assert-MockCalled Set-WorkdayWorkerOtherId -Exactly 0 94 | } 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /source/tests/Update-WorkdayWorkerPhone.Tests.ps1: -------------------------------------------------------------------------------- 1 | Get-Module WorkdayApi | Remove-Module -Force 2 | Import-Module "$PsScriptRoot\..\WorkdayApi.psd1" -Force 3 | Import-Module "$PsScriptRoot\Invoke-WorkdayRequestHelper.psm1" -Force -DisableNameChecking 4 | 5 | Describe Update-WorkdayWorkerPhone { 6 | InModuleScope WorkdayApi { 7 | 8 | Mock Get-WorkdayWorkerPhone { 9 | [pscustomobject][ordered]@{ 10 | WorkerWid = $null 11 | WorkerDescriptor = $null 12 | UsageType = 'Work' 13 | DeviceType = 'Landline' 14 | Number = '+1 (517) 123-4567' 15 | Extension = '4321' 16 | Primary = $true 17 | Public = $true 18 | } 19 | } 20 | 21 | Mock Set-WorkdayWorkerPhone { 22 | [pscustomobject][ordered]@{ 23 | Success = $true 24 | Message = 'Success' 25 | Xml = 'Success' 26 | } 27 | } 28 | 29 | Context DifferentNumber { 30 | It 'Calls Set-WorkdayWorkerPhone when a new number is presented.' { 31 | $response = Update-WorkdayWorkerPhone -WorkerId 1 -Number 2 32 | Assert-MockCalled Set-WorkdayWorkerPhone -Exactly 1 33 | } 34 | 35 | It 'Works when passed a Worker XML object.' { 36 | $worker = Mock_Invoke-WorkdayRequest_ExampleWorker 37 | $response = Update-WorkdayWorkerPhone -WorkerXml $worker.Xml -Number 2 38 | Assert-MockCalled Set-WorkdayWorkerPhone -Exactly 2 39 | } 40 | } 41 | 42 | Context SameNumber { 43 | It 'Skips calling Set-WorkdayWorkerPhone when a duplicate number is presented.' { 44 | $response = Update-WorkdayWorkerPhone -WorkerId 1 -Number '15171234567' -Extension '4321' 45 | Assert-MockCalled Get-WorkdayWorkerPhone -Exactly 1 46 | Assert-MockCalled Set-WorkdayWorkerPhone -Exactly 0 47 | } 48 | } 49 | 50 | } 51 | } --------------------------------------------------------------------------------