PowerShell 技能连载 - WSL 集成与互操作

适用于 PowerShell 7.0 及以上版本

Windows Subsystem for Linux (WSL) 已经从一个实验性的兼容层发展为成熟的 Linux 运行环境。WSL2 基于真正的 Linux 内核,支持 systemd、Docker 以及绝大多数原生 Linux 应用。对于日常在 Windows 上工作的运维工程师和开发者来说,WSL 提供了一条低成本的 Linux 工具链接入路径——无需双系统,无需虚拟机管理程序的开销。

PowerShell 与 WSL 的互操作不仅限于简单的命令转发。借助 wsl 命令行工具、\\wsl$ 网络路径以及双向的进程调用机制,可以在一个脚本中自由混合 Windows 和 Linux 工具。例如,用 PowerShell 采集 Windows 事件日志,再通过管道传给 WSL 中的 awk 做文本分析;或者反过来,在 WSL 中编译项目后调用 PowerShell 部署到 Windows 服务。这种混合工作流在 DevOps 和跨平台自动化场景中尤为实用。

本文将从实例管理、跨平台数据交换和自动化部署三个维度,展示 PowerShell 与 WSL 深度集成的实战技巧。

管理 WSL 实例生命周期

日常工作中,我们经常需要创建、备份、迁移 WSL 实例。PowerShell 可以把 wsl.exe 的能力封装成可复用的管理函数,实现实例的批量运维。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# 定义 WSL 实例管理工具集
function Get-WslInstance {
<# 获取所有 WSL 发行版的详细信息 #>
$raw = wsl --list --verbose 2>&1
$lines = $raw | Select-Object -Skip 2 | Where-Object { $_ -match '\S' }

foreach ($line in $lines) {
$parts = $line.Trim() -split '\s+'
[PSCustomObject]@{
IsDefault = $line -match '^\*'
Name = $parts[0] -replace '^\*', ''
State = $parts[1]
Version = $parts[2]
}
}
}

function Export-WslInstance {
<# 将 WSL 实例导出为 tar 文件,用于备份或迁移 #>
param(
[Parameter(Mandatory)][string]$Name,
[Parameter(Mandatory)][string]$OutputPath
)

if (-not (Test-Path (Split-Path $OutputPath -Parent))) {
New-Item -ItemType Directory -Path (Split-Path $OutputPath -Parent) -Force |
Out-Null
}

Write-Host "正在导出 $Name ..." -ForegroundColor Cyan
wsl --export $Name $OutputPath

$size = [math]::Round((Get-Item $OutputPath).Length / 1GB, 2)
Write-Host "导出完成:$OutputPath (${size} GB)" -ForegroundColor Green
}

function Import-WslInstance {
<# 从 tar 文件导入为新的 WSL 实例 #>
param(
[Parameter(Mandatory)][string]$Name,
[Parameter(Mandatory)][string]$InstallPath,
[Parameter(Mandatory)][string]$SourceFile
)

if (-not (Test-Path $InstallPath)) {
New-Item -ItemType Directory -Path $InstallPath -Force | Out-Null
}

Write-Host "正在导入 $Name ..." -ForegroundColor Cyan
wsl --import $Name $InstallPath $SourceFile
Write-Host "导入完成:$Name => $InstallPath" -ForegroundColor Green
}

function Remove-WslInstance {
<# 注销并删除 WSL 实例(谨慎使用) #>
param(
[Parameter(Mandatory)][string]$Name,
[switch]$Force
)

if (-not $Force) {
$confirm = Read-Host "确认要删除 WSL 实例 '$Name' 吗?(yes/no)"
if ($confirm -ne 'yes') {
Write-Host "已取消" -ForegroundColor Yellow
return
}
}

wsl --unregister $Name
Write-Host "已删除 WSL 实例:$Name" -ForegroundColor Red
}

# 批量备份所有运行中的实例
$instances = Get-WslInstance | Where-Object State -eq 'Running'
$backupDir = "D:\WSL-Backups\$(Get-Date -Format 'yyyyMMdd')"

