Why Microsoft Support Frustrates So Many Users (And What Needs to Change)

Microsoft is a tech giant with decades of experience and products that touch nearly every corner of the digital world—Windows, Office, Azure, Xbox, and more. So Why Microsoft Support Frustrates so many people? Even, despite its reach and resources, one recurring pain point continues to frustrate customers and IT professionals alike: Microsoft Support.
What has inspired me to write an article about this is the several experiences I have had with Microsoft over the years and how it has gotten progressively worse. The straw that broke the camel’s back was here.
It will go down in my support experience as the worst I have ever encountered!
So, let’s talk about why Microsoft Support often leaves users feeling stranded—and what could be done to fix it.
Automated Support – Why Microsoft Support Frustrates
One of the most common complaints is the heavy reliance on automation and chatbots. While AI-driven support can be helpful for basic questions, many users report going in circles with bots that don’t understand their issue, or that simply redirect them to irrelevant knowledge base articles.
I do not mind the email support option, but the bigger issue is that a lot of problems I experience are on the server side and MS support treats EVERYTHING like it is client-side. This is where the “Labyrinth” complaint comes to mind. This is one of the reasons why I don’t pick the phone option. The technician always wants to start a remote session and that is the last thing I need.
Most of the time, it is a user of mine that needs support and a remote session just isn’t feasible. I am not a user; I am a technician myself!
Support for Critical Services Isn’t Always… Supportive
Another reason why Why Microsoft Support Frustrates so much in terms of support is that Azure, Microsoft 365, and Dynamics 365 are mission-critical for many businesses. Yet, even for enterprise users, support responses can be delayed, vague, or incomplete. Time-sensitive issues sometimes take days to resolve, often bouncing between tiers or departments.
You can go to the service health page to see what’s going on. But it doesn’t tell you much. You really have to go to third-party sources like this one. This isn’t just frustrating, it’s a business risk.
Disjointed Experience Across Products
Need help with an Office 365 license, a OneDrive sync issue, and a problem with a Windows update? From the portal It looks like the company that sells tightly integrated solution, but it’s not. You’ll likely be shuffled across different support teams, each with limited knowledge of the others. The result is a fragmented experience that lacks the cohesion you need.
The Community Does More Than the Company
Ironically, some of the best “Microsoft support” doesn’t come from Microsoft. It comes from independent MVPs, IT forums, YouTube tutorials, and bloggers. While this speaks to the strength of the Microsoft community, it also underscores a weakness in official support infrastructure. I almost exclusively use these support channels to solve my M365 issues. Over the years I have become increasingly disillusioned with Microsoft Support.
Premium Support Comes at a Premium Price
Microsoft does offer higher tiers of support for enterprise users (e.g., Premier or Unified Support), but they’re costly and still not always timely. Small and mid-sized businesses often feel left behind, with limited access to real experts unless they pay more.
So, What Should Microsoft Do?
To be fair, supporting an ecosystem as vast as Microsoft’s is a herculean task. But if they’re serious about user satisfaction, here are a few ideas:
- Invest in human-first support, especially for issues automation can’t solve.
- Create centralized, cross-product teams that can tackle integrated problems holistically.
- Make diagnostics transparent and user-friendly, with clearer error messages and guided troubleshooting.
- Empower community contributors with better tools, faster bug escalations, and more collaboration.
Final Thoughts – Why Microsoft Support Frustrates
Microsoft’s products are powerful—but support is their biggest weakness. For a company so deeply embedded in the digital infrastructure of the world, improving the support experience isn’t optional, it’s essential.
Let’s hope they start listening to the people who depend on them most: their users. Nah….that would never work……
Resources in Exchange Don’t Respond to Meeting Requests

Your resource rooms have been working for as long as you remember. Why then, suddenly, do Resources in Exchange Don’t Respond to Meeting Requests? You set up these rooms ages ago and they just worked. It is supposed to be easy.
You didn’t change anything. And the wild goose chase begins……Of the things it could be I will go through two fixes that didn’t work and one that did for me.
Corrupt Free/Busy Data on Resource or Client Email Box
This could be a reason Resources in Exchange Don’t Respond to Meeting Requests and was suggested to me by Microsoft. It is a program called MFCMapi. It is like a registry editor for your Outlook profile. From here you can open the resource room profile (You will probably need to create one) and locate two free / busy files. They are called localFreeBusy and Sniffer. You need to delete them. The screenshots are below:



