Test.EmailServerProfileANDMailbox.psm1
##__________This Module Test Email Server Profile and mailbox in Dynamics 365 CRM instance___________## ##_____________________________________Author : YASH GUPTA (YG)______________________________________## #This function is used to send email at higher priority of failed mailbox details to the User. function Send-EmailToNotifyError{ [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory=$false)] [string] $loc, [parameter(Mandatory=$true)] [string] $EmailTo, [parameter(Mandatory=$true)] [string] $SMTPServer, [parameter(Mandatory=$true)] [int] $SMTPPort, [parameter(Mandatory=$true)] [string] $EnvName, [parameter(Mandatory=$true)] [string] $MailboxName ) try{ #Subject, Body and SMTP Details $Subject = (Get-Date).ToString('MM-dd-yyyy hh:mm:ss') + " Alert: Mailbox Status failure in "+ $EnvName $StoredSMTPCredential = Get-StoredCredential -Target SMTPLogin -AsCredentialObject If (!$StoredSMTPCredential) { $psCred = Get-Credential -Message "Enter your EmailID and Password" $cre = New-StoredCredential -Target SMTPLogin -Credentials $psCred -Persist LocalMachine $StoredSMTPCredential = Get-StoredCredential -Target SMTPLogin } $SMTPAuthUsername = $StoredSMTPCredential.UserName $SMTPAuthPassword = $StoredSMTPCredential.Password $EmailFrom = $SMTPAuthUsername $Body = "Dear Tester, The Mailbox " + $MailboxName +" if failed on " +(Get-Date).ToString('MM-dd-yyyy hh:mm:ss') + " Please find Attachment of Mailbox Status History. NOTE: This is an autogenerated mail. Please do not reply. Thanks and Regards, Administrator" $mailmessage = New-Object system.net.mail.mailmessage $mailmessage.from = ($EmailFrom) $mailmessage.To.add($EmailTo) $mailmessage.Subject = $Subject $mailmessage.Body = $Body $mailmessage.Priority = [System.Net.Mail.MailPriority]::High $attachment = New-Object System.Net.Mail.Attachment($loc1) $mailmessage.Attachments.Add($attachment) $SMTPClient = New-Object Net.Mail.SmtpClient("$SMTPServer", "$SMTPPort") $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("$SMTPAuthUsername", "$SMTPAuthPassword") $SMTPClient.Send($mailmessage) Write-Host Email Send Successfully to $EmailTo } catch{ Write-Host An Error Has Ocuured $_.Exception.Message } <# .SYNOPSIS This function is used to send Email if anything goes wrong in mailbox. .DESCRIPTION Author : Yash Gupta(YG). This function is automatically triggered by Test-Mailbox. This function is a parameterised function. You should pass arguments to the function using Named parametered. The credentials will be saved in Window's Credential Manager. .OUTPUTS Send Email #> } #This function is used get last tested date of mailbox. function Get-MailboxLastTestDate{ [CmdletBinding(SupportsShouldProcess)] PARAM( [parameter(Mandatory=$true)] [string] $MailboxName ) $result = Get-CrmRecords -EntityLogicalName mailbox -FilterAttribute name -FilterOperator eq $MailboxName -Fields testmailboxaccesscompletedon $value = foreach($j in $result.CrmRecords){$j.testmailboxaccesscompletedon} return $value <# .SYNOPSIS This function is used to get last test date and time of mailbox. .DESCRIPTION Author : Yash Gupta(YG). This function is tiggered by Test-Mailbox. #> } #This function is used get the status of mailbox and save the details in csv file. function Test-Mailbox{ #.ExternalHelp Test.EmailServerProfileANDMailbox.help.xml [CmdletBinding(SupportsShouldProcess)] PARAM( [parameter(Mandatory=$true)] [string]$MailboxName, [parameter(Mandatory=$true)] [string]$URL, [parameter(Mandatory=$true)] [string]$ServerProfileName, [parameter(Mandatory=$true)] [string]$DataFilepath, [parameter(Mandatory=$true)] [string]$EmailTo, [parameter(Mandatory=$true)] [string]$SMTPServer, [parameter(Mandatory=$true)] [int]$SMTPPort ) try{ #Checking Required Module $PackageArray = "CredentialManager","Microsoft.Xrm.Data.Powershell" foreach($i in $PackageArray){ Write-Host Intalling required Modules. if(Get-Module -ListAvailable -Name $i){ } else{ Install-Module -Name $i -Force } } $StoredCredential = Get-StoredCredential -Target PowershellLogin If(!$StoredCredential) { $psCred = Get-Credential -Message "Enter your Credential for Dynamics 365 Environment" $strcred = New-StoredCredential -Target PowershellLogin -Credentials $psCred -Persist LocalMachine $StoredCredential = Get-StoredCredential -Target PowershellLogin } $trgtUserName = $StoredCredential.UserName $trgtPass = $StoredCredential.Password $cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $trgtUserName, $trgtPass #________________________Connecting CRM______________________ Write-Host Connecting to CRM/CDS... $trgtCRMOrg = Connect-CrmOnline -Credential $cred -ServerUrl $URL Write-Host Connected to Dynamics 365 $URL $result = Get-CrmRecords -EntityLogicalName mailbox -FilterAttribute name -FilterOperator eq $MailboxName -Fields name,mailboxid $value = foreach($j in $result.CrmRecords){$j.name;$j.mailboxid.Guid} $Oldvalue = Get-MailboxLastTestDate -MailboxName $j.name #Test and enabling the mailbox Set-CrmRecord -conn $trgtCRMOrg -EntityLogicalName mailbox -Id $j.mailboxid.Guid -Fields @{testemailconfigurationscheduled=$true} Write-Host The Mailbox has been Tested and Enabled. Please wait... Start-Sleep 1 $Newvalue = Get-MailboxLastTestDate -MailboxName $j.name #Checking last tested date and time for mailbox while($Oldvalue.Equals($Newvalue)){ Start-Sleep 4 $Newvalue = Get-MailboxLastTestDate -MailboxName $j.name } Write-Host The Mailbox is Tested and Enabled. #Fetch XML on Entity Mailbox Details $fetchXml = @" <fetch> <entity name="mailbox" > <attribute name="incomingemailstatus" /> <attribute name="outgoingemailstatus" /> <attribute name="averagetotalduration" /> <attribute name="mailboxstatus" /> <attribute name="name" /> <attribute name="emailserverprofile" /> <attribute name="mailboxid" /> <attribute name="statuscode" /> <attribute name="emailrouteraccessapproval" /> <attribute name="isemailaddressapprovedbyo365admin" /> <attribute name="testemailconfigurationscheduled" /> <attribute name="testmailboxaccesscompletedon" /> <filter> <condition attribute="name" operator="eq" value="$MailboxName" /> </filter> </entity> </fetch> "@ $FetchResult = Get-CrmRecordsByFetch -conn $trgtCRMOrg -Fetch $fetchXml -AllRow $CheckServerProfile = foreach($i in $FetchResult.CrmRecords){ if(!($i.emailserverprofile).Equals($ServerProfileName)){ [System.Windows.MessageBox]::Show("The mailbox " +$MailboxName+ " is not present in " +$ServerProfileName+"",'No Result Found','Ok','warning') exit } } Write-Host Mailbox Status is retrieved from $URL #Creating Tablubar format to store in CSV File $tableEntity = New-Object system.Data.DataTable "MailboxStaus" $tblcol1 = New-Object system.Data.DataColumn Date, ([string]) $tblcol2 = New-Object system.Data.DataColumn Name, ([string]) $tblcol3 = New-Object system.Data.DataColumn Incoming_Email_Status, ([string]) $tblcol4 = New-Object system.Data.DataColumn Outgoing_Email_Status, ([string]) $tblcol5 = New-Object system.Data.DataColumn Status_Code, ([string]) $tblcol6 = New-Object system.Data.DataColumn Mailbox_Status, ([string]) $tblcol7 = New-Object system.Data.DataColumn Average_Total_Duration, ([string]) $tblcol8 = New-Object system.Data.DataColumn Email_Router_Access_Approval, ([string]) $tblcol9 = New-Object system.Data.DataColumn IsEmailAddressApprovedbyo365Admin, ([string]) $tblcol10 = New-Object system.Data.DataColumn Test_Emailconfigurationscheduled, ([string]) $tblcol11 = New-Object system.Data.DataColumn Test_Mailboxaccesscompletedon, ([string]) $tableEntity.columns.add($tblcol1) $tableEntity.columns.add($tblcol2) $tableEntity.columns.add($tblcol3) $tableEntity.columns.add($tblcol4) $tableEntity.columns.add($tblcol5) $tableEntity.columns.add($tblcol6) $tableEntity.columns.add($tblcol7) $tableEntity.columns.add($tblcol8) $tableEntity.columns.add($tblcol9) $tableEntity.columns.add($tblcol10) $tableEntity.columns.add($tblcol11) $FetchResult = Get-CrmRecordsByFetch -conn $trgtCRMOrg -Fetch $fetchXml -AllRows #$solutionEntity = New-Object System.Collections.Generic.List[Guid] $FetchResult.CrmRecords | ForEach-Object{ $tblrow = $tableEntity.NewRow() $tblrow.Date = (Get-Date).ToString('MM-dd-yyyy hh:mm:ss') $tblrow.Name = $_.name $tblrow.Incoming_Email_Status = $_.incomingemailstatus $tblrow.Outgoing_Email_Status = $_.outgoingemailstatus $tblrow.Status_Code = $_.statuscode $tblrow.Mailbox_Status = $_.mailboxstatus $tblrow.Average_Total_Duration = $_.averagetotalduration $tblrow.Email_Router_Access_Approval = $_.emailrouteraccessapproval $tblrow.IsEmailAddressApprovedbyo365Admin = $_.isemailaddressapprovedbyo365admin $tblrow.Test_Emailconfigurationscheduled = $_.testemailconfigurationscheduled $tblrow.Test_Mailboxaccesscompletedon = $_.testmailboxaccesscompletedon $tableEntity.Rows.Add($tblrow) $FetchResult = Get-CrmRecordsByFetch -conn $trgtCRMOrg -Fetch $fetchXml -AllRow $result = foreach($i in $FetchResult.CrmRecords){ $i.name $i.mailboxid.Guid $i.testemailconfigurationscheduled $i.testmailboxaccesscompletedon } } #Exporting Data in CSV File $tableEntity | Export-Csv -NoTypeInformation -Path $DataFilepath -Append Write-Host The Mailbox Status is exported. " " | Add-Content $DataFilepath if($tblrow.Name -eq $MailboxName){ if(($tblrow.Incoming_Email_Status -eq "Failure") -or ($tblrow.Outgoing_Email_Status -eq "Failure") -or ($tblrow.Status_Code -eq "Inactive") -or ($tblrow.Mailbox_Status -eq "Not Run") -or ($tblrow.Mailbox_Status -eq "Failure") -or ($tblrow.Email_Router_Access_Approval -eq "Empty") -or ($tblrow.IsEmailAddressApprovedbyo365Admin -eq "No") -or ($tblrow.Outgoing_Email_Status -eq "Not Run") -or ($tblrow.Incoming_Email_Status -eq "Not Run")){ Write-Host Something went wrong in mailbox. Please Check your mail for more details. Send-EmailToNotifyError -loc $DataFilepath -EmailTo $EmailTo -SMTPServer $SMTPServer -SMTPPort $SMTPPort -EnvName $trgtCRMOrg.ConnectedOrgFriendlyName -MailboxName $MailboxName } } } catch{ Write-Host An Error has occured $_.Exception.Message } <# .SYNOPSIS This function is used to check Status Mailbox. .DESCRIPTION Author : Yash Gupta(YG). This function triggered by Get-EmailServerProfile This function is a parameterised function. You should pass arguments to the function using Named parametered. The credentials will be saved in Window's Credential Manager. .OUTPUTS Create CSV file in same folder where script is saved. Send Email to given Email Id. .EXAMPLE Test-Mailbox -MailboxName $MialboxName -URL $URL -EmailTo $EmailTo -ServerProfileName $ServerProfileName -DataFilepath $DataFilepath -SMTPServer $SMTPServer -SMTPPort $SMTPPort .EXAMPLE Test-Mailbox -MailboxName "Mailbox Name" - URL "http:\\example.dynamics.crm8.com" -EmailTo "someone@domain.com" -ServerProfileName "Server Profile Name" -DataFilePath "C:\Test.EmailServerProfileANDMailbox\Mailbox Status.csv" -SMTPServer "SMTP Server Name" -SMTPPort 25 #> } #This function is used get details of Email Server profile and notify if it is Inactivate. function Test-EmailServerProfile{ # .ExternalHelp Test.EmailServerProfileANDMailbox.help.xml [CmdletBinding(SupportsShouldProcess)] PARAM( [parameter(Mandatory=$true)] [string]$ServerProfileName, [parameter(Mandatory=$true)] [string]$URL, [parameter(Mandatory=$true)] [string]$DataFilepath, [parameter(Mandatory=$true)] [string]$EmailTo, [parameter(Mandatory=$true)] [string]$SMTPServer, [parameter(Mandatory=$true)] [int]$SMTPPort ) try{ #Checking Required Module $PackageArray = "CredentialManager","Microsoft.Xrm.Data.Powershell" foreach($i in $PackageArray){ Write-Host Intalling required Modules. if(Get-Module -ListAvailable -Name $i){ } else{ Install-Module -Name $i -Force } } $StoredCredential = Get-StoredCredential -Target PowershellLogin If(!$StoredCredential) { $psCred = Get-Credential -Message "Enter your Credentials for Dynamics 365 Environment" $strcred = New-StoredCredential -Target PowershellLogin -Credentials $psCred -Persist LocalMachine $StoredCredential = Get-StoredCredential -Target PowershellLogin } $trgtUserName = $StoredCredential.UserName $trgtPass = $StoredCredential.Password $cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $trgtUserName, $trgtPass #________________________Connecting CRM______________________ Write-Host Connecting to CRM/CDS... $trgtCRMOrg = Connect-CrmOnline -Credential $cred -ServerUrl $URL Write-Host Connected to Dynamics 365 $URL #Fetching Email Server Profile Details $fetchXml = @" <fetch> <entity name="emailserverprofile" > <attribute name="name" /> <attribute name="statecode" /> <attribute name="statuscode" /> <filter> <condition attribute="name" operator="eq" value="$ServerProfileName" /> </filter> </entity> </fetch> "@ $FetchResult = Get-CrmRecordsByFetch -conn $trgtCRMOrg -Fetch $fetchXml -AllRow $result = foreach($i in $FetchResult.CrmRecords){ $i.name $i.statecode $i.statuscode } if($i.statecode.Equals("Inactive") -and $i.statuscode.Equals("Inactive")){ [System.Windows.MessageBox]::Show('Email Server profile is not Active','Not Active','Ok','warning') break } else{ Write-Host Email Server Profile is Activated. $MialboxName = Read-Host "Which Mailbox's status are you looking for?" Test-Mailbox -MailboxName $MialboxName -URL $URL -ServerProfileName $ServerProfileName -DataFilepath $DataFilepath -EmailTo $EmailTo -SMTPServer $SMTPServer -SMTPPort $SMTPPort } } catch{ Write-Host An Error has occured $_.Exception.Message } <# .SYNOPSIS This function is used to get Status Email Server Profile and linked Mailbox and will notify if anything goes wrong. .DESCRIPTION Author : Yash Gupta(YG). This function is a parameterised function. You should pass arguments to the function using Named parametered. The credentials will be saved in Window's Credential Manager. .OUTPUTS Ask for mailbox name, Create CSV file in same folder where script is saved, Send Email to given Email Id. .EXAMPLE Test-EmailServerProfile -ServerProfileName $ServerProfileName -URL $URL -DataFilepath $DataFilepath -EmailTo $EmailTo -SMTPServer $SMTPServer -SMTPPort $SMTPPort .EXAMPLE Test-EmailServerProfile -ServerProfileName "Server Profile Name -URL "https:\\example.crm8.dynamics.com" -DataFilepath "C:\Test.EmailServerProfileANDMailbox\Mailbox Status.csv" -EmailTo "someone@domain.com" -SMTPServer "SMTP Server" -SMTPPort 25 #> } #This function is used to test incoming and outgoing mail to and from Mailbox ID respectively. function SendReceiveMail-Mailbox{ # .ExternalHelp Test.EmailServerProfileANDMailbox.help.xml [CmdletBinding(SupportsShouldProcess)] PARAM( [parameter(Mandatory=$true)] [string]$MailboxEmailId, [parameter(Mandatory=$true)] [string]$TestEmailId, [parameter(Mandatory=$true)] [int]$PortForTestEmailId, [parameter(Mandatory=$true)] [string]$SMTPServerForTestEmailId, [parameter(Mandatory=$true)] [int]$PortForMailboxEmailId, [parameter(Mandatory=$true)] [string]$SMTPServerForMailboxEmailId ) try{ $ToMailbox = $host.ui.PromptForCredential("Need credentials", "Please enter your user name and password for TestEmail ID.", "", "NetBiosUserName") Send-MailMessage -From $TestEmailId -Subject "Test Subject to check incoming" -To $MailboxEmailId -Body "Test Body From PowerShell" -Credential $ToMailbox -Port $PortForTestEmailId -SmtpServer $SMTPServerForTestEmailId Write-Host Email Send Successfully to $MailboxEmailId from $TestEmailId $FromMailbox = $host.ui.PromptForCredential("Need credentials", "Please enter your user name and password for Mailbox ID.", "", "NetBiosUserName") Send-MailMessage -From $MailboxEmailId -Subject "Test Subject to check outgoing" -To $TestEmailId -Body "Test Body From PowerShell" -Credential $FromMailbox -Port $PortForMailboxEmailId -SmtpServer $SMTPServerForMailboxEmailId Write-Host Email Send Successfully to $TestEmailId from $MailboxEmailId } catch{ Write-Host An Error has occured $_.Exception.Message } <# .SYNOPSIS This Cmdlet will test the mailbox by sending and receiving the email to and from mailbox respectively. .DESCRIPTION Author : Yash Gupta(YG). This function is a parameterised function. You should pass arguments to the function using Named parametered. .OUTPUTS Send and receive Email to given Email Id. .EXAMPLE SendReceiveMail-Mailbox -MailboxEmailId $MailboxEmailId -TestEmailId $TestEmailId -PortForTestEmailId $PortForTestEmailId -SMTPServerForTestEmailId $SMTPServerForTestEmailId -PortForMailboxEmailId $PortForMailboxEmailId -SMTPServerForMailboxEmailId $SMTPServerForMailboxEmailId .EXAMPLE SendReceiveMail-Mailbox -MailboxEmailId "mailbox@domain.com" -TestEmailId "Someone@domain.com" -PortForTestEmailId 25 -SMTPServerForTestEmailId "smtp.domain.com" -PortForMailboxEmailId 25 -SMTPServerForMailboxEmailId "smtp.domain.com" #> } |