PSsession issue?

Everything in the dashboard works except the email purge section when the ComplianceSearchAction cmdlet’s are invoked. I’m doing a check on the session station which returns a valid ID. The same code works in a powershell script. The log shows that the cmdlet isn’t recognized which to me seems like the remote session was disconnected.

Jun 19, 2021 2:55 PM An error occurred: The term 'New-ComplianceSearchAction' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Endpoint: btnDelete
Session: 9de54224-039d-401a-a512-3b3f460bf816
File: 
Endpoint Start Line: 5
Endpoint End Line: 26
Stack Trace: at <ScriptBlock>, <No file>: line 9
$DBContent = {
    New-UDForm -Content {   
        New-UDGrid -Container -Content {
            New-UDRow -Id Row -Columns {
                New-UDColumn -SmallSize 2 -LargeSize 2 -SmallOffset 1 -Content {
                    New-UDStyle -Style '.MuiInputLabel-shrink {
                        transform: translate(0, 1.5px) scale(0.75);
                        transform-origin: top left;
                        min-width: 230px;
                        }' -Content {
                        New-UDPaper -Elevation 2 -Content {
                            New-UDTextbox -Id tbSender -Label "Enter Sender's email address"
                        }
                    }
                }
                New-UDColumn -SmallSize 4 -LargeSize 4 -SmallOffset 1 -Content {
                    New-UDPaper -Elevation 2 -Content {
                        New-UDTextbox -Id tbSubject -Label "Enter subject of phishing email" -FullWidth
                    }
                }

                New-UDColumn -SmallSize 3 -LargeSize 3 -SmallOffset 1 -Content {
                    New-UDPaper -Elevation 2 -Content {
                        New-UDDatePicker -Id dpStart -Label "Start date range" -Variant inline
                        New-UDDatePicker -Id dpEnd -Label "End date range" -Variant inline
                    }
                }
            }
        }
    } -OnSubmit {
        $MailSender = Get-UDElement -Id tbSender 
        $Subject = Get-UDElement -Id tbSubject
        $StartDate = Get-UDElement -Id dpStart
        $EndDate = Get-UDElement -Id dpEnd
        $SearchID = "Remove Phishing Message"
        $ContentQuery = '(c:c)(received=' + $StartDate.value + '..' + $EndDate.value + ')(senderauthor=' + $MailSender.value + ')(subjecttitle="' + $Subject.value + '")'
        
        $MySession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri 'https://ps.compliance.protection.outlook.com/powershell-liveid/' -Credential $AzureADAdmin -Authentication Basic -AllowRedirection
        if ($MySession -is [System.Management.Automation.Runspaces.PSSession]) {
            Import-PSSession $MySession -AllowClobber | Out-Null
            If (Get-ComplianceSearch -Identity $SearchID) {
                Show-UDToast -Message "Cleaning up old search" -Duration 2000 -BackgroundColor blue -MessageColor white
                Try {
                    Remove-ComplianceSearch -Identity $SearchID -Confirm:$False  
                } 
                Catch { 
                    Show-UDToast -Message "Unable to clean up the old search" -Duration 2000 -BackgroundColor red -MessageColor white
                    break 
                }
            }
            else { Show-UDToast -Message "No search found" -Duration 2000 }
            New-ComplianceSearch -Name $SearchID -ContentMatchQuery $ContentQuery -ExchangeLocation All -AllowNotFoundExchangeLocationsEnabled $True | Out-Null
            Show-UDToast -Message "Starting Search..." -Duration 1000 -BackgroundColor blue -MessageColor white
            Start-ComplianceSearch -Identity $SearchID | Out-Null
            $Seconds = 0
            While ((Get-ComplianceSearch -Identity $SearchID).Status -ne "Completed") {
                $Seconds++
                Show-UDToast -Message "Still searching... $Seconds" -Duration 1000 -BackgroundColor blue -MessageColor white
                Start-Sleep -Seconds 2
            }
            $ItemsFound = (Get-ComplianceSearch -Identity $SearchID).Items
            Start-Sleep -Seconds 3
            If ($ItemsFound -gt 0) {
                $Stats = Get-ComplianceSearch -Identity $SearchID | Select-Object -Expand SearchStatistics | Convertfrom-JSON
                $Data = $Stats.ExchangeBinding.Sources | Where-Object { $_.ContentItems -gt 0 }
                New-UDTypography -Id txtTotalItems -Text "Total Items found matching query: $ItemsFound" -Variant h5
                $Columns = @( 
                    New-UDTableColumn -Property Name -Title "Name"
                    New-UDTableColumn -Property ContentItems -Title 'Items'
                    New-UDTableColumn -Property ContentSize -Title 'Size'
                )
                New-UDTable -Data $Data -Id 'ItemsTable' -Title "Items found in the following mailboxes" -Columns $Columns 
    
                New-UDButton -Id "btnPurge" -Text "Purge Emails" -OnClick { 
                    Show-UDModal -Content {
                        New-UDAlert -Severity 'warning' -Content { 
                            New-UDHtml "Are you sure you want to purge the emails from <strong>$($MailSender.value)</strong>"
                            New-UDButton -Id btnDelete -Text "Purge" -OnClick {
                                Show-UDToast -Message "Session ID: $($Mysession.Id)" -Duration 5000 -BackgroundColor red -MessageColor white
                                Hide-UDModal
                                if ($MySession -is [System.Management.Automation.Runspaces.PSSession]) {
                                    $Iterations = 0; $ItemsProcessed = 0
                                    While ($ItemsProcessed -lt $ItemsFound) {
                                        $Iterations++
                                        Show-UDToast -Message "Deleting items... ($Iterations)" -Duration 1000
                                        New-ComplianceSearchAction -SearchName $SearchID -Purge -PurgeType SoftDelete -Confirm:$False
                                        While ((Get-ComplianceSearchAction -Identity "$($SearchID)_Purge").Status -ne "Completed") {
                                            Start-Sleep -Seconds 2 
                                        }
                                        $ItemsProcessed = $ItemsProcessed + 10
                                        Remove-ComplianceSearchAction -Identity "$($SearchID)_Purge" -Confirm:$False  
                                    }
                                }
                                Else { 
                                    Show-UDModal -Content {
                                        New-UDTypography -Text "No session still exists."
                                    } -FullWidth -MaxWidth 'md'
                                }
                            }
                            New-UDButton -Id btnDelCancel -Text "Cancel" -OnClick { 
                                Hide-UDModal 
                            }
                        } -Title "Warning"
                    } -Persistent -FullWidth -MaxWidth 'md'
                }
            }
            Else { 
                Show-UDModal -Content {
                    New-UDTypography -Text "No items found" 
                } -FullWidth -MaxWidth 'md'
            }
            
        }
        else {
            Show-UDModal -Content {
                New-UDTypography -Text "No session created." 
            } -FullWidth -MaxWidth 'md'
        }
        Remove-PSSession -Session $MySession
    }
}
$Pages = @()
$Pages += New-UDPage -Name 'Phishing Email Removal' -Content $DBContent -NavigationLayout Temporary -Navigation $Navigation
New-UDDashboard -Title "Phishing Email Removal" -Pages $Pages
Product: PowerShell Universal
Version: 2.0.3