Basic Configuration Settings on Resource Not Correct
Once again, nothing has changed so why would I check this (I am looking at you Microsoft)? They suggested the following:
1. Check Room Mailbox Auto-Processing Settings
Run this in Exchange Online PowerShell:
powershell
Get-CalendarProcessing -Identity “RoomName” | fl AutomateProcessing,BookingWindowInDays,AllowConflicts,AllBookInPolicy,AllRequestInPolicy,AllRequestOutOfPolicy,BookInPolicy,RequestInPolicy,RequestOutOfPolicy
You want to see:
– AutomateProcessing : AutoAccept
– AllBookInPolicy : True (or the user should be listed in BookInPolicy)
If not, set it like this:
powershell
Set-CalendarProcessing -Identity “RoomName” -AutomateProcessing AutoAccept -AllBookInPolicy $true
2. Check Delegate Permissions
Ensure the delegate has Editor or Full Access to the user’s calendar, and that the room is being added as a required attendee.
Also, verify that the delegate is not using “Send As” or “Send on Behalf” in a way that bypasses room booking policies.
3. Test Direct Booking
Try having the delegate book the room directly (not on behalf of someone else). If it works, the issue is likely with how delegate bookings are processed.
4. Use Message Tracking Logs
If you’re an admin, run a message trace in the Exchange Admin Center to see if the room received the booking request at all. The messages were getting to the resource but the resource was not responding. It was stuck….
Advanced Configuration Settings on Resource Not Correct
Here is how it finally got Resources in Exchange Don’t Respond to Meeting Requests fixed.
At this point, it looked like a client-side issue. But Resources in Exchange Don’t Respond to Meeting Requests still! However, it was working on some users and not others. I was one of the affected users. Something changed and not by me or my colleagues….
Finally, I found this Article. It is an obscure article from about 4 years ago. The affected admin was having problems booking resource rooms and they were not auto accepting. It was different in that instead of allowing anyone to book a room, they were using delegates. However, the base issue was the same.
If you run “Get-CalendarProcessing <resource room name> | fl” you get all configuration settings. There are 46 of them in total. Near the bottom, there is a setting called “ProcessExternalMeetingMessages”. It was set to false. It needs to be set to True:
Set-CalendarProcessing <resource room name> -ProcessExternalMeetingMessages $True
Low and behold the message loop between the person / delegate booking a resource and the resource accepting were finally closed. Things started flowing again.
How do you know you have Resources in Exchange Don’t Respond to Meeting Requests
When this issue is evident users might complain of meeting reservations not showing up in room calendars, or worse, if it is an intermittent problem (in my case), users complain of double bookings. Basically, a user booked a room, and it was not marked off in the resource, therefore technically still available. A user who wasn’t exhibiting the issue would book the same time and it would reserve the room, hence the double booking! Frustrating the say the least.
Why am I Telling You This
It is important to know that what it takes to solve a seemingly simple problem can take a long time. For me it was reaching out to Microsoft several times. They were no help, but I didn’t give up on my relentless google search, trying to find the right phrase that would yield a result. You know how when you search for something on Google and a million search results come up? I only had about 2 dozen and the article that finally fixed my issue WAS THE LAST ONE.
I wrote an article about my experience with Microsoft Support. I have had a lot of them.
I am also going to open this post up to comments. Please let me know what your experiences have been. I would love to hear!
Enrolling an Android Phone the Correct Way

So, would you like to know the correct way to enrolling an Android Phone? If you read this article, you will save yourself a lot of time in the process. Apparently, my content as of late has low value (says Google) so I guess I better beef it up a bit (JSYK, Google is full of shit).
What you Need to Do First When Enrolling an Android Phone
I have Written other Articles On Enrolling Devices in InTune but things have changed a bit so here is an updated version.
If you are replacing a user’s phone with a new one, you will need the passcode of the phone as well as their windows credentials to enroll the device. I rarely ask for this information for a user but sometimes it cannot be helped (make sure you have your ID badge handy LOL). If it is a brand-new user, you already have their Windows credentials, and you can create the passcode. Other Items that are really important:
- Make sure the SIM card is installed.
- Access to Wi-Fi.
- Set up MFA. See steps below.
You Will Have to Temporarily Setup MFA for New Users
MFA is mandatory. If you are setting up a phone upgrade for a user, you can use the MFA that is already set up on their old phone. For new users, you will need to temporarily set up MFA on the authenticator app on your phone (I can show you how to remove it after). For new phones, open an Incognito Window in Chrome and go to https://aka.ms/mfasetup
(If a New User)- Sign in with the username and password:



