Jump to content

Recommended Posts

Posted (edited)

Hi

 

I would like to convert CSV file into .ics format. After converting this file , i would like to upload to our school calendar using 0365 OWA.

There are many free online converters and bit concerned about the calendar converting online.

Please can you let me know if these is any free software i can download and install on a PC or a licenced version.

 

Thanks

Edited by genesis
Posted (edited)

https://docs.microsoft.com/en-us/graph/api/calendar-post-events?view=graph-rest-1.0&tabs=http

 

So the above is a link to the graph API for events in a calander. I will share some code later but would like someone to have a crack at doing this. I use PowerShell I will give you a starter for 10 and say look at getting a session token.....

 

The Graph API is a more refined way to do this as you do not have to smash holes in your environments by giving out Exchange impersonation permissions you can be way more fine grained.

 

In the first instance look at creating the events then we can look at how to manage updates but for that we need to get back the GUID for the events we create.

 

Also the graph API is throttled at just 10000 requests per min rather than the 50 requests per min using the EWS rest API...

 

Sorry will just add this, if you have a CSV with the data of your events in then with some PowerShell (or other language) covert that in to JSON no need for this convert to .ics and blah... (also .ics files are a little static and calendars generally dont stay that static when they meet the meat cylinders of us humans!) if you spend a bit of time understanding this there is no end to the possibilities that this unlocks and you will soon be writing out your staff and student events in to their calendars from what ever MIS system you use. And the cost to you is applying yourself to a little learning.

Edited by HPlum78
Posted (edited)

function Get-AZGraphToken{    

      [CmdletBinding()]         
               Param(            
                       [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true)]$ClientID,           
                       [Parameter(Position=1,Mandatory=$true,ValueFromPipeline=$true)]$ClientSecret,
                       [Parameter(Position=2,Mandatory=$false,ValueFromPipeline=$true)]$TenantDomain        
      )          

               ### Verbose output of paramters passed to function         
               Write-Verbose $PSBoundParameters        

               $LoginURL = 'https://login.microsoft.com'        
               $Resource = 'https://graph.microsoft.com'
   
               try            
              {
                   $Body = @{grant_type="client_credentials";resource=$Resource;client_id=$ClientID;client_secret=$ClientSecret}
                   $OAuth = Invoke-RestMethod -Method Post -Uri $LoginURL/$TenantDomain/oauth2/token?api-version=1.0 -Body $Body
                   return $OAuth
              }
              catch
             {
             #### Main catch for other unhandled errors in function
             Write-output "Unexpected error in function: $($MyInvocation.MyCommand) " -errorrecord $_
            }
}

 

I will help shift this on a little and post the PowerShell code to get a token from your tenant.

 

You will need to have created an app within Azure and create the secret and assign the API - Microsoft Graph - Calendars.Read and User.Read permissions initially.

https://docs.microsoft.com/en-us/graph/auth-v2-service?view=graph-rest-1.0

The above will help with that, if required I can help with this by posting some step by steps if required.

Edited by HPlum78
Posted

So the idea is that you can run the above function in PowerShell:-

