使用Format-Table中的PowerShell表达式可以获得多大的表现力?

时间:2012-06-07 15:57:48

标签: powershell

我有以下脚本输出用户的Exchange邮箱的颜色编码文件夹层次结构。如果它超过某个阈值(在这种情况下为20 MB),则输出红色线,如果不是,则输出灰色。

#Get Folder Size Breakdown to Table with Color Coding
get-mailbox $username |
Get-MailboxFolderStatistics |
ft @{
        Name="Name"
        Expression=
        {
            $prefix=""
            foreach($c in $_.FolderPath.ToCharArray())
            {
                if($c -eq '/'){$prefix+='-'}
            }
            if($_.FolderSize -gt 20MB)
            {
                $Host.UI.RawUI.ForegroundColor = "Red"
            } else
            { 
                $Host.UI.RawUI.ForegroundColor = "Gray"
            }
            $prefix + $_.Name
        }
    },
    FolderSize,
    FolderandSubfolderSize

此脚本存在一些问题。

如果处理的最后一个文件夹大于20 MB,则我的控制台文本在运行后仍为红色。 此脚本假定原始控制台文本为灰色。如果它不是格雷,那么我已经改变了用户的控制台文本。 如果你不在format-table表达式的上下文中,这两个都很容易解决,但我不能在我的生活中弄清楚是否有可能在这种特殊情况下解决这些问题。这是我尝试过的要点,但它不起作用。 (实际上我尝试了大约20种不同的变体)。

get-mailbox $username |
Get-MailboxFolderStatistics |
ft @{
        Name="Name"
        Expression=
        {
            $prefix=""
            $originalColor = $Host.UI.RawUI.ForegroundColor
            foreach($c in $_.FolderPath.ToCharArray())
            {
                if($c -eq '/'){$prefix+='-'}
            }
            if($_.FolderSize -gt 20MB)
            {
                $Host.UI.RawUI.ForegroundColor = "Red"
            }
            $prefix + $_.Name
            $Host.UI.RawUI.ForegroundColor = $originalColor
        }
    },
    FolderSize,
    FolderandSubfolderSize

注意:这样做的目的是最终将其压缩为单线。我知道我可以在启动管道之前存储变量,并在管道完成后恢复颜色,但这会带来乐趣/加重。我更好奇是否能在不改变管道基本结构的情况下实现这一目标。

1 个答案:

答案 0 :(得分:1)

我不认为这是可能的。基本上,每次Format-Table读取Name的表达式时,前景色都会改变。但是Format-Table可能不会立即从该表达式中写出值,因此您无法重置表达式中的颜色。

我认为你将不得不包装你的管道:

$originalColor = $Host.UI.RawUI.ForegroundColor

get-mailbox $username |
Get-MailboxFolderStatistics |
ft @{
        Name="Name"
        Expression=
        {
            $prefix = " " * (($_.FolderPath -split '/').Length)
            $Host.UI.RawUI.ForegroundColor = if($_.FolderSize -gt 20MB) { "Red" } else { $originalColor }
            $prefix + $_.Name
        }
    },
    FolderSize,
    FolderandSubfolderSize

$Host.UI.RawUI.ForegroundColor = $originalColor

另一种选择是编写自己的格式代码,找到每列的最大大小,然后使用Write-Host写出来:

$stats = get-mailbox $username |
    Get-MailboxFolderStatistics |

$nameMaxWidth = 0
$sizeMaxWidth = 0
$subFolderSizeMaxWidth = 0
$stats | ForEach-Object {

    if( $_.Name.Length -gt $nameMaxWidth )
    {
        $nameMaxWidth = $_.Name.Length + (($_.FolderPath -split '/').Length - 1)
    }

    $sizeWidth = $_.FolderSize.ToString().Length
    if( $sizeWidth -gt $sizeMaxWidth )
    {
        $sizeMaxWidth = $sizeWidth
    }

    $subSizeWidth = $_.FolderAndSubFolderSize.ToString().Length
    if( $subSizeWidth -gt $subFolderSizeMaxWidth )
    {
        $subFolderSizeMaxWidth = $subSizeWidth
    }
}

$stats | ForEach-Object {
    $colorParam = @{ }
    if( $_.FolderSize -gt 20MB )
    {
        $colorParam.ForegroundColor = 'Red'
    }

    $prefix = ' ' * (($_.FolderPath -split '/').Length - 1)
    Write-Host ("{0}{1,$nameMaxWidth}" -f $prefix,$_.Name) -NoNewLine @colorParam
    Write-Host "  " -NoNewline
    Write-Host ("{0,-$sizeMaxWidth}" -f $_.FolderSize) -NoNewLine
    Write-Host "  " -NoNewLine
    Write-Host ("{0,-$subFolderSizeMaxWidth}" -f $_.FolderAndSubFolderSize)
}