Intune is one of the fastest growing Microsoft Cloud offering, it’s features are expanding month over month.
There are still gaps which we need to fill, one such gap is: it does not has any option for Welcome Email for Enrolled Users.
The good part is that we have Intune Powershell Module that can assist us in developing our own custom welcome email solution.
Once you have the Module setup in your environment, download the PowerShell Spell 🙂 from below link and extract it.
Github link –> IntuneMDMWelcomeEmail.zip
Follow the below steps so that it works in your environment.
1. Update the IntuneMDMWELcomeMAIL.bat
powershell .\IntuneMDMWelcomeMail.ps1 -smtpserver “smtp server” -from “IntuneEnrollment@labtest.com” -erroremail ReportsLogs@labtest.com -countofchanges 100 -userid “serviceaccount@labtestcom”
SMTP Server: Enter the smtp server that is in your environment from which you relay application specific emails.
From: Email address from which you want to send the welcome email to user population.
Erroremail: Email to which you want alerts to be sent for failures.
countofchanges: that is a safety net or you can call it threshold, define as per your environment. (we know that in few hours our enrollment do not go beyond 100)
2. Encrypt the password for the service account using encrypt.bat
3. Edit the IntuneMDMWelcomeMail.ps1 file and update the welcome email verbiage.
Line number: 220
4. I have hashed the line that sends welcome email so that you can test first before execution
Line number: 231
#Send-MailMessage -SmtpServer $smtpserver -From $from -To $email -Subject “Intune – Welcome Email” -Body $body
Ones this is completed, you can schedule the batch file to run every hour or every few hours.
Note: It can happen that graph API times out if your tenant has large number of users, that is why scheduling multiple times is important ( script keeps track of whom it has already sent the email, it will not send welcome email again to same set of users)
It will start sending welcome email for newly enrolled MDM users.
You can run it ones interactively to check if its working fine or not(also do not forget to remove the # from send-mailmessage as described above in point 4)
On first run script will create logs, report and temp folder. (It will not send any email as it will create a starting point by creating a tempcsv, which you can modify if required by removing some users and rerun and send them a welcome email)
temp folder(csv file) keeps track of the users that have already been sent welcome email so that duplicity can be avoided.
Users that are enrolled in current day will only get the welcome email not the ones that have enrolled in the past.
<# .NOTES =========================================================================== Created with: ISE Created on: 11/4/2019 1:46 PM Created by: Vikas Sukhija Organization: Filename: IntuneMDMWelcomeMail.ps1 =========================================================================== .DESCRIPTION This scritp will send Welcome Email to Intune MDM users #> param ( [string]$smtpserver = $(Read-Host "Enter SMTP Server"), [string]$from = $(Read-Host "Enter From Address"), [string]$erroremail = $(Read-Host "Enter Address for Alerts and Errors"), [string]$userId = $(Read-Host "Enter Service Account to be used"), $countofchanges = $(Read-Host "Enter Count of changes to process before it breaks") ) function Write-Log { [CmdletBinding()] param ( [Parameter(Mandatory = $true,ParameterSetName = 'Create')] [array]$Name, [Parameter(Mandatory = $true,ParameterSetName = 'Create')] [string]$Ext, [Parameter(Mandatory = $true,ParameterSetName = 'Create')] [string]$folder, [Parameter(ParameterSetName = 'Create',Position = 0)][switch]$Create, [Parameter(Mandatory = $true,ParameterSetName = 'Message')] [String]$Message, [Parameter(Mandatory = $true,ParameterSetName = 'Message')] [String]$path, [Parameter(Mandatory = $false,ParameterSetName = 'Message')] [ValidateSet('Information','Warning','Error')] [string]$Severity = 'Information', [Parameter(ParameterSetName = 'Message',Position = 0)][Switch]$MSG ) switch ($PsCmdlet.ParameterSetName) { "Create" { $log = @() $date1 = Get-Date -Format d $date1 = $date1.ToString().Replace("/", "-") $time = Get-Date -Format t $time = $time.ToString().Replace(":", "-") $time = $time.ToString().Replace(" ", "") foreach ($n in $Name) {$log += (Get-Location).Path + "\" + $folder + "\" + $n + "_" + $date1 + "_" + $time + "_.$Ext"} return $log } "Message" { $date = Get-Date $concatmessage = "|$date" + "| |" + $Message +"| |" + "$Severity|" switch($Severity){ "Information"{Write-Host -Object $concatmessage -ForegroundColor Green} "Warning"{Write-Host -Object $concatmessage -ForegroundColor Yellow} "Error"{Write-Host -Object $concatmessage -ForegroundColor Red} } Add-Content -Path $path -Value $concatmessage } } } #Function Write-Log function Start-ProgressBar { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] $Title, [Parameter(Mandatory = $true)] [int]$Timer ) For ($i = 1; $i -le $Timer; $i++) { Start-Sleep -Seconds 1; Write-Progress -Activity $Title -Status "$i" -PercentComplete ($i /100 * 100) } } #################Check if logs folder is created#### $logpath = (Get-Location).path + "\logs" $testlogpath = Test-Path -Path $logpath if($testlogpath -eq $false) { Start-ProgressBar -Title "Creating logs folder" -Timer 10 New-Item -Path (Get-Location).path -Name Logs -Type directory } $Reportpath = (Get-Location).path + "\Report" $testlogpath = Test-Path -Path $Reportpath if($testlogpath -eq $false) { Start-ProgressBar -Title "Creating Report folder" -Timer 10 New-Item -Path (Get-Location).path -Name Report -Type directory } $temppath = (Get-Location).path + "\temp" $testlogpath = Test-Path -Path $temppath if($testlogpath -eq $false) { Start-ProgressBar -Title "Creating Temp folder" -Timer 10 New-Item -Path (Get-Location).path -Name temp -Type directory } ####################Load variables and log#################### $log = Write-Log -Name "MDMWelcome-Log" -folder "logs" -Ext "log" $Report1 = Write-Log -Name "MDMWelcome-Report" -folder "Report" -Ext "csv" $tempcsv = $temppath + "\tempcsv.csv" Write-Log -Message "Start.......Script" -path $log $Resource = "deviceManagement/managedDevices" $graphApiVersion = "v1.0" $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" $getdate = Get-Date -Hour 00 -Minute 00 -Second 00 ##################Userid & password################# $encrypted1 = Get-Content -Path ".\password1.txt" $pwd = ConvertTo-SecureString -String $encrypted1 $Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $userId, $pwd ###################Connect to Intune########################## try { Write-Log -Message "Connect to Intune" -path $log Connect-MSGraph -PSCredential $Credential } catch { $exception = $_.Exception Write-Log -Message "Error loading Modules" -path $log -Severity Error Write-Log -Message "$exception" -path $log -Severity Error Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error loading Module MDMWelcomeEmail" -Body $($_.Exception.Message) Start-ProgressBar -Title "exiting script Error loading Modules" -Timer 10 exit; } try { Write-Log -Message "Invoke Graph request" -path $log $Response = Invoke-MSGraphRequest -HttpMethod GET -Url $uri -Verbose $getmdm = $Response.value | where{($_.managementAgent -eq "mdm") -and ($_.enrolledDateTime -ge $getdate) -and ($_.deviceEnrollmentType -eq "userEnrollment")} $NextLink = $Response."@odata.nextLink" $count = 0 while ($NextLink -ne $null) { $count = $count + 1 $count $Response = (Invoke-MSGraphRequest -HttpMethod GET -Url $NextLink -Verbose) Write-Log -Message "Processing Page .....$count" -path $log $NextLink = $Response."@odata.nextLink" $getmdm += $Response.value | where{($_.managementAgent -eq "mdm") -and ($_.enrolledDateTime -ge $getdate) -and ($_.deviceEnrollmentType -eq "userEnrollment")} } $allMDM = $getmdm | select UserPrinCipalName -Unique #fetched all enrolled devices } catch { $exception = $_.Exception Write-Log -Message "Error Calling Graph API" -path $log -Severity Error Write-Log -Message "$exception" -path $log -Severity Error Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error Calling Graph API MMDMWelcomeEmail" -Body $($_.Exception.Message) Start-ProgressBar -Title "Error Calling Graph API" -Timer 10 exit; } ################Start comparing with previous data###################### try { $tespath = Test-Path -Path $tempcsv if($tespath -eq $false) { Write-Log -Message "Export.....to tempcsv as it does not exist" -path $log $allMDM | Export-Csv $tempcsv -NoTypeInformation } $tempimport = Import-Csv $tempcsv $change = Compare-Object -ReferenceObject $allMDM -DifferenceObject $tempimport -Property UserPrinCipalName $Removal = $change | Where-Object -FilterScript {$_.SideIndicator -eq "=>"} | Select-Object -ExpandProperty UserPrinCipalName $Addition = $change | Where-Object -FilterScript {$_.SideIndicator -eq "<="} | Select-Object -ExpandProperty UserPrinCipalName $removalcount = $Removal.count $additioncount = $Addition.count Write-Log -Message "Remove Count $removalcount - ignore" -path $log Write-Log -Message "Communication Count $additioncount" -path $log } catch { $exception = $_.Exception Write-Log -Message "Error Comparing the tempcsv with MDM" -path $log -Severity Error Write-Log -Message "$exception" -path $log -Severity Error Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error Comparing the tempcsv with MDM MDMWelcomeEmail" -Body $($_.Exception.Message) Start-ProgressBar -Title "Error Comparing the tempcsv with MDM" -Timer 10 exit; } if(($additioncount -gt "0") -and ($additioncount -lt $countofchanges)) { $collection = @() $Addition | ForEach-Object{ $error.clear() $email = $_ $body = @" Dear user, Intune Welcome Email, Intune Welcome Email. "@ $mcoll = "" | select UserPrincipalName, Status $mcoll.UserPrincipalName = $email Write-Log -Message "Sending welecome email.....$email" -path $log #Send-MailMessage -SmtpServer $smtpserver -From $from -To $email -Subject "Intune - Welcome Email" -Body $body if($error) { $mcoll.Status = "Error" Write-Log -Message "Sending welecome email.....$email - Failed" -path $log -Severity Warning } else{$mcoll.Status = "Success"} $collection += $mcoll } Write-Log -Message "Export.....Report" -path $log $collection | Export-Csv $Report1 -NoTypeInformation Write-Log -Message "Sending.......Report" -path $log Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "MDMWelcomeEmail - Report" -Body "MDMWelcomeEmail - Report" -Attachments $Report1 } elseif($additioncount -ge $countofchanges) { $exception = $_.Exception Write-Log -Message "Error Count $additioncount is greter then $countofchanges" -path $log -Severity Error Write-Log -Message "$exception" -path $log -Severity Error Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error Count $additioncount is greter then $countofchanges MDMWelcomeEmail" -Body $($_.Exception.Message) Start-ProgressBar -Title "Error Count $additioncount is greter then $countofchanges" -Timer 10 exit; } Write-Log -Message "Export.....to tempcsv" -path $log $allMDM | Export-Csv $tempcsv -NoTypeInformation ##############################Recycle Logs########################## Write-Log -Message "Recycle Logs" -path $log -Severity Information $path1 = (Get-Location).path + "\report" $path2 = (Get-Location).path + "\logs" $limit = (Get-Date).AddDays(-60) #for report recycling Get-ChildItem -Path $path1 | Where-Object {$_.CreationTime -lt $limit} | Remove-Item -recurse -Force Get-ChildItem -Path $path2 | Where-Object {$_.CreationTime -lt $limit} | Remove-Item -recurse -Force Write-Log -Message "Script Finished" -path $log -Severity Information Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Transcript Log - MDMWelcomeEmail" -Body "Transcript Log - MDMWelcomeEmail" -Attachments $log ###############################################################################
Thanks for reading and downloading
Tech Wizard