Powershell versions, write-host and colour coding tables!

Hello!

My nice shiny script that took me ages falls apart when I'm running it in Windows 10. I'm assuming because the PC that it is running on have a higher version of powershell.

Here's the original script. Its supposed to make a nice colour coded table of users in Office 365 with the colour depending on the department field, followed by a list of users with no department, followed by a list of users whose name begins with "ZZZ".....

 

# connect to O365 Import-Module MSOnline write-host "Enter the Office 365 Admin username and password" -ForegroundColor Green write-host "`n`n`n`n" Connect-MSOLService #-------------------USERS--------------------------- write-host "---------- Users ----------" -BackgroundColor DarkGreen $Users = get-msoluser | where {$_.displayname -NotLike "ZZZ*" -and ($_.department -eq "Contractor" -or $_.department -eq "AD User" -or $_.department -eq "Syndicated" -or $_.department -eq "System")} | Sort DisplayName #Get the original colsole colour to reset it back later $originalColor = $Host.UI.RawUI.BackgroundColor $Users | Format-Table -Property displayname, @{label = "Department" ; Expression = { if ($_.department -eq "Contractor") { $Host.ui.rawui.BackgroundColor = "DarkGreen" ; $_.department } if ($_.department -eq "AD User") { $Host.ui.rawui.BackgroundColor = "DarkGray" ; $_.department } if ($_.department -eq "Syndicated") { $Host.ui.rawui.BackgroundColor = "Red" ; $_.department } if ($_.department -eq "System") { $Host.ui.rawui.BackgroundColor = "Magenta" ; $_.department } } #end expression } #end hash #set the console colour back to the original $Host.UI.RawUI.BackgroundColor = $originalColor #-------------------ANOMALIES--------------------------- #List active users with no department set. $Anomalies = get-msoluser | where {$_.displayname -NotLike "ZZZ*" -and $_.department -ne "Contractor" -and $_.department -ne "AD User" -and $_.department -ne "Syndicated" -and $_.department -ne "System"} | select DisplayName, Department, UserPrincipalName, isLicensed | Sort DisplayName $anomaliesM = $Anomalies | measure $anomaliesM.count write-host "`n`n`n`n----------" $anomaliesM.count " Anomalies ----------" -BackgroundColor Cyan write-host "Active Users with no department set in Office 365`n" $Anomalies #-------------------LEAVERS--------------------------- write-host "`n`n`n`n---------- Leavers ----------" -BackgroundColor Red write-host "Office 365 users that have been set to 'ZZZ - ...'`n" get-msoluser | where {$_.displayname -Like "ZZZ*"} | select DisplayName, Department, UserPrincipalName, isLicensed | Sort DisplayName pause

 

...when I run this on on a Windows 10 PC then it seems to break at each "write-host" with all of the write-host printing first then the rest of the outputs coming after! I can correct this by using write-output instead but this looses my nice formatting.

It also loses all of the colour coding in the table!

The computer it works on returns $psversiontable.psversion as:

Major: 4

Minor: 0

Build: -1

Revision: -1

The computer it doesn't work on:

Major: 5

Minor: 1

Build: 14393

Revision: 1715

..................................does anyone have a clue why it breaks so badly between versions?

Also how do I post code so that it doesn't look a hideous mess?

 

Many thanks for any pointers.

