Graphimo.psm1
function Write-Color { <# .SYNOPSIS Write-Color is a wrapper around Write-Host. It provides: - Easy manipulation of colors, - Logging output to file (log) - Nice formatting options out of the box. .DESCRIPTION Author: przemyslaw.klys at evotec.pl Project website: https://evotec.xyz/hub/scripts/write-color-ps1/ Project support: https://github.com/EvotecIT/PSWriteColor Original idea: Josh (https://stackoverflow.com/users/81769/josh) .EXAMPLE Write-Color -Text "Red ", "Green ", "Yellow " -Color Red,Green,Yellow .EXAMPLE Write-Color -Text "This is text in Green ", "followed by red ", "and then we have Magenta... ", "isn't it fun? ", "Here goes DarkCyan" -Color Green,Red,Magenta,White,DarkCyan .EXAMPLE Write-Color -Text "This is text in Green ", "followed by red ", "and then we have Magenta... ", "isn't it fun? ", "Here goes DarkCyan" -Color Green,Red,Magenta,White,DarkCyan -StartTab 3 -LinesBefore 1 -LinesAfter 1 .EXAMPLE Write-Color "1. ", "Option 1" -Color Yellow, Green Write-Color "2. ", "Option 2" -Color Yellow, Green Write-Color "3. ", "Option 3" -Color Yellow, Green Write-Color "4. ", "Option 4" -Color Yellow, Green Write-Color "9. ", "Press 9 to exit" -Color Yellow, Gray -LinesBefore 1 .EXAMPLE Write-Color -LinesBefore 2 -Text "This little ","message is ", "written to log ", "file as well." ` -Color Yellow, White, Green, Red, Red -LogFile "C:\testing.txt" -TimeFormat "yyyy-MM-dd HH:mm:ss" Write-Color -Text "This can get ","handy if ", "want to display things, and log actions to file ", "at the same time." ` -Color Yellow, White, Green, Red, Red -LogFile "C:\testing.txt" .EXAMPLE # Added in 0.5 Write-Color -T "My text", " is ", "all colorful" -C Yellow, Red, Green -B Green, Green, Yellow wc -t "my text" -c yellow -b green wc -text "my text" -c red .NOTES CHANGELOG Version 0.5 (25th April 2018) ----------- - Added backgroundcolor - Added aliases T/B/C to shorter code - Added alias to function (can be used with "WC") - Fixes to module publishing Version 0.4.0-0.4.9 (25th April 2018) ------------------- - Published as module - Fixed small issues Version 0.31 (20th April 2018) ------------ - Added Try/Catch for Write-Output (might need some additional work) - Small change to parameters Version 0.3 (9th April 2018) ----------- - Added -ShowTime - Added -NoNewLine - Added function description - Changed some formatting Version 0.2 ----------- - Added logging to file Version 0.1 ----------- - First draft Additional Notes: - TimeFormat https://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx #> [alias('Write-Colour')] [CmdletBinding()] param ([alias ('T')] [String[]]$Text, [alias ('C', 'ForegroundColor', 'FGC')] [ConsoleColor[]]$Color = [ConsoleColor]::White, [alias ('B', 'BGC')] [ConsoleColor[]]$BackGroundColor = $null, [alias ('Indent')][int] $StartTab = 0, [int] $LinesBefore = 0, [int] $LinesAfter = 0, [int] $StartSpaces = 0, [alias ('L')] [string] $LogFile = '', [Alias('DateFormat', 'TimeFormat')][string] $DateTimeFormat = 'yyyy-MM-dd HH:mm:ss', [alias ('LogTimeStamp')][bool] $LogTime = $true, [ValidateSet('unknown', 'string', 'unicode', 'bigendianunicode', 'utf8', 'utf7', 'utf32', 'ascii', 'default', 'oem')][string]$Encoding = 'Unicode', [switch] $ShowTime, [switch] $NoNewLine) $DefaultColor = $Color[0] if ($null -ne $BackGroundColor -and $BackGroundColor.Count -ne $Color.Count) { Write-Error "Colors, BackGroundColors parameters count doesn't match. Terminated."; return } if ($LinesBefore -ne 0) { for ($i = 0; $i -lt $LinesBefore; $i++) { Write-Host -Object "`n" -NoNewline } } if ($StartTab -ne 0) { for ($i = 0; $i -lt $StartTab; $i++) { Write-Host -Object "`t" -NoNewLine } } if ($StartSpaces -ne 0) { for ($i = 0; $i -lt $StartSpaces; $i++) { Write-Host -Object ' ' -NoNewLine } } if ($ShowTime) { Write-Host -Object "[$([datetime]::Now.ToString($DateTimeFormat))]" -NoNewline } if ($Text.Count -ne 0) { if ($Color.Count -ge $Text.Count) { if ($null -eq $BackGroundColor) { for ($i = 0; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -NoNewLine } } else { for ($i = 0; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackGroundColor[$i] -NoNewLine } } } else { if ($null -eq $BackGroundColor) { for ($i = 0; $i -lt $Color.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -NoNewLine } for ($i = $Color.Length; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $DefaultColor -NoNewLine } } else { for ($i = 0; $i -lt $Color.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackGroundColor[$i] -NoNewLine } for ($i = $Color.Length; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $DefaultColor -BackgroundColor $BackGroundColor[0] -NoNewLine } } } } if ($NoNewLine -eq $true) { Write-Host -NoNewline } else { Write-Host } if ($LinesAfter -ne 0) { for ($i = 0; $i -lt $LinesAfter; $i++) { Write-Host -Object "`n" -NoNewline } } if ($Text.Count -ne 0 -and $LogFile -ne "") { $TextToFile = "" for ($i = 0; $i -lt $Text.Length; $i++) { $TextToFile += $Text[$i] } try { if ($LogTime) { Write-Output -InputObject "[$([datetime]::Now.ToString($DateTimeFormat))]$TextToFile" | Out-File -FilePath $LogFile -Encoding $Encoding -Append } else { Write-Output -InputObject "$TextToFile" | Out-File -FilePath $LogFile -Encoding $Encoding -Append } } catch { $_.Exception } } } function Connect-O365Graph { [cmdletBinding()] param( [string][alias('ClientID')] $ApplicationID, [string][alias('ClientSecret')] $ApplicationKey, [string] $TenantDomain, [ValidateSet("https://manage.office.com", "https://graph.microsoft.com")] $Resource = "https://manage.office.com" ) # https://dzone.com/articles/getting-access-token-for-microsoft-graph-using-oau-1 $Body = @{ grant_type = "client_credentials" resource = $Resource client_id = $ApplicationID client_secret = $ApplicationKey } try { $Authorization = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$($TenantDomain)/oauth2/token" -Body $body -ErrorAction Stop } catch { $ErrorMessage = $_.Exception.Message -replace "`n", " " -replace "`r", " " Write-Warning -Message "Connect-O365Graph - Error: $ErrorMessage" } if ($Authorization) { @{'Authorization' = "$($Authorization.token_type) $($Authorization.access_token)" } } else { $null } } function Get-GraphCalendarEvents { [cmdletBinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [string] $UserPrincipalName, [string] $CalendarID, [datetime] $DateStart, [datetime] $DateEnd ) #$Date1 = (Get-Date $DateStart -UFormat '+%Y-%m-%dT%H:%M:%S.000Z') #$Date2 = (Get-Date $DateEnd -UFormat '+%Y-%m-%dT%H:%M:%S.000Z') $Date1 = $DateStart $Date2 = $DateEnd $URI = "/users/$UserPrincipalName/calendars/$($CalendarID)/calendarView?startDateTime=$Date1&endDateTime=$Date2" $OneCalendar = Invoke-O365Graph -Uri $URI -Method GET -Headers $Headers $OneCalendar } function Get-GraphUserCalendars { [cmdletBinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [string] $UserPrincipalName ) Invoke-O365Graph -Uri "/users/$UserPrincipalName/calendars" -Method GET -Headers $Headers } function Get-GraphUsers { [cmdletBinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) Invoke-O365Graph -Uri "/users/" -Method GET -Headers $Headers } function Invoke-O365Graph { [cmdletBinding()] param( [uri] $PrimaryUri = 'https://graph.microsoft.com/v1.0', [uri] $Uri, [alias('Authorization')][System.Collections.IDictionary] $Headers, [validateset('GET', 'DELETE')][string] $Method = 'GET', [string] $ContentType = "application/json", [switch] $FullUri ) $RestSplat = @{ Headers = $Headers Method = $Method ContentType = $ContentType } if ($FullUri) { $RestSplat.Uri = $Uri } else { $RestSplat.Uri = -join ($PrimaryUri, $Uri) } try { $OutputQuery = Invoke-RestMethod @RestSplat -Verbose:$false if ($Method -eq 'GET') { if ($OutputQuery.value) { $OutputQuery.value } if ($OutputQuery.'@odata.nextLink') { $RestSplat.Uri = $OutputQuery.'@odata.nextLink' $MoreData = Invoke-O365Graph @RestSplat -FullUri if ($MoreData) { $MoreData } } } else { return $true } } catch { $RestError = $_.ErrorDetails.Message if ($RestError) { try { $ErrorMessage = ConvertFrom-Json -InputObject $RestError $ErrorMy = -join ('JSON Error:' , $ErrorMessage.error.code, ' ', $ErrorMessage.error.message, ' Additional Error: ', $_.Exception.Message) Write-Warning $ErrorMy } catch { Write-Warning $_.Exception.Message } } else { Write-Warning $_.Exception.Message } if ($Method -ne 'GET') { return $false } } } function Remove-GraphMailboxCalendar { [cmdletBinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [string] $UserPrincipalName, [string] $CalendarID ) $URI = "/users/$UserPrincipalName/calendars/$($CalendarID)" Invoke-O365Graph -Uri $URI -Method DELETE -Headers $Headers } function Remove-GraphMailboxCalendarEvent { [cmdletBinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [string] $UserPrincipalName, [string] $CalendarID, [string] $EventID, [int] $Batches = 30, [switch] $All ) if ($All) { [int] $StartDay = -9200 [int] $FinalDay = 60000 do { $EndDay = $StartDay + $Batches $Date1 = (Get-Date).AddDays($StartDay) $Date2 = (Get-Date).AddDays($EndDay) #Write-Verbose "Remove-GraphMailboxCalendarEvent - Processing user $UserPrincipalName for $CalendarID from $Date1 to $Date2" #Write-Color "Remove-GraphMailboxCalendarEvent - Processing user $UserPrincipalName for $CalendarID from $Date1 to $Date2" -Color DarkMagenta $CalendarEvents = Get-GraphCalendarEvents -UserPrincipalName $UserPrincipalName -Headers $Headers -DateStart $Date1 -DateEnd $Date2 -CalendarID $CalendarID #Write-Color "Count of Events ", $CalendarEvents.Count, ' for dates ', $Date1, ' and ', $Date2 -Color yellow, white, yellow, white, yellow, white, yellow Write-Color "Remove-GraphMailboxCalendarEvent - Processing user $UserPrincipalName / found $($CalendarEvents.Count) events from $Date1 to $Date2" -Color Blue #Write-Verbose "Remove-GraphMailboxCalendarEvent - Processing user $UserPrincipalName / found $($CalendarEvents.Count) events from $Date1 to $Date2" foreach ($Event in $CalendarEvents) { # Write-Color "Deleting $UserPrincipalName $URIEvent $CalendarID $EventID" -Color Yellow, White, Blue $Output = Remove-GraphMailboxCalendarEvent -Headers $Headers -UserPrincipalName $UserPrincipalName -CalendarID $CalendarID -EventID $Event.ID } $StartDay = $StartDay + $Batches } while ($EndDay -lt $FinalDay) } else { if ($EventID) { $URIEvent = "/users/$UserPrincipalName/calendars/$($CalendarID)/events/$($EventID)" #Write-Verbose "Remove-GraphMailboxCalendarEvent - Processing user $UserPrincipalName / deleting event $($EventID)" #Write-Color "Deleting $URIEvent" -Color Yellow, White, Blue Invoke-O365Graph -Uri $URIEvent -Method DELETE -Headers $Headers } } } Export-ModuleMember -Function @('Connect-O365Graph', 'Get-GraphCalendarEvents', 'Get-GraphUserCalendars', 'Get-GraphUsers', 'Invoke-O365Graph', 'Remove-GraphMailboxCalendar', 'Remove-GraphMailboxCalendarEvent') -Alias @() |