1

I am trying to display StrongAuthenticationMethods from the azure object (user) in a more readable way inside of the script which will reset the MFA method.

When I call variable $mfa

$UserPname = Read-Host "Please enter e-mail address"
$AzureUser=Get-MsolUser -UserPrincipalName "$UserPname"

$methode = $AzureUser.StrongAuthenticationMethods
$mfa = $methode | Select-Object MethodType, IsDefault
$mfa

it gives me a nice table:

----------           ---------
PhoneAppOTP              False
PhoneAppNotification      True

When I try to write-host this variable:

Write-Host $mfa

It gives me:

Write-Host $mfa
@{MethodType=PhoneAppOTP; IsDefault=False} @{MethodType=PhoneAppNotification; IsDefault=
True}

How can I display this MethodType and IsDefault properties in the best readable way using write-host?

Thanks for the information in advance!

Stan Di
  • 83
  • 1
  • 2
  • 7
  • The question is why you need `Write-Host` to begin with ? Your object is being stringified which is why you see that way. There is no need for `Write-Host` at all. – Santiago Squarzon Jul 14 '22 at 14:18
  • Without the write-host variable $mfa, I don't see the table at all. The script jumps to the "switch structure", exactly to the last part of the script: Write-Host "Would you like to reset MFA for the user $UserPname" if (($methode)) { $Readhost = Read-Host " ( y / n ) " Switch ($ReadHost) { Y {Set-MsolUser -UserPrincipalName “$UserPname”-StrongAuthenticationMethods $p} N {Write-Host "No actions"} Default {Write-Host "No actions"} }} – Stan Di Jul 14 '22 at 14:32
  • In the top level script, outputting a variable will cause it to automatically be sent to a formatting cmdlet like ```Format-Table``` or ```Format-List``` and displayed in the console. Inside a function, doing the same thing will send the value to the output stream of the function as if you'd used ```write-output```. If you want to display the text *on the console* from inside a function you can do something like ```write-host ($mfa | format-table | out-string)``` *but* that should only be used for display / logging purposes and not for downstream data processing. – mclayton Jul 14 '22 at 14:32

2 Answers2

1

Write-Host ($mfa | Format-Table | Out-String)

Mason
  • 523
  • 1
  • 4
  • 10
0

To print synchronous, richly formatted output to the host (display), use the Out-Host cmdlet rather than Write-Host: Out-Host uses PowerShell's rich formatting system, whereas Write-Host essentially performs .ToString() stringification, which often results in unhelpful output.

# Forces instant output to the display, 
# but note that such output *cannot be captured*.
# Use ... | Format-Table | Out-Host to force tabular formatting,
# but with a custom object with 4 or fewer properties that isn't necessary.
$mfa | Out-Host

Judging by your later comments, the reason you want this is the well-known problem of the situational lack of synchronization between pipeline output and to-host output (as well as output to other streams), which can cause displayed output to print out of order.

# !! Read-Host executes FIRST
[pscustomobject] @{ print='me' }
Read-Host 'Press ENTER to continue'
# Workaround: Out-Host forces instant printing to the display,
#             but note that such output then cannot be captured. 
[pscustomobject] @{ print='me' } | Out-Host
Read-Host 'Press ENTER to continue'

The problem is limited to a very specific - albeit common - scenario: implicitly table-formatted output for types that do not have formatting data defined for them.

mklement0
  • 382,024
  • 64
  • 607
  • 775