You will need to click next. You cannot enroll the phone without MFA.


Click Next.
Leave the below screen up on your computer:

Go to your Authenticator App and click the “+” button to add the users account, then choose work or school. Then Scan the QR Code from your computer screen:


Click Next on your computer screen:

You will be given a test number on the screen:

Enter the number into your phone:

Click Yes on the phone and then click Next on the computer screen:

Click Next.

MFA is set up temporarily on your phone to help with the enrollment of the user’s phone, click done.
Get the QR code
If you have gotten this far you have already set up a profile in Intune. Go to Devices / Android / Enrollment and pick the profile that you create to enroll the Android Device(s).

And then token. The QR Code will look something like this:

You can print this code out and have it ready when you need to enroll a mobile device.
Actually Enrolling a Mobile Device
The mobile device you are enrolling in must be set to factory defaults. If it is a brand-new phone this has been done already. If it is a phone that has never been enrolled in Endpoint Manager, it needs to be factory reset. If the phone is already enrolled in Endpoint Manager and you need to redeploy it to another user, you need to wipe the phone and re-enroll. You will have to look at the end of this article for information on how to do this. It is a multi-part series. You might want to check that article out too.
- To begin enrolling, at the first screen you see when the phone is turned on, tap continuously in the center of the screen until you see the QR code scanner (About 5 times). The process will begin.

- Next you will be asked to connect to Wi-Fi. Connect the phone with its passphrase you are enrolling onto it.

- Find Your Wifi and click connect.

- Tap at least the first two check boxes and tap agree.

- Tap Next.

- Tap continue.

- Let this screen load.

- Tap Next.

- Sign in with the user’s name and password.

- You will be prompted for MFA. Enter the number into the App either on your phone (new User) or in the user’s old phone (User Upgrade).

- The enrollment process will start.


- Tap “Install”.

- The following Apps are installed. All the other LOB Apps will be installed after if you have set any up. Tap done.


- Tap “setup” to register the device.

- Tap “sign in” to for Intune.

- Tap Continue.

- Tap “Register”.

- You may get this screen again. Tap Continue.

- Tap “Next”.

- Tap Next Again.

- You may have set a device category. Pick one and Tap OK.

- Tap done.

- You will be brought to the home screen of the phone.

- The phone is enrolled, and it is good practice to rename it in the InTune portal. Please go to https://intune.microsoft.com/ to do so. But it is not 100% necessary.
- At this point, if it is a phone upgrade for an existing user you can use Samsung Smart Switch to Bring over the users’ data from their old phone. If this is a new user, you can skip this step.
- All the LOB Apps (If you do that) should be downloaded to the phone. It takes a few minutes after the phone is enrolled. You will see notifications on the phone while they are downloading and installing. Please remove all unnecessary apps on the phone by long pressing them on the home screen and tapping “Remove”.
- Swipe up to see all app and long press and Tap “Add to Home Screen”.
- Go into each app essential app for the user and configure. Once again, only if you have set this up.
- Please set up their MFA. Use the same steps above that you used to temporarily set up MFA to enroll the phone. MFA is still set up on your phone in case of the new user or you can use the old phone of the upgrade user.
- Don’t forget to add a passcode to the phone. It is just good security.
Why Am I Giving you Info About Enrolling an Android Phone
There are several ways to be Enrolling an Android Phone but at the moment this is by far the fastest a most reliable way to go about Enrolling an Android Phone. Microsoft will inevitably change things. My site is dedicated to giving you useful up to date information so you can get on with administering your M365 tenant. whether you are a small business, MSP or fortune 500 company. This information will save you precious time!
Clean Up Outlook Mail (2 Ways)

If you need to Clean Up Outlook Mail it can be very easy. You just need to do it right. In this article, I can show two ways or steps if you will that can make this process very easy. The thing is you need to do these steps in the correct order to make the most out of your clean up.
I originally wrote a smaller article on this before. But this one is more comprehensive. Let’s begin with the first step on how to Clean Up Outlook Mail…..
Step One – Clean Up Outlook Mail with Mailbox Clean Up
Using this step will be very helpful and prepare you for executing step two. More on that later.
Click File at the top left and then “Mailbox Clean Up”

