December 22, 2025

April 23, 2024 | Dan

Quickly Provision a Phone in Teams Admin

Quickly Provision a Phone in Teams Admin

Quickly Provision a Phone in Teams Admin

If you license users for Teams Phone Standard you will need to Quickly Provision a Phone in Teams Admin. It also happens if you unlicensed a user for Teams and then reconsidered. It drops the phone number, and it will have to be re-provisioned

Follow the Steps below and you will have the users phone number back in no time!

Open PowerShell

Star PowerShell from Windows. You can either choose Windows PowerShell or Windows PowerShell ISE. I prefer ISE since I can cut and paste code and run it from the console a lot easier:

Provision a Phone in Teams Admin

Install and Connect to the Teams Module

When the box is loaded. Install the module:

Install-Module -Name MicrosoftTeams

Then Connect:

Connect-MicrosoftTeams

You may want to put this into a nifty PowerShell script that automates the process if you feel you are going to be provisioning or de-provisioning phones quite often.

User Numbers when you Provision a Phone in Teams

Here I will show you not only how to add a user telephone number but also remove a telephone user number. Of course, removing a user number is important when they either change numbers or do not need the number anymore (i.e. – leave the organization).

Add User Number

Here is the example of setting the telephone number, assigning a default policy and enambling voicemail.

Set-CsPhoneNumberAssignment -Identity userid@<tenant.domain> -PhoneNumber '+1XXXXXXX' -PhoneNumberType DirectRouting

Grant-CsOnlineVoiceRoutingPolicy -Identity userid @<tenant.domain>  -PolicyName "Policy Given to You by your Telco Provider" – or one you or your admin created

Set-CsOnlineVoiceMailUserSettings -Identity userid @<tenant.domain> -VoicemailEnabled $true

Remove User Number

In this example the user has the phone number and any policy assigned to them removed.

Grant-CsOnlineVoiceRoutingPolicy -Identity userid @<tenant.domain> -PolicyName $null

Remove-CsPhoneNumberAssignment -Identity userid @<tenant.domain>  -RemoveAll

There you have it.  A way to Quickly Provision a Phone in Teams Admin.

Share: Facebook Twitter Linkedin
April 19, 2024 | Dan

Assigning Microsoft Licensing Gives Errors

Assigning Microsoft Licensing Gives Errors

Have you ever had an issue where Assigning Microsoft Licensing Gives Errors? Depending on how you license your users, it could be because you use a combination of Group licensing and manual licensing. If you use more than one third party to purchase licenses, I wouldn’t be surprised if you run into this.

I will give an example. This has happened in the past when trying to assign an Exchange Online Plan 2 license for a user. There is some inherited licensing that cause errors when trying to remove the Exchange Plan1 license and add the Exchange Online Plan 2 license.

The cause in this case was the Microsoft Teams Standard License inherited from the Group licensing in Azure. To be able to assign the new exchange license I had to do the following:

Steps To Successfully Assign License

  1. Remove the user from the Group Licensing Group in Azure AD
  2. Remove all licenses the user has in the admin portal (User Details)
  3. Re-add the above licenses except the Exchange Online Plan 1 license. You would add the Exchange Online Plan 2 license and Save Changes in the Admin Portal (User Details).
  4. Re-add the user to the Group License Group in Azure AD.
  5. Re-provision the users phone number.

This is a good process to follow regularly as it will come up from time to time. Don’t worry, repetition helps with learning so if you forget and run into this error a few time you will get the hint LOL.

Re-Add User Number When Assigning Microsoft Licensing Gives Errors

Set-CsPhoneNumberAssignment -Identity userid@<tenant.domain> -PhoneNumber '+1XXXXXXX' -PhoneNumberType DirectRouting

Grant-CsOnlineVoiceRoutingPolicy -Identity userid@<tenant.domain> -PolicyName "<Policy your Telco gave you or one you set up>"

Set-CsOnlineVoiceMailUserSettings -Identity userid@<tenant.domain> -VoicemailEnabled $true

If you don’t check the teams phone number provisioning you may end up with a problem like this. Double check the MS Teams portal to ensure the phone number was added back. This is a bit of a pain, but it works.

Share: Facebook Twitter Linkedin
April 4, 2024 | Dan

Automatically Add Signature to Outlook with VB Script

Automatically Add Signature to Outlook

Microsoft has added the ability for email signatures to roam. This is great news for users who use Outlook on multiple devices as it stores signature settings at the mailbox level and not directly in Outlook’s settings. You want to Automatically Add Signature to Outlook but sometimes, you can’t.

