From 43996eba097f618ce1d50a3c48ec4b48e5c6f4d2 Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Thu, 8 Nov 2018 14:26:25 -0600 Subject: [PATCH] v2.18.1 - added in fixes for #87, #111, and #53 ## 2.18.1 * [Issue #87](https://github.com/scrthq/PSGSuite/issues/87) * Added: Additional scopes during Service creation for `Get-GSCourseParticipant` and `Get-GSClassroomUserProfile` to enable pulling of full user profile information. - _Thanks, [@jdstanberry](https://github.com/jdstanberry)!_ * [Issue #111](https://github.com/scrthq/PSGSuite/issues/111) * Added: `DisableReminder` switch parameter to `New-GSCalendarEvent` and `Update-GSCalendarEvent` to remove Reminder inheritance from the calendar the event is on as well as any Reminder overload definitions. * [Issue #53](https://github.com/scrthq/PSGSuite/issues/53) * Updated: `Get-GSContactList` and `Remove-GSContact` Token retrieval and overall cleanup * Various/Other * Updated: `Get-GSToken` to align parameters more with `New-GoogleService` --- CHANGELOG.md | 122 +++++++++-------- PSGSuite/PSGSuite.psd1 | 2 +- .../Public/Authentication/Get-GSToken.ps1 | 15 ++- .../Public/Calendar/New-GSCalendarEvent.ps1 | 126 +++++++++-------- .../Calendar/Update-GSCalendarEvent.ps1 | 127 ++++++++++-------- .../Classroom/Get-GSClassroomUserProfile.ps1 | 6 +- .../Classroom/Get-GSCourseParticipant.ps1 | 6 +- .../Public/Contacts/Get-GSContactList.ps1 | 104 +++++++------- PSGSuite/Public/Contacts/Remove-GSContact.ps1 | 77 +++++------ README.md | 11 ++ 10 files changed, 324 insertions(+), 272 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48855b74..739add2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,64 +1,76 @@ # Changelog * [Changelog](#changelog) - * [2.18.0](#2180) - * [2.17.2](#2172) - * [2.17.1](#2171) - * [2.17.0](#2170) - * [2.16.1](#2161) - * [2.16.0](#2160) - * [2.15.4](#2154) - * [2.15.3](#2153) - * [2.15.2](#2152) - * [2.15.1](#2151) - * [2.15.0](#2150) - * [2.14.1](#2141) - * [2.14.0](#2140) - * [2.13.2](#2132) - * [2.13.1](#2131) - * [2.13.0](#2130) - * [2.12.1](#2121) - * [2.12.0](#2120) - * [2.11.0](#2110) - * [2.10.2](#2102) - * [2.10.1](#2101) - * [2.10.0](#2100) - * [2.9.0](#290) - * [2.8.1](#281) - * [2.8.0](#280) - * [2.7.2](#272) - * [2.7.1](#271) - * [2.7.0](#270) - * [2.6.3](#263) - * [2.6.2](#262) - * [2.6.1](#261) - * [2.6.0](#260) - * [2.5.4](#254) - * [2.5.3](#253) - * [2.5.2](#252) - * [2.5.1](#251) - * [2.5.0](#250) - * [2.4.0](#240) - * [2.3.0](#230) - * [2.2.1](#221) - * [2.2.0](#220) - * [2.1.5](#215) - * [2.1.3 / 2.1.4](#213--214) - * [2.1.2](#212) - * [2.1.1](#211) - * [2.1.0](#210) - * [2.0.3](#203) - * [2.0.2](#202) - * [2.0.1](#201) - * [2.0.0](#200) - * [New Functionality](#new-functionality) - * [Breaking Changes in 2.0.0](#breaking-changes-in-200) - * [Gmail Delegation Management Removed](#gmail-delegation-management-removed) - * [Functions Removed](#functions-removed) - * [Functions Aliased](#functions-aliased) + * [2.18.1](#2181) + * [2.18.0](#2180) + * [2.17.2](#2172) + * [2.17.1](#2171) + * [2.17.0](#2170) + * [2.16.1](#2161) + * [2.16.0](#2160) + * [2.15.4](#2154) + * [2.15.3](#2153) + * [2.15.2](#2152) + * [2.15.1](#2151) + * [2.15.0](#2150) + * [2.14.1](#2141) + * [2.14.0](#2140) + * [2.13.2](#2132) + * [2.13.1](#2131) + * [2.13.0](#2130) + * [2.12.1](#2121) + * [2.12.0](#2120) + * [2.11.0](#2110) + * [2.10.2](#2102) + * [2.10.1](#2101) + * [2.10.0](#2100) + * [2.9.0](#290) + * [2.8.1](#281) + * [2.8.0](#280) + * [2.7.2](#272) + * [2.7.1](#271) + * [2.7.0](#270) + * [2.6.3](#263) + * [2.6.2](#262) + * [2.6.1](#261) + * [2.6.0](#260) + * [2.5.4](#254) + * [2.5.3](#253) + * [2.5.2](#252) + * [2.5.1](#251) + * [2.5.0](#250) + * [2.4.0](#240) + * [2.3.0](#230) + * [2.2.1](#221) + * [2.2.0](#220) + * [2.1.5](#215) + * [2.1.3 / 2.1.4](#213--214) + * [2.1.2](#212) + * [2.1.1](#211) + * [2.1.0](#210) + * [2.0.3](#203) + * [2.0.2](#202) + * [2.0.1](#201) + * [2.0.0](#200) + * [New Functionality](#new-functionality) + * [Breaking Changes in 2.0.0](#breaking-changes-in-200) + * [Gmail Delegation Management Removed](#gmail-delegation-management-removed) + * [Functions Removed](#functions-removed) + * [Functions Aliased](#functions-aliased) *** +## 2.18.1 + +* [Issue #87](https://github.com/scrthq/PSGSuite/issues/87) + * Added: Additional scopes during Service creation for `Get-GSCourseParticipant` and `Get-GSClassroomUserProfile` to enable pulling of full user profile information. - _Thanks, [@jdstanberry](https://github.com/jdstanberry)!_ +* [Issue #111](https://github.com/scrthq/PSGSuite/issues/111) + * Added: `DisableReminder` switch parameter to `New-GSCalendarEvent` and `Update-GSCalendarEvent` to remove Reminder inheritance from the calendar the event is on as well as any Reminder overload definitions. +* [Issue #53](https://github.com/scrthq/PSGSuite/issues/53) + * Updated: `Get-GSContactList` and `Remove-GSContact` Token retrieval and overall cleanup +* Various/Other + * Updated: `Get-GSToken` to align parameters more with `New-GoogleService` + ## 2.18.0 * [Issue #87](https://github.com/scrthq/PSGSuite/issues/87) diff --git a/PSGSuite/PSGSuite.psd1 b/PSGSuite/PSGSuite.psd1 index 35310a3d..042b5ef2 100644 --- a/PSGSuite/PSGSuite.psd1 +++ b/PSGSuite/PSGSuite.psd1 @@ -12,7 +12,7 @@ RootModule = 'PSGSuite.psm1' # Version number of this module. - ModuleVersion = '2.18.0' + ModuleVersion = '2.18.1' # ID used to uniquely identify this module GUID = '9d751152-e83e-40bb-a6db-4c329092aaec' diff --git a/PSGSuite/Public/Authentication/Get-GSToken.ps1 b/PSGSuite/Public/Authentication/Get-GSToken.ps1 index 388a20b3..20a24da9 100644 --- a/PSGSuite/Public/Authentication/Get-GSToken.ps1 +++ b/PSGSuite/Public/Authentication/Get-GSToken.ps1 @@ -1,17 +1,22 @@ function Get-GSToken { <# .Synopsis - Gets a Service Account Access Token from Google Apps + Requests an Access Token for REST API authentication. Defaults to 3600 seconds token expiration time. + .DESCRIPTION - Requests Access Token using Service Account and P12 key file, returns the token directly. Defaults to 3600 seconds token expiration time. + Requests an Access Token for REST API authentication. Defaults to 3600 seconds token expiration time. + .EXAMPLE - $token = Get-GSToken -P12KeyPath "C:\PSGoogle.p12" -Scopes "https://www.googleapis.com/auth/admin.directory.user" -AppEmail "psg@nf.iam.gserviceaccount.com" -AdminEmail "google.admin.account@domain.com" - .EXAMPLE - $token = Get-GSToken + $Token = Get-GSToken -Scopes 'https://www.google.com/m8/feeds' -AdminEmail $User + $headers = @{ + Authorization = "Bearer $($Token)" + 'GData-Version' = '3.0' + } #> Param ( [parameter(Mandatory = $true)] + [Alias('Scope')] [ValidateNotNullOrEmpty()] [string[]] $Scopes, diff --git a/PSGSuite/Public/Calendar/New-GSCalendarEvent.ps1 b/PSGSuite/Public/Calendar/New-GSCalendarEvent.ps1 index 205dd341..063e2d42 100644 --- a/PSGSuite/Public/Calendar/New-GSCalendarEvent.ps1 +++ b/PSGSuite/Public/Calendar/New-GSCalendarEvent.ps1 @@ -2,62 +2,65 @@ function New-GSCalendarEvent { <# .SYNOPSIS Creates a new calendar event - + .DESCRIPTION Creates a new calendar event - + .PARAMETER Summary Event summary - + .PARAMETER Description Event description - + .PARAMETER User - The primary email or UserID of the user. You can exclude the '@domain.com' to insert the Domain in the config or use the special 'me' to indicate the AdminEmail in the config. + The primary email or UserID of the user. You can exclude the '@domain.com' to insert the Domain in the config or use the special 'me' to indicate the AdminEmail in the config. Defaults to the AdminEmail in the config. - + .PARAMETER CalendarID The calendar ID of the calendar you would like to list events from. Defaults to the user's primary calendar. - + .PARAMETER AttendeeEmails - The email addresses of the attendees to add. - + The email addresses of the attendees to add. + NOTE: This performs simple adds without additional attendee options. If additional options are needed, use the Attendees parameter instead. - + .PARAMETER Attendees The EventAttendee object(s) to add. Use Add-GSEventAttendee with this parameter for best results. - + .PARAMETER Location Event location - + .PARAMETER EventColor Color of the event as seen in Calendar - + + .PARAMETER DisableReminder + When $true, disables inheritance of the default Reminders from the Calendar the event was created on. + .PARAMETER LocalStartDateTime Start date and time of the event. Lowest precendence of the three StartDate parameters. Defaults to the time the function is ran. - + .PARAMETER LocalEndDateTime End date and time of the event. Lowest precendence of the three EndDate parameters. Defaults to 30 minutes after the time the function is ran. - + .PARAMETER StartDate String representation of the start date. Middle precendence of the three StartDate parameters. - + .PARAMETER EndDate String representation of the end date. Middle precendence of the three EndDate parameters. - + .PARAMETER UTCStartDateTime String representation of the start date in UTC. Highest precendence of the three StartDate parameters. - + .PARAMETER UTCEndDateTime String representation of the end date in UTC. Highest precendence of the three EndDate parameters. - + .EXAMPLE New-GSCalendarEvent "Go to the gym" -StartDate (Get-Date "21:00:00") -EndDate (Get-Date "22:00:00") @@ -94,6 +97,9 @@ function New-GSCalendarEvent { [String] $EventColor, [parameter(Mandatory = $false)] + [Switch] + $DisableReminder, + [parameter(Mandatory = $false)] [DateTime] $LocalStartDateTime = (Get-Date), [parameter(Mandatory = $false)] @@ -147,53 +153,59 @@ function New-GSCalendarEvent { Add-GSEventAttendee -Email $_ } } - foreach ($calId in $CalendarID) { - $body = New-Object 'Google.Apis.Calendar.v3.Data.Event' - if ($Attendees) { - $body.Attendees = [Google.Apis.Calendar.v3.Data.EventAttendee[]]$Attendees - } - foreach ($key in $PSBoundParameters.Keys) { - switch ($key) { - EventColor { - $body.ColorId = $colorHash[$EventColor] + $body = New-Object 'Google.Apis.Calendar.v3.Data.Event' + if ($Attendees) { + $body.Attendees = [Google.Apis.Calendar.v3.Data.EventAttendee[]]$Attendees + } + foreach ($key in $PSBoundParameters.Keys) { + switch ($key) { + EventColor { + $body.ColorId = $colorHash[$EventColor] + } + DisableReminder { + $reminder = New-Object 'Google.Apis.Calendar.v3.Data.Event+RemindersData' -Property @{ + UseDefault = (-not $DisableReminder) } - Default { - if ($body.PSObject.Properties.Name -contains $key) { - $body.$key = $PSBoundParameters[$key] - } + $body.Reminders = $reminder + } + Default { + if ($body.PSObject.Properties.Name -contains $key) { + $body.$key = $PSBoundParameters[$key] } } } - $body.Start = if ($UTCStartDateTime) { - New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ - DateTime = $UTCStartDateTime - } + } + $body.Start = if ($UTCStartDateTime) { + New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ + DateTime = $UTCStartDateTime } - elseif ($StartDate) { - New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ - Date = (Get-Date $StartDate -Format "yyyy-MM-dd") - } + } + elseif ($StartDate) { + New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ + Date = (Get-Date $StartDate -Format "yyyy-MM-dd") } - else { - New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ - DateTime = $LocalStartDateTime - } + } + else { + New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ + DateTime = $LocalStartDateTime } - $body.End = if ($UTCEndDateTime) { - New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ - DateTime = $UTCEndDateTime - } + } + $body.End = if ($UTCEndDateTime) { + New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ + DateTime = $UTCEndDateTime } - elseif ($EndDate) { - New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ - Date = (Get-Date $EndDate -Format "yyyy-MM-dd") - } + } + elseif ($EndDate) { + New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ + Date = (Get-Date $EndDate -Format "yyyy-MM-dd") } - else { - New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ - DateTime = $LocalEndDateTime - } + } + else { + New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ + DateTime = $LocalEndDateTime } + } + foreach ($calId in $CalendarID) { Write-Verbose "Creating Calendar Event '$($Summary)' on calendar '$calId' for user '$U'" $request = $service.Events.Insert($body,$calId) $request.Execute() | Add-Member -MemberType NoteProperty -Name 'User' -Value $U -PassThru | Add-Member -MemberType NoteProperty -Name 'CalendarId' -Value $calId -PassThru @@ -209,4 +221,4 @@ function New-GSCalendarEvent { } } } -} \ No newline at end of file +} diff --git a/PSGSuite/Public/Calendar/Update-GSCalendarEvent.ps1 b/PSGSuite/Public/Calendar/Update-GSCalendarEvent.ps1 index 14cf9480..f782739e 100644 --- a/PSGSuite/Public/Calendar/Update-GSCalendarEvent.ps1 +++ b/PSGSuite/Public/Calendar/Update-GSCalendarEvent.ps1 @@ -2,65 +2,68 @@ function Update-GSCalendarEvent { <# .SYNOPSIS Updates an event - + .DESCRIPTION Updates an event - + .PARAMETER EventID The unique Id of the event to update - + .PARAMETER CalendarID The Id of the calendar Defaults to the user's primary calendar. .PARAMETER User - The primary email or UserID of the user. You can exclude the '@domain.com' to insert the Domain in the config or use the special 'me' to indicate the AdminEmail in the config. + The primary email or UserID of the user. You can exclude the '@domain.com' to insert the Domain in the config or use the special 'me' to indicate the AdminEmail in the config. Defaults to the AdminEmail in the config. - + .PARAMETER Summary Event summary - + .PARAMETER Description Event description - + .PARAMETER AttendeeEmails - The email addresses of the attendees to add. - + The email addresses of the attendees to add. + NOTE: This performs simple adds without additional attendee options. If additional options are needed, use the Attendees parameter instead. - + .PARAMETER Attendees The EventAttendee object(s) to add. Use Add-GSEventAttendee with this parameter for best results. - + .PARAMETER Location Event location - + .PARAMETER EventColor Color of the event as seen in Calendar - + + .PARAMETER DisableReminder + When $true, disables inheritance of the default Reminders from the Calendar the event was created on. + .PARAMETER LocalStartDateTime Start date and time of the event. Lowest precendence of the three StartDate parameters. Defaults to the time the function is ran. - + .PARAMETER LocalEndDateTime End date and time of the event. Lowest precendence of the three EndDate parameters. Defaults to 30 minutes after the time the function is ran. - + .PARAMETER StartDate String representation of the start date. Middle precendence of the three StartDate parameters. - + .PARAMETER EndDate String representation of the end date. Middle precendence of the three EndDate parameters. - + .PARAMETER UTCStartDateTime String representation of the start date in UTC. Highest precendence of the three StartDate parameters. - + .PARAMETER UTCEndDateTime String representation of the end date in UTC. Highest precendence of the three EndDate parameters. - + .EXAMPLE New-GSCalendarEvent "Go to the gym" -StartDate (Get-Date "21:00:00") -EndDate (Get-Date "22:00:00") @@ -70,6 +73,7 @@ function Update-GSCalendarEvent { Param ( [parameter(Mandatory = $true,Position = 0,ValueFromPipelineByPropertyName = $true)] + [Alias('Id')] [String[]] $EventId, [parameter(Mandatory = $false,ValueFromPipelineByPropertyName = $true)] @@ -100,6 +104,9 @@ function Update-GSCalendarEvent { [String] $EventColor, [parameter(Mandatory = $false)] + [Switch] + $DisableReminder, + [parameter(Mandatory = $false)] [DateTime] $LocalStartDateTime, [parameter(Mandatory = $false)] @@ -153,53 +160,59 @@ function Update-GSCalendarEvent { Add-GSEventAttendee -Email $_ } } - foreach ($calId in $CalendarID) { - $body = New-Object 'Google.Apis.Calendar.v3.Data.Event' - if ($Attendees) { - $body.Attendees = [Google.Apis.Calendar.v3.Data.EventAttendee[]]$Attendees - } - foreach ($key in $PSBoundParameters.Keys) { - switch ($key) { - EventColor { - $body.ColorId = $colorHash[$EventColor] + $body = New-Object 'Google.Apis.Calendar.v3.Data.Event' + if ($Attendees) { + $body.Attendees = [Google.Apis.Calendar.v3.Data.EventAttendee[]]$Attendees + } + foreach ($key in $PSBoundParameters.Keys) { + switch ($key) { + EventColor { + $body.ColorId = $colorHash[$EventColor] + } + DisableReminder { + $reminder = New-Object 'Google.Apis.Calendar.v3.Data.Event+RemindersData' -Property @{ + UseDefault = (-not $DisableReminder) } - Default { - if ($body.PSObject.Properties.Name -contains $key) { - $body.$key = $PSBoundParameters[$key] - } + $body.Reminders = $reminder + } + Default { + if ($body.PSObject.Properties.Name -contains $key) { + $body.$key = $PSBoundParameters[$key] } } } - $body.Start = if ($UTCStartDateTime) { - New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ - DateTime = $UTCStartDateTime - } + } + $body.Start = if ($UTCStartDateTime) { + New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ + DateTime = $UTCStartDateTime } - elseif ($StartDate) { - New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ - Date = (Get-Date $StartDate -Format "yyyy-MM-dd") - } + } + elseif ($StartDate) { + New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ + Date = (Get-Date $StartDate -Format "yyyy-MM-dd") } - elseif ($LocalStartDateTime) { - New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ - DateTime = $LocalStartDateTime - } + } + elseif ($LocalStartDateTime) { + New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ + DateTime = $LocalStartDateTime } - $body.End = if ($UTCEndDateTime) { - New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ - DateTime = $UTCEndDateTime - } + } + $body.End = if ($UTCEndDateTime) { + New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ + DateTime = $UTCEndDateTime } - elseif ($EndDate) { - New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ - Date = (Get-Date $EndDate -Format "yyyy-MM-dd") - } + } + elseif ($EndDate) { + New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ + Date = (Get-Date $EndDate -Format "yyyy-MM-dd") } - elseif ($LocalEndDateTime) { - New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ - DateTime = $LocalEndDateTime - } + } + elseif ($LocalEndDateTime) { + New-Object 'Google.Apis.Calendar.v3.Data.EventDateTime' -Property @{ + DateTime = $LocalEndDateTime } + } + foreach ($calId in $CalendarID) { foreach ($evId in $EventId) { Write-Verbose "Updating Calendar Event '$evId' on calendar '$calId' for user '$U'" $request = $service.Events.Patch($body,$calId,$evId) @@ -217,4 +230,4 @@ function Update-GSCalendarEvent { } } } -} \ No newline at end of file +} diff --git a/PSGSuite/Public/Classroom/Get-GSClassroomUserProfile.ps1 b/PSGSuite/Public/Classroom/Get-GSClassroomUserProfile.ps1 index 52c486ae..913e671c 100644 --- a/PSGSuite/Public/Classroom/Get-GSClassroomUserProfile.ps1 +++ b/PSGSuite/Public/Classroom/Get-GSClassroomUserProfile.ps1 @@ -33,7 +33,11 @@ function Get-GSClassroomUserProfile { ) Begin { $serviceParams = @{ - Scope = 'https://www.googleapis.com/auth/classroom.rosters' + Scope = @( + 'https://www.googleapis.com/auth/classroom.rosters' + 'https://www.googleapis.com/auth/classroom.profile.emails' + 'https://www.googleapis.com/auth/classroom.profile.photos' + ) ServiceType = 'Google.Apis.Classroom.v1.ClassroomService' } $service = New-GoogleService @serviceParams diff --git a/PSGSuite/Public/Classroom/Get-GSCourseParticipant.ps1 b/PSGSuite/Public/Classroom/Get-GSCourseParticipant.ps1 index de8bae98..c596ae1a 100644 --- a/PSGSuite/Public/Classroom/Get-GSCourseParticipant.ps1 +++ b/PSGSuite/Public/Classroom/Get-GSCourseParticipant.ps1 @@ -74,7 +74,11 @@ function Get-GSCourseParticipant { $User = "$($User)@$($Script:PSGSuite.Domain)" } $serviceParams = @{ - Scope = 'https://www.googleapis.com/auth/classroom.rosters' + Scope = @( + 'https://www.googleapis.com/auth/classroom.rosters' + 'https://www.googleapis.com/auth/classroom.profile.emails' + 'https://www.googleapis.com/auth/classroom.profile.photos' + ) ServiceType = 'Google.Apis.Classroom.v1.ClassroomService' User = $User } diff --git a/PSGSuite/Public/Contacts/Get-GSContactList.ps1 b/PSGSuite/Public/Contacts/Get-GSContactList.ps1 index 6e2d62a5..276d4050 100644 --- a/PSGSuite/Public/Contacts/Get-GSContactList.ps1 +++ b/PSGSuite/Public/Contacts/Get-GSContactList.ps1 @@ -21,67 +21,61 @@ Function Get-GSContactList { [parameter(Mandatory = $false, Position = 0, ValueFromPipelineByPropertyName = $true)] [Alias("PrimaryEmail", "UserKey", "Mail")] [ValidateNotNullOrEmpty()] - [string] + [string[]] $User = $Script:PSGSuite.AdminEmail ) - Begin { - if ($User -ceq 'me') { - $User = $Script:PSGSuite.AdminEmail - } - elseif ($User -notlike "*@*.*") { - $User = "$($User)@$($Script:PSGSuite.Domain)" - } - $serviceParams = @{ - Scope = 'https://www.google.com/m8/feeds' - ServiceType = 'Google.Apis.Gmail.v1.GmailService' - User = $User - } - $service = New-GoogleService @serviceParams - $Token = ($service.HttpClientInitializer.GetAccessTokenForRequestAsync()).Result - $Uri = "https://www.google.com/m8/feeds/contacts/$($User)/full?max-results=150" - $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" - $headers.Add("GData-Version", "3.0") - $headers.Add("Authorization", "Bearer $($Token)") - } Process { - try { - Write-Verbose "Getting all contacts for user '$User'" - $Raw = @() - $Response = Invoke-WebRequest -Method Get -Uri $Uri -Headers $headers -ContentType 'application/xml' - $Feed = [xml]$Response.Content - $Raw += $feed.feed.entry - $Next = $Feed.Feed.Link | Where-Object {$_.rel -eq "next"} | Select-Object -ExpandProperty Href - While ($Next) { - $Response = Invoke-WebRequest -Method Get -Uri $Next -Headers $headers -ContentType 'application/xml' - $Feed = [xml]$Response.Content - $Raw += $feed.feed.entry - $Next = $Feed.Feed.Link | Where-Object {$_.rel -eq "next"} | Select-Object -ExpandProperty Href - } - If ($Raw) { - ForEach ($i in $Raw) { - New-Object PSObject -Property @{ - Etag = $i.etag - Id = ($i.id.Split("/")[-1]) - User = $User - Updated = $i.updated - Edited = $i.edited.'#text' - Category = $i.category - Title = $i.title - Name = $i.name - PhoneNumber = $i.phonenumber - Path = $(if($i.email.rel){$i.email.rel}else{$null}) - EmailAddresses = $(if($i.email.address){$i.email.address}else{$null}) - FullObject = $i + foreach ($U in $User) { + try { + if ($U -ceq 'me') { + $U = $Script:PSGSuite.AdminEmail + } + elseif ($U -notlike "*@*.*") { + $U = "$($U)@$($Script:PSGSuite.Domain)" + } + $Token = Get-GSToken -Scopes 'https://www.google.com/m8/feeds' -AdminEmail $U + $Uri = "https://www.google.com/m8/feeds/contacts/$($U)/full?max-results=5000" + $headers = @{ + Authorization = "Bearer $($Token)" + 'GData-Version' = '3.0' + } + Write-Verbose "Getting all contacts for user '$U'" + $Raw = @() + do { + $Response = Invoke-WebRequest -Method Get -Uri ([Uri]$Uri) -Headers $headers -ContentType 'application/xml' -Verbose:$false + $Feed = [xml]$Response.Content + $Raw += $feed.feed.entry + $Uri = $Feed.Feed.Link | Where-Object {$_.rel -eq "next"} | Select-Object -ExpandProperty Href + Write-Verbose "Retrieved $($Raw.Count) contacts..." + } + until (-not $Uri) + If ($Raw) { + ForEach ($i in $Raw) { + [PSCustomObject]@{ + User = $U + Id = ($i.id.Split("/")[-1]) + Title = $i.title + FullName = $i.name.fullName + GivenName = $i.name.givenName + FamilyName = $i.name.familyName + EmailAddresses = $(if($i.email.address){$i.email.address}else{$null}) + PhoneNumber = $i.phonenumber + Updated = $i.updated + Edited = $i.edited.'#text' + Path = $(if($i.email.rel){$i.email.rel}else{$null}) + Etag = $i.etag + FullObject = $i + } } } } - } - catch { - if ($ErrorActionPreference -eq 'Stop') { - $PSCmdlet.ThrowTerminatingError($_) - } - else { - Write-Error $_ + catch { + if ($ErrorActionPreference -eq 'Stop') { + $PSCmdlet.ThrowTerminatingError($_) + } + else { + Write-Error $_ + } } } } diff --git a/PSGSuite/Public/Contacts/Remove-GSContact.ps1 b/PSGSuite/Public/Contacts/Remove-GSContact.ps1 index 5c593582..f0db013a 100644 --- a/PSGSuite/Public/Contacts/Remove-GSContact.ps1 +++ b/PSGSuite/Public/Contacts/Remove-GSContact.ps1 @@ -6,16 +6,18 @@ Function Remove-GSContact { .DESCRIPTION Removes the specified contact + .PARAMETER ContactID + The ContactID to be removed. + .PARAMETER User The primary email or UserID of the user. You can exclude the '@domain.com' to insert the Domain in the config or use the special 'me' to indicate the AdminEmail in the config. Defaults to the AdminEmail in the config. .PARAMETER Etag - The Etag string from a Get-GSContactList object. Used to ensure that no changes have been made to the contact since it was viewed, to ensure no data loss. + The Etag string from a Get-GSContactList object. Used to ensure that no changes have been made to the contact since it was viewed in order to prevent data loss. - .PARAMETER ContactID - The ContactID to be removed. + Defaults to special Etag value *, which can be used to bypass this verification and process the update regardless of updates from other clients. .EXAMPLE Recommended to use Get-GSContactList to find and pipe desired contacts to Remove-GSContact: @@ -29,56 +31,51 @@ Function Remove-GSContact { Param ( [parameter(Mandatory = $false, Position = 0, ValueFromPipelineByPropertyName = $true)] + [Alias("Id")] + [string[]] + $ContactId, + [parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [Alias("PrimaryEmail", "UserKey", "Mail")] [ValidateNotNullOrEmpty()] [string] $User = $Script:PSGSuite.AdminEmail, - [parameter(Mandatory = $true, Position = 1, ValueFromPipelineByPropertyName = $true)] - [string] - $Etag, - [parameter(Mandatory = $false, Position = 2, ValueFromPipelineByPropertyName = $true)] - [Alias("Id")] + [parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] - $ContactID + $Etag = '*' ) - Begin { + Process { if ($User -ceq 'me') { $User = $Script:PSGSuite.AdminEmail } elseif ($User -notlike "*@*.*") { $User = "$($User)@$($Script:PSGSuite.Domain)" } - } - Process { - if ($PSCmdlet.ShouldProcess("Removing contact ID: $ContactID for $User")) { - Write-Verbose "Removing contact ID: $ContactID for $User" - try { - $serviceParams = @{ - Scope = 'https://www.google.com/m8/feeds' - ServiceType = 'Google.Apis.Gmail.v1.GmailService' - User = $User - } - $service = New-GoogleService @serviceParams - $Token = ($service.HttpClientInitializer.GetAccessTokenForRequestAsync()).Result - $Uri = "https://www.google.com/m8/feeds/contacts/$($User)/full/$($ContactID)" - $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" - $headers.Add("GData-Version", "3.0") - $headers.Add("Authorization", "Bearer $($Token)") - $headers.Add("If-Match", "$Etag") - $Response = Invoke-WebRequest -Method "Delete" -Uri $Uri -Headers $headers - If ($Response.StatusCode -eq "200") { - Write-Verbose "Successfully deleted contact ID: $ContactID for $User" - } - Else { - Write-Verbose "HTTP $($Response.StatusCode): $($Response.StatusDescription)" - } - } - catch { - if ($ErrorActionPreference -eq 'Stop') { - $PSCmdlet.ThrowTerminatingError($_) + $Token = Get-GSToken -Scopes 'https://www.google.com/m8/feeds' -AdminEmail $User + $headers = @{ + Authorization = "Bearer $($Token)" + 'GData-Version' = '3.0' + 'If-Match' = $Etag + } + foreach ($Id in $ContactID) { + if ($PSCmdlet.ShouldProcess("Removing contact ID '$Id' for $User")) { + Write-Verbose "Removing contact ID '$Id' for $User" + try { + $Uri = "https://www.google.com/m8/feeds/contacts/$($User)/full/$($Id)" + $Response = Invoke-WebRequest -Method "Delete" -Uri ([Uri]$Uri) -Headers $headers -Verbose:$false + If ($Response.StatusCode -eq "200") { + Write-Verbose "Successfully deleted contact ID '$Id' for $User" + } + Else { + Write-Verbose "HTTP $($Response.StatusCode): $($Response.StatusDescription)" + } } - else { - Write-Error $_ + catch { + if ($ErrorActionPreference -eq 'Stop') { + $PSCmdlet.ThrowTerminatingError($_) + } + else { + Write-Error $_ + } } } } diff --git a/README.md b/README.md index ea40857c..71ecbc31 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,17 @@ Update-GSSheetValue Export-GSSheet ### Most recent changes +#### 2.18.1 + +* [Issue #87](https://github.com/scrthq/PSGSuite/issues/87) + * Added: Additional scopes during Service creation for `Get-GSCourseParticipant` and `Get-GSClassroomUserProfile` to enable pulling of full user profile information. - _Thanks, [@jdstanberry](https://github.com/jdstanberry)!_ +* [Issue #111](https://github.com/scrthq/PSGSuite/issues/111) + * Added: `DisableReminder` switch parameter to `New-GSCalendarEvent` and `Update-GSCalendarEvent` to remove Reminder inheritance from the calendar the event is on as well as any Reminder overload definitions. +* [Issue #53](https://github.com/scrthq/PSGSuite/issues/53) + * Updated: `Get-GSContactList` and `Remove-GSContact` Token retrieval and overall cleanup +* Various/Other + * Updated: `Get-GSToken` to align parameters more with `New-GoogleService` + #### 2.18.0 * [Issue #87](https://github.com/scrthq/PSGSuite/issues/87)