
There’s a lot of long manual processes in the Teams Admin Center, like entering configuration profiles for devices like Phones, Panels, Displays, and Teams Rooms on Android. If you work as a consultant, you probably have to redo all this work on each tenant you work on. People maybe add 50-100 profiles for each tenant. This is really time-consuming.
My friend Jens Madsen asked me if it was possible to automate this? Yes, it is! Thanks for the idea Jens, and the extensive CSV file with predefined profiles for various countries/timezones.
You can find the CSV file here. (If it is downloaded as xls, open and save as CSV with comma as separator)
Now you can save hours of work and almost by one click upload this automatically. Only thing you need before running the script is a token from the Teams Admin Center.
You get this by opening the dev mode of your browser (F12 in Edge Chromium) and click network. Then go to the configuration profiles pages for one of the device types. In this case, Displays. In the Dev tab, look for the name ‘configProfiles’. Here you can find a token. Copy the token and paste it into the script when running it. That’s it!

### Teams Devices Configuration Profiles Uploader ### | |
### Version 1.0 ### | |
### Author: Alexander Holmeset ### | |
### Email: [email protected] ### | |
### Twitter: twitter.com/alexholmeset ### | |
### Blog: alexholmeset.blog ### | |
### Thanks to Jens Madsen for idea and extensive CSV ### | |
### with predefined configuration profiles. ### | |
### https://twitter.com/JensHMadsen ### | |
$PowerShellVersion = ((Get-Host).Version).Major | |
If($PowerShellVersion -eq 7){ | |
Write-Host "PowerShell 7 does not support interatctive input longer than 1024 characters." | |
Write-Host "Open script in editor and paste token in token variable at line 25 instead of read host command." | |
Write-Host "Then remove line 11 to 20." | |
return | |
} | |
Write-Host "================ Teams Devices Configuration Profiles Uploader ================" | |
Write-Host "" | |
$Token = Read-Host "Enter Teams Admin Center token to authenticate" | |
#Checking if token is valid. | |
Try{ | |
$URL = "https://admin.devicemgmt.teams.microsoft.com/api/v2/configProfiles" | |
$header = @{Authorization = "Bearer $token"} | |
$ConfigProfiles = (((Invoke-RestMethod -Uri $URL -Method GET -Headers $header -ContentType "application/json").paginatedconfigprofiles).baseinfo).id | |
} | |
Catch{Write-Host "";Write-Host "Authentication failed!" -ForegroundColor red;Return} | |
Write-Host "" | |
Write-Host "Authentication OK!" -ForegroundColor Green | |
Write-Host "" | |
function UploadConfigProfiles { | |
$URL = "https://admin.devicemgmt.teams.microsoft.com/api/v2/configProfiles" | |
$header = @{Authorization = "Bearer $token"} | |
$DeviceProfiles = Import-Csv (Read-Host "Enter full path of CSV file included filename") | |
foreach($DeviceProfile in $DeviceProfiles){ | |
$body = @" | |
{ | |
"identity":"$($DeviceProfile.identity)", | |
"deviceType":"$($DeviceProfile.deviceType)", | |
"description":"$($DeviceProfile.description)", | |
"configProfileCreationType":$($DeviceProfile.configProfileCreationType), | |
"deviceLock":"$($DeviceProfile.deviceLock)", | |
"deviceLockTimeout":"$($DeviceProfile.deviceLockTimeout)", | |
"deviceLockPin":"$($DeviceProfile.deviceLockPin)", | |
"language":"$($DeviceProfile.language)", | |
"timeZone":"$($DeviceProfile.timeZone)", | |
"timeZoneId":"$($DeviceProfile.timeZoneId)", | |
"dateFormat":"$($DeviceProfile.dateFormat)", | |
"timeFormat":"$($DeviceProfile.timeFormat)", | |
"displayScreenSaver":"$($DeviceProfile.displayScreenSaver)", | |
"screenSaverTimeout":"$($DeviceProfile.screenSaverTimeout)", | |
"displayBacklitBrightness":"$($DeviceProfile.displayBacklitBrightness)", | |
"displayBacklitTimeout":"$($DeviceProfile.displayBacklitTimeout)", | |
"displayHighContrast":"$($DeviceProfile.displayHighContrast)", | |
"silentMode":"$($DeviceProfile.silentMode)", | |
"officeStartHours":"$($DeviceProfile.officeStartHours)", | |
"officeEndHours":"$($DeviceProfile.officeEndHours)", | |
"powersaving":"$($DeviceProfile.powersaving)", | |
"loggingEnabled":"$($DeviceProfile.loggingEnabled)", | |
"loggingTypes":"$($DeviceProfile.loggingTypes)", | |
"networkDhcp":"$($DeviceProfile.networkDhcp)", | |
"networkWifi":"$($DeviceProfile.networkWifi)", | |
"networkPcPort":"$($DeviceProfile.networkPcPort)", | |
"deviceDefaultAdminPassword":"$($DeviceProfile.deviceDefaultAdminPassword)", | |
"screenCapture":"$($DeviceProfile.screenCapture)", | |
"dhcpEnabled":"$($DeviceProfile.dhcpEnabled)", | |
"hostName":"$($DeviceProfile.hostName)", | |
"domainName":"$($DeviceProfile.domainName)", | |
"ipAddress":"$($DeviceProfile.ipAddress)", | |
"subnetMask":"$($DeviceProfile.subnetMask)", | |
"defaultGateway":"$($DeviceProfile.defaultGateway)", | |
"primaryDNS":"$($DeviceProfile.primaryDNS)", | |
"secondaryDNS":"$($DeviceProfile.secondaryDNS)", | |
"theme":{"name":"$($DeviceProfile.theme)"}, | |
"usageStateIndicatorBusyStateColor":{"name":"$($DeviceProfile.usageStateIndicatorBusyStateColor)"} | |
} | |
"@ | |
Invoke-RestMethod -Uri $URL -Method POST -Headers $header -ContentType "application/json" -Body $body | |
} | |
Write-Host "Configuration profiles upload is completed!" | |
} | |
function DeleteConfigProfiles { | |
Write-Host "" | |
Write-Host "Are you sure you want to delete all configuration profiles?" | |
Write-Host "" | |
$input = Read-Host "Type Yes or No." | |
switch ($input) | |
{ | |
'Yes' { | |
If($input -like "Yes"){ | |
Write-Host "" | |
Write-Host "Deletion of configuration profiles initiated!" | |
Write-Host "" | |
} | |
} 'No' { | |
Write-Host "" | |
Write-Host 'Script aborted!' -ForegroundColor Red | |
return | |
} | |
} | |
$URL = "https://admin.devicemgmt.teams.microsoft.com/api/v2/configProfiles" | |
$header = @{Authorization = "Bearer $token"} | |
while ($ConfigProfilesCount -ne 0 ) { | |
$ConfigProfiles = (((Invoke-RestMethod -Uri $URL -Method GET -Headers $header -ContentType "application/json").paginatedconfigprofiles).baseinfo).id | |
$ConfigProfilesCount = $ConfigProfiles.Count | |
foreach($ConfigProfile in $ConfigProfiles){ | |
$count2-- | |
Write-Host "" | |
"Configuration profile deleted!" | |
$url2 = "https://admin.devicemgmt.teams.microsoft.com/api/v2/configProfiles/$ConfigProfile" | |
Invoke-RestMethod -Uri $URL2 -Method DELETE -Headers $header | |
} | |
} | |
If($input -like "Yes"){ | |
write-Host "" | |
Write-Host "Configuration Profiles deleteion completed!" | |
} | |
} | |
Write-Host "" | |
Write-Host "1: Press '1' to uplload config prolfiles to Teams Admin Center." | |
Write-Host "2: Press '2' to delete all config profies from Teams Admin Center." | |
Write-Host "Q: Press 'Q' to quit." | |
Write-Host "" | |
$input = Read-Host "Please make a selection" | |
switch ($input) | |
{ | |
'1' { | |
Write-Host "" | |
UploadConfigProfiles | |
} '2' { | |
Write-Host "" | |
DeleteConfigProfiles | |
} | |
'q' { | |
return | |
} | |
} | |
[…] https://alexholmeset.blog/2021/12/18/teams-devices-configuration-profiles-uploader/ […]
LikeLike
thank your for this great script. Not too sure I will have a super-global customer like the CSV files implies, but if I do, I already know how to handle it. 😉
best regards from Vienna, Austria
HST
LikeLike
Thanks 🙂 yeah, I guess its not often you need that an extensive list, but at least you have a list to choose from now, hehe
LikeLike