foreach ($inst in $instances) {
$tar = Join-Path $backupDir "$($inst.Name).tar"
Export-WslInstance -Name $inst.Name -OutputPath $tar
}

执行结果示例:

1
2
3
4
正在导出 Ubuntu-24.04 ...
导出完成:D:\WSL-Backups\20251217\Ubuntu-24.04.tar (1.85 GB)
正在导出 Debian ...
导出完成:D:\WSL-Backups\20251217\Debian.tar (0.92 GB)

跨平台命令调用与数据交换

PowerShell 与 WSL 之间的数据交换是互操作的核心。下面展示几种常见模式:结构化数据传递、环境变量共享,以及双向脚本编排。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 封装一个通用的 WSL 命令执行器
function Invoke-WslCommand {
param(
[Parameter(Mandatory)][string]$Command,
[string]$Distribution,
[switch]$AsJson
)

$args = @()
if ($Distribution) { $args += '-d', $Distribution }
$args += '--', 'bash', '-c', $Command

$result = & wsl @args 2>&1
$result = $result | Out-String

if ($AsJson -and $result) {
try {
return $result | ConvertFrom-Json
} catch {
Write-Warning "JSON 解析失败,返回原始文本"
return $result
}
}
return $result.Trim()
}

# 场景 1:用 Linux 工具分析 Windows 日志
# 先用 PowerShell 导出事件日志为 CSV,再用 WSL 的 awk 统计
$csvPath = "$env:TEMP\security_events.csv"
Get-WinEvent -LogName Security -MaxEvents 500 |
Select-Object TimeCreated, Id, LevelDisplayName, Message |
Export-Csv $csvPath -NoTypeInformation -Encoding UTF8

# 将 Windows 路径转为 WSL 可访问的路径
$wslCsv = ($csvPath -replace '^([A-Z]):', { '/mnt/' + $_.Groups[1].Value.ToLower() } `
-replace '\\', '/')

$stats = Invoke-WslCommand "awk -F',' '{print `$3}' $wslCsv | sort | uniq -c | sort -rn"
Write-Host "安全事件级别分布:" -ForegroundColor Cyan
Write-Host $stats

# 场景 2:从 WSL 获取系统信息,返回结构化对象
$sysInfo = Invoke-WslCommand -AsJson -Command @"
cat /etc/os-release | grep -E '^(NAME|VERSION)=' | while IFS='=' read -r k v; do echo "\"`$k\": \"`$v\","; done | sed '1s/^/{/;$s/,$/}/'
"@

if ($sysInfo -is [string]) {
# 备用方案:手动收集
$osName = (Invoke-WslCommand "cat /etc/os-release | grep '^NAME=' | cut -d'=' -f2").Trim('"')
$osVer = (Invoke-WslCommand "cat /etc/os-release | grep '^VERSION=' | cut -d'=' -f2").Trim('"')
$sysInfo = [PSCustomObject]@{ NAME = $osName; VERSION = $osVer }
}

Write-Host "`nWSL 系统信息:" -ForegroundColor Cyan
Write-Host " 发行版:$($sysInfo.NAME)"
Write-Host " 版本:$($sysInfo.VERSION)"

# 场景 3:利用 WSL 中独有的工具处理数据
# 使用 xq(jq 的 XML 版本)解析 Windows 无法原生处理的 XML
$xmlReport = Invoke-WslCommand @"
if command -v xq &>/dev/null; then
curl -s https://example.com/feed.xml | xq '.rss.channel.item[] | .title' 2>/dev/null
else
echo 'xq not installed, fallback to xmlstarlet'
curl -s https://example.com/feed.xml | xmlstarlet sel -t -m '//item/title' -v '.' -n 2>/dev/null
fi
"@

Write-Host "`nRSS 标题提取:" -ForegroundColor Cyan
Write-Host $xmlReport

执行结果示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
安全事件级别分布:
420 信息
45 审核
28 警告
7 错误

WSL 系统信息:
发行版:Ubuntu
版本:24.04.1 LTS (Noble Numbat)

RSS 标题提取:
PowerShell 7.5 发布:新特性一览
.NET 9 正式可用
Azure 新增多云管理功能

