使用Start-Process调用pnputil.exe失败问题求助
解决Start-Process调用PNPUtil失败的问题
我来帮你理清这个问题——你遇到的坑其实是PowerShell里Start-Process的参数传递逻辑和直接调用exe完全不一样,之前的写法要么没正确指定参数结构,要么变量没被展开,要么引号配对错误,导致PNPUtil接收到的参数完全不符合要求。
先说说你之前写法的问题:
- 直接把参数跟在exe后面:
Start-Process PNPUtil.exe /add-driver $item.FullName /install
这不符合Start-Process的语法,它需要用-ArgumentList(或简写-Args)来明确传递参数,否则后面的内容会被当成错误的参数名处理。 - 单引号包裹参数:
Start-Process PNPUtil -ArgumentList '/add-driver $item.FullName /install'
PowerShell里单引号内的变量不会被展开,$item.FullName会被当成字面量字符串传给PNPUtil,它自然找不到对应的驱动文件。 - 其他引号混用的写法:要么变量展开出错,要么引号配对错误,导致参数被拆分成了错误的片段,PNPUtil无法识别。
正确的写法有两种,推荐第一种:
1. 用数组传递参数(最稳妥,适配路径含空格的场景)
$Driver = Get-ChildItem "$PSScriptRoot" -Recurse -Filter "*inf" foreach ($item in $Driver) { # 用数组传递每个参数,PowerShell会自动处理空格和引号 Start-Process PNPUtil.exe -ArgumentList @('/add-driver', $item.FullName, '/install') -Wait -NoNewWindow }
这里加了两个实用参数:
-Wait:让PowerShell等待当前驱动安装完成后再处理下一个,和你直接调用的行为一致;-NoNewWindow:不在新的命令行窗口运行,输出会直接显示在当前控制台。
2. 用双引号正确展开变量(适合简单场景)
如果你习惯用字符串传递参数,要确保变量被正确展开,同时路径含空格时用转义引号包裹:
$Driver = Get-ChildItem "$PSScriptRoot" -Recurse -Filter "*inf" foreach ($item in $Driver) { # 用`"转义双引号,确保路径被正确包裹;$()确保对象属性正确展开 Start-Process PNPUtil.exe -ArgumentList "/add-driver `"$($item.FullName)`" /install" -Wait -NoNewWindow }
额外补充:捕获PNPUtil的输出
如果你需要捕获安装的输出或错误信息,直接调用可以直接捕获,但Start-Process默认不会把输出返回给当前控制台。可以用以下方式实现:
$Driver = Get-ChildItem "$PSScriptRoot" -Recurse -Filter "*inf" foreach ($item in $Driver) { $process = Start-Process PNPUtil.exe -ArgumentList @('/add-driver', $item.FullName, '/install') ` -Wait -NoNewWindow -PassThru ` -RedirectStandardOutput "install_$($item.BaseName)_out.txt" ` -RedirectStandardError "install_$($item.BaseName)_err.txt" # 查看退出码判断是否安装成功 if ($process.ExitCode -eq 0) { Write-Host "驱动 $($item.Name) 安装成功!" } else { Write-Warning "驱动 $($item.Name) 安装失败,退出码:$($process.ExitCode)" } }
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

