Installing Windows Packages with winget

In this post I’ll tell you about the Windows Package Manager and winget tool (currently in preview) for installing Windows packages. Feel free to use my sample script as a starting point for downloading useful tools and applications for Windows.

Background

Last week my primary laptop (~4 months old) ran into some issues and I attempted a restore from a weekly backup taken just a few days before. Unfortunately the restore put the machine into an unusable state (a sign that I won’t be using that backup software any longer). After a re-install of Windows I was once again put to the task of re-installing dozens of applications. I have gone through this process many times before, but this time around I thought it would be good to test out the new Windows Package Manager and winget tool.

Solution

Disclaimer: At time of writing, Windows Package Manager and the winget  tool are in public preview and may be substantially modified before they are generally available. Microsoft makes no warranties, express or implied, with respect to the information provided here.

Use the winget tool to install and manage applications
https://docs.microsoft.com/en-us/windows/package-manager/winget

The first step is to install the winget tool. There are a few options for installation and I chose to download from the releases from the winget repository.

Once installed you can run commands for search, show, install and more. I tested a few installations interactively but once I got the hang of it I scripted out a list of commonly used tools and applications that I use on almost all of my machines. Below is my script that you are free to copy and adapt as you see fit. I have chosen PowerShell to run the script but that is not a requirement.

Note: If you do not see the below Gist please refer to code at this location: PS-WinGet_Apps_To_Install.ps1

winget install Microsoft.dotnet
winget install Microsoft.PowerShell
winget install Microsoft.WindowsTerminal
winget install Postman.Postman
winget install Notepad++.Notepad++
winget install Telerik.Fiddler
winget install Microsoft.VisualStudioCode
winget install Microsoft.VisualStudio.Enterprise
winget install Microsoft.Powertoys
winget install microsoft.mousewithoutborder
winget install OBSProject.OBSStudio
winget install VideoLAN.VLC
winget install LINQPad.LINQPad
winget install WinDirStat.WinDirStat
winget install Microsoft.AzureCLI
winget install Microsoft.AzureStorageEmulator
winget install Microsoft.AzureStorageExplorer
winget install Microsoft.AzureFunctionsCoreTools
winget install Microsoft.EdgeDev
winget install Microsoft.Teams

Do read the note (link) in documentation about scripting winget. If an installer launches a new process that can lead to starting the next installation before the previous completes. This may result in unexpected issues or failed installations.

Conclusion

I found winget to be very helpful in re-installing a dozen or more applications on my refreshed laptop. The next time you need to install (or re-install) an application I would encourage you to check for it with the Windows Packager Manager and winget tool. Happy installing!

-Frog Out

Presenting at Collab365 GlobalCon3

I have the privilege of presenting “Introduction to Microsoft Graph Development” at the upcoming Collab365 GlobalCon3 taking place Sept 8-11, 2020.  This is a free online conference with MVPs and experts from around the world presenting on developer, IT Pro, and adoption topics.

Title: Introduction to Microsoft Graph Development

Abstract: “I hear that I need to use Microsoft Graph for developing against Office 365 but I have no clue where to start.” “I want to grant access to company data without throwing in the entire kitchen sink.” Fear not fellow developers and admins. This session we will ramp you up to a 200 level knowledge on the pertinent parts of Microsoft Graph including endpoints available, syntax, authentication flows, and more. We will also cover useful examples of what can be accomplished using these APIs. Prior experience with Microsoft Graph is not required but can be helpful.

You can also purchase an all-access pass which includes lifetime access to the videos, additional e-books, and more.  Looking forward to participating in this great event.

Calling Microsoft Graph Endpoint with Delegated Implicit Authentication Does Not Include Azure AD Roles

Recently I was working with a Microsoft Graph partner and ran into an interesting scenario around calling Microsoft Graph endpoints from SharePoint Framework (SPFx) web parts using delegated permissions that I want to share.

Scenario

The partner was building a SPFx web part that was making calls to Microsoft Graph using the MSGraphClient. While making calls to specific endpoints on Microsoft Graph they were receiving a 403 Forbidden error response. We checked the permissions granted and consented and everything appeared in order.

403 Forbidden error screenshot.

Digging deeper into the MSGraphClient implementation I found that it uses an ImplicitMSALAuthenticationProvider for acquiring the authentication token. Implicit authentication is important to keep in mind in this scenario.

Use the MSGraphClient to connect to Microsoft Graph https://docs.microsoft.com/en-us/sharepoint/dev/spfx/use-msgraph

Microsoft Graph JavaScript Client Library – Authenticate for the Microsoft Graph service https://www.npmjs.com/package/@microsoft/microsoft-graph-client#2-authenticate-for-the-microsoft-graph-service