自动化部署场景:混合 Windows/Linux 工具链

在实际的 CI/CD 和运维自动化中,经常需要将 Windows 原生工具与 Linux 工具链串联起来。下面的示例展示了一个完整的混合部署脚本:在 WSL 中编译 Node.js 项目,然后在 Windows 上完成 IIS 部署。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# 混合平台部署脚本
function Invoke-HybridDeploy {
param(
[string]$ProjectName = "webapp",
[string]$WslProjectPath = "/home/user/projects/$ProjectName",
[string]$WinDeployPath = "C:\inetpub\wwwroot\$ProjectName",
[string]$Distribution = "Ubuntu-24.04"
)

# 阶段 1:在 WSL 中拉取代码并构建
Write-Host "`n[1/4] 在 WSL 中拉取最新代码..." -ForegroundColor Cyan
$pullResult = Invoke-WslCommand -Distribution $Distribution -Command @"
cd $WslProjectPath && git pull origin main 2>&1 | tail -5
"@
Write-Host $pullResult

# 阶段 2:在 WSL 中执行 npm 构建
Write-Host "`n[2/4] 在 WSL 中执行构建..." -ForegroundColor Cyan
$buildResult = Invoke-WslCommand -Distribution $Distribution -Command @"
cd $WslProjectPath &&
npm ci --prefer-offline 2>&1 | tail -3 &&
npm run build 2>&1 | tail -5
"@
Write-Host $buildResult

# 阶段 3:将构建产物从 WSL 文件系统复制到 Windows
Write-Host "`n[3/4] 复制构建产物到 Windows..." -ForegroundColor Cyan
$wslDistPath = "\\wsl$\$Distribution$WslProjectPath\dist"

if (Test-Path $WinDeployPath) {
$backup = "$WinDeployPath.bak.$(Get-Date -Format 'yyyyMMdd_HHmmss')"
Move-Item $WinDeployPath $backup -Force
Write-Host "已备份旧版本到 $backup" -ForegroundColor Yellow
}

Copy-Item $wslDistPath $WinDeployPath -Recurse -Force
$fileCount = (Get-ChildItem $WinDeployPath -Recurse -File).Count
Write-Host "已复制 $fileCount 个文件到 $WinDeployPath" -ForegroundColor Green

# 阶段 4:用 PowerShell 进行 Windows 端配置
Write-Host "`n[4/4] 更新 IIS 配置..." -ForegroundColor Cyan

# 确保 IIS 应用池存在
$poolName = "${ProjectName}Pool"
if (-not (Get-IISAppPool -Name $poolName -ErrorAction SilentlyContinue)) {
New-IISAppPool -Name $poolName -Force
Write-Host "已创建应用池:$poolName"
}

# 更新站点物理路径
$site = Get-IISSite -Name $ProjectName -ErrorAction SilentlyContinue
if ($site) {
$site.Applications["/"].VirtualDirectories["/"].PhysicalPath = $WinDeployPath
Write-Host "已更新站点路径" -ForegroundColor Green
}

# 验证部署结果
$indexPath = Join-Path $WinDeployPath "index.html"
if (Test-Path $indexPath) {
$hash = (Get-FileHash $indexPath -Algorithm SHA256).Hash.Substring(0, 16)
Write-Host "`n部署成功!index.html 校验:$hash" -ForegroundColor Green
}

# 阶段 5:健康检查(用 WSL 中的 curl)
Write-Host "`n健康检查..." -ForegroundColor Cyan
$health = Invoke-WslCommand -Distribution $Distribution -Command @"
curl -sS -o /dev/null -w '%{http_code} %{time_total}s' http://localhost:8080/ 2>/dev/null || echo 'unreachable'
"@
Write-Host "HTTP 状态:$health"
}

# 执行部署
Invoke-HybridDeploy -ProjectName "webapp"

执行结果示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[1/4] 在 WSL 中拉取最新代码...
Already up to date.
Updating 3f2a1b0..7c8d9e0
Fast-forward
src/App.js | 12 ++++++------
2 files changed, 6 insertions(+), 6 deletions(-)

