mirror of
https://github.com/aphrody-labs/PowerShell.git
synced 2026-10-17 04:36:39 +00:00
436 lines
23 KiB
PowerShell
436 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-WMIObject 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;
|
|
}
|
|
}
|
|
}
|
|
"@
|
|
|
|
Export-ModuleMember Start-Trace, Stop-Trace, Enable-WSManTrace, Disable-WSManTrace, Enable-PSTrace, Disable-PSTrace, Enable-PSWSManCombinedTrace, Disable-PSWSManCombinedTrace, Get-LogProperties, Set-LogProperties
|