Powershell script with automation account and managed identity Unauthorized when sending e-mail

188 Views Asked by At

I have been struggling with this script in Azure Automation to send a report to an e-mail but won't work. I have granted the required permission to the servicePrincipal but I get all the time The remote server returned an error: (401) Unauthorized. I even tried to connect with the scopes, but still the same. Then I tried to connect to AzAccount then get the AzAccessToken and then connect to graph using AccessToken but here I got an error

Connect-MgGraph : Cannot bind parameter 'AccessToken'. Cannot convert the "eyJ0
 value of type "System.String" to type "System.Security.SecureString". At line:5 char:30 + Connect-MgGraph -AccessToken $token.Token +

I am getting the output of the variables $inactiveUsers and $htmlReport so the issue is with the e-mail

See the permissions: enter image description here What am I doing wrong ?

# Connect to Microsoft Graph
Connect-MgGraph -Identity

# inactive users with license(s)
$inactiveUsers = Get-MgUser -Filter 'accountEnabled eq false and assignedLicenses/$count ne 0' -ConsistencyLevel eventual -CountVariable licensedUserCount -All -Select UserPrincipalName,DisplayName

# Create a report variable
$userReport = @()

# Build the report
$htmlReport = "<html><body><h2>Disabled users with licenses report</h2><table border='1'><tr><th>User Principal Name</th><th>Display Name</th></tr>"

foreach ($user in $inactiveUsers) {
    $userPrincipalName = $user.UserPrincipalName
    $displayName = $user.DisplayName

    $htmlReport += "<tr><td>$userPrincipalName</td><td>$displayName</td></tr>"

    $userInfo = [PSCustomObject]@{
        UserPrincipalName = $userPrincipalName
        DisplayName = $displayName
    }

    $userReport += $userInfo
}

$htmlReport += "</table></body></html>"

# Send the email
$recipientEmail = "[email protected]"
$subject = "Disabled users with licenses report"

# Construct the email
$emailMessage = @{
    "subject" = $subject
    "body" = @{
        "contentType" = "HTML"
        "content" = $htmlReport
    }
    "toRecipients" = @(@{ "emailAddress" = @{ "address" = $recipientEmail } })
}

# Convert to JSON
$emailJson = $emailMessage | ConvertTo-Json

# Send the email, this part is  not working and I don't know why...
$sendEmailUri = "https://graph.microsoft.com/v1.0/users/[email protected]/sendMail"
$sendEmailParams = @{
    "Uri" = $sendEmailUri
    "Method" = 'POST'
    "Body" = $emailJson
    "Headers" = @{
        "Content-Type" = "application/json"
    }
}

try {
    Invoke-RestMethod @sendEmailParams -ErrorAction Stop
    Write-Host "Email sent successfully."
} catch {
    Write-Error "Error sending email: $_"
}
1

There are 1 best solutions below

0
Sridevi On BEST ANSWER

The error occurred as you are calling Invoke-RestMethod without passing access token as a secure string (ConvertTo-SecureString $graphToken -AsPlainText -Force) in Authorization header.

To resolve the error, you need to either pass access token as secure string or use Send-MgUserMail as @user2250152 suggested.

Initially, I granted below permissions to the automation account's service principal like this:

enter image description here

Now, I ran below modified script by replacing with Send-MgUserMail and got response:

Import-Module Microsoft.Graph.Authentication
Import-Module Microsoft.Graph.Users
Import-Module Microsoft.Graph.Users.Actions

# Connect to Microsoft Graph
Connect-MgGraph -Identity

# inactive users with license(s)
$inactiveUsers = Get-MgUser -Filter 'accountEnabled eq false and assignedLicenses/$count ne 0' -ConsistencyLevel eventual -CountVariable licensedUserCount -All -Select UserPrincipalName,DisplayName

# Create a report variable
$userReport = @()

# Build the report
$htmlReport = "<html><body><h2>Disabled users with licenses report</h2><table border='1'><tr><th>User Principal Name</th><th>Display Name</th></tr>"

foreach ($user in $inactiveUsers) {
    $userPrincipalName = $user.UserPrincipalName
    $displayName = $user.DisplayName

    $htmlReport += "<tr><td>$userPrincipalName</td><td>$displayName</td></tr>"

    $userInfo = [PSCustomObject]@{
        UserPrincipalName = $userPrincipalName
        DisplayName = $displayName
    }

    $userReport += $userInfo
}

$htmlReport += "</table></body></html>"

# Send the email
$recipientEmail = "[email protected]"
$subject = "Disabled users with licenses report"

# Construct the email message
$emailMessage = @{
    "Message" = @{
        "subject" = $subject
        "body" = @{
            "contentType" = "HTML"
            "content" = $htmlReport
        }
        "toRecipients" = @(@{ "emailAddress" = @{ "address" = $recipientEmail } })
    }
    "saveToSentItems" = $true 
}

# Convert to JSON with a higher depth limit
$emailJson = $emailMessage | ConvertTo-Json -Depth 5

try {
    Send-MgUserMail -UserId "[email protected]" -BodyParameter $emailJson 
    Write-Output "Email sent successfully."
}
catch {
    Write-Error "Error sending email: $_"
}

Response:

enter image description here

To confirm that, I checked the same in user's Sent Items where mail sent successfully like this:

enter image description here