Powershell 如何在电子邮件正文或控制台屏幕中以表格形式显示变量结果?

Powershell 如何在电子邮件正文或控制台屏幕中以表格形式显示变量结果?,powershell,Powershell,下面用于获取登录用户并以电子邮件形式发送的脚本非常有效,但仅限于控制台输出 我试图以表格的形式获取结果,因此控制台和电子邮件正文中的结果如下: Server, ConnectionType, User, ID, State PRDSVR16, rdp-tcp#44, SVC-SQL, 4, Active PRDSVR10, rdp-tcp#27, Admin.domain, 6, Disc SVR25-VM,console,domain.admin,8,Active 在新窗口中打开 以下是脚本

下面用于获取登录用户并以电子邮件形式发送的脚本非常有效,但仅限于控制台输出

我试图以表格的形式获取结果,因此控制台和电子邮件正文中的结果如下:

Server, ConnectionType, User, ID, State
PRDSVR16, rdp-tcp#44, SVC-SQL, 4, Active
PRDSVR10, rdp-tcp#27, Admin.domain, 6, Disc
SVR25-VM,console,domain.admin,8,Active
在新窗口中打开

以下是脚本:

$Today = Get-Date -Format 'F'
$SessionList = "`n`nRDP Session List - " + $Today + "`n`n"
$CurrentSN = 0

# Get a list of servers from Active Directory
write-progress -activity "Getting list of servers from Active Directory" -status "... please wait ..."

$Servers = (Get-ADComputer -Filter { Enabled -eq $True -and OperatingSystem -like "*Server*" } -Properties OperatingSystem -SearchBase "OU=Data Center,DC=Company,DC=com") |
                Where-Object { Test-Connection $_.Name -Count 1 -Quiet } |
                Select-Object -ExpandProperty Name

$NumberOfServers = $Servers.Count

# Iterate through the retrieved list to check RDP sessions on each machine
ForEach ($Server in $Servers)
{
    Write-Host "Processing $Server ..." -ForegroundColor Yellow
    Write-progress -activity "Checking RDP Sessions" -status "Querying $Server" -percentcomplete (($CurrentSN / $NumberOfServers) * 100)
    
    try
    {
        $SessionList += qwinsta /server:$Server |
        Select-Object -Skip 1 |
        % {
            [PSCustomObject] @{
                Type = $_.Substring(1, 18).Trim()
                User = $_.Substring(19, 20).Trim()
                ID   = $_.Substring(41, 5).Trim()
                State = $_.Substring(48, 6).Trim()
            }
        } |
        ? { $_.Type -notin 'console', 'services', 'rdp-tcp' -and $_.User -ne $null -and $_.User -ne 65536 } |
        % {
            "`n$Server logged in by $($_.User) on $($_.Type), session id $($_.ID) $($_.state)"
        }
    }
    catch
    {
        $SessionList += "`n Unable to query " + $Server
        write-host "Unable to query $Server! `n $($Error[0].Exception)" -foregroundcolor Red
    }
    
    $CurrentSN++
}

# Send the output the screen.
$SessionList + "`n`n"

$sendMailArgs = @{
    From = "$env:USERNAME@$env:userdnsdomain"
    To   = 'SOC@domain.com'
    SmtpServer = 'SMTP.domain.com'
    Priority = 'High'
    Body = $SessionList | Select-Object @{ N = 'Server'; E = { $Server } },
                                        @{ N = 'User'; E = { $_.User } },
                                        @{ N = 'LogonType'; E = { $_.Type } },
                                        @{ N = 'ID'; E = { $_.ID } },
                                        @{ N = 'State'; E = { $_.State } }
    Subject = "$($SessionList.Count) Logged On users from $($NumberOfServers) online servers as at $($Today)"
}

Send-MailMessage @sendMailArgs

如果在数据和所述数据的表示(或格式)之间保持严格的分离,则在不同位置呈现收集的信息会更容易

例如,对于
$SessionList
,这意味着在循环中执行的操作要少于当前尝试执行的操作:

$ErrorList = @()
$SessionList = foreach($server in $servers){
    try{
        qwinsta /server:$Server |Select-Object -Skip 1 |ForEach-Object {
            [PSCustomObject] @{
                Server = $server
                Type   = $_.Substring(1, 18).Trim()
                User   = $_.Substring(19, 20).Trim()
                ID     = $_.Substring(41, 5).Trim()
                State  = $_.Substring(48, 6).Trim()
            }
        } |Where-Object { $_.Type -notin 'console', 'services', 'rdp-tcp' -and $_.User -ne $null -and $_.User -ne 65536 } 
    }
    catch{
        $ErrorList += [pscustomobject]@{
            Server = $server
            ErrorRecord = $_
        }
    }
}
请注意我是如何不构造任何字符串的——我只是创建自定义对象,过滤它们——然后让它们保持原样

现在,根据需要为不同的输出介质格式化数据变得更加容易:

# For console output, simply pipe to Format-Table
$SessionList |Format-Table
if($ErrorList.Count -gt 0){
    Write-Warning "The following servers had errors, please inspect"
    $ErrorList |Format-Table
}

# For email output we can use `ConvertTo-Html`
$Body = $SessionList |ConvertTo-Html -As Table -Fragment
if($ErrorList.Count -gt 0){
  $ErrorTable = $ErrorList |ConvertTo-Html -As Table -Fragment
  $Body = $Body,$ErrorTable -join '<br />'
}

$sendMailArgs = @{
    # ...
    Body = ConvertTo-Html -Body $Body -Title "Session list"
    BodyAsHtml = $true
    # ...
}
#对于控制台输出,只需通过管道格式化表格即可
$SessionList |格式表
如果($ErrorList.Count-gt 0){
写入警告“以下服务器有错误,请检查”
$ErrorList |格式表
}
#对于电子邮件输出,我们可以使用“转换为Html”`
$Body=$SessionList |转换为Html-As-Table-Fragment
如果($ErrorList.Count-gt 0){
$ErrorTable=$ErrorList |转换为Html-作为表格-片段
$Body=$Body,$ErrorTable-连接'
' } $sendMailArgs=@{ # ... Body=converttohtml-Body$Body-Title“会话列表” BodyAsHtml=$true # ... }
Hi@mathias,非常感谢您帮助显示[PSCustomObject]@{},现在它工作得很好。我感谢你在这件事上的帮助。