Introduction
Recently a colleague from a previous employer of mine pinged me about connecting to Skype for Business using the Unified Communications Web API (UCWA). UCWA is the REST API that comes with Skype for Business 2015 and exposes Instant Messaging and Presence capabilities. Initially UCWA was only for the OnPremise release of S4B, but this has recently been extended to Skype for Business Online.
The detail on leveraging the UCWA is all here however when it comes to actually doing it, it gets a little daunting. This blog by Matthew Proctor gives more hope and a few more threads to pull on to get something working. After jumping through a few hoops and also being pointed in the right direction from this post from Adam I got the sequence sorted to authenticate, access the API using PowerShell and then actually doing something with it. I thought I’d write it up so I can save someone else the pain (and myself if I need it in the future).
Getting Started
As per the title I’m going to show you connecting to and consuming information from Skype for Business Online using PowerShell. Naturally you’re going to need to have an Office365 Tenant with S4B and all the pre-requisites associated with that configured (such as your CNAME and SRV S4B DNS settings etc).
This post covers using PowerShell to:
- Authenticate to the UCWA API
- Get your S4B account details
- Change your status between Busy, Away and Available, Do not disturb
- Get your Contacts
- Get your Contacts status
That should give you enough to also get started and munge it for whatever you need.
Authenticating
The following script gets you authenticated to S4B Online via the API. Change the script for your S4BO account and associated password. Also update for your S4BO tenant Autodiscover URL.
Create the UCWA Application
The following script will create an application on the UCWA endpoint. The Endpoint ID you can make up yourself. Same for the Application name.
Change your Presence, Get your Contacts & their Status
Now you can do what you want or need to with the API. Here are a few examples of changing your status, getting your contacts, getting the status of your contacts.
Contacts Statuses
Contacts List
Follow Darren on Twitter @darrenjrobinson
$rootappurl is not defined. What’s that supposed to be?
My bad. Didn’t post those two lines. Updated in GIT. You should see it now at the bottom of the Authenticating Script.
Thanks, that works now.
Now trying pull out the conferenceID for the current user (e.g. from the Dial-in Conferencing page). I have the onlineMeeting ID so can construct the MeetingURL but the conference ID eludes me.
I got the onlineMeetingID (the last part of the current user’s default MeetingURL like this:
$data = Invoke-WebRequest -Uri (“$rootappurl/$appid/onlineMeetings/myOnlineMeetings”) -Method Get -Headers @{“Authorisation”=”Bearer $authcwt”} -ContentType “application/json” -UseBasicParsing
$onlineMeetingID = ($data.content | ConvertFrom-Json)._embedded.myAssignedOnlineMeeting.onlineMeetingID
Any idea where the ConferenceID can be found?
Once you have the onlineMeetingID, add that to your URI and make another GET call eg.
https://YOURDOMAIN/ucwa/oauth/v1/applications/YOURAPPID/onlineMeetings/myOnlineMeetings/MEETINGID
In the content of the response you will find the conferenceID.
BTW, I worked it out by looking at the API doco here https://msdn.microsoft.com/en-us/skype/ucwa/myonlinemeeting_ref
I was reading that doc but I never would have thought of that. Works like a charm. You’re a legend. Thanks.
Have this pretty solid now. Thanks for your help. Started down another rabbit hole which is conversation history.
If I look under here:
$rootappurl/$appid/communication
I see conversations, startMessaging, startOnlineMeeting and joinOnlineMeeting
Seems like i should have a few more: https://msdn.microsoft.com/en-us/skype/ucwa/communication_ref
But the one I think I really need is conversationLogs. Any idea why it’s missing or how to get at it?
Thanks
Hey Tony, yes I’m seeing the same as you. It appears to be because of the scope of the application. Looks like to access CommunicationLogs we need to specify a different scope. I’ll have a mess around and see if I can work it out.
Hello,
Thanks for the great script but i have an issue on office 365, i receive the following error when it gets the oauth token :
{“error”:”unsupported_grant_type”}
Does it mean we can’t make it work with a full O365 s4b infra ?
Thanks.
missed this comment. Try a different Grant Type Method as detailed here https://ucwa.skype.com/documentation/GettingStarted-Authentication
Hello Darren,
I desperately tried to use your code to access to Skype for Business Online, and I’m stuck at the Oauth request.
So do we have to register a specific UCWA apps prior to run the scripts ?
If yes, what is the process ?
Thanks,
I’m guessing you are getting an error from the webrequest response on line 20? Something like
Invoke-WebRequest :
500 – Internal server error.
Server Error
500 – Internal server error.
There is a problem with the resource you are looking for, and it cannot be displayed.
This is usually the case if the account you are using has the password to not-expire. Change the password for the account and you should be all good.
Alternatively you may have S4B configured in a different method. If you are on Domain joined machine, try using the Integrated Windows Authentication Grant Type as detailed here urn:microsoft.rtc:windows https://ucwa.skype.com/documentation/GettingStarted-Authentication
Hello,
Can I query my online meetings based on the expiration time?
Hey Pavan. Just looking at it and it appears you’d need to return all meetings https://msdn.microsoft.com/en-us/skype/ucwa/myonlinemeetings_ref then enumerate through them.
Oh, I need a solution for onprem. Can this be adapted?
I don’t see why not. Checkout the references here for On Premise Skype for Business https://msdn.microsoft.com/en-us/skype/ucwa/developingucwaapplicationsforskypeforbusinessserver
Does this script (still) work on Skype Online with Azure AD? I get an error:
Invoke-WebRequest : {“error”:”unsupported_grant_type”}
And the documentation at https://msdn.microsoft.com/en-us/skype/ucwa/authenticationinucwa states “Note: If your application authenticates against an on-premises server, follow the authentication flow as described in this article. If the application authenticates against an online server, follow the Azure AD authentication flow as described in “Authentication using Azure AD.””
And the documentation at https://msdn.microsoft.com/en-us/skype/ucwa/authenticationusingazuread only describes an interactive user login.
Hi Darren, I’m facing this “fixed-credentials” auth with S4B Online since a while but I never found a solution. The auth flow works well when using the interactive method, but I couldn’t make it work with user/pass written in code as you do here.
I tried your script but the main issue regards the autodiscover url. As far as I know the main S4B Online autodiscover is https://webdir.online.lync.com/autodiscover/autodiscoverservice.svc/root, which is the main hub that replies with the secondary hub url(s). When I tried it, the script simply told that “We couldn’t AuthN with the username & password provided. Update and try again”, so it seems it’s not the valid autodiscover url. All works fine with an on-prem S4B server. Any suggestion?
Thanks
Is your S4B online tenant federated and requiring MFA ?
I’m not an administrator of this tenant, but from Azure AD console I can see that all domains and subdomains are federated (I knew this also by the user experience on login). About MFA I can’t be totaly sure but, from a user experience I did never receive any multi-factor auth request or option.
I guess that the grant type ‘password’ can only work for Azure AD users or when you enable the AD Connect with password synchronization, because there is no way to delegate Azure to validate user and password when you are using an external STS provider (ADFS or another one, like in this case)
also grant type password is only allowed for app registrations in Azure AD of type system and not of type webapp.
Hi
I am actually working on getting s4b status
I tried your code but I am getting this error
Could not retrieve S4B Autodiscover information on https://lyncdiscoverinternal.domain.com/
I tried using ucwa in python also. But there also i got the same error. what is wrong here?
can anyone help me out with this!!!!
Thanks
Rather than programmatically discovering it, hard code the variable for your environment.
Hi
I am trying to connect to Skype For Business Online through Powershell with your code but I am having some issues.
I am getting the error: Invoke-WebRequest : {“error”:”unsupported_grant_type”} when posting my password to the URL.
I am using the password grant type and I am getting this error on a few tenants
I was wondering:
IN your script you convert your password to a secure $pwd variable, is this necassary?
Did you first create an application in Azure AD?
Thanks in advance!
Do you know if we can utilize a similar process to connect to UCWA 2.0? It appears that getting oAuth Token doesn’t work if you are connecting to O365 version.
Hey JRR, I haven’t revisited this since I wrote it. Is your environment Federated or AAD auth?