c748652c34
commit 8cec8f150da7583b7af5efbe2853efee0179750c
445 lines
23 KiB
PowerShell
445 lines
23 KiB
PowerShell
<#
|
||
Windows PowerShell Diagnostics Module
|
||
This module contains a set of wrapper scripts that
|
||
enable a user to use ETW tracing in Windows
|
||
PowerShell.
|
||
#>
|
||
|
||
$script:Logman="$env:windir\system32\logman.exe"
|
||
$script:wsmanlogfile = "$env:windir\system32\wsmtraces.log"
|
||
$script:wsmprovfile = "$env:windir\system32\wsmtraceproviders.txt"
|
||
$script:wsmsession = "wsmlog"
|
||
$script:pssession = "PSTrace"
|
||
$script:psprovidername="Microsoft-Windows-PowerShell"
|
||
$script:wsmprovidername = "Microsoft-Windows-WinRM"
|
||
$script:oplog = "/Operational"
|
||
$script:analyticlog="/Analytic"
|
||
$script:debuglog="/Debug"
|
||
$script:wevtutil="$env:windir\system32\wevtutil.exe"
|
||
$script:slparam = "sl"
|
||
$script:glparam = "gl"
|
||
|
||
function Start-Trace
|
||
{
|
||
Param(
|
||
[Parameter(Mandatory=$true,
|
||
Position=0)]
|
||
[string]
|
||
$SessionName,
|
||
[Parameter(Position=1)]
|
||
[string]
|
||
$OutputFilePath,
|
||
[Parameter(Position=2)]
|
||
[string]
|
||
$ProviderFilePath,
|
||
[Parameter()]
|
||
[Switch]
|
||
$ETS,
|
||
[Parameter()]
|
||
[ValidateSet("bin", "bincirc", "csv", "tsv", "sql")]
|
||
$Format,
|
||
[Parameter()]
|
||
[int]
|
||
$MinBuffers=0,
|
||
[Parameter()]
|
||
[int]
|
||
$MaxBuffers=256,
|
||
[Parameter()]
|
||
[int]
|
||
$BufferSizeInKB = 0,
|
||
[Parameter()]
|
||
[int]
|
||
$MaxLogFileSizeInMB=0
|
||
)
|
||
|
||
Process
|
||
{
|
||
$executestring = " start $SessionName"
|
||
|
||
if ($ETS)
|
||
{
|
||
$executestring += " -ets"
|
||
}
|
||
|
||
if ($OutputFilePath -ne $null)
|
||
{
|
||
$executestring += " -o $OutputFilePath"
|
||
}
|
||
|
||
if ($ProviderFilePath -ne $null)
|
||
{
|
||
$executestring += " -pf $ProviderFilePath"
|
||
}
|
||
|
||
if ($Format -ne $null)
|
||
{
|
||
$executestring += " -f $Format"
|
||
}
|
||
|
||
if ($MinBuffers -ne 0 -or $MaxBuffers -ne 256)
|
||
{
|
||
$executestring += " -nb $MinBuffers $MaxBuffers"
|
||
}
|
||
|
||
if ($BufferSizeInKB -ne 0)
|
||
{
|
||
$executestring += " -bs $BufferSizeInKB"
|
||
}
|
||
|
||
if ($MaxLogFileSizeInMB -ne 0)
|
||
{
|
||
$executestring += " -max $MaxLogFileSizeInMB"
|
||
}
|
||
|
||
& $script:Logman $executestring.Split(" ")
|
||
}
|
||
}
|
||
|
||
function Stop-Trace
|
||
{
|
||
param(
|
||
[Parameter(Mandatory=$true,
|
||
Position=0)]
|
||
$SessionName,
|
||
[Parameter()]
|
||
[switch]
|
||
$ETS
|
||
)
|
||
|
||
Process
|
||
{
|
||
if ($ETS)
|
||
{
|
||
& $script:Logman update $SessionName -ets
|
||
& $script:Logman stop $SessionName -ets
|
||
}
|
||
else
|
||
{
|
||
& $script:Logman update $SessionName
|
||
& $script:Logman stop $SessionName
|
||
}
|
||
}
|
||
}
|
||
|
||
function Enable-WSManTrace
|
||
{
|
||
|
||
# winrm
|
||
"{04c6e16d-b99f-4a3a-9b3e-b8325bbc781e} 0xffffffff 0xff" | out-file $script:wsmprovfile -encoding ascii
|
||
|
||
# winrsmgr
|
||
"{c0a36be8-a515-4cfa-b2b6-2676366efff7} 0xffffffff 0xff" | out-file $script:wsmprovfile -encoding ascii -append
|
||
|
||
# WinrsExe
|
||
"{f1cab2c0-8beb-4fa2-90e1-8f17e0acdd5d} 0xffffffff 0xff" | out-file $script:wsmprovfile -encoding ascii -append
|
||
|
||
# WinrsCmd
|
||
"{03992646-3dfe-4477-80e3-85936ace7abb} 0xffffffff 0xff" | out-file $script:wsmprovfile -encoding ascii -append
|
||
|
||
# IPMIPrv
|
||
"{651d672b-e11f-41b7-add3-c2f6a4023672} 0xffffffff 0xff" | out-file $script:wsmprovfile -encoding ascii -append
|
||
|
||
#IpmiDrv
|
||
"{D5C6A3E9-FA9C-434e-9653-165B4FC869E4} 0xffffffff 0xff" | out-file $script:wsmprovfile -encoding ascii -append
|
||
|
||
# WSManProvHost
|
||
"{6e1b64d7-d3be-4651-90fb-3583af89d7f1} 0xffffffff 0xff" | out-file $script:wsmprovfile -encoding ascii -append
|
||
|
||
# Event Forwarding
|
||
"{6FCDF39A-EF67-483D-A661-76D715C6B008} 0xffffffff 0xff" | out-file $script:wsmprovfile -encoding ascii -append
|
||
|
||
Start-Trace -SessionName $script:wsmsession -ETS -OutputFilePath $script:wsmanlogfile -Format bincirc -MinBuffers 16 -MaxBuffers 256 -BufferSizeInKb 64 -MaxLogFileSizeInMB 256 -ProviderFilePath $script:wsmprovfile
|
||
}
|
||
|
||
function Disable-WSManTrace
|
||
{
|
||
Stop-Trace $script:wsmsession -ets
|
||
}
|
||
|
||
function Enable-PSWSManCombinedTrace
|
||
{
|
||
param (
|
||
[switch] $DoNotOverwriteExistingTrace
|
||
)
|
||
|
||
$provfile = [io.path]::GetTempFilename()
|
||
|
||
$traceFileName = [string][Guid]::NewGuid()
|
||
if ($DoNotOverwriteExistingTrace) {
|
||
$fileName = [string][guid]::newguid()
|
||
$logfile = $pshome + "\\Traces\\PSTrace_$fileName.etl"
|
||
} else {
|
||
$logfile = $pshome + "\\Traces\\PSTrace.etl"
|
||
}
|
||
|
||
"Microsoft-Windows-PowerShell 0 5" | out-file $provfile -encoding ascii
|
||
"Microsoft-Windows-WinRM 0 5" | out-file $provfile -encoding ascii -append
|
||
|
||
if (!(Test-Path $pshome\Traces))
|
||
{
|
||
mkdir -Force $pshome\Traces | out-null
|
||
}
|
||
|
||
if (Test-Path $logfile)
|
||
{
|
||
Remove-Item -Force $logfile | out-null
|
||
}
|
||
|
||
Start-Trace -SessionName $script:pssession -OutputFilePath $logfile -ProviderFilePath $provfile -ets
|
||
|
||
remove-item $provfile -Force -ea 0
|
||
}
|
||
|
||
function Disable-PSWSManCombinedTrace
|
||
{
|
||
Stop-Trace -SessionName $script:pssession -ets
|
||
}
|
||
|
||
function Set-LogProperties
|
||
{
|
||
param(
|
||
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
|
||
[Microsoft.PowerShell.Diagnostics.LogDetails]
|
||
$LogDetails,
|
||
[switch] $Force
|
||
)
|
||
|
||
Process
|
||
{
|
||
if ($LogDetails.AutoBackup -and !$LogDetails.Retention)
|
||
{
|
||
throw (New-Object System.InvalidOperationException)
|
||
}
|
||
|
||
$enabled = $LogDetails.Enabled.ToString()
|
||
$retention = $LogDetails.Retention.ToString()
|
||
$autobackup = $LogDetails.AutoBackup.ToString()
|
||
$maxLogSize = $LogDetails.MaxLogSize.ToString()
|
||
$osVersion = [Version] (Get-Ciminstance Win32_OperatingSystem).Version
|
||
|
||
if (($LogDetails.Type -eq "Analytic") -or ($LogDetails.Type -eq "Debug"))
|
||
{
|
||
if ($LogDetails.Enabled)
|
||
{
|
||
if($osVersion -lt 6.3.7600)
|
||
{
|
||
& $script:wevtutil $script:slparam $LogDetails.Name -e:$Enabled
|
||
}
|
||
else
|
||
{
|
||
& $script:wevtutil /q:$Force $script:slparam $LogDetails.Name -e:$Enabled
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if($osVersion -lt 6.3.7600)
|
||
{
|
||
& $script:wevtutil $script:slparam $LogDetails.Name -e:$Enabled -rt:$Retention -ms:$MaxLogSize
|
||
}
|
||
else
|
||
{
|
||
& $script:wevtutil /q:$Force $script:slparam $LogDetails.Name -e:$Enabled -rt:$Retention -ms:$MaxLogSize
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if($osVersion -lt 6.3.7600)
|
||
{
|
||
& $script:wevtutil $script:slparam $LogDetails.Name -e:$Enabled -rt:$Retention -ab:$AutoBackup -ms:$MaxLogSize
|
||
}
|
||
else
|
||
{
|
||
& $script:wevtutil /q:$Force $script:slparam $LogDetails.Name -e:$Enabled -rt:$Retention -ab:$AutoBackup -ms:$MaxLogSize
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function ConvertTo-Bool([string]$value)
|
||
{
|
||
if ($value -ieq "true")
|
||
{
|
||
return $true
|
||
}
|
||
else
|
||
{
|
||
return $false
|
||
}
|
||
}
|
||
|
||
function Get-LogProperties
|
||
{
|
||
param(
|
||
[Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)] $Name
|
||
)
|
||
|
||
Process
|
||
{
|
||
$details = & $script:wevtutil $script:glparam $Name
|
||
$indexes = @(1,2,8,9,10)
|
||
$value = @()
|
||
foreach($index in $indexes)
|
||
{
|
||
$value += @(($details[$index].SubString($details[$index].IndexOf(":")+1)).Trim())
|
||
}
|
||
|
||
$enabled = ConvertTo-Bool $value[0]
|
||
$retention = ConvertTo-Bool $value[2]
|
||
$autobackup = ConvertTo-Bool $value[3]
|
||
|
||
New-Object Microsoft.PowerShell.Diagnostics.LogDetails $Name, $enabled, $value[1], $retention, $autobackup, $value[4]
|
||
}
|
||
}
|
||
|
||
function Enable-PSTrace
|
||
{
|
||
param(
|
||
[switch] $Force,
|
||
[switch] $AnalyticOnly
|
||
)
|
||
|
||
$Properties = Get-LogProperties ($script:psprovidername + $script:analyticlog)
|
||
|
||
if (!$Properties.Enabled) {
|
||
$Properties.Enabled = $true
|
||
if ($Force) {
|
||
Set-LogProperties $Properties -Force
|
||
} else {
|
||
Set-LogProperties $Properties
|
||
}
|
||
}
|
||
|
||
if (!$AnalyticOnly) {
|
||
$Properties = Get-LogProperties ($script:psprovidername + $script:debuglog)
|
||
if (!$Properties.Enabled) {
|
||
$Properties.Enabled = $true
|
||
if ($Force) {
|
||
Set-LogProperties $Properties -Force
|
||
} else {
|
||
Set-LogProperties $Properties
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function Disable-PSTrace
|
||
{
|
||
param(
|
||
[switch] $AnalyticOnly
|
||
)
|
||
$Properties = Get-LogProperties ($script:psprovidername + $script:analyticlog)
|
||
if ($Properties.Enabled) {
|
||
$Properties.Enabled = $false
|
||
Set-LogProperties $Properties
|
||
}
|
||
|
||
if (!$AnalyticOnly) {
|
||
$Properties = Get-LogProperties ($script:psprovidername + $script:debuglog)
|
||
if ($Properties.Enabled) {
|
||
$Properties.Enabled = $false
|
||
Set-LogProperties $Properties
|
||
}
|
||
}
|
||
}
|
||
add-type @"
|
||
using System;
|
||
|
||
namespace Microsoft.PowerShell.Diagnostics
|
||
{
|
||
public class LogDetails
|
||
{
|
||
public string Name
|
||
{
|
||
get
|
||
{
|
||
return name;
|
||
}
|
||
}
|
||
private string name;
|
||
|
||
public bool Enabled
|
||
{
|
||
get
|
||
{
|
||
return enabled;
|
||
}
|
||
set
|
||
{
|
||
enabled = value;
|
||
}
|
||
}
|
||
private bool enabled;
|
||
|
||
public string Type
|
||
{
|
||
get
|
||
{
|
||
return type;
|
||
}
|
||
}
|
||
private string type;
|
||
|
||
public bool Retention
|
||
{
|
||
get
|
||
{
|
||
return retention;
|
||
}
|
||
set
|
||
{
|
||
retention = value;
|
||
}
|
||
}
|
||
private bool retention;
|
||
|
||
public bool AutoBackup
|
||
{
|
||
get
|
||
{
|
||
return autoBackup;
|
||
}
|
||
set
|
||
{
|
||
autoBackup = value;
|
||
}
|
||
}
|
||
private bool autoBackup;
|
||
|
||
public int MaxLogSize
|
||
{
|
||
get
|
||
{
|
||
return maxLogSize;
|
||
}
|
||
set
|
||
{
|
||
maxLogSize = value;
|
||
}
|
||
}
|
||
private int maxLogSize;
|
||
|
||
public LogDetails(string name, bool enabled, string type, bool retention, bool autoBackup, int maxLogSize)
|
||
{
|
||
this.name = name;
|
||
this.enabled = enabled;
|
||
this.type = type;
|
||
this.retention = retention;
|
||
this.autoBackup = autoBackup;
|
||
this.maxLogSize = maxLogSize;
|
||
}
|
||
}
|
||
}
|
||
"@
|
||
|
||
|
||
if ($psedition.ToLower() -eq "core")
|
||
{
|
||
# Currently we only support these cmdlets as logman.exe is not working on Nano/Lot system.
|
||
Export-ModuleMember Enable-PSTrace, Disable-PSTrace, Get-LogProperties, Set-LogProperties
|
||
}
|
||
else
|
||
{
|
||
Export-ModuleMember Start-Trace, Stop-Trace, Enable-WSManTrace, Disable-WSManTrace, Enable-PSTrace, Disable-PSTrace, Enable-PSWSManCombinedTrace, Disable-PSWSManCombinedTrace, Get-LogProperties, Set-LogProperties
|
||
}
|