Test.EmailServerProfileANDMailbox.psm1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
##__________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"
#>

}