This might be because of how runspaces are being used in UD. While the $MySession variable has been moved to the OnClick button runspace, it might not be correctly importing the modules due to how Import-Session works.

Can you you try to create a new session in the OnClick handler and call Import-PSSession within there to see if that helps?

Creating a new session does work. Is it possible to reuse the session?

It should be. Can you try avoiding calling New-PSSession and just call Import-PSSession in the OnClick?

Importing the session does work and it makes sense that it would be starting a new runspace and require it to be imported again.

Now I have another issue. When the session closes or I cancel the email purge I attempt to remove the session, remove the table, then show a text string and a button but it returns a React error that according to the decoder it is expecting an array?

Objects are not valid as a React child (found: Error: Minified React error #310; visit https://reactjs.org/docs/error-decoder.html?invariant=310 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.). If you meant to render a collection of children, use an array instead.
                New-UDTable -Data $Data -Id 'ItemsTable' -Title "Items found in the following mailboxes" -Columns $Columns 
                New-UDButton -Id "btnPurge" -Text "Purge Emails" -OnClick { 
                    Show-UDModal -Content {
                        New-UDAlert -Severity 'warning' -Content { 
                            New-UDHtml "Are you sure you want to purge the emails from <strong>$($MailSender.value)</strong>"
                            New-UDButton -Id btnDelete -Text "Purge" -OnClick {
                                Import-PSSession $MySession -AllowClobber | Out-Null
                                Hide-UDModal
                                if ($MySession -is [System.Management.Automation.Runspaces.PSSession]) {
                                    $Iterations = 0; $ItemsProcessed = 0
                                    While ($ItemsProcessed -lt $ItemsFound) {
                                        $Iterations++
                                        Show-UDToast -Message "Starting the purge... ($Iterations)" -Duration 2000  -BackgroundColor red -MessageColor white
                                        New-ComplianceSearchAction -SearchName $SearchID -Purge -PurgeType SoftDelete -Confirm:$False
                                        While ((Get-ComplianceSearchAction -Identity "$($SearchID)_Purge").Status -ne "Completed") {
                                            Start-Sleep -Seconds 2 
                                            Show-UDToast -Message "Purging items..." -Duration 2000  -BackgroundColor red -MessageColor white
                                        }
                                        $ItemsProcessed = $ItemsProcessed + 10
                                        Remove-ComplianceSearchAction -Identity "$($SearchID)_Purge" -Confirm:$False 
                                        Show-UDToast -Message "Search action removed." -Duration 2000  -BackgroundColor red -MessageColor white 
                                    }
                                }
                                Else { 
                                    Show-UDModal -Content {
                                        New-UDTypography -Text "No session still exists."
                                    } -FullWidth -MaxWidth 'md'
                                }
                                Remove-PSSession -Id $MySession
                                Remove-UDElement -Id 'ItemsTable'

                                New-UDTypography -Text 'Purge complete'
                                New-UDButton -Text "Search Again" -Icon (New-UDIcon -Icon hand_point_left ) -OnClick {
                                    Invoke-UDRedirect -Url "$DBUrl/phrem"
                                } 
                            }
                            New-UDButton -Id btnDelCancel -Text "Cancel" -OnClick { 
                                Hide-UDModal 
                                Remove-PSSession -Id $MySession
                                Remove-UDElement -Id 'ItemsTable'

                                New-UDTypography -Text 'Purge canceled'
                                New-UDButton -Text "Search Again" -Icon (New-UDIcon -Icon hand_point_left ) -OnClick {
                                    Invoke-UDRedirect -Url "$DBUrl/phrem"
                                } 
                            }
                        } -Title "Warning"
                    } -Persistent -FullWidth -MaxWidth 'md'
                }

Can you verify that it’s part of the remove? Or is it because you are calling New-UDTypography and New-UDButton in the OnClick?

I would imagine that text and button wouldn’t show up. You’d need to call Set-UDElement or Add-UDElement to add it to the page from the OnClick.

I’m going to post the entire dashboard code. Everything is working with the exception of the commented sections that both return React error #31. I’ve been trying to figure out what the problem might be for that last 3 days. :crazy_face: I give up.

$temail = 'someone@somehere.com'
$tsub = 'Email subject'
$Navigation = @(
    New-UDListItem -Label "Home" -OnClick { Invoke-UDRedirect "$DBUrl/" }
    New-UDListItem -Label "Remove phishing email" -OnClick { Invoke-UDRedirect "$DBUrl/phrem" }
    If ($Roles -contains "Administrator") {
        New-UDListItem -Label "Administration" -OnClick { Invoke-UDRedirect "$DBUrl/admin" -OpenInNewWindow }  
    }    
)
$DBContent = {
    New-UDForm -Content {   
        New-UDGrid -Id 'GridOne' -Container -Content {
            New-UDRow -Id Row -Columns {
                New-UDColumn -SmallSize 2 -LargeSize 2 -Content {
                    New-UDStyle -Style '.MuiInputLabel-shrink {
                        transform: translate(0, 1.5px) scale(0.75);
                        transform-origin: top left;
                        min-width: 230px;
                        }' -Content {
                        New-UDPaper -Elevation 2 -Content {
                            New-UDTextbox -Id tbSender -Label "Enter Sender's email address" -Value $temail
                        }
                    }
                }
                New-UDColumn -SmallSize 4 -LargeSize 4 -Content {
                    New-UDPaper -Elevation 2 -Content {
                        New-UDTextbox -Id tbSubject -Label "Enter subject of phishing email" -Value $tsub -FullWidth
                    }
                }

                New-UDColumn -SmallSize 3 -LargeSize 3 -Content {
                    New-UDPaper -Elevation 2 -Content {
                        New-UDDatePicker -Id dpStart -Label "Start date range" -Variant inline
                        New-UDDatePicker -Id dpEnd -Label "End date range" -Variant inline
                    }
                }
            }
        }
    } -OnSubmit {
        $MailSender = Get-UDElement -Id tbSender 
        $Subject = Get-UDElement -Id tbSubject
        $StartDate = Get-UDElement -Id dpStart
        $EndDate = Get-UDElement -Id dpEnd
        $StrStartDate = Get-Date $StartDate.value -Format "MM/dd/yyyy"
        $StrEndDate = Get-Date $EndDate.value -Format "MM/dd/yyyy"
        New-UDCard -Id 'DetailsCard' -Title "Search Details" -Content { 
            New-UDHtml "<strong>Sender: </strong> $($MailSender.value)"
            New-UDHtml "&nbsp; &nbsp; &nbsp; &nbsp;<strong>Subject: </strong> $($Subject.value)"
            New-UDHtml "&nbsp; &nbsp; &nbsp; &nbsp;<strong>Search Start: </strong> $StrStartDate"
            New-UDHtml "&nbsp; &nbsp; &nbsp; &nbsp;<strong>Search End: </strong> $StrEndDate"
        }
        $SearchID = "Remove Phishing Message"
        $ContentQuery = '(c:c)(received=' + $StartDate.value + '..' + $EndDate.value + ')(senderauthor=' + $MailSender.value + ')(subjecttitle="' + $Subject.value + '")'
        
        $MySession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri 'https://ps.compliance.protection.outlook.com/powershell-liveid/' -Credential $AzureADAdmin -Authentication Basic -AllowRedirection
        if ($MySession -is [System.Management.Automation.Runspaces.PSSession]) {
            Import-PSSession $MySession -AllowClobber | Out-Null
            If (Get-ComplianceSearch -Identity $SearchID) {
                Show-UDToast -Message "Cleaning up old search" -Duration 2000 -BackgroundColor blue -MessageColor white
                Try {
                    Remove-ComplianceSearch -Identity $SearchID -Confirm:$False  
                } 
                Catch { 
                    Show-UDToast -Message "Unable to clean up the old search" -Duration 2000 -BackgroundColor red -MessageColor white
                    break 
                }
            }
            else { Show-UDToast -Message "No search found" -Duration 2000 }
            New-ComplianceSearch -Name $SearchID -ContentMatchQuery $ContentQuery -ExchangeLocation All -AllowNotFoundExchangeLocationsEnabled $True | Out-Null
            Show-UDToast -Message "Starting Search..." -Duration 1000 -BackgroundColor blue -MessageColor white
            Start-ComplianceSearch -Identity $SearchID | Out-Null
            $Seconds = 0
            While ((Get-ComplianceSearch -Identity $SearchID).Status -ne "Completed") {
                $Seconds++
                Show-UDToast -Message "Still searching... $Seconds" -Duration 1000 -BackgroundColor blue -MessageColor white
                Start-Sleep -Seconds 2
            }
            $ItemsFound = (Get-ComplianceSearch -Identity $SearchID).Items
            Start-Sleep -Seconds 3
            If ($ItemsFound -gt 0) {
                $Stats = Get-ComplianceSearch -Identity $SearchID | Select-Object -Expand SearchStatistics | Convertfrom-JSON
                $Data = $Stats.ExchangeBinding.Sources | Where-Object { $_.ContentItems -gt 0 }
                New-UDTypography -Id txtTotalItems -Text "Total Items found matching query: $ItemsFound" -Variant h5
                $Columns = @( 
                    New-UDTableColumn -Property Name -Title "Name" -IncludeInExport -IncludeInSearch
                    New-UDTableColumn -Property ContentItems -Title 'Items' -IncludeInExport
                    New-UDTableColumn -Property ContentSize -Title 'Size' -IncludeInExport
                )
                New-UDTable -Data $Data -Id 'ItemsTable' -Title "Items found in the following mailboxes" -Columns $Columns -ShowSort -ShowExport -ShowSearch -ShowPagination
                Remove-PSSession -Session $MySession
                New-UDButton -Id 'btnPurge' -Text "Purge Emails" -OnClick { 
                    Show-UDModal -Content {
                        New-UDAlert -Severity 'warning' -Content { 
                            New-UDHtml "Are you sure you want to purge the emails from <strong>$($MailSender.value)</strong>"
                            New-UDButton -Id btnDelete -Text "Purge" -OnClick {
                                $MyNewSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri 'https://ps.compliance.protection.outlook.com/powershell-liveid/' -Credential $AzureADAdmin -Authentication Basic -AllowRedirection
                                Import-PSSession $MyNewSession -AllowClobber | Out-Null
                                Hide-UDModal
                                if ($MyNewSession -is [System.Management.Automation.Runspaces.PSSession]) {
                                    $Iterations = 0; $ItemsProcessed = 0
                                    While ($ItemsProcessed -lt $ItemsFound) {
                                        $Iterations++
                                        Show-UDToast -Message "Starting the purge... ($Iterations)" -Duration 2000  -BackgroundColor red -MessageColor white
                                        New-ComplianceSearchAction -SearchName $SearchID -Purge -PurgeType SoftDelete -Confirm:$False
                                        While ((Get-ComplianceSearchAction -Identity "$($SearchID)_Purge").Status -ne "Completed") {
                                            Start-Sleep -Seconds 2 
                                            Show-UDToast -Message "Purging items..." -Duration 2000  -BackgroundColor red -MessageColor white
                                        }
                                        $ItemsProcessed = $ItemsProcessed + 10
                                        Remove-ComplianceSearchAction -Identity "$($SearchID)_Purge" -Confirm:$False 
                                        Show-UDToast -Message "Search action removed." -Duration 2000  -BackgroundColor red -MessageColor white 
                                    }
                                }
                                Else { 
                                    Show-UDModal -Content {
                                        New-UDTypography -Text "No session still exists."
                                    } -FullWidth -MaxWidth 'md'
                                }
                                Get-PSSession | Remove-PSSession
                                #----- This section causes a React error #31
                                Remove-UDElement -Id 'ItemsTable' #--- Remove the table of emails that were found
                                Remove-UDElement -Id 'btnPurge' #--- Remove purge email button
                                New-UDElement -Tag 'div' -Id 'info' -Content {
                                    New-UDTypography -Text 'Purge complete' #--- Show that the purge is complete
                                    New-UDButton -Id 'btnSearchAgain' -Text 'Search Again' -Icon (New-UDIcon -Icon hand_point_left) -OnClick {
                                        Invoke-UDRedirect -Url "$DBUrl/phrem"
                                    }
                                }
                                #----- End section
                            }
                            New-UDButton -Id btnDelCancel -Text "Cancel" -OnClick { 
                                Hide-UDModal 
                                Get-PSSession | Remove-PSSession
                                #----- This section causes a React error #31
                                Remove-UDElement -Id 'btnPurge' #----- Remove purge email button
                                New-UDElement -Tag 'div' -Id 'info' -Content {
                                    New-UDTypography -Text "Purge canceled" #--- Show that the purge was canceled
                                    New-UDButton -Id 'btnNewSearch' -Text 'New Search' -Icon (New-UDIcon -Icon hand_point_left) -OnClick {
                                        Invoke-UDRedirect -Url "$DBUrl/phrem"
                                    }
                                }
                                #----- End section
                            }
                        } -Title "Warning"
                    } -Persistent -FullWidth -MaxWidth 'md'
                }
            }
            Else { 
                Show-UDModal -Content {
                    New-UDTypography -Text "No items found" 
                } -FullWidth -MaxWidth 'md'
            }
            Get-PSSession | Remove-PSSession
        }
        else {
            Show-UDModal -Content {
                New-UDTypography -Text "No session created." 
            } -FullWidth -MaxWidth 'md'
        }
        Remove-PSSession -Session $MySession
    }
}
$Pages = @()
$Pages += New-UDPage -Name 'Phishing Email Removal Test' -Content $DBContent -NavigationLayout Temporary -Navigation $Navigation
New-UDDashboard -Title "Phishing Email Removal Test" -Pages $Pages