Mailbox Cleanup looks like this:

You can click “Mailbox Size”. It will show the folders in your email and give you a general idea of where items are stored.

You can look for “items older than” or “items Larger than” you can determine which items you can delete:

Once you have found what you are looking for you can highlight all the items in the result, right click, and choose “delete”:

Once you are done searching and deleting older items by date and / or size, you can empty your deleted items folder:

Now that you are done this you have (known or not) prepared for the next step…Auto-Archiving.
Step Two – Clean Up Outlook Mail with Auto-Archive
- Click File / Options / Advanced / Auto Archive Settings:

2. Once you have opened Auto-Archive Settings from options, you need to set them:

3. You will need to configure at least 4 settings. They are:
Enable Auto archive – You won’t be able to configure any other settings until you check this box.
Frequency – specify in Days how often you would like archive to run (in days).
Date to Start Auto Archive – When auto Archive runs it checks for items older than you specify and adds them to the archive. You can specify Months / Weeks / Days, or you can choose to permanently delete old items. I wouldn’t recommend this unless you are an advanced user and know how to work with .ost files.
Once Auto-Archive runs once you will see it in your Outlook underneath your inbox as a searchable mail store:

Depending on the plan you have with Exchange Online, you will have limits to how much data you can store. Online it is between 50GB and 100GB (depending on how you are licensed). The Size of your Auto-Archive file can only be up to 1.5 TB. I would figure if you have that much mail you might be using your email account for more than just email storage. Maybe time to move some of that to OneDrive!
Active Teams Users in Phone Directory – 2 Steps

So, do you have users complain that when they dial for a name in your team’s main auto-attendant, they get more than Active Teams Users in Phone Directory? Maybe a user that hasn’t worked for years in the company and their name is still an option…. not really. I will explain why.
Why It Appears Like Active Teams Users in Phone Directory
I have written several articles on Teams Administration. This is just another stop on an otherwise long journey! You can do everything to rid the user of the system. You can block their sign-in, you can remove the team’s number, heck you can even take all their licenses away. But why are they still showing up in the Teams Phone Directory of your main Auto-Attendant? I will tell you why and how to remedy it in 2 steps.
Why is this happening?
Since M365 has several systems cobbled together over the years, not all aspects of information update automatically or are related to each other. MS Teams is a great example of this since it was really developed separate from the rest of M365 and shoe-horned in. I will show you later in the article how to use what is called a “dial – scope” in Teams Admin. Here are the Steps to fix this.
Create an Entra Group of Users You Want in the Directory
You can do this manually or through Dynamic Membership Rules to keep only Active Teams Users in Phone Directory. An example of a dynamic membership rule could be one based on licensing. Typically, when a user is offboarded by the organization the user is un-licensed from Teams. This would effectively remove them from the group and the directory:

But I am getting ahead of myself. On to the next step.
Create a Dial Scope for Active Teams Users in Phone Directory
I have a great article on how to set up an Auto-Attendant in Teams. This shows you how to set up an Auto-Attendant but there is a section called a Dial Scope. In this section it allows you to put a group into the dial scope. So, when the Auto-Attendant asks you to dial by name only those who are licensed for teams (and therefore active) can be searched. You can add a group to include in the search and if you want to fine tune a little bit, you can also have an “exclude” group:

Android Fully Managed Devices and Samsung Smart Sync in InTune

