我无法显示从哈希表转换而来的名为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>='{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
错误:我修改了Calculated属性,如下所示:@{n="登录类型";e={$hashLogoType[quot;$($_.LogoType("]}},
不知怎的,它仍然没有显示列"0">登录类型";,但是,LogoType列上的原始值仍然显示为10、3等。。。?
我看到两个问题。
$hashLogonType
在函数内部定义,在全局范围内不可用- 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
原则上,可以修改原始功能。但是,我没有任何数据可以测试。也许道格能帮上忙。他似乎可以访问事件日志。
你必须做两件事。
- 在
ParseEventMessage()
的作用域中添加一个具有整数键的哈希表。例如,将哈希表添加到ParseEventMessage()
的Begin
块中 - 上面写着
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>='{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 { }
}
$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