无管理员权限下获取Write-EventLog可用的-LogName和-Source列表
无管理员权限下获取Write-EventLog可用的-LogName和-Source列表
我太懂这种尴尬了——没管理员权限,没法用New-EventLog创建自定义的日志或源,直接调用Write-EventLog还会因为找不到合法参数抛出权限报错,就像你碰到的这个情况:
PS C:\> try { Write-EventLog -LogName "Application" -Source 'NewApplication' -EventId "400" -Message "TEST MESSAGE" } catch { $_ | Format-List * -Force | Out-String } PSMessageDetails : Exception : System.Security.SecurityException: The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security. at System.Diagnostics.EventLog.FindSourceRegistration(String source, String machineName, Boolean readOnly, Boolean wantToCreat...
别着急,咱们用普通用户权限就能执行的命令,找出系统里已经存在、且咱们能访问的LogName和对应Source列表就行,具体方法如下:
1. 获取所有可访问的LogName列表
用这条命令过滤掉无权限访问的日志,只保留咱们能正常读取的:
Get-EventLog -List | Where-Object { $_.Entries.Count -ge 0 -or $_.LogDisplayName } | Select-Object Log, LogDisplayName
原理是Get-EventLog -List会列出系统全部日志,但像Security这种日志普通用户碰不了,所以通过Where-Object筛选出能读取条目或者有显示名的合法日志,避免权限报错。
2. 获取指定LogName对应的可用Source列表
拿到合法的LogName后,比如Application,用这条命令提取该日志下所有已存在的唯一Source:
$targetLog = "Application" Get-EventLog -LogName $targetLog -EntryType Information -Source * | Select-Object -ExpandProperty Source -Unique | Sort-Object
它会从目标日志的信息条目中提取所有用过的Source,去重后排序,直接就能用在Write-EventLog的-Source参数里。
3. 更高效的一站式获取方法
用Get-WinEvent可以一次性拿到所有可访问日志及其对应的Source,权限处理更友好:
Get-WinEvent -ListLog * -ErrorAction SilentlyContinue | ForEach-Object { [PSCustomObject]@{ LogName = $_.LogName Sources = $_.ProviderNames -join ', ' } } | Where-Object { $_.Sources }
这条命令会自动跳过无权限的日志,输出每个可访问日志的名称和对应的所有Source,一目了然。
找到合适的组合后,比如用Application日志和Windows Error Reporting这个Source,就可以安全执行Write-EventLog了,不会再触发权限异常~
备注:内容来源于stack exchange,提问作者SATO Yusuke
相关产品推荐
相关产品推荐

