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
adam
June 21, 2021, 12:53pm
2
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?
adam
June 22, 2021, 12:46pm
4
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'
}
adam
June 26, 2021, 1:49pm
6
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. 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 " <strong>Subject: </strong> $($Subject.value)"
New-UDHtml " <strong>Search Start: </strong> $StrStartDate"
New-UDHtml " <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