Powershell计算属性-正在调用HashTable枚举器



我无法显示从哈希表转换而来的名为Logon Type的计算属性列。

下面的脚本运行良好,但我只需要将原始值转换为更有意义的描述。

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

错误:我修改了Calculated属性,如下所示:@{n="登录类型";e={$hashLogoType[quot;$($_.LogoType("]}},

不知怎的,它仍然没有显示列"0">登录类型";,但是,LogoType列上的原始值仍然显示为10、3等。。。?

我看到两个问题。

  1. $hashLogonType在函数内部定义,在全局范围内不可用
  2. CCD_ 2的密钥由[string]而不是由[int]

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

否则,请在变量作用域中保留一份$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

Edit:是的,Mike是绝对正确的,哈希表是在get-logonevents函数中定义的,没有使用。我已经把它搬出去了,现在应该可以用了。

我认为你应该颠倒哈希表的赋值。那么,作为int或字符串都应该有效。我这样做了,效果很好。

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
}
}
}
$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 { }
}
$hashLogonType = @{
2 = "Interactive"
3 = "Network"
5 = "Service"
7 = "Unlock"
8 = "NetworkCleartext"
9 = "NewCredentials"
10 = "RemoteInteractive"
11 = "CachedInteractive"
}
$TargetDomainNameException = @('Window Manager','Font Driver Host')
$exceptionRegex = $TargetDomainNameException -join "|"
Get-LogonEvents -ComputerName 'Localhost' -MaxEvents 10 -OutVariable LogonEvents | 
Where-Object { ($_.TargetDomainName -notmatch $exceptionRegex) } | 
Select-Object WorkstationName, 
TargetUserName, 
TargetDomainName, 
Type,
@{n="LogonType";e={$hashLogonType.[int]$_.logontype}}, 
ProcessName, 
IPAddress, 
@{n="Host Name"; e={([System.Net.Dns]::GetHostByAddress($_.IPaddress).Hostname)}}, 
TimeCreated | 
Out-GridView

最新更新