I used https://jwt.ms (provided by the Microsoft Identity Platform team) to decode a sample token from the partner and then again to decode an access token I had acquired in my lab environment. I noticed that the partner’s access token did not have the “wids” claim while my lab access token did have that claim.

Thanks to a contact in O365 software engineering who was able to confirm that the “wids” claim contains the tenant-wide roles assigned to the user. As noted in the documentation implicit authentication flows may not return the “wids” claim due to token length concerns.

Screenshot of documentation on "wids" claim.  Highlight that this claim might not be returned for implicit authentication flow.

Microsoft identity platform access tokens – payload claims

https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens#payload-claims

Looking at one of the Microsoft Graph endpoints that the partner was calling (getOffice365GroupsActivityDetail) we found the below note explaining that when using delegated permissions (which the partner was using) the user context must also be assigned to an appropriate Azure AD limited administrator role.

Note: For delegated permissions to allow apps to read service usage reports on behalf of a user, the tenant administrator must have assigned the user the appropriate Azure AD limited administrator role. For more details, see Authorization for APIs to read Microsoft 365 usage reports.

https://docs.microsoft.com/en-us/graph/api/reportroot-getoffice365groupsactivitydetail?view=graph-rest-1.0#permissions

Putting the pieces together, the query was failing an authentication check because the access token passed to the endpoint did not have the necessary claim containing the assigned Azure AD roles. Hence the “invalid permissions” response.

Conclusion

This is an edge case scenario that took some collaboration with various groups within Microsoft to track down. Many thanks to my peers who helped with identifying additional information as we investigated. I submitted a pull request to the SPFx documentation that has been merged to call out this behavior (see Known Issues on this link). So far that I can tell only the Microsoft 365 usage reports endpoints on Microsoft Graph may have an Azure AD role requirement.

Authorization for APIs to read Microsoft 365 usage reports
https://docs.microsoft.com/en-us/graph/reportroot-authorization

Hopefully this post helps others who may run into this scenario. If you find additional similar scenarios feel free to let me know in the comments.

-Frog Out

Outlook Calendar Tips for Remote Teams

As mentioned in my last blog post A New Role with Microsoft Graph Team, I mentioned I am joining the Microsoft Graph team. One of the nice aspects of our team is that we are diverse and globally dispersed. With the different time zones that our team all reside in I thought it would be helpful to review a few of my calendar settings in Outlook desktop and Outlook on the Web to help with scheduling meetings or calls.

Working / Meeting Hours

Set your working / meeting days and hours so that teammates will know when you are generally available for scheduled meetings or calls. Personally, I wake up early most days and hence my start of the day is likely earlier than some others.

Outlook desktop: File -> Options -> Calendar -> Work time

Outlook calendar settings for working hours

Outlook on the Web: Settings -> Calendar -> View -> Meeting hours

Outlook on the Web calendar settings for meeting hours

Time Zones

Since my team is all over the world, it is important to be aware of time zones for scheduling meetings. In Outlook desktop it is possible to set your primary time zone and display 2 additional time zones. In the following screenshot I have set Eastern Time (US & Canada) as my primary time zone with additional time zones for Pacific Time (US & Canada) and East Africa Time (Nairobi). I have purposely kept the labels short so that they fit easily in the display on calendar views.

Outlook desktop: File -> Options -> Calendar -> Time zones

I have only been able to add a single time zone in Outlook on the Web. If someone knows a way to add multiple please let me know in the comments or contact me.

Outlook on the Web: Settings -> Calendar -> Language and time

End Meetings Early

Whether you are hosting a meeting in-person or online there are many reasons you may want to end your meeting early including:

  • Allow attendees time to walk to their next meeting room
  • Encourage attendees to wrap up their meeting without overlapping the following time block
  • Give attendees time for a mental break / chance to use the restroom in between meetings
  • …and more

Outlook desktop: File -> Options -> Calendar -> Calendar options

Outlook on the Web: Settings -> Calendar -> Events and invitations -> End appointments and meetings early

Share Free / Busy Times

In addition to setting your working / meeting hours, you can also come to show your free / busy times (and more) with other people.

Outlook desktop: File -> Options -> Calendar -> Calendar options -> Free/Busy Options

By default you may see that all users in your organization are able to see your free / busy times. You can adjust permission levels to show more details or add / remove additional people to have access to view your calendar.

Outlook on the Web: Settings -> Calendar -> Shared calendars

Publish Calendar

Aside from showing your free / busy times to people internal to your organization, sometimes you may want to publish your calendar to people external to your organization. Currently I have found this easiest to do through Outlook on the Web.

Outlook on the Web: Settings -> Calendar Shared calendars -> Publish a calendar

After you publish your desired calendar you can provide people with either an HTML (render in browser) or ICS (universal calendar file format) link.

Conclusion

