powershell - 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>='{0}' and @SystemTime<='{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 等...?
解决方案
我看到两个问题。
$hashLogonType
在函数内部定义,在全局范围内不可用。- 的键
$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
原则上可以修改原来的功能。但是,我没有任何数据可以测试。也许道格可以提供帮助。他似乎可以访问事件日志。
你必须做两件事。
- 在范围内添加一个带有整数键的哈希表
ParseEventMessage()
。例如,将哈希表添加到ParseEventMessage()
'Begin
块。 - 它说的地方
Add-Member -MemberType NoteProperty -Name MachineName -Value $obj.MachineName -PassThru
通过扩展该管道添加另一个属性:
Add-Member -MemberType NoteProperty -Name LogonTitle -Value {$myHashTable[$_.LogonType]} -PassThru
推荐阅读
- java - javafx中的线程
- sql - SQL - 根据 2 个日期之间的天数从 1 个记录创建多个记录
- python - 在 conda 虚拟环境中以 pip 兼容格式创建 requirements.txt
- javascript - Bookshelf.js fetchAll() 性能
- r - 如何更正箱线图的标签获取 R 中每对的 p 值
- scala - Scala递归api调用
- excel - 使用 MSHTML.HTMLDocument 时强制 documentMode
- r - knitr 中的数字大小与拼凑或牛图
- amazon-web-services - AWS 生命周期管理器将其作为备份的快照保存在哪里
- powershell - 在扫描 TCP 和 UDP 端口脚本中缺少成员的 psobjects 数组