Tom

 

  • OK... so I've massively simplified the script and I still get the write-host issue...

    write-host "---------- Before ----------"
    get-msoluser
    write-host "---------- After ----------"

    I would expect to write "Before", list all users, write "After".

    Instead I get "Before", "After" and then list all users (See the screenshot below).

     

    Any help would be appreciated.

  • In reply to Fearpig:

    Have you tried to use Write-Output instead of Write-Host?
  • In reply to vandreytrindade:

    Yep.... write-output gets things in the correct order but messes up the formatting.
    Its supposed to be a very visual output for 1st line guys to refer to.
  • In reply to Fearpig:

    I have found one thing......

    Write-host is working fine, its everything else that's broken!! The commands are not defaulting to output to Host and are defaulting to some other pipeline! Where-ever they are going they only output AFTER the script has completed.

    This fixes the problem....


    write-host "---------- Before ----------"

    get-msoluser | out-host

    write-host "---------- After ----------"

     

    ....but I thought commands should default to to host unless otherwise specified.

    So now my questions have morphed into...

    • How do I tell what the default action for commands is (i.e. output to host)?
    • How do I change what the default is?
  • As for your code. Copy from the ISE into notepad and make sure of its look before posting.

    Adjust in notepad as needed.

    Or

    This forum does provide a RichText Editor link for you to post you code.

    As for your concern.

     

    You are mixing and matching approaches to output colorized results.

    I'd suggest, pick one or the other and remain consistent.

    There are a few things you can do here to clean up the code.

    I have run every version of PoSH since it's monad days, and never encountered

    or heard anyone else encounter what you are describing. Yet, I've not seen a

    this was as well.

    BTW, unless you are using color, other formatting tricks, you don't even need

    to execute Write-*

    This...

    write-host "`n`n`n`n---------- Leavers ----------

    and this ..

    "`n`n`n`n---------- Leavers ----------

    Output the same the thing, the same way.

    You can even to this, for the whole I need X number of space between lines.

    "`n"*4

    Or lets say you need a divider line between records... then...

    "-"*10

    So, except for the color lines, you can drop Write-Host from any other line.

    Well, you can even drop those by using your $Host.UI.RawUI approach.

    So, not that you really need this, but you could try... to see if things render better.
    Yet, the renser shoudl be the same accross versions, but we've all seen our share of
    wierd things with products. Though I provide teh formatting mangle-ment below, it
    might be better to think about doing this as a HTML report vs a screen only thing.



    # Connect to O365

    function Set-TextColor
    {
    [CmdletBinding()]

    param (
    [ValidateNotNullOrEmpty()]
    [System.ConsoleColor[]]$Background = [System.Enum]::GetValues([System.ConsoleColor]),
    [ValidateNotNullOrEmpty()]
    [System.ConsoleColor[]]$Foreground = [System.Enum]::GetValues([System.ConsoleColor])
    )

    $Host.UI.RawUI.BackgroundColor = $Background
    $Host.UI.RawUI.ForegroundColor = $Foreground
    }

    Import-Module MSOnline

    Set-TextColor -Background Yellow -Foreground Green;"Enter the Office 365 Admin username and password"
    "`n"*4

    Connect-MSOLService

    #-------------------USERS---------------------------

    Set-TextColor -Background Yellow -Foreground DarkGreen;"-"*10 + 'Users' + "-"*10

    $Users = get-msoluser | where {$_.displayname `
    -NotLike "ZZZ*" -and ($_.department `
    -eq "Contractor" -or $_.department `
    -eq "AD User" -or $_.department `
    -eq "Syndicated" -or $_.department `
    -eq "System")} | Sort DisplayName

    # Get the original colsole colour to reset it back later
    $originalColor = $Host.UI.RawUI.BackgroundColor

    $Users | Format-Table -Property displayname,
    @{label = "Department" ;
    Expression = { if ($_.department -eq "Contractor")
    { Set-TextColor -Background DarkGreen -Foreground White;
    $_.department }

    if ($_.department -eq "AD User")
    { Set-TextColor -Background Blue -Foreground White;
    $_.department }

    if ($_.department -eq "Syndicated")
    { Set-TextColor -Background Red -Foreground White;
    $_.department }

    if ($_.department -eq "System")
    { Set-TextColor -Background Magenta -Foreground White;
    $_.department } }
    #end expression
    }

    #end hash #set the console colour back to the original
    # $Host.UI.RawUI.BackgroundColor = $originalColor
    $psISE.Options.RestoreDefaults()

    #-------------------ANOMALIES---------------------------

    #List active users with no department set.
    $Anomalies = get-msoluser `
    | where {$_.displayname `
    -NotLike "ZZZ*" -and $_.department `
    -ne "Contractor" -and $_.department `
    -ne "AD User" -and $_.department `
    -ne "Syndicated" -and $_.department `
    -ne "System"} `
    | select DisplayName, Department, UserPrincipalName, isLicensed `
    | Sort DisplayName

    $anomaliesM = $Anomalies `
    | measure $anomaliesM.count

    Set-TextColor -Background Cyan -Foreground White; "`n"*4 + "-"*10 + $anomaliesM.count + 'Anomalies ' + "-"*10

    "Active Users with no department set in Office 365`n" + $Anomalies

    #-------------------LEAVERS---------------------------

    Set-TextColor -Background Red -Foreground White;"`n"*4 + "-"*10 + ' Leavers ' + "-"*10

    "Office 365 users that have been set to 'ZZZ - ...'`n"
    get-msoluser `
    | where {$_.displayname -Like "ZZZ*"} `
    | select DisplayName, Department, UserPrincipalName, isLicensed `
    | Sort DisplayName pause