Office 365 room mailboxes CalendarProcessing access via Microsoft Graph - powershell

When using rooms and equipments, Exchange (in Office 365, but in other versions as well) uses a number of options to handle requests for those resources in events.
By default, Exchange will for instance strip the subject when creating the event in the room's calendar, and replace it with the organiser name. If you then try to fetch the room's calendar (for a meeting room display, for instance), you'll only have the organiser name instead of the subject of each meeting.
This may be appropriate in some scenarios, but in many others one wants the actual subject to be shown in that calendar.
To achieve that, the only option I know of is to use the Powershell Set-CalendarProcessing cmdlet to change DeleteSubject, AddOrganizerToSubject and more.
In a SaaS environment this is pretty annoying as you need the Office 365 admin to use Powershell to do this operation, which may not be completely straightforward, or you need to ask for the user's login and password and pass them to Powershell, which raises security issues, and will not work in many scenarios (2FA, SAML auth...).
Is there a way to access these settings via Microsoft Graph?
Alternatively, if not available via Microsoft Graph, is there a way to use a Microsoft Graph oAuth token to perform this operation via Linux Powershell? I know it's possible to use oAuth tokens, but despite all my efforts I haven't managed to find a way to perform regular hosted oAuth login and use the token received for this purpose.
Any hints welcome!
Edit
To clarify: I'm in a SaaS scenario where I am the SaaS provider, so I need to allow admins of my customers to change those settings easily or automatically, it's not to access my own room mailboxes (I would use powershell for that).