Get-AZGraphToken -ClientId be68bfbd-4012-b52c-b56b-d1e421c0bc62 -ClientSecret oM3LA449hap78CK?A_dpU[m@7nb-AXDH4 -TenantDomain 'plumtreeservices.onmicrosoft.com'

 

You should get what is shown in the attached screen grab.

GraphToken.PNG

 

I would recomend that you put that in a $Var:-

$AzToken = Get-AZGraphToken -ClientId be68bfbd-4012-b52c-b56b-d1e421c0bc62 -ClientSecret oM3LA449hap78CK?A_dpU[m@7nb-AXDH4 -TenantDomain 'plumtreeservices.onmicrosoft.com'

Posted (edited)

If you are still with me then the next part will get the events from a calendar:-

We are going to use the function above and get a token from Azure so that we can start to read events from a calendar using the GRAPH api.

### Get a token from Azure
[color=#333333]$AzToken = Get-AZGraphToken -ClientId be68bfbd-4012-b52c-b56b-d1e421c0bc62 -ClientSecret oM3LA449hap78CK?A_dpU[m@7nb-AXDH4 -TenantDomain 'plumtreeservices.onmicrosoft.com'

### Setting up the session object
[/color][color=#333333]$session = [/color]New-Object Microsoft.PowerShell.Commands.WebRequestSession
### setting the header object and assigning it the correct parameters and token
$headers = New-Object "System.Collections.Generic.Dictionary[[string],[string]]"
$headers.Add("Content-Type", 'application/json')
$headers.Add("Authorization", 'Bearer ' + $($AzToken.access_token) )
$headers.Add("Prefer", 'outlook.timezone="Greenwich Standard Time"')

### the upn of the user that we are going to get the events of
$upn = '[email protected]'
### invoke the call
Invoke-RestMethod -Method Get -SessionVariable $session -Headers $headers -Uri "https://graph.microsoft.com/v1.0/users/$UPN/calendar/events?$select=subject,body,bodyPreview,organizer,attendees,start,end,location"

 

You should start seeing events streaming up the PowerShell windows (make sure that you have some events in the calendar in the future!)

Edited by HPlum78
Posted (edited)

So if I aint lost you along the way here, the next part is to actually do some damage! the following function creates an event in a calendar in O365:-

 

You will need to add the required permission to the app you created earlier to Calendars.ReadWrite the MS documentation is here https://docs.microsoft.com/en-us/graph/api/calendar-post-events?view=graph-rest-1.0&tabs=http

 

function Add-EXOLAppointment
{    
[CmdletBinding()]         
      Param(
           [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true)][string]$Body,
           [Parameter(Position=1,Mandatory=$true,ValueFromPipeline=$true)][string]$Subject,
           [Parameter(Position=2,Mandatory=$true,ValueFromPipeline=$true)][datetime]$StartDate,
           [Parameter(Position=3,Mandatory=$true,ValueFromPipeline=$true)][datetime]$EndDate,
           [Parameter(Position=4,Mandatory=$true,ValueFromPipeline=$true)][string]$Location,
           [Parameter(Position=5,Mandatory=$true,ValueFromPipeline=$true)][string]$UPN,
           [Parameter(Position=6,Mandatory=$true,ValueFromPipeline=$true)]$Token
       )
         ### Verbose output of parameters passed to function
        Write-Verbose $PSBoundParameters
           try
           { 
                    $mybody = [pscustomobject]@{
                            contentType = "HTML"
                            content = $body
                   }
                   
                   $mystart = [pscustomobject]@{
                       dateTime = $StartDate.ToString("yyyy-MM-ddTHH:mm:ss")
                       timeZone = "Greenwich Standard Time"
                   }

                   $myend = [pscustomobject]@{
                       dateTime = $EndDate.ToString("yyyy-MM-ddTHH:mm:ss")
                       timeZone = "Greenwich Standard Time"
                   }

                   $mylocation = [pscustomobject]@{
                       displayname = $location
                     }

                   $JSON = [pscustomobject]@{
                       Subject = $Subject 
                       body = $mybody
                       start = $myStart
                       end = $myEnd
                       location = $myLocation
                       showAs = 'busy'
                   }

                   $RequestJSON = $JSON | ConvertTo-Json

                   $headers = New-Object "System.Collections.Generic.Dictionary[[string],[string]]"
                   $headers.Add("Content-Type", 'application/json')
                   $headers.Add("Authorization", 'Bearer ' + $($token))
                   $headers.Add("Prefer", 'outlook.timezone="Greenwich Standard Time"')
                   
                   if ($session){
                           Write-Output "Creating New Appointment for user: $UPN"
                           $result = Invoke-RestMethod -SessionVariable $session -Headers $headers -Uri "https://graph.microsoft.com/v1.0/users/$UPN/calendar/events" -Body $RequestJSON -UseBasicParsing -Method Post
                       }
                   else{
                       Write-Output "Existing session not found"
                   }

                   if ($result.id){
                       return $result.id
                   }                    else{
                       return $false
                   }
           }
           catch
           {                  
                   #### Main catch for other unhandled errors in function
                   Write-Output "Unexpected error in function: $($MyInvocation.MyCommand) " -errorrecord $_
           }
}

 

So this function takes a number of inputs to create an event in a calendar via a GRAPH call this is essentially what can be used to take you CSV file data and create the events based on that data. The $UPN parameter is the account that you are going to create the event for.

Edited by HPlum78
Fixing the code formatting

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...