A challenge with Android Enterprise managed devices is the lack of ability to restore data from an old device to a new device. You want to use Android fully managed devices and Samsung Smart Sync. Other than that, there really isn’t anything else for back in the Android Enterprise. The Samsung Smart Switch is a great solution for personal devices so why not Intune enrolled devices?
It can be, but this only works out of the box for the Personally Owned Devices with Work and Corporate Owned Devices With Work Profile (the Samsung Smart Switch app is only supported in the personal profile) enrollments.
The Samsung Smart Switch app is not designed for enterprise environments and will be restricted by default.
It can be done with the more restrictive Corporate-owned Fully Managed User Devices but there are 2 steps involved. Thats what this post is about.
Android Fully Managed Devices and Samsung Smart Sync App Distribution
When looking at using the Samsung Smart Switch app on Android Enterprise fully managed devices, the app should be distributed by using Microsoft Intune. That will make sure that the backup and restore functionality will be available. The distribution of the Samsung Smart Switch app can be achieved by going through the seven steps below.
- Open the Microsoft Endpoint Manager admin center portal navigate to Apps > All apps > Android
- On the Android | Android apps blade, click Add to open the Select app type page
- On the Select “app type” page, select Managed Google Play app as App type and click Select
- On the Managed Google Play page, search for the Samsung Smart Switch Mobile app, select the app and click Approve
- On the Permissions dialog, click Approve
- On the Approval settings dialog, select Keep approved when app requests new permissions click Done
- Click Sync (as shown below in Figure 1) to synchronize the “approved app” to Microsoft Intune:

Configuration of the Samsung Smart Switch app
After distributing the Samsung Smart Switch app to Android Enterprise fully managed devices, the app must be configured by using Microsoft Intune. That configuration is the Allow SmartSwitch Run (allow_run) configuration key that can be enabled to make sure that the app can be used on Android Enterprise fully managed devices. The configuration of the Samsung Smart Switch app can be achieved by going through the seven steps below.
- Open the Microsoft Endpoint Manager admin center portal navigate to Apps > App configuration profiles
- On the Apps | App configuration policies blade, click Add > Managed devices
- On the Basics page, provide the following information and click Next
- Name: Provide a valid name for the app configuration policy
- Description: (Optional) Provide a valid name for the app configuration policy
- Device enrollment type: (Grayed out) Managed devices
- Platform: Select Android Enterprise
- Profile Type: Select All Profile Types, Fully Managed, Dedicated, and Corporate-Owned Work Profile Only or Personally Owned Work Profile Only depending on the devices that should get this policy assigned
- Targeted app: Select Samsung Smart Switch Mobile
- On the Settings page, provide at least the following information (as shown below in Figure 2) and click Next:

- Configuration Settings format: Select Use configuration designer
- Click Add to add the Allow SmartSwitch Run configuration key and check the box with the configuration value
- On the Scope tags page, configure the applicable scope tags and click Next
- On the Assignments page, configure the assignment by selecting the applicable group and click Next
- On the Review + create page, review the configuration and click Create
User experience with the Samsung Smart Switch app
When Android fully managed devices and Samsung Smart Sync are used together, the user experience can be simply verified by opening the app. When the configuration was not successfully applied, the message Security policy restricts use of Smart Switch will show as shown below in Figure 3, and when the configuration was successfully applied, the app will open as shown below in Figure 4. Before the user gets to that screen, many permissions must be approved to make sure that the data can be restored. After that the user can choose how to transfer data to the device. Simply walk through the app and select the device that is sending the data, or connect the device to PC
More information on Android fully managed devices and Samsung Smart Sync
For more information about Samsung Smart Switch and the configuration, refer to the following docs.
Automate FTP with PowerShell