I don't see anything in the MS Graph Reference that would do what you want. With that said, the barriers you state in your question for using the remote powershell api shouldn't be hard to accomodate.
For starters, your IT provider for email should work with you to configure rooms the way that you want/need. If they are willing to delegate this to you, then there are ways to set up Role Based Access Control (https://4sysops.com/archives/create-custom-rbac-roles-in-exchange-and-office-365/) to give you only access to calendar processing.
Likewise, MS has posted instructions and tools to use MFA with Exchange Online Powershell (https://learn.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps).

According to your description, I assume you want to get the subject of a meeting room.
There is no reference on official Doc for your case yet, we can post this issue to the Graph support on the User Voice.

The only interface I'm aware of for managing this (beyond the Exchange UI of course) is PowerShell.
This isn't supported by Microsoft Graph or Exchange Web Services. It's worth noting that even if this operation was supported, it would still require an Admin to execute it. Operations of this nature almost always require Admin Consent.

Try using JEA (Just Enough Administration) or PSSessionConfigurations . Create a constrained endpoints and give access for necessary user/groups for required cmdlets.

Related

Create Teams meeting by Microsoft Graph or other means

I'd like to create MS Teams meetings from another application.
The Teams application is running on the computer, outlook is not used though.
How would I accomplish this the best / easiest way without (much) user interaction?
As far as I can see, the best option would be to use the REST API to create a meeting using the api-URL https://graph.microsoft.com/v1.0/me/events.
If I can also create a meeting commandline or by COM objects or something else, I could do that, too.
So here would be what I did for research with graph so far:
I can log on to https://developer.microsoft.com/en-us/graph/graph-explorer and use my user to create meetings and get the response. To do that, I modified the permission to read / read-write the calendar. If I copy the access token and use it with a powershell Invoke-RestMethod, it also does what I want. I can do the same with Connect-Graph -Scopes "Calendars.ReadWrite". But it would show this big browser windows about the login as X.
I read about apps, but if I use the apps ID and so on to log in silently, it seems like I am not in the current user scope but in a process scope and that's different. At least I set the API permissions up to also have access to Calendars.ReadWrite via Microsoft Graph, but I get an Access denied error if I try to run the same New-MgUserEvent to create a meeting for the current user (that is running the local powershell).
If use the token with Connect-MgGraph, it displays the client and tenantID and the ContextScope is process, not current user, so that would fit.
If I understand it correctly, I could use the token to get another one for a user... (reference is this: https://learn.microsoft.com/en-us/graph/auth-v2-user )
If I use the Connect-Graph -ForceRefresh parameter (which I guess would do the same, the popup tells me I'm logged in as the current user (not process).
This is a bit odd, so before I try to use the rest api and fumble a bit around:
Can I use the example from the link to refresh the token to get a user token that has the rights that I defined (and be able to access the calendar)?
Or is there some misunderstanding on my part?
Would it be a better idea to just use something like powershell, have the user log in once per day and leave the process in the background and create the new entries from there?
Do you have to refresh a token when you use connect-graph? Or could that be done better by Rest web api, if I can export the token?
The idea of having an app that would have access to all calendars would seem like a bigger security risk and I'd kind of want to avoid that. If I could configure the apps to have access to only one specific calendar, that would be cool, too. But I did not find it when looking around.
Thanks and best regards to all that took their time to read and consider to help.

Create MS Teams chats with MS Graph (or PowerShell)

I'm currently trying to use Microsoft Graph to send a Microsoft Teams Chat message to a specific employee.
The idea behind that is that I want to be able to send chat messages using PowerShell, but for now, I'd be happy to get it done in Microsoft Graph first and build a PowerShell script afterward.
Important: I don't want to post a message to a Channel, only in a 1:1 chat.
What I've tried:
I'm able to get the current chats for my own user by using:
https://graph.microsoft.com/beta/users/{myid}/chats
If, however, I try that with a different user's id, I get a 401 (permission denied) error. I can't even see their current chats even though I have all available permissions.
In the error message, it says the following:
"User Id must match the API caller when called in delegated mode"
... but I don't want to use delegated mode since that'd mean I'm executing the commands as if I would be that user, and therefore couldn't create the chat message which I want in the first place.
It might sound rather confusing, so I hope you get what I mean.
To my knowledge, there's no way to send a message directly to the user without some kind of context. The problem becomes, for instance, where would the message appear, and who would it be from?
If you could deal with it being inside a Channel instead, then PowerShell is fine as you can set up a webhook to do this. I've done the same, from PS -> Teams a few years ago, so I assume it should still work. This article should help.
Alternatively, if you really want a "1-1" conversation, so to speak, you need to create and register a Bot, so that the message comes "from someone" to the user. This concept is called Pro-active Messaging and I've posted more about it here. However, coming purely from PowerShell it's going to be a LOT of work:
Create a Bot in Azure to get the App ID and Password. Technically this would be a non-existent Bot as there's no implementation, which means if the user were to reply it would go nowhere. This might be ok? You could possibly try build an Azure Function Bot in PowerShell, but not something I've done myself so can't advise (I've only used C# for Bots thus far)
Create a Conversation ID, and save it for later - again, a bunch of work.
Convert the code (e.g. from my post above) into PowerShell, referencing the relevant NuGet packages.
So, I'd recommend trying to find an approach using a Teams Channel rather, and messaging the user there, if you can manage that in your use case?
Unless all of this is irrelevant if you're trying to send on behalf of another user?
The term "Delegated" in this context refers to the type of permissions claims included in the OAuth token. There are two types; Application and Delegated.
There are two key rules when it comes to Application vs. Delegated scopes:
A single token may only contain a single type of scope. In other words, the token itself is either an Application or Delegated token, never a combination of the two.
The type of scopes applied to a Token is determined by the OAuth Grant you used to obtain it:
Authorization Code: Delegated
Implicit: Delegated
Client Credentials: Application
With regard to the List Chats (/chats) endpoint, only Delegated permissions are supported:
Delegated (work or school account): Chat.Read, Chat.ReadWrite
Delegated (personal Microsoft account): Not supported.
Application: Not supported.
There is a general rule of thumb when it comes to permissions in Microsoft Graph (I use 'general' here since there are a couple of exceptions in older endpoints): Delegated scopes that only apply to the current user end in Read or ReadWrite while those that apply to any user end in .All.
Since these two scopes (Chat.Read and Chat.ReadWrite) do not end in .All, and only Delegated scopes are supported, this tells you that the only Chats you are able to access are those owned by the currently authenticated User. In other words, you cannot read another User's chat messages via the API.
If you think about it, this makes a lot of sense. If you didn't have an authenticated User, who would the Chat message you sent be "from"? A chat message requires both a Sender and a Recipient.
For your scenario, there are a couple of possible workarounds from a Teams ChatBot to simply setting up a new User that you authenticate as and send messages to other Users from.

Did I reinvent the wheel with multiple user access to 3rd party API within Google Apps Script?

I'm developing a system which, when submitting a form through Google Forms, a script will take the data from the sheet which the data is submitted to and then set up a project in a project management software (Zoho projects), and also create Google folder structures based on the information provided.
In other words, a google form is the one location from which all project infrastructure will be created in their corresponding locations and software.
In order for this system to work properly, I need every user who has access to the form to be able to perform the same actions on every software which the script is tied to, regardless of their permissions level for each.
This necessitates the script using only one set of credentials for the 3rd party API which is authorized at a high level, and having all users of the form access only those credentials in order to get the consistent results that are needed.
The problem with this is that I cannot (or at least I don't think I can,) use the OAuth2.0 library for GAS, as user authentication would be to access only the data which the user operating the software has; this would produce many errors in the code because utilizing credentials of different authority levels while attempting to perform the same tasks which require high levels of authority would yield many errors, and lead to inconsistent functionality with the script. On top of this, because I'm referencing a 3rd party API, there's no "Service Account" that I can use to act on behalf of highly authorized users.
To resolve this issue, I've built my own wrapper library for this API in Google Apps Script and built my own authentication system in which user credentials are automatically renewed and managed using the PropertiesService capabilities. I have established access to a highly-authorized user's data through this system. I access this data in my script instead of authenticating with the OAuth2 library for Google Apps Script in order to allow consistent results from the software.
I've found my own method that works for this scenario, but after all the work I've went through, am wondering if I have reinvented the wheel. Is there any other more established way to have multiple users interface with one set of credentials of a 3rd party API through Google Apps Script? Or is this a unique situation that required the solution that I came up with?
Thanks in advance!
You could instead use GAS to create webapp that runs as you every time, and then passes ownership of the related zoho and google drive files to the user after the script runs.

Authorising Office365 logic app API Connection with PowerShell

Trying to setup a bunch of logic apps with supporting Azure functions etc. concept is to utilize ML/Azure functions/Logic apps etc. to setup an automated mailing system.
Everything is deployed using ADO/Git with CD/CI pipelines, but we have a problem with the Office365 connector that needs authorisation after creation. For now, we have followed this article that creates a windows form for authentication.
This works fine, but we want to do this at scale and thus are looking for a silent approach, any ideas or links would be appreciated?
PS. Use does not require MFA
At the moment, the Office365 API authorisation works with the OAuth 2.0 Authorisation Code Grant Type, which means, you can only get the authorisation code by getting the user owning the mailbox (or having access to the shared mailbox) to sign in to get the code. This behaviour of the API is by design. Thus, there is no way to fully automate this.
If you don't need different accounts for different Logic Apps, you can create those API connections with PowerShell (still requiring the user to login in) for each environment and then use the already provisioned API in our CD pipeline.

Why I should NOT use Facebook Connect or OpenId for logging in users?

Jeff Atwood argues that we should stop asking users to register on our websites because we should rather use their "internet driver's license -- that is, [their] existing Twitter, Facebook, Google, or OpenID credentials" for authenticating them.
While I am beginning to think that he may be right, I could not yet decide and I am looking for arguments against letting foreign sites gain control over personal web pages.
Do you see any dangers of authenticating users like this?
if you want a more in depth response based from someone who has dealt with this technology before, you should listen to the recent .NET Rocks with Rob Connery which was precisely about this topic.
http://www.dotnetrocks.com/default.aspx?showNum=626
After listening to it I decided to NOT use OpenID on my site.
Here is the link to Rob's blog post on the subject:
http://blog.wekeroad.com/thoughts/open-id-is-a-party-that-happened
Here are a number of reasons why not, although each comes with caveats:
If you only authenticate with one external service, anyone who doesn't use that service cannot use yours.
If your external authentication service goes down, users won't be able to use yours until theirs comes back up; similarly, slowdowns in their authentication server will also affect you.
Requiring users to authenticate with another service requires them to accept that service's EULA, which may be a turnoff for some; similarly, it ties you morally to whatever decisions your authenticating service makes. In particular it can make you appear to be a satellite, spinoff or affiliate of the auth site, since users have to see their logo every time they try to use your service.
The external auth domain gets a perfect snapshot of your viewership, giving them a lot of insight into what your company is doing. Since their analytical tools and staff are generally top-notch, they may conceivably know more about your user base than you do.
The major way to avoid this problem is to allow people to use the service of their choice, instead of a single service. If you are limited to developing one, for development time constraints, using OpenID is the best bet because many other authentication domains also qualify as OpenIDs, and therefore ameliorates most of the above problems.
I think using IDs from any of these big names are ok as long as you don't provide service that needs an endpoint like email, IM etc.
However, OpenID is just not trust-worthy. If you have any doubts, try this OpenID
http://opennoid.appspot.com/anyid
This is a disposable ID that doesn't require a password to login.