Powershell -显示相邻两个表的内容

pes8fvy9  于 2023-02-23  发布在  Shell
关注(0)|答案(3)|浏览(150)

我正在尝试为处理用户更改的管理员显示信息,以便轻松查看对Active Directory用户中的某些字段所做的更改。我已编写PowerShell脚本来处理这些更改,但在为运行该脚本的管理员设置输出格式时遇到问题。有关类似但不同的问题,请参阅this post
我的代码:

$output = [pscustomobject]@{'UserName' = $user.samAccountName; 'FirstName' = $user.GivenName;'LastName' = $user.Surname;'DisplayName' = $user.DisplayName;'UPN' = $user.UserPrincipalName;'E-Mail_Address' = $user.proxyAddresses;'Title' = $user.Title;'Office' = $user.PhysicalDeliveryOfficeName;'Dept' = $user.Department;}
$output[$index++] | Add-Member -NotePropertyMembers @{'NewUserName' = $samAccountName; 'NewFirstName' = $firstName;'NewLastName' = $lastname;'NewDisplayName' = $displayName;'NewUPN' = $UPN;'NewE-Mail_Address' = $SMTP1;'NewTitle' = $Title;'Newoffice' = $office;'NewDept' = $department;}
$output

输出:

UserName          : FirstLast
FirstName         : First
LastName          : Last
DisplayName       : First Last
UPN               : FirstLast@company.com
E-Mail_Address    : SMTP:FirstLast@company.com
Title             : CEO
Office            : HQ
Dept              : Executives
NewDept           : Maintenance
NewE-Mail_Address : SMTP:FirstLast@company.com
NewOffice         : The Dump
NewFirstName      : First
NewLastName       : Last
NewUserName       : FirstLast
NewDisplayName    : First Last
NewUPN            : FirstLast@company.com
NewTitle          : Trash Collector

预期输出:

UserName          : FirstLast                     NewUserName       : FirstLast
FirstName         : First                         NewFirstName      : First
LastName          : Last                          NewLastName       : Last
DisplayName       : First Last                    NewDisplayName    : First Last
UPN               : FirstLast@company.com         NewUPN            : FirstLast@company.com
E-Mail_Address    : SMTP:FirstLast@company.com    NewE-Mail_Address : SMTP:FirstLast@company.com
Title             : CEO                           NewTitle          : Trash Collector
Office            : HQ                            Newoffice         : The Dump
Dept              : Executives                    NewDept           : Maintenance
ndasle7k

ndasle7k1#

下面将创建两个相邻的格式列表输出。
因为这很可能不适合控制台屏幕的宽度,所以首先捕获输出,然后使用Out-String输出,其中-Width参数的数值较大。
像这样,你也可以保存到文本文件.

$outputOld = [pscustomobject]@{
                'UserName' = $user.samAccountName; 'FirstName' = $user.GivenName;
                'LastName' = $user.Surname;'DisplayName' = $user.DisplayName;
                'UPN' = $user.UserPrincipalName;'E-Mail_Address' = $user.proxyAddresses;
                'Title' = $user.Title;'Office' = $user.PhysicalDeliveryOfficeName;
                'Dept' = $user.Department}
$outputNew = [pscustomobject]@{
                'NewUserName' = $samAccountName; 'NewFirstName' = $firstName;
                'NewLastName' = $lastname;'NewDisplayName' = $displayName;'NewUPN' = $UPN;
                'NewE-Mail_Address' = $SMTP1;'NewTitle' = $Title;'Newoffice' = $office;
                'NewDept' = $department}

# capture the Format-List output of each object and split into a string array
$outLeft  = @(($outputOld | Format-List | Out-String) -split '\r?\n')
$outRight = @(($outputNew | Format-List | Out-String) -split '\r?\n')

# determine the maximum length of each string in the list that goes to the left
$maxLength = ($outLeft | Measure-Object -Property Length -Maximum).Maximum
# get the maximum number of lines
$maxLines  = [math]::Max($outLeft.Count, $outRight.Count)

# collect the combined output
$result = for ($i = 0; $i -lt $maxLines; $i++) {
    $left  = if ($i -lt $outLeft.Count) { "{0,-$maxLength}" -f $outLeft[$i] } else { ' ' * $maxLength }
    $right = if ($i -lt $outRight.Count) { $outRight[$i] } else {''}
    ('{0}    {1}' -f $left, $right).TrimEnd()
}

# display on screen
$result | Out-String -Width 1000

# save to text file
$result | Out-String -Width 1000 | Set-Content -Path 'D:\Test\output.txt'
x7rlezfr

x7rlezfr2#

这不会产生与您所追求的“完全”相同的逐字符输出,但它“确实”产生了“类似”的东西,使用内置的格式化方法,而无需对值进行大量字符串化。
首先,设置一些测试数据,这需要对示例代码做一些小的修改,以生成两个对象,而不是组合的$output变量:

$oldValues = [pscustomobject] [ordered] @{
    "UserName"          = "FirstLast"
    "FirstName"         = "First"
    "LastName"          = "Last"
    "DisplayName"       = "First Last"
    "UPN"               = "FirstLast@company.com"
    "E-Mail_Address"    = "SMTP:FirstLast@company.com"
    "Title"             = "CEO"
    "Office"            = "HQ"
    "Dept"              = "Executives"
};

$newValues = [pscustomobject] [ordered] @{
    "NewDept"           = "Maintenance"
    "NewE-Mail_Address" = "SMTP:FirstLast@company.com"
    "NewOffice"         = "The Dump"
    "NewFirstName"      = "First"
    "NewLastName"       = "Last"
    "NewUserName"       = "FirstLast"
    "NewDisplayName"    = "First Last"
    "NewUPN"            = "FirstLast@company.com"
    "NewTitle"          = "Trash Collector"
};

接下来,我们将变量Map到PropertyName, OldValue, NewValue对象数组中:

$rows = $oldValues.psobject.properties `
    | foreach-object {
        $property = $_;
        [pscustomobject] [ordered] @{
            "PropertyName" = $property.Name
            "OldValue"     = $property.Value
            "NewValue"     = $newValues.("New" + $property.Name) 
        }
    };

然后,我们可以使用内置的cmdlet对其进行格式化:

$rows | format-table

# PropertyName   OldValue                   NewValue
# ------------   --------                   --------
# UserName       FirstLast                  FirstLast
# FirstName      First                      First
# LastName       Last                       Last
# DisplayName    First Last                 First Last
# UPN            FirstLast@company.com      FirstLast@company.com
# E-Mail_Address SMTP:FirstLast@company.com SMTP:FirstLast@company.com
# Title          CEO                        Trash Collector
# Office         HQ                         The Dump
# Dept           Executives                 Maintenance

好处是您可以使用Format-Table参数调整列宽、自动换行等,甚至可以使用Format-List

$rows | format-list

# ... etc ...
#
# PropertyName : Title
# OldValue     : CEO
# NewValue     : Trash Collector
#
# PropertyName : Office
# OldValue     : HQ
# NewValue     : The Dump
#
# ... etc ...

您可以过滤它以仅显示 * 更改 * 的值:

$rows | where-object { $_.NewValue -ne $_.OldValue } | format-table

# PropertyName OldValue   NewValue
# ------------ --------   --------
# Title        CEO        Trash Collector
# Office       HQ         The Dump
# Dept         Executives Maintenance

它依赖于格式为“Xyz-〉NewXyz“的属性名称,但是如果不是在所有情况下都是这样,也有一些方法可以解决这个问题...

b4lqfgs4

b4lqfgs43#

你可以使用ANSIESCAPE代码来应用修饰。2这个例子是基于pscustomobject的,它包含所有的值,但是你可以创建两个pscustomobject来使代码更清晰。
注:
在Ps6中将ESC更改为$([char] 27)或'e(谢谢mclayton先生)
我更喜欢使用添加成员项目每个项目。
已使用PowerShell 5.1($PSVersionTable命令)进行测试。

$output = [pscustomobject]@{'UserName' = 'User1'; 'FirstName' = '$user.GivenName';'LastName' = '$user.Surname';'DisplayName' = '$user.DisplayName';'UPN' = '$user.UserPrincipalName';'E-Mail_Address' = '$user.proxyAddresses';'Title' = '$user.Title';'Office' = '$user.PhysicalDeliveryOfficeName';'Dept' = '$user.Department';}
$output | Add-Member -NotePropertyMembers @{'NewUserName' = 'User2'}
$output | Add-Member -NotePropertyMembers @{'NewFirstName' = '$firstName'}
$output | Add-Member -NotePropertyMembers @{'NewLastName' = '$lastname'}
$output | Add-Member -NotePropertyMembers @{'NewDisplayName' = '$displayName'}
$output | Add-Member -NotePropertyMembers @{'NewUPN' = '$UPN'}
$output | Add-Member -NotePropertyMembers @{'NewE-Mail_Address' = '$SMTP1'}
$output | Add-Member -NotePropertyMembers @{'NewTitle' = '$Title'}
$output | Add-Member -NotePropertyMembers @{'Newoffice' = '$office'}
$output | Add-Member -NotePropertyMembers @{'NewDept' = '$department'}
    
# Counter for column 1 and column 2
$Counter =0
$Counter1 =0

# Temporally variables
$Text 
$Label

# Do the magic
foreach( $property in $output.psobject.properties.name )
{
    
if ( $Counter -lt 9 )
{
    $Counter = $Counter +1
    $Text = $output.$property
    $Label = $property
    echo "ESC[$Counter;1H $Label : $Text "
    
} else
{
    $Counter1 = $Counter1 +1
    $Text = $output.$property
    $Label = $property
    echo "ESC[$Counter1;60H $Label :  $Text "
    } 
    
}

#Move to end
echo "ESC[20;1H  "

结果

其他ANSI命令

快乐编码我的朋友。

相关问题