Automate FTP with PowerShell
So, you want to Automate FTP with PowerShell? Well, you have come to the right place. FTP is not dead . In fact, it is still quite widely used. If all you need is files to be transferred from one place to another, it is the best choice.
Why would you need to Automate FTP with PowerShell
There are several reasons you would need to automate FTP with PowerShell. One is compatibility. Batch files are still around but to get them to automate FTP, you must call on third party programs that may or may not be kept up to date. As OSes start to update the third party application may fall behind. This leads me to my second point….
Security with PowerShell
You can be more granular with security and PowerShell. It is baked into M365 and local AD so you can be sure that only the users you require can run the script to Automate FTP with PowerShell.
Prerequisites to the Script
You will need the following before you can run the script to Automate FTP with PowerShell.
WinSCP Automation
The script calls on WinSCP FTP Automation to load a DLL so it can connect to your required FTP Server and transfer files. You need to register the DLL in the Directory it is going to be called from. The documentation is a bit confusing but simply put, extract the DLL to the same folder as the script. Then drop to CMD prompt and navigate to that folder and then register the DLL:
%WINDIR%\Microsoft.NET\Framework64\<version>\RegAsm.exe WinSCPnet.dll /codebase /tlb Make sure the version of .NET you are using is specified in <version>. I used v4.0.30319
So, my command looked like this:
%WINDIR%\Microsoft.NET\Framework64 v4.0.30319\RegAsm.exe WinSCPnet.dll /codebase /tlb If Running the Script on a Server
You need to make sure the Above DLL is registered for the user account running the script. You also need Full Control file security on the folder that houses the script. The reason for this is you need to be able to rename and move files in and around the file structure which otherwise require admin access. Without this, the script will not run.
If Connecting to SFTP
You will need to get the SSHHost Key If connecting with a password or both the SSHHost Key and SSHKeyPath file (if not using a password) and point to where it is stored (Preferable in the same folder as everything else).
But if you connect manually to these servers, you already have this information. If not, reach out to the vendor or organization you need to connect to. My example only needs the SSH Host Key.
Bonus: If You Plan to Notify of Completion or Errors via Email
If you plan To Send Mail In PowerShell , you will need to create an App Registration in Entra with the correct permission to send mail and then have that account give consent to allow it to be used to send mail through API (like PowerShell). I have written an article about it. You should check it out. It will help Automate FTP with PowerShell.
The Script
This is an example of a PowerShell Script to Automate FTP with PowerShell by downloading a file, renaming it and then moving it:
try
{
# Load WinSCP .NET assembly
Add-Type -Path “C:\Path\To\WinSCP\Automation\WinSCPnet.dll” ## https://winscp.net/download/WinSCP-5.19.6-Automation.zip
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
Protocol = [WinSCP.Protocol]::Sftp # Port 22 Sftp | FTP Port: 21
HostName = “<ip address>” #IP TO FTP/SFTP
UserName = “<username>” #USERNAME
Password = <password>!” #PASSWORD LEAVE EMPTY IF YOU USE PRIVATE KEY LIKE THIS( Password = “” )
SshHostKeyFingerprint = “ssh-ed25519 255 UINj1Jc5jKcADtEwF0dd0tUjjk4KNp3JN6EyQf5G7ns”
#SshPrivateKeyPath= “C:\Users\Admin\private.ppk” #If you use password make “SshPrivateKeyPath” to a comment or delete the line!
}
$session = New-Object WinSCP.Session
try
{
# Connect
$session.Open($sessionOptions)
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
$transferResult =
$session.GetFiles(“/incoming/Sample.csv”, “C:\Path\To\File\Upload\”, $False, $transferOptions) #Get files from incoming to upload
# Use $session.PutFiles(LocalPath, RemotePath) instead If you are wanting to send files to the SFTP/FTP Server.
# Throw on any error
$transferResult.Check()
# Print results
foreach ($transfer in $transferResult.Transfers)
{
Write-Host “Download of $($transfer.FileName) to $localPath succeeded”
$transferResult.Transfers
}
}
finally
{
# Disconnect, clean up (Session.Close to exit the session!)
$session.Close()
}
#exit 0
}
catch
{
Write-Host “Error: $($_.Exception.Message)”
.\NotifyMailFailed.ps1
exit 1
}
$Exist = Test-Path “C:\Path\To\File\Upload\”, Sample.csv” -PathType Leaf
$IsTrue = $Exist
if ($IsTrue) {
# rename file and move to Archive Folder
# Write file is there
$time = Get-Date -Format “MM-dd-yyyy”
Rename-Item -Path ” C:\Path\To\File\Upload\Sample.csv” -NewName Sample_$time.CSV
Move-Item -Path ” C:\Path\To\File\Upload\*.csv” -Destination ” C:\Path\To\File\Upload\saved”
## Notifying Via Email Upload is Complete
#refer to https://quickm365tips.com/the-correct-way-to-send-mail-in-powershell/
.\NotifyMail.ps1
} else {
# Write file is NOT there
## Notifying Via Email Upload is Complete
#refer to https://quickm365tips.com/the-correct-way-to-send-mail-in-powershell/
.\NotifyMailFailed.ps1
}
Benefits When You Automate FTP with PowerShell
When you can automate any process that is normally done manually, it is a benefit. It saves you time from performing several steps and concentrates on what you need to do most. Probably analyzing the data (Not retrieving it)!
Another Benefit is if you must automate several FTP services all you have to do is copy the script and change the particulars. You will be up and running in no time 😊
A Simple Script for M365 Licenses

