Did you follow and give the necessary Exch Roles as well?
https://learn.microsoft.com/en-us/powershell/exchange/app-only-auth-powershell-v2?view=exchange-ps
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
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:
These are the permissions for the entra application, I gave as much permissions as I could find
Please help me!
How could I get it to recognize the parameter UserCertificate?
Other ideas to let it run unattended?
Thanks
Tim
Did you follow and give the necessary Exch Roles as well?
https://learn.microsoft.com/en-us/powershell/exchange/app-only-auth-powershell-v2?view=exchange-ps