From 00879327d9b24055e9ed49e1424502997888e871 Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Mon, 6 Mar 2023 17:00:34 -0600 Subject: [PATCH 01/14] README for Teacher Schedules to Calendar Example --- .../README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Sample_Usage_Scripts/Blackbaud SIS Teacher Schedules to Google Calendar CSVs/README.md diff --git a/Sample_Usage_Scripts/Blackbaud SIS Teacher Schedules to Google Calendar CSVs/README.md b/Sample_Usage_Scripts/Blackbaud SIS Teacher Schedules to Google Calendar CSVs/README.md new file mode 100644 index 0000000..fb3121f --- /dev/null +++ b/Sample_Usage_Scripts/Blackbaud SIS Teacher Schedules to Google Calendar CSVs/README.md @@ -0,0 +1,15 @@ +# Blackbaud SIS Teacher Schedules to Google Calendar CSVs + +## Overview +A sample PowerShell script that uses the PowerShell SKYAPI Module to create importable Google Calendar schedules for faculty from the Blackbaud School Envirionment. It outputs CSV files, one for each teacher. Teachers can manually import as needed. Throw them in a shared Google Drive folder or somewhere else for easy access. + +## Prerequisites +- SKYAPI PowerShell Module (https://github.com/Sekers/SKYAPI) +- Create a Blackbaud app registration to enable API access. See the SKYAPI PowerShell Module Wiki for more information. + +## File: 'Create Importable Faculty Google Calendar CSVs.ps1' +The script. Edit the config variables as needed. + +## File: 'Import Teacher Schedule into Google Calendar - Teacher Instructions.docx' +Sample instruction page to give to your faculty as end-users. + From ab03b46730dc893aaf13667c550708e92e341e8b Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Tue, 7 Mar 2023 16:05:34 -0600 Subject: [PATCH 02/14] FIXED LINKS BB BROKE --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3374920..494ee10 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ See [CHANGELOG.md](./CHANGELOG.md) for information on the latest updates, as wel ## Current API Support -This module started out with a focus on working with the Blackbaud SKY API [Education Management School API](https://developer.blackbaud.com/skyapi/bbem/school) but [SKY API endpoints](https://developer.blackbaud.com/skyapi/products) for [Raiser's Edge NXT](https://developer.blackbaud.com/skyapi/products/renxt), [Financial Edge NXT](https://developer.blackbaud.com/skyapi/products/fenxt), [Church Management](https://developer.blackbaud.com/skyapi/products/bbcm), etc. are being added in. It is designed so that additional endpoints can be added in quickly & easily. +This module started out with a focus on working with the Blackbaud SKY API [Education Management School API](https://developer.blackbaud.com/skyapi/bbem/school) but [SKY API endpoints](https://developer.blackbaud.com/skyapi/products) for [Raiser's Edge NXT](https://developer.blackbaud.com/skyapi/renxt), [Financial Edge NXT](https://developer.blackbaud.com/skyapi/fenxt), [Church Management]https://developer.blackbaud.com/skyapi/bbcm), etc. are being added in. It is designed so that additional endpoints can be added in quickly & easily. See the [SKYAPI Wiki](https://github.com/Sekers/SKYAPI/wiki) for a list of the [endpoints currently supported](https://github.com/Sekers/SKYAPI/wiki#api-endpoints). From 445f7482f9fe546ad72fc6f78da239577e23d578 Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Mon, 13 Mar 2023 14:07:49 -0500 Subject: [PATCH 03/14] REMOVED LINKS PARAMETER FROM New-SchoolUserPhone Blackbaud's team found that this endpoint was not actually designed to create that link with another user. They have updated the example and the endpoint documentation to reflect this as well as added a new work item for the team to add a new endpoint to handle the linking functionality. When this endpoint is released it will be announced in the change logs. --- SKYAPI/Functions/New-SchoolUserPhone.ps1 | 39 +------------------ .../@SKYAPI Module/SKYAPI_Examples.ps1 | 2 - 2 files changed, 1 insertion(+), 40 deletions(-) diff --git a/SKYAPI/Functions/New-SchoolUserPhone.ps1 b/SKYAPI/Functions/New-SchoolUserPhone.ps1 index f83da24..5621005 100644 --- a/SKYAPI/Functions/New-SchoolUserPhone.ps1 +++ b/SKYAPI/Functions/New-SchoolUserPhone.ps1 @@ -20,20 +20,6 @@ function New-SchoolUserPhone .PARAMETER type_id Required. The type ID of the specified phone number. The type ID corresponds with the type of phone number (ex. Cell, Work, Home). Use Get-SchoolUserPhoneType to get a list of phone types. - .PARAMETER links - Optional array of PhoneTypeLink objects for linking. Each PSObject should match the PhoneTypeLink Model. - More Info: https://developer.sky.blackbaud.com/docs/services/school/operations/V1UsersByUser_idPhonesPost#PhoneTypeLink - Schema: - "links": [ - { - "id": 0, - "shared": true, - "shared_relationship": "string", - "shared_user": "string", - "type_id": "string", - "user_id": 0 - } - ] .EXAMPLE New-SchoolUserPhone -User_ID 3154032,5942642 -number "(555) 555-5555" -type_id 331 @@ -60,13 +46,7 @@ function New-SchoolUserPhone Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] - [int]$type_id, - - [Parameter( - Position=3, - ValueFromPipeline=$true, - ValueFromPipelineByPropertyName=$true)] - [array]$links # Optional array of PhoneTypeLink objects for linking. + [int]$type_id ) # Set the endpoints @@ -83,23 +63,6 @@ function New-SchoolUserPhone # Remove the $User_ID parameter since we don't pass that on $parameters.Remove('User_ID') | Out-Null - # Build PhoneTypeLink Model - if ($links.Count -ge 1) - { - #TODO Verify PhoneTypeLinks Format (this functionality isn't working yet so I don't know what needs to be done to verify) - foreach ($PhoneTypeLink in $links) - { - # $($PhoneTypeLink | Get-Member -MemberType NoteProperty).count - throw "Sorry. Using SKY API to link phone numbers between users doesn't currently work. Blackbaud is aware of the issue with this endpoint and is looking into it." - } - } - else # No related users to link so create array with one empty object (otherwise the API returns an error). - { - $PhoneTypeLink = [PSCustomObject]@{} - [array]$PhoneTypeLinks = @($PhoneTypeLink) - $parameters.Add('links',$PhoneTypeLinks) - } - # Get the SKY API subscription key $sky_api_config = Get-SKYAPIConfig -ConfigPath $sky_api_config_file_path $sky_api_subscription_key = $sky_api_config.api_subscription_key diff --git a/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 b/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 index 2057a8e..95afcb8 100644 --- a/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 +++ b/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 @@ -334,8 +334,6 @@ <# New-SchoolUserPhone (Use Get-SchoolUserPhoneType to get a list of phone types) - Notes: Linking using the -links parameter doesn't currently work and Blackbaud is looking into the issue with the endpoint. - You can specify multiple user IDs with this function but it will not link them (each user record will have the number added without them sharing it). #> # New-SchoolUserPhone -User_ID 3154032,5942642 -number "(555) 555-5555" -type_id 331 From 60678fbf833a99f820217288052addcdc4466ee3 Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Mon, 13 Mar 2023 14:33:23 -0500 Subject: [PATCH 04/14] NEW ENDPOINT: Get-SchoolUserAddressType --- .../Functions/Get-SchoolUserAddressType.ps1 | 54 +++++++++++++++++++ SKYAPI/SKYAPI.psd1 | 1 + .../@SKYAPI Module/SKYAPI_Examples.ps1 | 5 ++ 3 files changed, 60 insertions(+) create mode 100644 SKYAPI/Functions/Get-SchoolUserAddressType.ps1 diff --git a/SKYAPI/Functions/Get-SchoolUserAddressType.ps1 b/SKYAPI/Functions/Get-SchoolUserAddressType.ps1 new file mode 100644 index 0000000..5fc4a9e --- /dev/null +++ b/SKYAPI/Functions/Get-SchoolUserAddressType.ps1 @@ -0,0 +1,54 @@ +function Get-SchoolUserAddressType +{ + <# + .LINK + https://github.com/Sekers/SKYAPI/wiki + + .LINK + Endpoint: https://developer.sky.blackbaud.com/docs/services/school/operations/V1UsersAddresstypesGet + + .SYNOPSIS + Education Management School API - Returns a collection of address types. + + .DESCRIPTION + Education Management School API - Returns a collection of address types. + Accessible by any authorized user. + + .PARAMETER ReturnRaw + Returns the raw JSON content of the API call. + + .EXAMPLE + Get-SchoolUserAddressType + #> + + [cmdletbinding()] + param( + [Parameter( + Position=0, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [switch]$ReturnRaw + ) + + # Set the endpoints + $endpoint = 'https://api.sky.blackbaud.com/school/v1/users/addresstypes' + + # Set the response field + $ResponseField = "value" + + # Get the SKY API subscription key + $sky_api_config = Get-SKYAPIConfig -ConfigPath $sky_api_config_file_path + $sky_api_subscription_key = $sky_api_config.api_subscription_key + + # Grab the security tokens + $AuthTokensFromFile = Get-SKYAPIAuthTokensFromFile + + if ($ReturnRaw) + { + $response = Get-SKYAPIUnpagedEntity -url $endpoint -api_key $sky_api_subscription_key -authorisation $AuthTokensFromFile -ReturnRaw + return $response + } + + $response = Get-SKYAPIUnpagedEntity -url $endpoint -api_key $sky_api_subscription_key -authorisation $AuthTokensFromFile -response_field $ResponseField + $response +} diff --git a/SKYAPI/SKYAPI.psd1 b/SKYAPI/SKYAPI.psd1 index 746ba6f..c3c8f0a 100644 --- a/SKYAPI/SKYAPI.psd1 +++ b/SKYAPI/SKYAPI.psd1 @@ -108,6 +108,7 @@ FunctionsToExport = @( 'Get-SchoolTerm', 'Get-SchoolTimeZone', 'Get-SchoolUser', + 'Get-SchoolUserAddressType', 'Get-SchoolUserBBIDStatus', 'Get-SchoolUserByRole', 'Get-SchoolUserEducation', diff --git a/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 b/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 index 95afcb8..68f68b8 100644 --- a/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 +++ b/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 @@ -321,6 +321,11 @@ # Update-SchoolUser -User_ID 1757293 -custom_field_one "my data" -email "useremail@domain.edu" -first_name "John" -preferred_name "Jack" # Update-SchoolUser -User_ID 1757293,2878846 -custom_field_one "my data" +<# + Get-SchoolUserAddressType +#> +# Get-SchoolUserAddressType + <# Get-SchoolUserPhoneType #> From f890ab30d22ff4d3ac3496788ac24821f58e0397 Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Mon, 13 Mar 2023 15:39:10 -0500 Subject: [PATCH 05/14] NEW ENDPOINTS: Get-SchoolUserAddress & New-SchoolUserAddress --- SKYAPI/Functions/Get-SchoolUserAddress.ps1 | 69 ++++++ SKYAPI/Functions/New-SchoolUserAddress.ps1 | 202 ++++++++++++++++++ SKYAPI/SKYAPI.psd1 | 2 + .../@SKYAPI Module/SKYAPI_Examples.ps1 | 29 ++- 4 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 SKYAPI/Functions/Get-SchoolUserAddress.ps1 create mode 100644 SKYAPI/Functions/New-SchoolUserAddress.ps1 diff --git a/SKYAPI/Functions/Get-SchoolUserAddress.ps1 b/SKYAPI/Functions/Get-SchoolUserAddress.ps1 new file mode 100644 index 0000000..c068710 --- /dev/null +++ b/SKYAPI/Functions/Get-SchoolUserAddress.ps1 @@ -0,0 +1,69 @@ +function Get-SchoolUserAddress +{ + <# + .LINK + https://github.com/Sekers/SKYAPI/wiki + + .LINK + Endpoint: https://developer.sky.blackbaud.com/docs/services/school/operations/V1UsersByUser_idAddressesGet + + .SYNOPSIS + Education Management School API - Returns a collection addresses for one or more user IDs. + + .DESCRIPTION + Education Management School API - Returns a collection addresses for one or more user IDs. + + .PARAMETER User_ID + Required. Array of user IDs for each user you want addresses of returned. + .PARAMETER ReturnRaw + Returns the raw JSON content of the API call. + + .EXAMPLE + Get-SchoolUserAddress -User_ID 3154032,5942642 + + #> + + [cmdletbinding()] + Param( + [Parameter( + Position=0, + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [int[]]$User_ID, # Array as we loop through submitted IDs + + [Parameter( + Position=1, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [switch]$ReturnRaw + ) + + # Get the SKY API subscription key + $sky_api_config = Get-SKYAPIConfig -ConfigPath $sky_api_config_file_path + $sky_api_subscription_key = $sky_api_config.api_subscription_key + + # Grab the security tokens + $AuthTokensFromFile = Get-SKYAPIAuthTokensFromFile + + # Set the endpoints + $endpoint = 'https://api.sky.blackbaud.com/school/v1/users/' + $endUrl = '/addresses' + + # Set the response field + $ResponseField = "value" + + # Get data for one or more IDs + foreach ($uid in $User_ID) + { + if ($ReturnRaw) + { + $response = Get-SKYAPIUnpagedEntity -uid $uid -url $endpoint -endUrl $endUrl -api_key $sky_api_subscription_key -authorisation $AuthTokensFromFile -ReturnRaw + $response + continue + } + + $response = Get-SKYAPIUnpagedEntity -uid $uid -url $endpoint -endUrl $endUrl -api_key $sky_api_subscription_key -authorisation $AuthTokensFromFile -response_field $ResponseField + $response + } +} diff --git a/SKYAPI/Functions/New-SchoolUserAddress.ps1 b/SKYAPI/Functions/New-SchoolUserAddress.ps1 new file mode 100644 index 0000000..ac0fbb4 --- /dev/null +++ b/SKYAPI/Functions/New-SchoolUserAddress.ps1 @@ -0,0 +1,202 @@ +function New-SchoolUserAddress +{ + <# + .LINK + https://github.com/Sekers/SKYAPI/wiki + + .LINK + Endpoint: https://developer.sky.blackbaud.com/docs/services/school/operations/V1UsersByUser_idAddressesPost + + .SYNOPSIS + Education Management School API - Creates a new address record for the specified user IDs and returns the ID of the address created. + + .DESCRIPTION + Education Management School API - Creates a new address record for the specified user IDs and returns the ID of the address created. + + .PARAMETER User_ID, + Required. Array of the user IDs. + .PARAMETER number + Required. The address. + .PARAMETER type_id + Required. The type ID of the specified address. The type ID corresponds with the type of address (ex. Business/College, Home, Summer). + Use Get-SchoolUserAddressType to get a list of address types. + .PARAMETER country + Country full name (e.g., United States). Must be a full country name from the school's list of countries. + .PARAMETER line_one + Address Line 1 (e.g., 123 Main Street). + .PARAMETER line_two + Address Line 2 (e.g., Suite 100). + .PARAMETER line_three + Address Line 3. + .PARAMETER city + City (e.g., Charelston). + .PARAMETER state + State 2-letter abbreviation (e.g., SC) or full name. + .PARAMETER postal_code + Postal code. + .PARAMETER province + Province. + .PARAMETER region + Region. + .PARAMETER mailing_address + Set to true to set this address as a mailing address. A user can have multiple mailing addresses. + .PARAMETER primary + Set to true to make this the primary address. A user can have only one primary address. + + .EXAMPLE + New-SchoolUserAddress -User_ID 3156271 -type_id 1005 -country 'United States' -line_one '129 Huntington Drive' + .EXAMPLE + $params = @{ + 'User_ID' = 3156271 + 'type_id' = 1005 + 'country' = "United States" + 'line_one' = "129 Huntington Drive" + 'line_two' = "Unit 406" + 'line_three' = "Lower Level" + 'city' = "Chicago" + 'state' = "IL" + 'postal_code' = "60601" + 'province' = "Land of Provinces" + 'region' = "North Central" + 'mailing_address' = $true + 'primary' = $true + } + New-SchoolUserAddress @params + #> + + [cmdletbinding()] + Param( + [Parameter( + Position=0, + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [int[]]$User_ID, # Array as we loop through submitted IDs + + [Parameter( + Position=1, + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [int]$type_id, + + [Parameter( + Position=2, + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$country, + + [Parameter( + Position=3, + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$line_one, + + [Parameter( + Position=4, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$line_two, + + [Parameter( + Position=5, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$line_three, + + [Parameter( + Position=6, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$city, + + [Parameter( + Position=7, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$state, + + [Parameter( + Position=8, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$postal_code, + + [Parameter( + Position=9, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$province, + + [Parameter( + Position=10, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$region, + + [Parameter( + Position=11, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [bool]$mailing_address, + + [Parameter( + Position=12, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [bool]$primary + ) + + # Set the endpoints + $endpoint = 'https://api.sky.blackbaud.com/school/v1/users/' + $endUrl = '/addresses' + + # Set the parameters + $parameters = @{} + foreach ($parameter in $PSBoundParameters.GetEnumerator()) + { + $parameters.Add($parameter.Key,$parameter.Value) + } + + # Remove the $User_ID parameter since we don't pass that on + $parameters.Remove('User_ID') | Out-Null + + # Get the SKY API subscription key + $sky_api_config = Get-SKYAPIConfig -ConfigPath $sky_api_config_file_path + $sky_api_subscription_key = $sky_api_config.api_subscription_key + + # Grab the security tokens + $AuthTokensFromFile = Get-SKYAPIAuthTokensFromFile + + # Verify the address type doesn't already exists for any of the users. + foreach ($uid in $User_ID) + { + $UserAddresses = Get-SchoolUserAddress -User_ID $uid + if ($UserAddresses.type_id -contains $type_id) + { + throw "User $uid already has address of type id $type_id" + } + } + + # Set data for one or more IDs + foreach ($uid in $User_ID) + { + # Clear out old user_id parameter and add in new. NO IDEA WHY THEY NEED THIS IN THE REQUEST BODY AS IT'S PART OF THE ENDPOINT URL. + $parameters.Remove('user_id') | Out-Null + $parameters.Add('user_id',$uid) + + $response = Submit-SKYAPIEntity -uid $uid -url $endpoint -end $endUrl -api_key $sky_api_subscription_key -authorisation $AuthTokensFromFile -params $parameters + $response + } +} diff --git a/SKYAPI/SKYAPI.psd1 b/SKYAPI/SKYAPI.psd1 index c3c8f0a..e20a2f4 100644 --- a/SKYAPI/SKYAPI.psd1 +++ b/SKYAPI/SKYAPI.psd1 @@ -108,6 +108,7 @@ FunctionsToExport = @( 'Get-SchoolTerm', 'Get-SchoolTimeZone', 'Get-SchoolUser', + 'Get-SchoolUserAddress', 'Get-SchoolUserAddressType', 'Get-SchoolUserBBIDStatus', 'Get-SchoolUserByRole', @@ -124,6 +125,7 @@ FunctionsToExport = @( 'Get-SchoolVenueBuilding', 'Get-SchoolYear', 'New-SchoolEventCategory', + 'New-SchoolUserAddress', 'New-SchoolUserOccupation', 'New-SchoolUserPhone', 'Remove-SchoolUserRelationship', diff --git a/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 b/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 index 68f68b8..fc48072 100644 --- a/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 +++ b/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 @@ -326,6 +326,33 @@ #> # Get-SchoolUserAddressType +<# + Get-SchoolUserAddress +#> +# Get-SchoolUserAddress -User_ID 3154032,5942642 + +<# + New-SchoolUserAddress + (Use Get-SchoolUserAddressType to get a list of address types) +#> +# New-SchoolUserAddress -User_ID 3156271 -type_id 1005 -country 'United States' -line_one '129 Huntington Drive' +# $params = @{ +# 'User_ID' = 3156271 +# 'type_id' = 1005 +# 'country' = "United States" +# 'line_one' = "129 Huntington Drive" +# 'line_two' = "Unit 406" +# 'line_three' = "Lower Level" +# 'city' = "Chicago" +# 'state' = "IL" +# 'postal_code' = "60601" +# 'province' = "Land of Provinces" +# 'region' = "North Central" +# 'mailing_address' = $true +# 'primary' = $true +# } +# New-SchoolUserAddress @params + <# Get-SchoolUserPhoneType #> @@ -347,7 +374,7 @@ #> # New-SchoolUserOccupation -User_ID 3156271, 3294459 -business_name "Don's Auto" -job_title "Director of Shiny Things" -current $true # $params = @{ -# '-User_ID' = 3156271 +# 'User_ID' = 3156271 # 'business_name' = "Don's Auto" # 'job_title' = "Director of Shiny Things" # 'business_url' = "https://donsauto.com" From 396119620f4f708b3366cb89cd71bed52d411918 Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Mon, 13 Mar 2023 15:39:43 -0500 Subject: [PATCH 06/14] MINOR TYPO IN CMDLET EXAMPLE --- SKYAPI/Functions/New-SchoolUserOccupation.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SKYAPI/Functions/New-SchoolUserOccupation.ps1 b/SKYAPI/Functions/New-SchoolUserOccupation.ps1 index a1bc490..4432698 100644 --- a/SKYAPI/Functions/New-SchoolUserOccupation.ps1 +++ b/SKYAPI/Functions/New-SchoolUserOccupation.ps1 @@ -51,7 +51,7 @@ function New-SchoolUserOccupation New-SchoolUserOccupation -User_ID 3156271, 3294459 -business_name "Don's Auto" -job_title "Director of Shiny Things" -current $true .EXAMPLE $params = @{ - '-User_ID' = 3156271 + 'User_ID' = 3156271 'business_name' = "Don's Auto" 'job_title' = "Director of Shiny Things" 'business_url' = "https://donsauto.com" From 5d3db5c4336ddae35b77105ff7fe8611fd3f6cc1 Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Mon, 13 Mar 2023 15:47:19 -0500 Subject: [PATCH 07/14] MINOR BUILT-IN HELP CORRECTIONS --- SKYAPI/Functions/New-SchoolUserAddress.ps1 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/SKYAPI/Functions/New-SchoolUserAddress.ps1 b/SKYAPI/Functions/New-SchoolUserAddress.ps1 index ac0fbb4..6dde433 100644 --- a/SKYAPI/Functions/New-SchoolUserAddress.ps1 +++ b/SKYAPI/Functions/New-SchoolUserAddress.ps1 @@ -15,15 +15,13 @@ function New-SchoolUserAddress .PARAMETER User_ID, Required. Array of the user IDs. - .PARAMETER number - Required. The address. .PARAMETER type_id Required. The type ID of the specified address. The type ID corresponds with the type of address (ex. Business/College, Home, Summer). Use Get-SchoolUserAddressType to get a list of address types. .PARAMETER country - Country full name (e.g., United States). Must be a full country name from the school's list of countries. + Required. Country full name (e.g., United States). Must be a full country name from the school's list of countries. .PARAMETER line_one - Address Line 1 (e.g., 123 Main Street). + Required. Address Line 1 (e.g., 123 Main Street). .PARAMETER line_two Address Line 2 (e.g., Suite 100). .PARAMETER line_three From e339de9368eefb12453127d18ca92b0b9b8c137b Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Mon, 13 Mar 2023 16:09:02 -0500 Subject: [PATCH 08/14] Minor address state/province clarification --- SKYAPI/Functions/New-SchoolUserAddress.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SKYAPI/Functions/New-SchoolUserAddress.ps1 b/SKYAPI/Functions/New-SchoolUserAddress.ps1 index 6dde433..2803a87 100644 --- a/SKYAPI/Functions/New-SchoolUserAddress.ps1 +++ b/SKYAPI/Functions/New-SchoolUserAddress.ps1 @@ -29,11 +29,11 @@ function New-SchoolUserAddress .PARAMETER city City (e.g., Charelston). .PARAMETER state - State 2-letter abbreviation (e.g., SC) or full name. + State 2-letter abbreviation (e.g., SC) or full name. Available only with country choices that use states. .PARAMETER postal_code Postal code. .PARAMETER province - Province. + Province. Available only with country choices that use provinces. .PARAMETER region Region. .PARAMETER mailing_address From bde337068a17e0dcdcde60f55c04d6e991c1d5ff Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Mon, 13 Mar 2023 16:12:32 -0500 Subject: [PATCH 09/14] UPDATED PROVINCE ADDRESS EXAMPLES --- SKYAPI/Functions/New-SchoolUserAddress.ps1 | 2 +- Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SKYAPI/Functions/New-SchoolUserAddress.ps1 b/SKYAPI/Functions/New-SchoolUserAddress.ps1 index 2803a87..53e1a60 100644 --- a/SKYAPI/Functions/New-SchoolUserAddress.ps1 +++ b/SKYAPI/Functions/New-SchoolUserAddress.ps1 @@ -54,7 +54,7 @@ function New-SchoolUserAddress 'city' = "Chicago" 'state' = "IL" 'postal_code' = "60601" - 'province' = "Land of Provinces" + 'province' = "Angus" 'region' = "North Central" 'mailing_address' = $true 'primary' = $true diff --git a/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 b/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 index fc48072..0703d64 100644 --- a/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 +++ b/Sample_Usage_Scripts/@SKYAPI Module/SKYAPI_Examples.ps1 @@ -346,7 +346,7 @@ # 'city' = "Chicago" # 'state' = "IL" # 'postal_code' = "60601" -# 'province' = "Land of Provinces" +# 'province' = "Angus" # 'region' = "North Central" # 'mailing_address' = $true # 'primary' = $true From 4974336ef16a3c4407efc3e798481075812e1127 Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Tue, 21 Mar 2023 09:53:40 -0500 Subject: [PATCH 10/14] RESOLVE DST ISSUE WITH Get-SchoolScheduleMeeting The timezone returned by Blackbaud was previously only being checked against the list of timezone IDs on the system. We also need to check it against the Standard Name and Daylight Name. --- .../Functions/Get-SchoolScheduleMeeting.ps1 | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 b/SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 index e8b9451..4c6d5f8 100644 --- a/SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 +++ b/SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 @@ -146,8 +146,17 @@ function Get-SchoolScheduleMeeting # Remove the School Time Zone parameter since we don't pass it on to the API. $parameters.Remove('SchoolTimeZoneId') | Out-Null - # Convert SchoolTimeZone to TimeZoneInfo object. + # Convert SchoolTimeZone to TimeZoneInfo object. Check match for ID, then StandardName, then DaylightName. $SchoolTimeZone = Get-TimeZone -ListAvailable | Where-Object -Property Id -EQ $SchoolTimeZoneId + if ([string]::IsNullOrEmpty($SchoolTimeZone)) + { + $SchoolTimeZone = Get-TimeZone -ListAvailable | Where-Object -Property StandardName -EQ $SchoolTimeZoneId + } + $SchoolTimeZone = Get-TimeZone -ListAvailable | Where-Object -Property Id -EQ $SchoolTimeZoneId + if ([string]::IsNullOrEmpty($SchoolTimeZone)) + { + $SchoolTimeZone = Get-TimeZone -ListAvailable | Where-Object -Property DaylightName -EQ $SchoolTimeZoneId + } # Get the SKY API subscription key $sky_api_config = Get-SKYAPIConfig -ConfigPath $sky_api_config_file_path @@ -241,7 +250,16 @@ function Get-SchoolScheduleMeeting $start_time = ($meeting.start_time -split "T")[1] $start_time = ($start_time -split "-")[0] $start_time = [System.String]::Concat($meeting_date,"T",$start_time) - $start_time = ([System.TimeZoneInfo]::ConvertTimeToUtc($start_time, $SchoolTimeZone)) # Convert to UTC, specifying the time zone. + + try + { + $start_time = ([System.TimeZoneInfo]::ConvertTimeToUtc($start_time, $SchoolTimeZone)) # Convert to UTC, specifying the time zone. + } + catch + { + write-host "Start Time: $start_time" + } + $end_time = (($meeting.end_time) -split "T")[1] $end_time = ($end_time -split "-")[0] From 44bc1082874015aefea8eb61661466f5974476a6 Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Tue, 21 Mar 2023 09:56:32 -0500 Subject: [PATCH 11/14] REMOVE ACCIDENTALLY LEFT IN DEBUG CODE --- SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 b/SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 index 4c6d5f8..dd4b674 100644 --- a/SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 +++ b/SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 @@ -250,16 +250,7 @@ function Get-SchoolScheduleMeeting $start_time = ($meeting.start_time -split "T")[1] $start_time = ($start_time -split "-")[0] $start_time = [System.String]::Concat($meeting_date,"T",$start_time) - - try - { - $start_time = ([System.TimeZoneInfo]::ConvertTimeToUtc($start_time, $SchoolTimeZone)) # Convert to UTC, specifying the time zone. - } - catch - { - write-host "Start Time: $start_time" - } - + $start_time = ([System.TimeZoneInfo]::ConvertTimeToUtc($start_time, $SchoolTimeZone)) # Convert to UTC, specifying the time zone. $end_time = (($meeting.end_time) -split "T")[1] $end_time = ($end_time -split "-")[0] From d1cbd88114d7e956be31841916582eb1d899e638 Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Tue, 21 Mar 2023 09:58:34 -0500 Subject: [PATCH 12/14] REMOVE EXTRA COPIED LINE --- SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 b/SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 index dd4b674..1b35f6a 100644 --- a/SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 +++ b/SKYAPI/Functions/Get-SchoolScheduleMeeting.ps1 @@ -152,7 +152,6 @@ function Get-SchoolScheduleMeeting { $SchoolTimeZone = Get-TimeZone -ListAvailable | Where-Object -Property StandardName -EQ $SchoolTimeZoneId } - $SchoolTimeZone = Get-TimeZone -ListAvailable | Where-Object -Property Id -EQ $SchoolTimeZoneId if ([string]::IsNullOrEmpty($SchoolTimeZone)) { $SchoolTimeZone = Get-TimeZone -ListAvailable | Where-Object -Property DaylightName -EQ $SchoolTimeZoneId From 4c8d55802828c68c1ece646b99a24d2db1884328 Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Tue, 21 Mar 2023 10:16:09 -0500 Subject: [PATCH 13/14] UPDATES TO CHANGELOG & MANIFEST FOR RELEASE 0.3.10 --- CHANGELOG.md | 20 ++++++++++++++++++++ SKYAPI/SKYAPI.psd1 | 5 +++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f47621..4500e91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog for SKYAPI PowerShell Module +## [0.3.10](https://github.com/Sekers/SKYAPI/tree/0.3.10) - (2023-03-21) + +### Fixes + +- Resolved bug where Get-SchoolScheduleMeeting returned an error after DST begins in timezones that practice advancing clocks during warmer months. + +### Features + +- New Endpoint: [Get-SchoolUserAddressType](https://developer.sky.blackbaud.com/docs/services/school/operations/V1UsersAddresstypesGet) +- New Endpoint: [Get-SchoolUserAddress](https://developer.sky.blackbaud.com/docs/services/school/operations/V1UsersByUser_idAddressesGet) +- New Endpoint: [New-SchoolUserAddress](https://developer.sky.blackbaud.com/docs/services/school/operations/V1UsersByUser_idAddressesPost) + +### Other +- Updated links in README to Blackbaud API documentation as the documentation website had slightly changed structure. +- A few minor example and built-in help updates, clarifications, and typo fixes. +- Removed the 'links' parameter from New-SchoolUserPhone as Blackbaud never actually implemented this feature in the endpoint and updated their documentation. See the [February 28, 2023 Education Management API changelog](https://developer.blackbaud.com/skyapi/support/changelog/bbem) for further information. + +Author: [**@Sekers**](https://github.com/Sekers) + +--- ## [0.3.9](https://github.com/Sekers/SKYAPI/tree/0.3.9) - (2023-03-06) ### Features diff --git a/SKYAPI/SKYAPI.psd1 b/SKYAPI/SKYAPI.psd1 index e20a2f4..1f43789 100644 --- a/SKYAPI/SKYAPI.psd1 +++ b/SKYAPI/SKYAPI.psd1 @@ -12,7 +12,7 @@ RootModule = 'SKYAPI.psm1' # Version number of this module. -ModuleVersion = '0.3.9' +ModuleVersion = '0.3.10' # Supported PSEditions CompatiblePSEditions = @('Desktop','Core') @@ -130,7 +130,8 @@ FunctionsToExport = @( 'New-SchoolUserPhone', 'Remove-SchoolUserRelationship', 'Set-SchoolUserRelationship', - 'Update-SchoolUser' + 'Update-SchoolUser', + 'Update-SchoolUserAddress' ) # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. From 8dca3e73fbcba5e2436e14908da4a619acb4b87c Mon Sep 17 00:00:00 2001 From: Sekers <46898253+Sekers@users.noreply.github.com> Date: Tue, 21 Mar 2023 10:19:06 -0500 Subject: [PATCH 14/14] PRELIMINARY CODE FOR Update-SchoolUserAddress --- SKYAPI/Functions/Update-SchoolUserAddress.ps1 | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 SKYAPI/Functions/Update-SchoolUserAddress.ps1 diff --git a/SKYAPI/Functions/Update-SchoolUserAddress.ps1 b/SKYAPI/Functions/Update-SchoolUserAddress.ps1 new file mode 100644 index 0000000..3e0efb9 --- /dev/null +++ b/SKYAPI/Functions/Update-SchoolUserAddress.ps1 @@ -0,0 +1,193 @@ +function Update-SchoolUserAddress +{ + <# + .LINK + https://github.com/Sekers/SKYAPI/wiki + + .LINK + Endpoint: https://developer.sky.blackbaud.com/docs/services/school/operations/V1UsersByUser_idAddressesByAddress_idPatch + + .SYNOPSIS + Education Management School API - Updates the address record of a user. Returns the ID of the address just updated upon success. + + .DESCRIPTION + Education Management School API - pdates the address record of a user. Returns the ID of the address just updated upon success. + Requires at least one of the following roles in the Education Management system: + - SKY API Data Sync + + .PARAMETER user_id + Required. User ID for the user you want to update the address of. + .PARAMETER address_id + Required. The ID of the address to be updated. + .PARAMETER type_id + The type ID of the specified address. The type ID corresponds with the type of address (ex. Business/College, Home, Summer). + Use Get-SchoolUserAddressType to get a list of address types. + .PARAMETER country + Country full name (e.g., United States). Must be a full country name from the school's list of countries. + .PARAMETER line_one + Address Line 1 (e.g., 123 Main Street). + .PARAMETER line_two + Address Line 2 (e.g., Suite 100). + .PARAMETER line_three + Address Line 3. + .PARAMETER city + City (e.g., Charelston). + .PARAMETER state + State 2-letter abbreviation (e.g., SC) or full name. Available only with country choices that use states. + .PARAMETER postal_code + Postal code. + .PARAMETER province + Province. Available only with country choices that use provinces. + .PARAMETER region + Region. + .PARAMETER mailing_address + Set to true to set this address as a mailing address. A user can have multiple mailing addresses. + .PARAMETER primary + Set to true to make this the primary address. A user can have only one primary address. + + + + + + + .EXAMPLE + Update-SchoolUser -User_ID 1757293 -custom_field_one "my data" -email "useremail@domain.edu" -first_name "John" -preferred_name "Jack" + .EXAMPLE + Update-SchoolUser -User_ID 1757293,2878846 -custom_field_one "my data" + #> + + [cmdletbinding()] + Param( + [Parameter( + Position=0, + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [int]$user_id, + + [Parameter( + Position=1, + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [int]$address_id, + + [Parameter( + Position=2, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [int]$type_id, + + [Parameter( + Position=3, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$country, + + [Parameter( + Position=4, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$line_one, + + [Parameter( + Position=5, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$line_two, + + [Parameter( + Position=6, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$line_three, + + [Parameter( + Position=7, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$city, + + [Parameter( + Position=8, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$state, + + [Parameter( + Position=9, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$postal_code, + + [Parameter( + Position=10, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$province, + + [Parameter( + Position=11, + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [string]$region + ) + + throw "Sorry, the function for this endpoint is not currently available. It will be made available in a future release." + + # Set the endpoints + $endpoint = 'https://api.sky.blackbaud.com/school/v1/users/' + $endUrl = "/addresses/$($address_id)" + + # Set the parameters + $parameters = @{} + foreach ($parameter in $PSBoundParameters.GetEnumerator()) + { + $parameters.Add($parameter.Key,$parameter.Value) + } + + # Remove the Address ID parameter since we don't pass it on this way. + $parameters.Remove('address_id') | Out-Null + + + + $parameters.Remove('user_id') | Out-Null + + # # Add the Address ID in the way the endpoint wants. + # $parameters.Add('id',$address_id) + + # Build AddressTypeLink Model + # No related users to link so create array with one empty object (otherwise the API returns an error). + + # $AddressTypeLink = [PSCustomObject]@{} + # [array]$AddressTypeLinks = @($AddressTypeLink) + # $parameters.Add('links',$AddressTypeLinks) + + + # Get the SKY API subscription key + $sky_api_config = Get-SKYAPIConfig -ConfigPath $sky_api_config_file_path + $sky_api_subscription_key = $sky_api_config.api_subscription_key + + # Grab the security tokens + $AuthTokensFromFile = Get-SKYAPIAuthTokensFromFile + + # Set data for one or more IDs + + # DO I REALLY NEED TO DO THIS? WHY DID I DO IT FOR THE OTHER UPDATE? THE FOREACH? + [hashtable]$uid_parameters = $parameters.Clone() + $uid_parameters.Add('id',$address_id) + + + $response = Update-SKYAPIEntity -url $endpoint -uid $user_id -endUrl $endUrl -api_key $sky_api_subscription_key -authorisation $AuthTokensFromFile -params $uid_parameters + $response +}