In this post I walked through a number of calendar settings and preferences on my Outlook desktop and Outlook on the Web client. I hope this helps you to think of the diverse and global audience that you may be working with currently or in the future. If you have any additional tips you recommend please share them in the comments.

-Frog Out

A New Role with Microsoft Graph Team

For the past ~9 years I have had the personal and professional pleasure to be a Premier Field Engineer (PFE) with Microsoft. I love the passion and knowledge that my peers and I share on a daily basis with our customers and each other. Recently though an opportunity opened up that I couldn’t say no to.

Starting May 26th I am joining the Microsoft Graph team as a Sr. Customer & Partner Experience (CPX) PM. This is an entirely new role for the team and I will be the first member. I’m looking forward to the new opportunities and working with amazing teammates, many of whom I’ve worked with on side projects for the past 1-2 years.

I plan to continue writing content for my personal blog at least every other month, but you may see more Microsoft Graph related content or cross postings on the Microsoft Graph Blog. Considering that my highest viewed posts in the past few years have been Microsoft Graph related that may not be much of a change though 😉. I’ll also be more active on the newly released Microsoft Q&A site as well as Stack Overflow under the “microsoft-graph” tag.

Thanks to everyone who has helped and encouraged me in my growth with Microsoft Graph. Special thanks to Jeremy Thake, Yina Arenas, Jason Johnston, Darrel Miller, Vincent Biret, Gavin Barron, Srinivas Varukala, and many more.

-Frog Out

How I Develop Locally With GitHub and Azure DevOps Repos

A peer of mine recently asked about how I manage local code (projects, solutions, Git repos, etc.) that may or may not be synced to a cloud repository (GitHub, Azure DevOps, etc.)  Since I previously blogged about How I Blog – Updated 2018 and I’m a fan of re-using how many keys I have left I thought I would share my personal local development process.

 

Disclaimer

I like to to tell people that “I play a developer on TV”, meaning it has been at least 10 years since I’ve written code as a consultant that was actually deployed to a production system.  Sure I’ve written (or collaborated on) many samples (ex. .Net Core console sample for Microsoft Graph) and proof of concepts for customers these past 10 years, but it wasn’t the primary focus of my job.  So balance everything that I share with what others such as my friend Steve Smith (@Ardalis) share on his Weekly Dev Tips blog and podcast.

 

Local Folder Structure

Currently I develop on Windows so folders and paths will reflect that.  I don’t use the default folder that any of the IDEs or tools below use (generally under my user profile folder such as “c:\Users\[username]\…”).  Instead I create a new folder called Projects at the root of my primary drive (i.e. “c:\Projects”).  Below that folder I then have the following:

  • c:\Projects\_DevOps
  • c:\Projects\_GitHub
  • (All other local-only projects, ex. c:\Projects\localProject1)

Using the underscore for _DevOps and _GitHub means that those folders should be easy to find at the top of this folder structure even if I happen to inadvertently sort the folder.

As for project folders, I’ve thought about subdividing based on topic (ex. SharePoint Online, Azure, Microsoft Graph, etc.) or technology (ex. ASP.NET Core, Blazor, Console, etc.) but since I rarely have a large number of folders I haven’t done anything yet.  I do name my folders and projects based on topic though (ex. BTJ.SPO.ProjectName, BTJ.AZ.ProjectName, BTJ.MG.ProjectName, etc.)  This helps at least group together similar projects.

 

Git / GitHub / Azure DevOps Tools

I use a mix of the following tools to sync my repos and monitor issues or pull requests.

  • Visual Studio Code (VS Code) – VS Code has integrated supported in-box for Git.  I use this for committing and pushing code to my GitHub repositories.
  • Azure Repos Extension for Visual Studio Code – There is an extension for VS Code that adds additional functionality (ex. monitor builds, pull requests, and more) directly into VS Code.

  • GitHub Desktop client – GitHub offers a desktop client that allows you to sync code, create branches, review commit history, and more.  When I’m not directly in VS Code working on a repo I generally use GitHub Desktop.
  • Visual Studio Team Explorer – In general I start most projects in VS Code these days.  For the projects I do work in Visual Studio 2019 (ex. Blazor and some ASP.NET Core) I use the Team Explorer functionality (now available out of the box) to sync repos.  The integration with Azure DevOps and GitHub is good as well.
  • GitHub mobile app – I do submit and review a GitHub issues or pull requests on an infrequent basis.  When I am not at my desk I tend to use the newly released mobile app for GitHub.
  • Browser based pull requests – Some repositories that I collaborate on are very large and not well suited to sync locally (ex. Azure docs, Microsoft Graph docs, etc.)  For these I prefer submitting a pull request directly in the browser.  I previously blogged about this at How to Edit Microsoft Documentation on GitHub.

 

Conclusion

I hope you have found something useful in this post.  Please share your own suggestions or recommended tools / processes in the comments below.  Happy coding!

-Frog Out