You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何格式化PowerShell输出实现等间距,查询指定DC服务账号锁定状态

问题描述

需要查询指定域控制器上服务账号的锁定状态,不想使用微软ALTools工具(操作繁琐且运行缓慢,无需查询300余台DC)。当前脚本输出的「DC Site」「Is Locked Out」「LastBadPasswordAttempt」列未对齐,希望实现规整的对齐输出效果。

原使用脚本

$AD_DC_Servers = Get-ADDomainController -Filter {name -like "15CHAR*"} | 
    where { ($_.name -like "*SITE1*" -or 
             $_.name -like "*TWO*" -or 
             $_.name -like "*LONGEST*" ) -and ( 
             $_.site -notlike "*STAGING*" ) } | 
                Sort-Object Name

$UserProperties = @("AccountLockoutTime", 
                    "DisplayName", 
                    "Enabled", 
                    "isDeleted", 
                    "LastBadPasswordAttempt", 
                    "LockedOut", 
                    "lockoutTime", 
                    "UserPrincipalName")

$AD_User = Read-Host -Prompt "Enter Username"

foreach($DC in $AD_DC_Servers){
    $AD_User_Info = Get-ADUser -Server $dc -Identity $AD_User -Properties $UserProperties | select DisplayName, LockedOut, UserPrincipalName, LastBadPasswordAttempt
    $DC_Site      = $DC.Site
    $UserName     = $AD_User_Info.DisplayName
    $LockedOut    = $AD_User_Info.LockedOut
    #IF statement to determine output of the "LastBadPasswordAttempt" variable
        if($null -eq $AD_User_Info.LastBadPasswordAttempt){
            $LastBadPasswordAttempt = "N/A"
        }else{
            $LastBadPasswordAttempt = $AD_User_Info.LastBadPasswordAttempt
        }
    $output = "[ DC Checked: $DC ] [ DC Site: $DC_Site ] [ UserName: $UserName ] [ Is Locked Out: $LockedOut ] [ LastBadPasswordAttempt: $LastBadPasswordAttempt ]"
    Write-Host $output -ForegroundColor Cyan -BackgroundColor Black
}

当前输出

[ DC Checked: 15CHARSVRNAME01 ] [ DC Site: SITE1 ] [ UserName: SVC-ACCT-NAME ] [ Is Locked Out: False ] [ LastBadPasswordAttempt: 01/01/1970 00:00:00 ]
[ DC Checked: 15CHARSVRNAME03 ] [ DC Site: SITE_NUMBER_TWO ] [ UserName: SVC-ACCT-NAME ] [ Is Locked Out: False ] [ LastBadPasswordAttempt: N/A ]
[ DC Checked: 15CHARSVRNAME05 ] [ DC Site: SITE_WITH_LONGEST_NAME ] [ UserName: SVC-ACCT-NAME ] [ Is Locked Out: False ] [ LastBadPasswordAttempt: 01/01/1970 00:00:00 ]

理想输出

[ DC Checked: 15CHARSVRNAME01 ] [ DC Site: SITE1                  ] [ UserName: SVC-ACCT-NAME ] [ Is Locked Out: False ] [ LastBadPasswordAttempt: 01/01/1970 00:00:00 ]
[ DC Checked: 15CHARSVRNAME03 ] [ DC Site: SITE_NUMBER_TWO        ] [ UserName: SVC-ACCT-NAME ] [ Is Locked Out: True  ] [ LastBadPasswordAttempt: N/A                 ]
[ DC Checked: 15CHARSVRNAME05 ] [ DC Site: SITE_WITH_LONGEST_NAME ] [ UserName: SVC-ACCT-NAME ] [ Is Locked Out: False ] [ LastBadPasswordAttempt: 01/01/1970 00:00:00 ]

解决方案

要实现列对齐,核心是先收集所有数据并计算每列的最大宽度,再通过格式化字符串填充空格。修改后的脚本如下:

$AD_DC_Servers = Get-ADDomainController -Filter {name -like "15CHAR*"} | 
    where { ($_.name -like "*SITE1*" -or 
             $_.name -like "*TWO*" -or 
             $_.name -like "*LONGEST*" ) -and ( 
             $_.site -notlike "*STAGING*" ) } | 
                Sort-Object Name

$UserProperties = @("AccountLockoutTime", 
                    "DisplayName", 
                    "Enabled", 
                    "isDeleted", 
                    "LastBadPasswordAttempt", 
                    "LockedOut", 
                    "lockoutTime", 
                    "UserPrincipalName")

$AD_User = Read-Host -Prompt "Enter Username"

# 先收集所有查询结果,用于计算字段最大宽度
$results = foreach($DC in $AD_DC_Servers){
    $AD_User_Info = Get-ADUser -Server $dc -Identity $AD_User -Properties $UserProperties | select DisplayName, LockedOut, UserPrincipalName, LastBadPasswordAttempt
    $lastBadAttempt = if($null -eq $AD_User_Info.LastBadPasswordAttempt) { "N/A" } else { $AD_User_Info.LastBadPasswordAttempt.ToString() }
    
    [PSCustomObject]@{
        DCChecked = $DC.Name
        DCSite = $DC.Site
        UserName = $AD_User_Info.DisplayName
        IsLockedOut = $AD_User_Info.LockedOut.ToString()
        LastBadPasswordAttempt = $lastAttemptFormatted
    }
}

# 计算需要对齐的列的最大宽度
$maxDCSiteWidth = ($results.DCSite | Measure-Object -Property Length -Maximum).Maximum
$maxIsLockedWidth = ($results.IsLockedOut | Measure-Object -Property Length -Maximum).Maximum
$maxLastAttemptWidth = ($results.LastBadPasswordAttempt | Measure-Object -Property Length -Maximum).Maximum

# 按对齐格式输出结果
foreach($result in $results){
    $dcSiteFormatted = $result.DCSite.PadRight($maxDCSiteWidth)
    $isLockedFormatted = $result.IsLockedOut.PadRight($maxIsLockedWidth)
    $lastAttemptFormatted = $result.LastBadPasswordAttempt.PadRight($maxLastAttemptWidth)
    
    $output = "[ DC Checked: $($result.DCChecked) ] [ DC Site: $dcSiteFormatted ] [ UserName: $($result.UserName) ] [ Is Locked Out: $isLockedFormatted ] [ LastBadPasswordAttempt: $lastAttemptFormatted ]"
    Write-Host $output -ForegroundColor Cyan -BackgroundColor Black
}

关键说明

  1. 先将所有查询结果存入对象数组$results,方便提前统计各字段的最长长度
  2. 使用Measure-Object获取「DC Site」「Is Locked Out」「LastBadPasswordAttempt」三个字段的最大宽度
  3. 通过PadRight()方法将每个字段填充至对应最大宽度,实现列对齐
  4. 最终按格式化后的字符串输出,确保每列内容对齐规整

内容的提问来源于stack exchange,提问作者FlyingSubieSTi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 23:39:58