tracing: combine collect-wsl-logs.ps1 and collect-networking-logs.ps1 (#14089)

Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
This commit is contained in:
Ben Hillis 2026-01-22 11:18:54 -08:00 committed by GitHub
parent e663585eeb
commit b9b108c548
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 154 additions and 327 deletions

View File

@ -196,7 +196,7 @@ debugConsole=true
### Common Debugging Commands
- Debug shell: `wsl --debug-shell`
- Collect WSL logs: `powershell diagnostics\collect-wsl-logs.ps1`
- Network logs: `powershell diagnostics\collect-networking-logs.ps1`
- Network logs: `powershell diagnostics\collect-wsl-logs.ps1 -LogProfile networking`
## Critical Timing and Timeout Guidelines

View File

@ -53,13 +53,18 @@ Install [WPR](https://learn.microsoft.com/windows-hardware/test/wpt/windows-perf
To collect WSL networking logs, do the following steps in an administrative powershell prompt:
```
Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/microsoft/WSL/master/diagnostics/collect-networking-logs.ps1" -OutFile collect-networking-logs.ps1
Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/microsoft/WSL/master/diagnostics/collect-wsl-logs.ps1" -OutFile collect-wsl-logs.ps1
Set-ExecutionPolicy Bypass -Scope Process -Force
.\collect-networking-logs.ps1
.\collect-wsl-logs.ps1 -LogProfile networking
```
The script will output when log collection starts. Reproduce the problem, then press any key to stop the log collection.
The script will output the path of the log file once done.
For additional network creation logs (restarts WSL), use:
```
.\collect-wsl-logs.ps1 -LogProfile networking -RestartWslReproMode
```
<!-- Preserving anchors -->
<div id="8-detailed-logs"></div>
<div id="9-networking-logs"></div>
@ -81,9 +86,9 @@ The script will output the path of the log file once done.
For specific scenarios, you can use different log profiles:
- `.\collect-wsl-logs.ps1 -LogProfile storage` - Enhanced storage tracing
- `.\collect-wsl-logs.ps1 -LogProfile networking` - Networking-focused tracing
- `.\collect-wsl-logs.ps1 -LogProfile networking` - Comprehensive networking tracing (includes packet capture, tcpdump, etc.)
- `.\collect-wsl-logs.ps1 -LogProfile networking -RestartWslReproMode` - Networking tracing with WSL restart for network creation logs
- `.\collect-wsl-logs.ps1 -LogProfile hvsocket` - HvSocket-specific tracing
- `.\collect-networking-logs.ps1` - Alternative script for networking tracing
### 10) Reporting a Windows crash (BSOD)

View File

@ -1,320 +0,0 @@
#Requires -RunAsAdministrator
[CmdletBinding()]
Param (
$RestartWslReproMode = $false
)
function Collect-WindowsNetworkState {
param (
$ReproStep
)
# Collect host networking state relevant for WSL
# Using a try/catch for commands below, as some of them do not exist on all OS versions
try
{
Get-NetAdapter -includeHidden | select Name,ifIndex,NetLuid,InterfaceGuid,Status,MacAddress,MtuSize,InterfaceType,Hidden,HardwareInterface,ConnectorPresent,MediaType,PhysicalMediaType | Out-File -FilePath "$folder/Get-NetAdapter_$ReproStep.log" -Append
}
catch {}
try
{
& netsh nlm query all $folder/nlmquery_"$ReproStep".log
}
catch {}
try
{
Get-NetIPConfiguration -All -Detailed | Out-File -FilePath "$folder/Get-NetIPConfiguration_$ReproStep.log" -Append
}
catch {}
try
{
Get-NetRoute | Out-File -FilePath "$folder/Get-NetRoute_$ReproStep.log" -Append
}
catch {}
try
{
Get-NetFirewallHyperVVMCreator | Out-File -FilePath "$folder/Get-NetFirewallHyperVVMCreator_$ReproStep.log" -Append
}
catch {}
try
{
Get-NetFirewallHyperVVMSetting -PolicyStore ActiveStore | Out-File -FilePath "$folder/Get-NetFirewallHyperVVMSetting_ActiveStore_$ReproStep.log" -Append
}
catch {}
try
{
Get-NetFirewallHyperVProfile -PolicyStore ActiveStore | Out-File -FilePath "$folder/Get-NetFirewallHyperVProfile_ActiveStore_$ReproStep.log" -Append
}
catch {}
try
{
Get-NetFirewallHyperVRule -PolicyStore ActiveStore | Out-File -FilePath "$folder/Get-NetFirewallHyperVRule_ActiveStore_$ReproStep.log" -Append
}
catch {}
try
{
Get-NetFirewallRule -PolicyStore ActiveStore | Out-File -FilePath "$folder/Get-NetFirewallRule_ActiveStore_$ReproStep.log" -Append
}
catch {}
try
{
Get-NetFirewallProfile -PolicyStore ActiveStore | Out-File -FilePath "$folder/Get-NetFirewallProfile_ActiveStore_$ReproStep.log" -Append
}
catch {}
try
{
Get-NetFirewallHyperVPort | Out-File -FilePath "$folder/Get-NetFirewallHyperVPort_$ReproStep.log" -Append
}
catch {}
try
{
& hnsdiag.exe list all 2>&1 > $folder/hnsdiag_list_all_"$ReproStep".log
}
catch {}
try
{
& hnsdiag.exe list endpoints -df 2>&1 > $folder/hnsdiag_list_endpoints_"$ReproStep".log
}
catch {}
try
{
foreach ($port in Get-NetFirewallHyperVPort)
{
& vfpctrl.exe /port $port.PortName /get-port-state 2>&1 > "$folder/vfp-port-$($port.PortName)-get-port-state_$ReproStep.log"
& vfpctrl.exe /port $port.PortName /list-rule 2>&1 > "$folder/vfp-port-$($port.PortName)-list-rule_$ReproStep.log"
}
}
catch {}
try
{
& vfpctrl.exe /list-vmswitch-port 2>&1 > $folder/vfpctrl_list_vmswitch_port_"$ReproStep".log
}
catch {}
try
{
Get-VMSwitch | select Name,Id,SwitchType | Out-File -FilePath "$folder/Get-VMSwitch_$ReproStep.log" -Append
}
catch {}
try
{
Get-NetUdpEndpoint | Out-File -FilePath "$folder/Get-NetUdpEndpoint_$ReproStep.log" -Append
}
catch {}
}
$folder = "WslNetworkingLogs-" + (Get-Date -Format "yyyy-MM-dd_HH-mm-ss")
mkdir -p $folder
$wprpFile = "$folder/wsl.wprp"
$wprpProfile = "WSL-Networking"
$networkingBashScript = "$folder/networking.sh"
# Detect the super user first.
# Actually it's not definite that the super user is named "root". Instead, a user with uid=0 is what we are looking for. See #11693.
$superUser = & wsl.exe -- id -nu 0 # user name of the super user.
# Copy/Download supporting files
if (Test-Path "$PSScriptRoot/wsl.wprp")
{
Copy-Item "$PSScriptRoot/wsl.wprp" $wprpFile
}
else
{
Write-Host -ForegroundColor Yellow "wsl.wprp not found in the current directory. Downloading it from GitHub."
Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/microsoft/WSL/master/diagnostics/wsl.wprp" -OutFile $wprpFile
}
if (Test-Path "$PSScriptRoot/networking.sh")
{
Copy-Item "$PSScriptRoot/networking.sh" $networkingBashScript
}
else
{
Write-Host -ForegroundColor Yellow "networking.sh not found in the current directory. Downloading it from GitHub."
Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/microsoft/WSL/master/diagnostics/networking.sh" -OutFile $networkingBashScript
}
# Retrieve WSL version and wslconfig file
get-appxpackage MicrosoftCorporationII.WindowsSubsystemforLinux > $folder/appxpackage.txt
$wslconfig = "$env:USERPROFILE/.wslconfig"
if (Test-Path $wslconfig)
{
Copy-Item $wslconfig $folder
}
# Collect Linux & Windows network state before the repro
& wsl.exe -u $superUser -e $networkingBashScript 2>&1 > $folder/linux_network_configuration_before.log
Collect-WindowsNetworkState "before_repro"
if ($RestartWslReproMode)
{
# The WSL HNS network is created once per boot. Resetting it to collect network creation logs.
# Note: The below HNS command applies only to WSL in NAT mode
Get-HnsNetwork | Where-Object {$_.Name -eq 'WSL' -Or $_.Name -eq 'WSL (Hyper-V firewall)'} | Remove-HnsNetwork
# Stop WSL.
net.exe stop WslService
if(-not $?)
{
net.exe stop LxssManager
}
}
# Start logging.
$wprOutputLog = "$folder/wpr.txt"
wpr.exe -start "$wprpFile!$wprpProfile" -filemode 2>&1 >> $wprOutputLog
if ($LastExitCode -Ne 0)
{
Write-Host -ForegroundColor Yellow "Log collection failed to start (exit code: $LastExitCode), trying to reset it."
wpr.exe -cancel 2>&1 >> $wprOutputLog
wpr.exe -start "$wprpFile!$wprpProfile" -filemode 2>&1 >> $wprOutputLog
if ($LastExitCode -Ne 0)
{
Write-Host -ForegroundColor Red "Couldn't start log collection (exitCode: $LastExitCode)"
}
}
# Start packet capture using pktmon
pktmon start -c --flags 0x1A --file-name "$folder/pktmon.etl" | out-null
# Start WFP capture
netsh wfp capture start file="$folder/wfpdiag.cab"
# Start tcpdump. Using a try/catch as tcpdump might not be installed
$tcpdumpProcess = $null
try
{
$tcpdumpProcess = Start-Process wsl.exe -ArgumentList "-u $superUser tcpdump -n -i any -e -vvv > $folder/tcpdump.log" -PassThru
}
catch {}
try
{
Write-Host -NoNewLine -ForegroundColor Green "Log collection is running. Please reproduce the problem and press any key to save the logs."
$KeysToIgnore =
16, # Shift (left or right)
17, # Ctrl (left or right)
18, # Alt (left or right)
20, # Caps lock
91, # Windows key (left)
92, # Windows key (right)
93, # Menu key
144, # Num lock
145, # Scroll lock
166, # Back
167, # Forward
168, # Refresh
169, # Stop
170, # Search
171, # Favorites
172, # Start/Home
173, # Mute
174, # Volume Down
175, # Volume Up
176, # Next Track
177, # Previous Track
178, # Stop Media
179, # Play
180, # Mail
181, # Select Media
182, # Application 1
183 # Application 2
$Key = $null
while ($Key -Eq $null -Or $Key.VirtualKeyCode -Eq $null -Or $KeysToIgnore -Contains $Key.VirtualKeyCode)
{
if ([console]::KeyAvailable)
{
$Key = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
}
else
{
Start-Sleep -Seconds 1
}
}
Write-Host "`nSaving logs..."
}
finally
{
try
{
wsl.exe -u $superUser killall tcpdump
if ($tcpdumpProcess -ne $null)
{
Wait-Process -InputObject $tcpdumpProcess -Timeout 10
}
}
catch {}
netsh wfp capture stop
pktmon stop | out-null
wpr.exe -stop $folder/logs.etl 2>&1 >> $wprOutputLog
}
# Collect Linux & Windows network state after the repro
& wsl.exe -u $superUser -e $networkingBashScript 2>&1 > $folder/linux_network_configuration_after.log
Collect-WindowsNetworkState "after_repro"
try
{
# Collect HNS events from past 24 hours
$events = Get-WinEvent -ProviderName Microsoft-Windows-Host-Network-Service | Where-Object { $_.TimeCreated -ge ((Get-Date) - (New-TimeSpan -Day 1)) }
($events | ForEach-Object { '{0},{1},{2},{3}' -f $_.TimeCreated, $_.Id, $_.LevelDisplayName, $_.Message }) -join [environment]::NewLine | Out-File -FilePath "$folder/hns_events.log" -Append
}
catch {}
# Collect the old Tcpip6 registry values - as they can break WSL if DisabledComponents is set to 0xff
# see https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-ipv6-in-windows
try
{
Get-Item HKLM:SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters | Out-File -FilePath "$folder/tcpip6_parameters.log" -Append
}
catch {}
# Collect the setup and NetSetup log files
$netSetupPath = "$env:WINDIR/logs/netsetup"
if (Test-Path $netSetupPath)
{
Copy-Item $netSetupPath/* $folder
}
$setupApiPath = "$env:WINDIR/inf/setupapi.dev.log"
if (Test-Path $setupApiPath)
{
Copy-Item $setupApiPath $folder
}
Remove-Item $wprpFile
Remove-Item $networkingBashScript
$logArchive = "$(Resolve-Path $folder).zip"
Compress-Archive -Path $folder -DestinationPath $logArchive
Remove-Item $folder -Recurse
Write-Host -ForegroundColor Green "Logs saved in: $logArchive. Please attach that file to the GitHub issue."

View File

@ -3,11 +3,45 @@
[CmdletBinding()]
Param (
$LogProfile = $null,
[switch]$Dump = $false
[switch]$Dump = $false,
[switch]$RestartWslReproMode = $false
)
Set-StrictMode -Version Latest
function Collect-WindowsNetworkState {
param (
$Folder,
$ReproStep
)
# Collect host networking state relevant for WSL
# Using a try/catch for commands below, as some of them do not exist on all OS versions
try { Get-NetAdapter -includeHidden | select Name,ifIndex,NetLuid,InterfaceGuid,Status,MacAddress,MtuSize,InterfaceType,Hidden,HardwareInterface,ConnectorPresent,MediaType,PhysicalMediaType | Out-File -FilePath "$Folder/Get-NetAdapter_$ReproStep.log" -Append } catch {}
try { & netsh nlm query all $Folder/nlmquery_"$ReproStep".log } catch {}
try { Get-NetIPConfiguration -All -Detailed | Out-File -FilePath "$Folder/Get-NetIPConfiguration_$ReproStep.log" -Append } catch {}
try { Get-NetRoute | Out-File -FilePath "$Folder/Get-NetRoute_$ReproStep.log" -Append } catch {}
try { Get-NetFirewallHyperVVMCreator | Out-File -FilePath "$Folder/Get-NetFirewallHyperVVMCreator_$ReproStep.log" -Append } catch {}
try { Get-NetFirewallHyperVVMSetting -PolicyStore ActiveStore | Out-File -FilePath "$Folder/Get-NetFirewallHyperVVMSetting_ActiveStore_$ReproStep.log" -Append } catch {}
try { Get-NetFirewallHyperVProfile -PolicyStore ActiveStore | Out-File -FilePath "$Folder/Get-NetFirewallHyperVProfile_ActiveStore_$ReproStep.log" -Append } catch {}
try { Get-NetFirewallHyperVRule -PolicyStore ActiveStore | Out-File -FilePath "$Folder/Get-NetFirewallHyperVRule_ActiveStore_$ReproStep.log" -Append } catch {}
try { Get-NetFirewallRule -PolicyStore ActiveStore | Out-File -FilePath "$Folder/Get-NetFirewallRule_ActiveStore_$ReproStep.log" -Append } catch {}
try { Get-NetFirewallProfile -PolicyStore ActiveStore | Out-File -FilePath "$Folder/Get-NetFirewallProfile_ActiveStore_$ReproStep.log" -Append } catch {}
try { Get-NetFirewallHyperVPort | Out-File -FilePath "$Folder/Get-NetFirewallHyperVPort_$ReproStep.log" -Append } catch {}
try { & hnsdiag.exe list all 2>&1 > $Folder/hnsdiag_list_all_"$ReproStep".log } catch {}
try { & hnsdiag.exe list endpoints -df 2>&1 > $Folder/hnsdiag_list_endpoints_"$ReproStep".log } catch {}
try {
foreach ($port in Get-NetFirewallHyperVPort) {
& vfpctrl.exe /port $port.PortName /get-port-state 2>&1 > "$Folder/vfp-port-$($port.PortName)-get-port-state_$ReproStep.log"
& vfpctrl.exe /port $port.PortName /list-rule 2>&1 > "$Folder/vfp-port-$($port.PortName)-list-rule_$ReproStep.log"
}
} catch {}
try { & vfpctrl.exe /list-vmswitch-port 2>&1 > $Folder/vfpctrl_list_vmswitch_port_"$ReproStep".log } catch {}
try { Get-VMSwitch | select Name,Id,SwitchType | Out-File -FilePath "$Folder/Get-VMSwitch_$ReproStep.log" -Append } catch {}
try { Get-NetUdpEndpoint | Out-File -FilePath "$Folder/Get-NetUdpEndpoint_$ReproStep.log" -Append } catch {}
}
$folder = "WslLogs-" + (Get-Date -Format "yyyy-MM-dd_HH-mm-ss")
mkdir -p $folder | Out-Null
@ -52,6 +86,40 @@ else
}
}
# Networking-specific setup
if ($LogProfile -eq "networking")
{
# Copy/download networking.sh script
$networkingBashScript = "$folder/networking.sh"
if (Test-Path "$PSScriptRoot/networking.sh")
{
Copy-Item "$PSScriptRoot/networking.sh" $networkingBashScript
}
else
{
Write-Host -ForegroundColor Yellow "networking.sh not found in the current directory. Downloading it from GitHub."
Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/microsoft/WSL/master/diagnostics/networking.sh" -OutFile $networkingBashScript
}
# Detect the super user (uid=0, not necessarily named "root" - see #11693)
$superUser = & wsl.exe -- id -nu 0
# Collect Linux & Windows network state before the repro
& wsl.exe -u $superUser -e $networkingBashScript 2>&1 > $folder/linux_network_configuration_before.log
Collect-WindowsNetworkState -Folder $folder -ReproStep "before_repro"
if ($RestartWslReproMode)
{
# The WSL HNS network is created once per boot. Resetting it to collect network creation logs.
# Note: The below HNS command applies only to WSL in NAT mode
Get-HnsNetwork | Where-Object {$_.Name -eq 'WSL' -Or $_.Name -eq 'WSL (Hyper-V firewall)'} | Remove-HnsNetwork
# Stop WSL
net.exe stop WslService
if(-not $?) { net.exe stop LxssManager }
}
}
reg.exe export HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss $folder/HKCU.txt 2>&1 | Out-Null
reg.exe export HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Lxss $folder/HKLM.txt 2>&1 | Out-Null
reg.exe export HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\P9NP $folder/P9NP.txt 2>&1 | Out-Null
@ -106,6 +174,24 @@ if ($LastExitCode -Ne 0)
}
}
# Start networking-specific captures
$tcpdumpProcess = $null
if ($LogProfile -eq "networking")
{
pktmon start -c --flags 0x1A --file-name "$folder/pktmon.etl" | out-null
netsh wfp capture start file="$folder/wfpdiag.cab"
# Ensure WSL is running before collecting network state
& wsl.exe -- true 2>&1 | Out-Null
# Start tcpdump (may not be installed)
try
{
$tcpdumpProcess = Start-Process wsl.exe -ArgumentList "-u $superUser tcpdump -n -i any -e -vvv > $folder/tcpdump.log" -WindowStyle Hidden -PassThru
}
catch {}
}
try
{
Write-Host -NoNewLine "Log collection is running. Please "
@ -151,9 +237,65 @@ try
}
finally
{
# Stop networking-specific captures
if ($LogProfile -eq "networking")
{
try
{
wsl.exe -u $superUser killall tcpdump
if ($tcpdumpProcess -ne $null)
{
Wait-Process -InputObject $tcpdumpProcess -Timeout 10
}
}
catch {}
netsh wfp capture stop
pktmon stop | out-null
}
wpr.exe -stop $folder/logs.etl 2>&1 >> $wprOutputLog
}
# Networking-specific post-repro collection
if ($LogProfile -eq "networking")
{
# Collect Linux & Windows network state after the repro
& wsl.exe -u $superUser -e $networkingBashScript 2>&1 > $folder/linux_network_configuration_after.log
Collect-WindowsNetworkState -Folder $folder -ReproStep "after_repro"
try
{
# Collect HNS events from past 24 hours
$events = Get-WinEvent -ProviderName Microsoft-Windows-Host-Network-Service | Where-Object { $_.TimeCreated -ge ((Get-Date) - (New-TimeSpan -Day 1)) }
($events | ForEach-Object { '{0},{1},{2},{3}' -f $_.TimeCreated, $_.Id, $_.LevelDisplayName, $_.Message }) -join [environment]::NewLine | Out-File -FilePath "$folder/hns_events.log" -Append
}
catch {}
# Collect the old Tcpip6 registry values - as they can break WSL if DisabledComponents is set to 0xff
# see https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-ipv6-in-windows
try
{
Get-Item HKLM:SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters | Out-File -FilePath "$folder/tcpip6_parameters.log" -Append
}
catch {}
# Collect the setup and NetSetup log files
$netSetupPath = "$env:WINDIR/logs/netsetup"
if (Test-Path $netSetupPath)
{
Copy-Item $netSetupPath/* $folder
}
$setupApiPath = "$env:WINDIR/inf/setupapi.dev.log"
if (Test-Path $setupApiPath)
{
Copy-Item $setupApiPath $folder
}
Remove-Item $networkingBashScript
}
if ($Dump)
{
$Assembly = [PSObject].Assembly.GetType('System.Management.Automation.WindowsErrorReporting')

View File

@ -21,7 +21,7 @@ logs_rules:
The script will output the path of the log file once done.
If this is a networking issue, please use [collect-networking-logs.ps1](https://github.com/Microsoft/WSL/blob/master/diagnostics/collect-networking-logs.ps1), following the instructions in [Collect WSL logs for networking issues](https://github.com/microsoft/WSL/blob/master/CONTRIBUTING.md#collect-wsl-logs-for-networking-issues)
If this is a networking issue, please use `.\collect-wsl-logs.ps1 -LogProfile networking` instead, following the instructions in [Collect WSL logs for networking issues](https://github.com/microsoft/WSL/blob/master/CONTRIBUTING.md#collect-wsl-logs-for-networking-issues)
Once completed please upload the output files to this GitHub issue.