If the signature is created programmatically for you by your IT admin or roaming signatures are turned off (also done by your IT admin) you will have to find other ways.

I will show you two ways. One way if you are an administrator and another way if you are a user.

Create a Signature for Your users as an Administrator

This might fall out of your skill set. It does require some scripting and HTML programming knowledge. Don’t worry, there are a lot of articles on the internet to help you with this. I will walk you through the steps.

Get familiar with the names of the names of the attributes in AD. You will be referring to them as you write the script that renders the HMTL code. The code will be written to a file and then placed in the %AppData%\Microsoft\Signatures\ location as an HTML file.

Here is the sample vbs code for a simple signature:

On Error Resume Next

Dim strUser,strName,strTitle,strMail,strPhone,strFax
Dim strCompany,strLocation,strAddress,strCity,strState
Dim strZip,strWeb,strInfo,ADObject

strSourceDir=replace(wscript.scriptfullname,wscript.scriptname,"")

Set fso=CreateObject("Scripting.FileSystemObject")
Set objSysInfo = CreateObject("ADSystemInfo")
Set WshShell = CreateObject("WScript.Shell")

                            'Active Directory Info Object
Set ADObject = CreateObject("ADSystemInfo")

strUser = ADObject.UserName

                            'Active Directory Connection
Set objUser = GetObject("LDAP://" & strUser)

                            'Pull Active Directory Info for this User

strOutlookVersion = Left(objOutlook.Version, 2)
strUserid = objUser.userPrincipalName
strFName = objUser.FirstName
strLName = objUser.LastName
strTitle = objUser.Title
strEmail = objUser.mail
strPhone = objUser.telephoneNumber


Dim objFSO, objWsh, appDataPath, pathToCopyTo, plainTextFile ,imagePath
Dim plainTextFilePath, richTextFile, richTextFilePath, htmlFile, htmlFilePath, SigFilename

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objWsh = CreateObject("WScript.Shell")
appDataPath = objWsh.ExpandEnvironmentStrings("%APPDATA%")
pathToCopyTo = appDataPath & "\Microsoft\Signatures\"

'Create HTML Signature


htmlFilePath = pathToCopyTo & "ACMESignature.htm"
Set htmlFile = objFSO.CreateTextFile(htmlFilePath, TRUE)
htmlfile.WriteLine("<html>")
htmlfile.WriteLine("<head>")
htmlfile.WriteLine("<p>" & strFName & " " & strLName & "</p>")
htmlfile.WriteLine("<p>" & strTitle & "</p>")
htmlfile.WriteLine("<p>" & "Acme Company" & "</p>")
htmlfile.WriteLine("<p>" & "P. " & strPhone & "</p>")
htmlfile.WriteLine("<p>" & "E. " & "<a href=""strEmail"">" & strEmail& "</a>" & "</p>")
htmlfile.WriteLine("</body>")
htmlfile.WriteLine("</html>")

htmlFile.Close

'Applying the signature in Outlook’s settings.
Set objWord = CreateObject("Word.Application")
Set objSignatureObjects = objWord.EmailOptions.EmailSignature

'Setting the signature as default for new messages.
objSignatureObjects.NewMessageSignature = "ACCSignature"

Set objFSO = Nothing
Set objWsh = Nothing

'Connect to Registry
Dim objShell, RegKey
Set objShell =  CreateObject("WScript.Shell")

Set objShell = Nothing

Create a Signature as a user

You will need some skills in HTML Coding. You can use any WYSIWYG editor to do the job. There are also a lot of tutorials on the net to do this. In this case all you need to do is create an HTML file to your liking and copy it to %AppData%\Microsoft\Signatures\ . Here is the sample html code you can save as a .html:

<html>
  <head>
  <p>John Smith</p>
  <p>President</p>
  <p>Acme Company</p>
  <p>P. 555-1212</p>
  <p>E. <a href="mailto:jsmtih@acme.com">jsmith@acme.com</a></p>
  </head>
  <body>
</html>

The Result When You Automatically Add Signature to Outlook

Whether you programmatically add it through a script of manually ad the html file you will get this:

Automatically Add Signature to Outlook

This is one of the many aspects in outlook you can automate. At least being able to Automatically Add Signature to Outlook can be easy.

Share: Facebook Twitter Linkedin
March 28, 2024 | Dan

Switching M365 Licensing using PowerShell

Switching M365 Licensing