[2/4] 在 WSL 中执行构建...
added 245 packages in 3.2s
> webapp@1.0.0 build
> vite build
✓ built in 4.21s

[3/4] 复制构建产物到 Windows...
已备份旧版本到 C:\inetpub\wwwroot\webapp.bak.20251217_083000
已复制 42 个文件到 C:\inetpub\wwwroot\webapp

[4/4] 更新 IIS 配置...
已更新站点路径

部署成功!index.html 校验:A3F8B2C1D4E5F607

健康检查...
HTTP 状态:200 0.032s

注意事项

  1. 路径风格转换:Windows 路径(C:\Users\)和 WSL 路径(/mnt/c/Users/)之间转换时,注意盘符大小写和斜杠方向,建议封装通用的转换函数避免手动拼接出错。
  2. \\wsl$ 网络路径性能:通过 \\wsl$\ 访问 WSL 文件系统比 /mnt/c 跨分区访问快得多,大文件操作优先在 WSL 原生文件系统中完成后再复制到 Windows。
  3. 环境变量隔离:Windows 和 WSL 的环境变量相互独立,$env:PATH 不会自动共享。如果需要传递变量,使用 WSLENV 配置共享映射规则。
  4. 并发安全:多个 PowerShell 脚本同时向同一个 WSL 实例发送命令可能导致输出交错,生产环境中建议对 WSL 调用加锁或使用独立实例。
  5. 退出码传递wsl -- command$LASTEXITCODE 返回的是 Linux 进程的退出码,但经过 PowerShell 管道处理后可能丢失,关键操作建议显式检查输出内容而非仅依赖退出码。
  6. 换行符陷阱:WSL 输出是 LF 换行,Windows 文件默认 CRLF。跨系统写入文本文件时注意使用统一的编码和换行符,否则可能导致配置文件解析失败。

PowerShell 技能连载 - WSL 集成操作

适用于 PowerShell 5.1 及以上版本(Windows),需要安装 WSL

Windows Subsystem for Linux (WSL) 让 Windows 和 Linux 无缝协作——在 Windows 上运行 Linux 工具链,同时享受 Windows 的图形界面和生态。PowerShell 可以通过 wsl 命令与 WSL 交互,调用 Linux 命令、管理 WSL 发行版、在两个环境之间传递数据。这种能力让运维人员可以在一个终端中同时使用 PowerShell 和 Bash 的优势。

本文将讲解 PowerShell 与 WSL 的集成操作技巧。

WSL 基本管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 查看已安装的 WSL 发行版
wsl --list --verbose

# 安装新的发行版
# wsl --install -d Ubuntu-24.04

# 设置默认发行版
wsl --set-default Ubuntu-24.04

# 管理 WSL 实例
function Get-WslDistributions {
$output = wsl --list --verbose 2>&1
# 解析输出(跳过标题行)
$lines = $output | Select-Object -Skip 2 | Where-Object { $_.Trim() }

foreach ($line in $lines) {
$parts = $line.Trim() -split '\s+'
if ($parts.Count -ge 3) {
$isDefault = $line -match '^\*'
[PSCustomObject]@{
IsDefault = $isDefault
Name = $parts[0] -replace '^\*', ''
State = $parts[1]
Version = $parts[2]
}
}
}
}

Get-WslDistributions | Format-Table -AutoSize

# 启动/停止 WSL
function Start-WslInstance {
param([string]$Distribution = "Ubuntu-24.04")

Write-Host "启动 WSL:$Distribution" -ForegroundColor Cyan
wsl -d $Distribution -- echo "WSL $Distribution 已启动"
}

function Stop-WslInstance {
param([string]$Distribution)

if ($Distribution) {
wsl -t $Distribution
Write-Host "已停止 WSL:$Distribution" -ForegroundColor Yellow
} else {
wsl --shutdown
Write-Host "已停止所有 WSL 实例" -ForegroundColor Yellow
}
}

# 查看 WSL 资源使用
function Get-WslResourceUsage {
$output = wsl -- bash -c "free -h && echo '---' && df -h / && echo '---' && nproc"
Write-Host $output
}

Get-WslResourceUsage