You need to juggle M365 Licenses, but you need to see who has them first? It seems simple, it is, and you can write a Script for M365 Licenses, but you will need to do a little preparation first.
Why Would you Need a Script for M365 Licenses
That is a very good question. A good example is that you are switch licensing vendors and you would like to see how many licenses you need to switch out. Once you know who has this license you can get a list and then switch them out.
I can give you a piece of advice. Add new licenses first and make sure they work before you remove the old licenses! Even if the old licenses sit expired, the new ones must be added first. I will write an article in the future of what happens if you do it backwards LOL.
A script for M365 licenses will help with this.
What you Need to Write the Script
You will need 4 Things.
- A csv file with the group of users you would like to check. This CSV will include three columns labelled UPName, DisplayName and Object ID
- The SKU ID of the Microsoft product you want to Check
- A PowerShell script to check the SKU
- A PowerShell script to deal with the SKU (in this case, remove)
Create a CSV for Your Script for M365 Licenses

This is an example CSV that you would use for your script. Name it Sample.csv so it is the same file that is referenced in the script.
To get this information, you will need to go to your Entra Portal and under all users, click download users:

You can use this info to create your sample.csv.
Get the SKU ID of the M365 License you Want to Query
You will need to connect to Microsoft Graph and run the command Get-MgSubscribedSku:
Connect-Graph -Scopes Organization.Read.All
Get-MgSubscribedSku | Select -Property Sku*, ConsumedUnits -ExpandProperty PrepaidUnits | Format-List You will get a listing of all licensed products in your tenant. From there you can get the SkuId:
SkuId : 06ebc4ee-1bb5-47dd-8120-11324bc54e06
SkuPartNumber : SPE_E5
In this example, we are querying the SkuID for the now discontinued E5 licensing. It has been happening for awhile but it might be hitting you now because your current agreement needs to be renewed. You will now need to copy the ID into a Script for M365 Licenses. Now that you have your CSV and License to query, it is now time for the Script for M365 Licenses.
Script to Check for the SKU
# Connect to Microsoft 365
Connect-MgGraph -Scopes User.Read.All, Organization.Read.All
#Path to UPN File #
$CSVPathUPN = ".\sample.csv"
##Run Script##
##Try import UPN CSV file##
Write-Host Importing CSV
try {
$UPNUsers = import-csv $CSVPathUPN -ErrorAction stop
}
catch {
throw "Error importing CSV: $($_.Exception.Message)"
break
}
foreach ($UPNUser in $UPNUsers) {
$Uname = $UPNUser.UPName
$Dname = $UPNUser.displayName
$ObjID = $UPNUser.ObjectID
# Checks if they have SPE5
# Define the license SKU you're checking for (e.g., "E5" or the SKU ID)
$Sku = "06ebc4ee-1bb5-47dd-8120-11324bc54e06"
# Get the user's license details
$CurrentLicenses = Get-MgUserLicenseDetail -UserId $Uname | Select-Object -ExpandProperty SkuId
# Check if the specified license is assigned
if ($Sku -in $CurrentLicenses) {
Write-Host "User '$Dname' has license: $Sku"
} else {
Write-Host "User '$Dname does not have license: $Sku"
}
}
Write-Host All done
The script will cycle through each user and tell you whether that user has that license.
Script to Remove for the SKU
Now that you know which user(s) have the licenses, you can compile your CSV above and run the following script to remove the them:
##Connect to Azure and MSGraph modules##
Connect-MgGraph -Scopes User.ReadWrite.All, Organization.Read.All
#Path to UPN File #
$CSVPathUPN = ".\sample.csv"
##Run Script##
##Try import UPN CSV file##
Write-Host Importing CSV
try {
$UPNUsers = import-csv $CSVPathUPN -ErrorAction stop
}
catch {
throw "Error importing CSV: $($_.Exception.Message)"
break
}
$f1Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5'
foreach ($UPNUser in $UPNUsers) {
$Uname = $UPNUser.UPName
$Dname = $UPNUser.displayName
$ObjID = $UPNUser.ObjectID
# Remove SPE5
Set-MgUserLicense -UserId $Uname -RemoveLicenses @($f1Sku.SkuId) -AddLicenses @() -ErrorAction Stop
Write-Host Remove Legacy E5 Licensing for $Dname ....
}
Write-Host All doneThis is a good way to write a Script for M365 Licenses!
