"Set-Mailbox : A parameter cannot be found that matches parameter name 'UserCertificate'" when using Entra Application

Tim Niedermaier 20 Reputation points
2024-07-24T13:49:24.6733333+00:00

Hello,

I have a powershell script to do a manual bulk upload of S/MIME certificates to exchange online, but it needs me to authenticate as a domain admin interactively on every run:


# Connect to Exchange-Online using your own Credentials
Install-Module -Name ExchangeOnlineManagement
Set-ExecutionPolicy RemoteSigned
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline

Get-ChildItem -Filter *.pem "C:\Scripts\SMIME_PubKeys_Man\Certs\" | 
ForEach-Object {
    $filename = $_.Name
    $mailaddress = $filename -replace ".{4}$"
    Write-Output "Before"
    Get-Mailbox -Identity $mailaddress | Format-Table -Property @{ e='UserPrincipalName'; width = 25 }, UserCertificate, UserSMimeCertificate
    $mailbox = Get-Mailbox -ResultSize unlimited | Where-Object {$_.PrimarySmtpAddress -eq $mailaddress} | Select-Object Identity
    $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("C:\Scripts\SMIME_PubKeys_Man\Certs\" + $_.Name)
    $certArray = New-Object System.Collections.ArrayList
    $certArray.Insert(0,$cert.GetRawCertData())
    Set-Mailbox -Identity $mailbox -UserCertificate $certArray -UserSmimeCertificate $certArray
    Write-Output "After"
    Get-Mailbox -Identity $mailaddress | Format-Table -Property @{ e='UserPrincipalName'; width = 25 }, UserCertificate, UserSMimeCertificate
}
Disconnect-ExchangeOnline -Confirm:$false


This works

Then I have made another one to fetch all cert files automatically from a smb share and then upload it daily to exchange online, this time i used an entra application to have it run unattended. However the entra application can't set a mailboxes UserCertificate

# tim.niedermaier 07/2024
# Define the SMB share path
$smbSharePath = "\\fileshare.domain.de\SMIME_PubKeys"
# Define the credentials to connect to the SMB share
$username = "ldap-smime"
$password = 'blablablabla'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($username, $securePassword)
#$workingdir = "C:\Scripts\SMIME\"
# Create a new PSDrive to connect to the SMB share
New-PSDrive -Name "SMBShare" -PSProvider "FileSystem" -Root $smbSharePath -Credential $credential
Copy-Item -Path "SMBShare:\" -recurse -force -Destination "C:\Scripts\SMIME_PubKeys_Auto\"
Remove-PSDrive -Name "SMBShare"
# Connect to Exchange Online using non-interactive authentication
$clientId = "blablablabla"
$keyPath = "C:\Scripts\SMIME_PubKeys_Auto\ldap-service.pfx"
$org = "tenant.onmicrosoft.com"
$keySecret = "blablablabla"
$secureKeyPW = ConvertTo-SecureString -String $keySecret -AsPlainText -Force
#Install-Module -Name ExchangeOnlineManagement
#Set-ExecutionPolicy RemoteSigned
Import-Module ExchangeOnlineManagement
#$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $clientId, $securePassword
Connect-ExchangeOnline -AppId $clientId -CertificatePassword $secureKeyPW -CertificateFilePath $keyPath -Organization $org
Get-ChildItem -Filter *.pem "C:\Scripts\SMIME_PubKeys_Auto\SMIME_PubKeys" | 
ForEach-Object {
    $filename = $_.Name
    # Rename the file, replacing _ with @ and removing everything between .com and .pem
    $fileName = $filename -replace '_', '@'
    $filename = $fileName -replace '(?<=\.com).*?(?=\.pem)', ''
    $mailaddress = $filename -replace ".{4}$"
    Write-Output "Before"
    Get-Mailbox -Identity $mailaddress | Format-Table -Property @{ e='UserPrincipalName'; width = 25 }, UserCertificate, UserSMimeCertificate
    $mailbox = Get-Mailbox -ResultSize unlimited | Where-Object {$_.PrimarySmtpAddress -eq $mailaddress} | Select-Object Identity
    $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("C:\Scripts\SMIME_PubKeys_Auto\SMIME_PubKeys\" + $_.Name)
    $certArray = New-Object System.Collections.ArrayList
    $certArray.Insert(0,$cert.GetRawCertData())
    Set-Mailbox -Identity $mailbox -UserCertificate $certArray -UserSmimeCertificate $certArray
    Write-Output "After"
    Get-Mailbox -Identity $mailaddress | Format-Table -Property @{ e='UserPrincipalName'; width = 25 }, UserCertificate, UserSMimeCertificate
}
Disconnect-ExchangeOnline -Confirm:$false

Output:

User's image

These are the permissions for the entra application, I gave as much permissions as I could find

User's image

Please help me!

How could I get it to recognize the parameter UserCertificate?

Other ideas to let it run unattended?

Thanks

Tim

Microsoft Exchange Online Management
Microsoft Exchange Online Management
Microsoft Exchange Online: A Microsoft email and calendaring hosted service.Management: The act or process of organizing, handling, directing or controlling something.
4,575 questions
PowerShell
PowerShell
A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
2,582 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
22,072 questions
0 comments No comments
{count} votes

Accepted answer
  1. Andy David - MVP 149.1K Reputation points MVP
    2024-07-24T14:37:04.4433333+00:00
    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.