执行结果示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  NAME            STATE       VERSION
* Ubuntu-24.04 Running 2
Debian Stopped 2

IsDefault Name State Version
--------- ---- ----- -------
True Ubuntu-24.04 Running 2
False Debian Stopped 2

启动 WSL:Ubuntu-24.04
WSL Ubuntu-24.04 已启动

total used free
Mem: 15Gi 4.2Gi 11Gi
Swap: 4.0Gi 0B 4.0Gi
---
Filesystem Size Used Avail Use% Mounted on
/dev/sdb 250G 45G 205G 18% /
---
8

跨系统命令调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 从 PowerShell 调用 Linux 命令
function Invoke-WslCommand {
param(
[Parameter(Mandatory)]
[string]$Command,

[string]$Distribution = "Ubuntu-24.04"
)

$result = wsl -d $Distribution -- bash -c $Command 2>&1
return $result
}

# 使用 Linux 工具处理数据
# 用 grep 过滤日志
$nginxErrors = Invoke-WslCommand "grep -c 'ERROR' /var/log/nginx/error.log 2>/dev/null || echo 0"
Write-Host "Nginx 错误数:$nginxErrors"

# 用 awk 处理 CSV
$awkResult = Invoke-WslCommand @"
awk -F',' '{sum += $3; count++} END {print "Average:", sum/count}' /tmp/data.csv
"@
Write-Host "AWK 结果:$awkResult"

# 用 jq 处理 JSON
$jsonResult = Invoke-WslCommand "echo '{\"name\":\"test\",\"value\":42}' | jq '.value'"
Write-Host "JSON 处理:$jsonResult"

# 用 find 查找文件
$found = Invoke-WslCommand "find /home -name '*.sh' -mtime -7 2>/dev/null | head -10"
Write-Host "最近修改的脚本:`n$found"

# 从 WSL 调用 PowerShell(反向调用)
$psResult = wsl -- powershell.exe -Command "Get-Date -Format 'yyyy-MM-dd HH:mm:ss'"
Write-Host "从 WSL 调用 PowerShell:$psResult"

# 混合管道:PowerShell 采集数据,Linux 处理
$processes = Get-Process | Select-Object Name, CPU,
@{N='MemMB'; E={[math]::Round($_.WorkingSet64/1MB,1)}} |
ConvertTo-Csv -NoTypeInformation

# 通过管道传给 Linux sort
$sorted = $processes | wsl -- sort -t',' -k3 -rn | wsl -- head -5
Write-Host "`n内存排序 Top 5(Linux sort):" -ForegroundColor Cyan
Write-Host $sorted

执行结果示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Nginx 错误数:23
JSON 处理:42

最近修改的脚本:
/home/user/scripts/backup.sh
/home/user/scripts/deploy.sh

从 WSL 调用 PowerShell:2025-07-25 08:30:15

内存排序 Top 5(Linux sort):
"chrome",1250.34,512.5
"vscode",234.56,345.2
"node",456.78,256.3
"msedge",345.12,198.7
"powershell",123.45,85.6

文件系统互操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 从 Windows 访问 WSL 文件
# WSL 文件系统在 \\wsl$\<发行版名>\ 下
$wslHome = "\\wsl$\Ubuntu-24.04\home"
Write-Host "WSL Home 目录内容:" -ForegroundColor Cyan
Get-ChildItem $wslHome | Select-Object Name, Length, LastWriteTime |
Format-Table -AutoSize

# 从 WSL 访问 Windows 文件
# Windows 的 C 盘在 WSL 中是 /mnt/c/
Invoke-WslCommand "ls /mnt/c/Users/$env:USERNAME/Desktop | head -5"

