1

I can't seem to figure out how to capture the quoted text below for parsing. I've tried setting it to a variable as well as redirecting all streams with *>&1 . How can I grab the output text? The *>&1 works for errors, but not for the text below for some reason? Writing to a file is not an option.

Connect-Mailbox -Identity $guidT -user $targetDNT -Alias $aliasT -Database $databaseT -DomainController $domainSpecificDCsSourceAccountT[0]

I've also tried

$outValue = Connect-Mailbox -Identity $guidT -user $targetDNT -Alias $aliasT -Database $databaseT -DomainController $domainSpecificDCsSourceAccountT[0] *>&1

WARNING: The operation completed successfully but the change will not become effective until Active Directory replication occurs.

[edit] For repro, this command appears to fall into the same situation, and is easier to setup/configure

$var = Set-Mailbox $sourceUserT -LitigationHoldEnabled $false

[edit2]

Some commands like set-mailbox will work if you change the type from a string to an array such as but connect-mailbox is not able to use that?

So this was kind of dumb luck, it works for the set-mailbox command but not the connect-mailbox command?

PS> Set-Mailbox "first.last" -LitigationHoldEnabled $false -WarningVariable wv
    WARNING: The command completed successfully but no settings of 'xxx/last, first' have been modified.

PS> $wv

PS>

However when it did it this way

[System.Collections.ArrayList]$wvar = @();
Set-Mailbox "onprem.detailee1" -LitigationHoldEnabled $false -WarningVariable +wvar
WARNING: The command completed successfully but no settings of 'xxxx/last, first' have been modified.

PS> write-host $wvar
The command completed successfully but no settings of 'xxxx/last, first' have been modified.

So Powershell cannot cast some outputs (warning, error, etc) to a string, however they can add the object to an array. Strangely enough the non-typing portion of the Powershell language is not applicable here.

mklement0
  • 382,024
  • 64
  • 607
  • 775
Bbb
  • 517
  • 6
  • 27

4 Answers4

0

You should be able to use the -WarningVariable Common Parameter to capture messages destined for the warning stream.

Connect-Mailbox -Identity $guidT -user $targetDNT -Alias $aliasT -Database $databaseT -DomainController $domainSpecificDCsSourceAccountT[0] -WarningVariable WarningVar

$WarningVar

The common parameters include variable options for messages sent to the error, information, and warning streams.

AdminOfThings
  • 23,946
  • 4
  • 17
  • 27
  • Hi, I agree but that was tried and it does not work for this command? I believe it may be an object typing issue? PS C:\Users\xx\Documents> PS C:\Users\xx\Documents> Connect-Mailbox -Identity $guidT -user $targetDNT -Alias $aliasT -Database $databaseT -DomainController $domainSpecificDCsSourceAccountT[0] -WarningVariable WarningVar WARNING: The operation completed successfully but the change will not become effective until Active Directory replication occurs. PS C:\Users\xx\Documents> $warningvar PS C:\Users\xx\Documents> – Bbb Jan 28 '20 at 15:59
  • Maybe it is doing two writes with the second write being empty string. Then it wipes out the variable if the append `+` is not applied. – AdminOfThings Jan 28 '20 at 16:07
  • Possibly, that would make sense. I can't get either to work with the connect-mailbox command. Do you have any ideas? – Bbb Jan 28 '20 at 16:16
  • The command behavior does seem bizarre. I've had some good results with calling the code within a script block: `$var = & {Connect-Mailbox ...} *>&1` – AdminOfThings Jan 28 '20 at 19:37
  • @AdminOfThings, I think the issue is buggy stream behavior when _implicit remoting_ is involved - see my answer. – mklement0 Apr 10 '20 at 20:12
0

One way I found to do this was to set erroraction explicitly to stop (-ea stop) for the cmdlet in a try catch statement, then I could get the exception value with $_.Exception.Message in the catch statement as it forces the cmdlet to have a terminating error.

This is something I've found to be frustrating coming from c# where a try/catch statement works without having to explicitly define an error as terminating or not. If you do not do that for some cmdlets, the try/catch will not work and it will never catch the terminating error.

Hopefully this helps others, more info

https://www.vexasoft.com/blogs/powershell/7255220-powershell-tutorial-try-catch-finally-and-error-handling-in-powershell

Bbb
  • 517
  • 6
  • 27
  • 1
    FYI: You can get c# like behaviour by setting `$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop` early in your script. Alternatively you can use `if(-not $?){Write-Warning "An error occurred: '$($Error[0].Exception.Message)'"}`. Hope that's of some help. See also: https://stackoverflow.com/questions/6834487/what-is-the-dollar-question-mark-variable-in-shell-scripting and https://stackoverflow.com/a/17461657/361842 – JohnLBevan Feb 12 '20 at 09:33
0

The problem most likely stems from buggy behavior with respect to streams from implicitly remoting commands, such as created via Import-PSSession; this GitHub issue is presumably related.

You have already found one workaround, as demonstrated in your question: if you explicitly create the target variable to pass to -WarningVariable as a System.Collections.ArrayList instance and pass the variable name prefixed with + (-WarningVariable +var) - normally intended for appending to a preexisting variable value - capturing the warning(s) is possible.

A slightly simpler workaround is to call the command via Invoke-Command and apply -WarningVariable to the latter:

Invoke-Command -WarningVariable warnings {
  Connect-Mailbox -Identity $guidT -user $targetDNT -Alias $aliasT -Database $databaseT -DomainController $domainSpecificDCsSourceAccountT[0]
}

# $warnings now contains any warnings emitted by the command.
mklement0
  • 382,024
  • 64
  • 607
  • 775
-1

Did you try the following?

$var = myCommand | out-string
Evan
  • 334
  • 1
  • 6
  • 18