I'm trying to execute a PowerShell script which retirves Exchange Online mailboxes. When running the script separately in PowerShell prompt and running the script via JAVA class file (in eclipse), the time taken is 5 minutes. But when invoking the script inside our application which is multi threaded JVM environment with huge heap memory, it takes almost double the time.
We are using ProcessBuilder to invoke the script and read the InuptStream. Only the script execution time is higher and parsing time is fast enough in JAVA side. If any extra info needed, feel free to comment.
I'm quite new to JAVA ProcessBuilder. So, still trying to understand some concepts.
I tried to trobleshoot in our environemnt but the issue seems to be of PowerShell side. I seacrhed everywhere about this but couldn't find any.
Edit: We are fetching mailboxes and processing to sort top 10 mailboxes based on usage and top inactive mailboxes in desired format. Please find the PowerShell snippet requested below:
Import-Module ExchangeOnlineManagement -ErrorAction Stop -WarningAction SilentlyContinue
Connect-ExchangeOnline -ShowBanner:$false -Credential $credential -ErrorAction Stop -WarningAction SilentlyContinue
$mailboxes = $null
if ($metricsList -contains "InactiveMailboxes" -or $metricsList -contains "TopMailboxes") {
$mailboxes = Get-EXOMailbox -ResultSize Unlimited -WarningAction SilentlyContinue | Where-Object { (!$_.Name.startswith("SystemMailbox")) -and (!$_.Name.startswith("FederatedEmail")) -and (!$_.Name.startswith("DiscoverySearchMailbox")) } | select -expand userprincipalname | Get-EXOMailboxStatistics -Properties DisplayName,ItemCount,TotalItemSize,LastLogonTime -WarningAction SilentlyContinue}
$inactivemailbox = $mailboxes | Where-Object { $_.LastLogonTime -ne $null } | Where-Object { $_.LastLogonTime -lt (Get-Date).AddDays(-30) } | Sort-Object LastLogonTime -Descending | Select-Object -First 100 | Select-Object DisplayName,LastLogonTime | ConvertTo-Csv -Delimiter "|" -NoTypeInformation | ForEach-Object { $_.Replace('"','') } | Select-Object -Skip 1
$topmailbox = $mailboxes | Sort-Object TotalItemSize -Descending | Select-Object -First 10 | Select-Object DisplayName,@{ Name = "TotalItemSizeMB"; expression = { [math]::Round(($_.TotalItemSize.ToString().split("(")[1].split(" ")[0].Replace(",","") / 1MB),2) } },ItemCount | ConvertTo-Csv -Delimiter "|" -NoTypeInformation | ForEach-Object { $_.Replace('"','') } | Select-Object -Skip 1
Java Code snippet: We are framing the script execution for ProcessBuilder like below for security reasons:
String POWERSHELL_PATH = System.getenv("SystemRoot") + File.separator + "System32" + File.separator + "WindowsPowerShell" + File.separator + "v1.0" + File.separator + "powershell.exe";
ProcessBuilder pb = new ProcessBuilder(POWERSHELL_PATH);
List args = [-ExecutionPolicy, Bypass, -NoLogo, -NonInteractive, -NoProfile, -WindowStyle, Hidden, "&{&, 'Script_With_Path', 'Comma separated args' }"]; // Sample values
pb.command().addAll(args);
Reading the InputStream as below:
BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));
while((str = br.readLine()) != null) {
if(str.indexOf("Script execution time was exceeded")!=-1) {
outputBuff.append("Error # Script execution time was exceeded for the host"); // NO I18N
br.close();
return;
}
outputBuff.append(str);
outputBuff.append("\n"); // NO I18N
}