# 双向文件复制
function Copy-WslFile {
param(
[Parameter(Mandatory)][string]$Source,
[Parameter(Mandatory)][string]$Destination,
[ValidateSet("WindowsToWsl", "WslToWindows")]
[string]$Direction = "WindowsToWsl"
)

if ($Direction -eq "WindowsToWsl") {
# Windows 路径转 WSL 路径
$wslSource = $Source -replace '^([A-Z]):', '/mnt/$1' -replace '\\', '/'
$wslDest = $Destination
wsl -- cp -r $wslSource $wslDest
Write-Host "已复制(Win->WSL):$Source => $Destination" -ForegroundColor Green
} else {
$wslSource = $Source
$winDest = $Destination
wsl -- cp -r $wslSource "/mnt/c/$($winDest -replace '^([A-Z]):\\' , { $_.Groups[1].Value.ToLower() + '/' } -replace '\\', '/')"
Write-Host "已复制(WSL->Win):$Source => $Destination" -ForegroundColor Green
}
}

# 同步项目目录到 WSL
$projectDir = "C:\Projects\MyApp"
$wslDest = "/home/user/projects/"
Copy-WslFile -Source $projectDir -Destination $wslDest -Direction WindowsToWsl

# 在 WSL 中执行构建
Invoke-WslCommand "cd /home/user/projects/MyApp && make build"

执行结果示例:

1
2
3
4
5
6
7
8
9
10
11
12
WSL Home 目录内容:
Name Length LastWriteTime
---- ------ -------------
user 0 2025-07-25 08:00:00
projects 0 2025-07-25 08:00:00
scripts 0 2025-07-25 08:00:00

Desktop
Documents
Downloads
已复制(Win->WSL):C:\Projects\MyApp => /home/user/projects/
Build complete.

开发环境管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 在 WSL 中管理开发环境
function Enter-WslDev {
param(
[string]$Distribution = "Ubuntu-24.04",
[string]$ProjectPath = "/home/user/projects"
)

Write-Host "进入 WSL 开发环境..." -ForegroundColor Cyan
wsl -d $Distribution -- cd $ProjectPath '&&' bash -l
}

# 检查 WSL 中的开发工具
function Test-WslDevTools {
$tools = @(
@{ Name = "git"; Command = "git --version" },
@{ Name = "node"; Command = "node --version" },
@{ Name = "python"; Command = "python3 --version" },
@{ Name = "docker"; Command = "docker --version" },
@{ Name = "make"; Command = "make --version | head -1" }
)

Write-Host "WSL 开发工具检查:" -ForegroundColor Cyan

foreach ($tool in $tools) {
try {
$version = (Invoke-WslCommand $tool.Command 2>&1) | Select-Object -First 1
if ($LASTEXITCODE -eq 0 -or $version) {
Write-Host " $($tool.Name):$version" -ForegroundColor Green
} else {
Write-Host " $($tool.Name):未安装" -ForegroundColor Yellow
}
} catch {
Write-Host " $($tool.Name):未安装" -ForegroundColor Yellow
}
}
}

Test-WslDevTools

# 在 WSL 中运行 Docker
function Invoke-WslDocker {
param(
[Parameter(Mandatory)]
[string]$Image,

[string]$Command = "echo 'Container running'"
)

$dockerCmd = "docker run --rm $Image bash -c '$Command'"
$result = Invoke-WslCommand $dockerCmd
Write-Host $result
}

# 快速启动 MySQL 测试容器
Invoke-WslDocker -Image "mysql:8.0" -Command "mysql --version"

执行结果示例:

1
2
3
4
5
6
7
8
WSL 开发工具检查:
git:git version 2.45.1
node:v20.14.0
python:Python 3.12.4
docker:Docker version 26.1.3
make:GNU Make 4.3

mysql Ver 8.0.38 for Linux on x86_64 (MySQL Community Server - GPL)

注意事项

  1. 路径转换:Windows 使用反斜杠和盘符(C:\),WSL 使用正斜杠和 /mnt/c/,注意转换
  2. 性能差异:跨文件系统(/mnt/c/)的 IO 性能远低于 WSL 原生文件系统(~/
  3. 换行符:Windows 用 \r\n,Linux 用 \n,跨系统处理文本时注意换行符转换
  4. 网络访问:WSL2 有独立的虚拟网络,从 WSL 访问 Windows 服务使用 $(hostname).local
  5. systemd 支持:WSL2 支持 systemd,需要在 /etc/wsl.conf 中启用
  6. 内存限制:WSL2 默认使用系统一半内存,可通过 .wslconfig 文件配置