PowerShell can automate several tasks that you might find yourself in M365 Administration. You may find yourself in an organization in the need of Switching M365 Licensing using PowerShell. At least I would use PowerShell. Changing licensing requires you to remove the older license and add the new licensing. Try manually doing that for hundreds of accounts…not cool. Using PowerShell is a lot faster. I will show you how to get it done in no time.

Figure out the SKU for your Licenses

When I say licenses, I mean the ones you currently have and the ones you want to replace them with. There are 2 ways to do this. If you don’t have a lot of licensing with Microsoft you can just look it up by going to this article by Microsoft. If you have a lot of different licensing or you would just like a handy CSV of what you currently have, go to this site. It has a nice PowerShell Script.

Switching M365 Licensing using PowerShell Example

In this example I am going to use an example of a company that is upgrading their licensing from M365 Business Premium, with Teams Phone Standard and Exchange Online Plan 2 to M365 E5, which includes all the old licensing plus more.

First things first, make sure you have enough of the new licensing. Go to licenses in the admin portal and make sure you have enough. The script will err after it runs out of licenses to switch. At that point you can also go back to the portal and see what users were missed and manually switch them.

The User List

For Switching M365 Licensing using PowerShell you need to create a CSV File that has the UPN of the user and their Display Name. the script will need it. In licenses you can go to the exact license and it will show all the users licensed to it. You can download the list as a CSV and it will help you create the list you need in the script.

The License SKU’s

Make a list of old SKU’s and the new ones. In my example I have the following:

Old – SPB (M365 Business Premium),MCV (Teams Phone Standard),EXCHANGEENTERPRISE(Exchange Online Plan 2)

New – SPE_E5 (M365 E5)

The Script

Here is the PowerShell Script that removes the old licenses and adds the new:

#Path to UPN File #

$CSVPathUPN = "C:\Path\To\CSV\usersexchplan2.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
}

$busprem = Get-MgSubscribedSku -All | Where SkuPartNumber -eq ' SPB '
$teamsphone = Get-MgSubscribedSku -All | Where SkuPartNumber -eq ' MCV '
$exchplan2 = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'EXCHANGEENTERPRISE'

foreach ($UPNUser in $UPNUsers) {
	
$Uname = $UPNUser.UPName
$Dname = $UPNUser.displayName

# Unassign Bus Prem and Teams Phone Standard

Write-Host Removing Bus Premium, Teams Phone Standard Licensing and Exchange Online for $Dname ....
Set-MgUserLicense -UserId $Uname -AddLicenses @{} -RemoveLicenses @($busprem.SkuId)
Set-MgUserLicense -UserId $Uname -AddLicenses @{} -RemoveLicenses @($teamsphone.SkuId)
Set-MgUserLicense -UserId $Uname -AddLicenses @{} -RemoveLicenses @($exchplan2.SkuId)
}

Write-Host Need to Pause so removed licenses can sync before adding the new ones

Pause

$e5Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5'

foreach ($UPNUser in $UPNUsers) {

$Uname = $UPNUser.UPName
$Dname = $UPNUser.displayName
# Assign E5	

Set-MgUserLicense -UserId $Uname -AddLicenses @{SkuId = $e5Sku.SkuId} -RemoveLicenses @()

Write-Host Added e5 Licensing for $Dname ....

}

Write-Host All done

You Need To Test!

Please do not run this script with your entire user list. Take a small sample. If something goes wrong you only have to work with a few users and not hundreds.

This example script is great for installations where most users have the same licensing but in cases where the user licensing in all over the place or they use group-based licensing, you will have to tweak the script. In a later post I will show you how to deal with assigning / removing licensing in a group-based scenario.

Share: Facebook Twitter Linkedin
March 27, 2024 | Dan

Set up Auto Archive Fast for Outlook

Set up Auto Archive Fast for Outlook

If you use Exchange Online for email in M365, great! Depending on your licensing structure you will have anywhere from 50 to 100 GB in storage space. However, that might not be enough. This article will show you how to Set up auto archive fast.

Why Configure Auto Archive for Outlook

The are a few reasons why you would want to do this. I already mentioned above that you could be running out of online storage space and need to free some up. Another reason is that you have some older email you don’t really read very often but would like to have it is a reference that is easily searchable. More reason to Set up Auto Archive Fast.

Configuring AutoArchive

  1. Click File / Options / Advanced / Auto Archive Settings:
Set up Auto Archive Fast for Outlook

2. Once you have open AutoArchive Settings from options, you need to set them:

Set up Auto Archive Fast for Outlook

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 in 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 AutoArchive runs once you will see it in your Outlook underneath your inbox as a searchable mail store:

Set up Auto Archive Fast for Outlook

You can get pretty fancy with Auto Archive if you know what you are doing. But if you are not sure, reach out to your IT Department. If not, your IT department better have a good backup solution. Otherwise, this article shows you how to Set up Auto Archive Fast.

Share: Facebook Twitter Linkedin
March 22, 2024 | Dan

Clearing Teams Cache on Multiple Profiles

Clearing Teams Cache on Multiple Profiles

You upgraded to Microsoft Teams 2.0. Great. The only issue is the new Team’s hangs on login. Clearing the Teams cache will do the trick. You know how to clear the cache for one user but what if the machine in question is logged into by several users? Manually deleting dozens if not hundreds of profiles could take a very long time. How do you go about Clearing Teams Cache on Multiple Profiles.

If you follow the tips in this article, you will have it done in No Time.

Prerequisites

The following needs to occur when Clearing Teams Cache on Multiple Profiles:

  1. Be an Admin on domain (obviously 😊).
  2. Run PowerShell on Domain where the computer(s) reside.
  3. The WinRM services needs to be running when the cache is cleared.
  4. Use the invoke command to run the PS command on the remote machine.
  5. For security purposes, stop the WinRM service when done.

Location For Clearing Teams Cache on Multiple Profiles

Microsoft Teams 2.0 has a new local for its cache. It is C:\Users\<UserName>\AppData\Local\Packages\MSTeams_8wekyb3d8bbwe\ . This is the location you need to work into your PowerShell command. If are still using Teams Classic Use C:\Users<UserName>\AppData\Local\Microsoft\Teams* to work into your PowerShell command.

Constructing The PowerShell Command

The command is constructed like this for Clearing Teams Cache on Multiple Profiles:

Get-Service -ComputerName <ComputerName> -Name WinRM | Start-Service

Invoke-Command -ComputerName <ComputerName>  -ScriptBlock { Remove-Item "C:\Users\*\AppData\Local\Packages\MSTeams_8wekyb3d8bbwe\*" -Force} -credential <yourusername>

Get-Service -ComputerName <ComputerName>  -Name WinRM | Stop-Service -Force



Running this command remote will remove the teams’ files from every user profile on the computer. If you want to make sure the command works before you pull the trigger, you can add the -whatif switch to the end of the Remove-Item command (before the quote).

If you have more than one machine to work on you can run a for each loop with a variable for <ComputerName> that reads the variable from a CSV file. This is a lot faster

Share: Facebook Twitter Linkedin
March 4, 2024 | Dan

2 Ways to Check M365 App Registration Logging

M365 App Registration Logging

You have created an App in Microsoft Entra and need to see where you can look at M365 App Registration Logging. This is important because the service that depends on it, whether it be with M365 or a 3rd party,  can fail and you need to find out why.

A log of any kind is always the best place to start. Here’s how you do it.

Accessing M365 App Registration Logging Through Sign-in Logs

It is quite simple really. All you must do is:

  1. Go into your Microsoft Entra Portal
  2. Go to Users / All Users / Sign-in Logs
  3. From here, you filter like you normally would but instead of filtering by user, you filter by Application.
  4. Enter your App Registration Name in “+Add Filter.”
  5. I like to filter by date so I can get a time window of what I am looking for.
M365 App Registration Logging

Accessing M365 App Registration Logging Through Audit Logs

You can also check M365 App Registration Logging by going into the Microsoft Entra audit logs.

It is also simple really. All you must do is:

  1. Go into your Microsoft Entra Portal
  2. Go to Users / All Users / Audit Logs
  3. From here, you filter by target (in this case, the user who the app registration is under).
  4. I also like to filter by date so I can get a time window of what I am looking for.
M365 App Registration Logging

When Would You Need Logging

M365 App Registration Logging is useful if one of your services that depends on an App Registration fails. Direct examples include, when you have a PowerShell script or a custom app that uses the app registration and some has change where it could throw an error.

Another example is when you use a third part service like a WordPress Plugin that requires the use of an App registration, and it starts to throw errors for whatever reason. The third-party logs may only be able to tell you that it failed trying to access or use the app registration. Anything more, you must go into the M365 logs. In my experience, outdated plugins can cause this. Changes in security on the App registration side can also cause this.

Hopefully using these 2 Ways at M365 App Registration Logging will be helpful on your troubleshooting journey.

