首页 > 解决方案 > Powershell 计算属性 - 调用 HashTable 枚举器?

问题描述

我无法显示从哈希表转换而来的名为登录类型的计算属性列。

下面的脚本工作正常,但我只需要将原始值数字转换为更有意义的描述。

function Get-LogonEvents {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('ServerName', 'Server', 'Name')]
        [string[]]$ComputerName,

        [Parameter(ValueFromPipelineByPropertyName = $true, Mandatory = $true)]
        [PSCredential]$Credential,

        [Parameter()]
        [ValidateSet("Service", "Interactive", "RemoteInteractive", "NetworkCleartext", "CachedInteractive", "Unlock", "NewCredentials", "Network", "*")]
        [string[]]$LogonType = @("Interactive", "RemoteInteractive", "CachedInteractive"),

        [string]$UserName,

        [Parameter()]
        [switch]$Oldest,

        [Parameter()]
        [int64]$MaxEvents,

        [Parameter()]
        [datetime]$StartTime = (Get-Date 1/1/1900),

        [Parameter()]
        [datetime]$StopTime = (Get-Date 1/1/2100)
    )
    Begin {
        Function ParseEventMessage {
            [CmdletBinding()]
            param(
                [Parameter(ValueFromPipeline = $true)]
                $obj
            )
            Begin {
                $defaultDisplaySet = 'TimeCreated', 'MachineName', 'TargetDomainName', 'TargetUserName'
                $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet(‘DefaultDisplayPropertySet’, [string[]]$defaultDisplaySet)
                $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)
                $myHash = @{ }
            }
            Process {

                ([xml]($obj.ToXml())).event.eventdata.data | ForEach-Object { $myHash[$PSItem.name] = $PSItem.'#text' }

                New-Object -TypeName PSObject -Property $myHash | ForEach-Object {

                    $PSItem.PSObject.TypeNames.Insert(0, "EventLogRecord.XMLParse")

                    $PSItem | Add-Member MemberSet PSStandardMembers $PSStandardMembers -PassThru |
                    Add-Member -MemberType NoteProperty -Name TimeCreated -Value $obj.timecreated -PassThru |
                    Add-Member -MemberType NoteProperty -Name MachineName -Value $obj.MachineName -PassThru
                }

            }
        }

        $hashLogonType = @{
            "Interactive"       = "2"
            "Network"           = "3"
            "Service"           = "5"
            "Unlock"            = "7"
            "NetworkCleartext"  = "8"
            "NewCredentials"    = "9"
            "RemoteInteractive" = "10"
            "CachedInteractive" = "11"
        }

        $filter = @"
    <QueryList>
        <Query Id="0" Path="Security">
        <Select Path="Security">
            *[System[
                (EventID='4624')
                and TimeCreated[@SystemTime&gt;='{0}' and @SystemTime&lt;='{1}']
            ]
                and EventData[
                    Data[@Name='LogonType'] and ({2})
                    {3}
                ]
            ]
        </Select>
        </Query>
    </QueryList>
"@
    }
    Process {
        foreach ($obj in $ComputerName) {
            if ($UserName) {
                $joinUserName = "and Data[@Name='TargetuserName'] and (Data='{0}')" -f $UserName
            }

            $joinLogonType = ($LogonType | ForEach-Object { $hashLogonType[$PSItem] }) -replace '^', "Data='" -replace '$', "'" -join " or "
            $objFilter = $filter -f (Get-Date $StartTime -Format s), (Get-Date $StopTime -Format s), $joinLogonType, $joinUserName

            $hashEventParm = @{
                ComputerName = $obj
                FilterXml    = $objFilter
            }

            if ($Credential) { $hashEventParm['Credential'] = $Credential }
            if ($MaxEvents) { $hashEventParm['MaxEvents'] = $MaxEvents }

            $objFilter | Write-Verbose

            Get-WinEvent @hashEventParm | ParseEventMessage
        }
    }
    End { }
}

$TargetDomainNameException = @('Window Manager','Font Driver Host')
$exceptionRegex = $TargetDomainNameException -join "|"

Get-LogonEvents -ComputerName 'Localhost' -MaxEvents 10 | 
    Where-Object { ($_.TargetDomainName -notmatch $exceptionRegex) } | 
    Select-Object WorkstationName, 
    TargetUserName, 
    TargetDomainName, 
    Type,
    LogonType,
    @{n ='LogonType'; e={$hashLogonType[[string]$_.LogonType]}}, 
    @{n = 'Logon Type'; e = {$hashLogonType["$($_.LogonType)"]}},
    ProcessName, 
    IPAddress, 
    @{n="Host Name"; e={([System.Net.Dns]::GetHostByAddress($_.IPaddress).Hostname)}}, 
    TimeCreated | 
    Out-GridView

错误:我修改了计算属性,如: @{n = 'Logon Type'; e = {$hashLogonType["$($_.LogonType)"]}},

不知何故,它仍然没有显示“登录类型”列,但是,LogonType列上的原始值仍然显示为 10、3 等...?

标签: powershell

解决方案


我看到两个问题。

  1. $hashLogonType在函数内部定义,在全局范围内不可用。
  2. 的键$hashLogonType是 by [string]not by [int]

如果您能够修改原始函数,您可能会考虑添加一个属性来保存 LogonType 的字符串值。

否则,请在变量范围内保留一个副本,$hashLogonType其中整数作为键,并以此为基础计算属性。


获得所需内容的最简单方法是创建自己的哈希表并在管道中使用它。

# Create a hash table for your own use in your variable scope. 
$myHashTable = @{
    2 = "Interactive"
    3 = "Network"
    5 = "Service"
    7 = "Unlock"
    8 = "NetworkCleartext"
    9 = "NewCredentials"
    10 = "RemoteInteractive"
    11 = "CachedInteractive"
}

# Shim object. 
$exampleObject = [PSCustomObject]@{
    LogonType = 2
    WorkstationName = "myHost.example.com"
    }

# Modify your pipeline to use your hash table. 
$exampleObject | 
  Select-Object -Property WorkstationName, LogonType, @{label="Logon Title";expression={$myHashTable[$_.LogonType]}}
PS> ./Answer 02.ps1

WorkstationName    LogonType Logon Title
---------------    --------- -----------
myHost.example.com         2 Interactive

原则上可以修改原来的功能。但是,我没有任何数据可以测试。也许道格可以提供帮助。他似乎可以访问事件日志。

你必须做两件事。

  1. 在范围内添加一个带有整数键的哈希表ParseEventMessage()。例如,将哈希表添加到ParseEventMessage()'Begin块。
  2. 它说的地方
Add-Member -MemberType NoteProperty -Name MachineName -Value $obj.MachineName -PassThru

通过扩展该管道添加另一个属性:

Add-Member -MemberType NoteProperty -Name LogonTitle -Value {$myHashTable[$_.LogonType]} -PassThru

推荐阅读