Share: Facebook Twitter Linkedin
February 24, 2024 | Dan

Use Get-PublicFolderItemStatistics for Notifications

You can Use Get-PublicFolderItemStatistics for Notifications to your advantage if you are an M365 administrator. Especially if you are in charge with doing something like maintaining a separate set of contacts for your organization based on a master list of Public folder contacts. You have to constantly check the Public folder for changes…

Get-PublicFolderItemStatistics for Notifications

I guess you could ask the department that maintains the public folder to let you know when there have been changes made or you can set up an automated way using PowerShell and Tasks Scheduler.

Prerequisites On How To Use Get-PublicFolderItemStatistics for Notifications

This may seem like a long list but if you have been administering M365 for awhile you probably already have these set up. If, not please make sure you have the following:

  • Be at least an Exchange Administrator in you Organization
  • Have the Exchange Online Management Module Installed in PowerShell
  • This is pretty important, you need to able to send mail in M365. This is not as simple as it used to be. You need to use an app registration in Azure AD to do this. I have written two articles about this. Please go here and here for more info

Once you have this set up, you can go on to the next step on how to Use Get-PublicFolderItemStatistics for Notifications.

Create a PowerShell Script To Check On the Public Folder

What this script does is allows you to Use Get-PublicFolderItemStatistics for Notifications that are sent by email to the email of your choosing. It looks for any changes that you set in the variable $baseline. If there is a change, the command Get-PublicFolderItemStatistics is piped into an html body that is formatted correctly for sending mail through the MS Graph API.

The contact listing in the public folder is sorted by modification date so you can tell which record was changed. In turn you can take this information and make the necessary changes to the separate copy of contacts you administer (more than likely through MS Graph). In the case of a delete, the record will not be there so you know which one to delete on your end.

After each change I edit the PowerShell script and change the variable $baseline. I add +1 for one Add, a -1 for one Delete and no change for a Change. You get the picture.

The Script

##Declare Parameters##

$clientID = "Your_Client_ID"
$clientSecret = "Your_Client_Secret"
$tenantID = "Your_Tenant_ID"

##Run Script##

Connect-ExchangeOnline

$baseline = <number>

$m = Get-PublicFolderItemStatistics -Identity "\Path\To\Public\Folder\Contacts" | Select Subject,LastModificationTime | Sort-Object -Property LastModificationTime -Descending

$m.count


if ($m.count -ne $baseline){
		

#Connect to GRAPH API

$MailSender = "sender_email"

#Connect to GRAPH API
$tokenBody = @{
    Grant_Type    = "client_credentials"
    Scope         = "https://graph.microsoft.com/.default"
    Client_Id     = $clientId
    Client_Secret = $clientSecret
}
$tokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantID/oauth2/v2.0/token" -Method POST -Body $tokenBody
$headers = @{
    "Authorization" = "Bearer $($tokenResponse.access_token)"
    "Content-type"  = "application/json"
}

$h = $m | ConvertTo-Html | select -Skip 4

$HTMLBody = @"
$h
"@

$msg = $HTMLBody

#Send Mail    
$URLsend = "https://graph.microsoft.com/v1.0/users/$MailSender/sendMail"
$BodyJsonsend = @"
                    {
                        "message": {
                          "subject": "Change in Public Folder Contacts.",
                          "body": {
                            "contentType": "HTML",
                            "content": "$msg"

                          },
                          "toRecipients": [
                            {
                              "emailAddress": {
                                "address": "email_you_specify"
                              }
                            }
                          ]
                        },
                        "saveToSentItems": "false"
                      }
"@

Invoke-RestMethod -Method POST -Uri $URLsend -Headers $headers -Body $BodyJsonsend

}else{
		Write-Host No Change!
}

Use Get-PublicFolderItemStatistics for Notifications Scheduled Task

You can run the above script manually if you want, you can set it up as a scheduled task to Use Get-PublicFolderItemStatistics for Notifications automatically. What you can do is write a small batch file and then call it periodically as a scheduled task. Here is the content of the simple batch file:

Powershell -File "C:\Patch\To\Batch\File\PublicFolderContactChange.ps1"

Create a task in Task Scheduler and used these settings if you like:

Use Get-PublicFolderItemStatistics for Notifications
Use Get-PublicFolderItemStatistics for Notifications
Use Get-PublicFolderItemStatistics for Notifications

Now that you have the scheduled task set up, when there is a change in the public folder, you will be notified via email and you can make the necessary changes on your end. Beats having to remember!

Share: Facebook Twitter Linkedin