You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过PHP正常运行PowerShell脚本?

问题:PHP调用PowerShell脚本未执行预期操作

1. 场景与现象

通过PHP代码调用PowerShell脚本时,脚本未执行预期的哈希计算与数据库插入操作,但直接在命令行用相同参数启动脚本则完全正常。

PHP调用代码

$hashingCommand = "start powershell -file C:\Apache24\htdocs\\runHashCalc.ps1 \\\$sAddr \\\$dAddr $name $algorithm";
pclose(popen($hashingCommand, 'r'));

WMIC捕获的实际执行命令

C:\>WMIC path win32_process get Caption,ProcessId,Commandline | findstr "testingCopyJob"
powershell.exe            powershell  -file C:\Apache24\htdocs\runHashCalc.ps1 \\ACTUALPATH\netstorage\User \\ACTUALPATH\netstorage\copyfolder testingCopyJob sha256  5036

命令行直接执行的正常输出

C:\>powershell  -file C:\Apache24\htdocs\runHashCalc.ps1 \\ACTUALPATH\netstorage\User \\ACTUALPATH\netstorage\copyfolder testingCopyJob sha256
 \\config.sample.inc.php
sha256
mariadb --user=username --password=******* -e 'INSERT INTO testingCopyJob (file_name,hash) VALUES (' \\config.sample.inc.php',' 8AA4CE89D12978E805C6A128745A1A885A1E6523220C6647886DC74DC13F421A')' *****_xsw
[...]

2. PowerShell脚本核心代码

[...]
gci -af -rec $sourceFolder | Foreach-Object {
    $cmd = Get-FileHash $_.FullName -Algorithm $algorithm | Format-List
    $asString = $cmd | ft | out-string
    $answerArray = $asString.Split([System.Environment]::NewLine,[System.StringSplitOptions]::RemoveEmptyEntries)
    $hash = $answerArray[1].Split(":")[1]
    $path = $answerArray[2] -split ':',2
    $aPath = $path[1]
    $aPath=$aPath.Replace($sourceFolder,'')
    $aPath=$aPath.Replace('\','\\')
    write-host $aPath | Out-File -FilePath C:\Apache24\htdocs\hashlog.log -Append
    write-host $algorithm | Out-File -FilePath C:\Apache24\htdocs\hashlog.log -Append
    write-host "mariadb --user=user --password=******* -e 'INSERT INTO $name (file_name,hash) VALUES ('$aPath','$hash')' *****_xsw" | Out-File -FilePath C:\Apache24\htdocs\hashlog.log -Append
    $answer = mariadb --user=user --password=******* -e "INSERT INTO $name (file_name,hash,source) VALUES ('$aPath','$hash',0)" *****_xsw
    write-host $answer | Out-File -FilePath C:\Apache24\htdocs\hashlog.log -Append
}
[...]

注:原脚本用write-host无法生成日志,改用write-output后日志正常,但核心操作仍未执行。

3. 故障原因分析

  • 权限不匹配:PHP运行在Apache服务账户(通常为NT AUTHORITY\SYSTEM或IUSR)下,该账户可能无网络共享路径访问权限、MariaDB写入权限,或部分目录操作权限。
  • 参数传递异常:WMIC显示命令末尾多了5036(疑似进程ID被错误追加),导致脚本接收的参数数量超出预期,逻辑执行出错。
  • 执行环境差异:服务账户的PowerShell环境未加载必要配置,或mariadb不在其PATH变量中,导致命令无法找到。
  • 字符串解析缺陷:通过解析Format-List/ft的格式化输出来提取哈希和路径,依赖输出格式稳定性,一旦环境(如本地化)变化就会解析失败,无法获取正确的$hash和$aPath。

4. 解决办法

修复权限问题

  • 给Apache服务账户授予网络共享路径的读取权限、MariaDB数据库的写入权限,确保日志目录的写入权限。

修正参数传递

修改PHP代码,避免start命令导致的额外参数追加,用escapeshellarg处理参数转义:

$sAddrEscaped = escapeshellarg($sAddr);
$dAddrEscaped = escapeshellarg($dAddr);
$nameEscaped = escapeshellarg($name);
$algorithmEscaped = escapeshellarg($algorithm);
$hashingCommand = "powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\\Apache24\\htdocs\\runHashCalc.ps1 $sAddrEscaped $dAddrEscaped $nameEscaped $algorithmEscaped";
pclose(popen($hashingCommand, 'r'));

统一执行环境

  • 在PowerShell脚本中指定mariadb的完整路径(如C:\Program Files\MariaDB\bin\mariadb.exe),避免依赖PATH变量。
  • 添加-NoProfile参数,避免加载不必要的用户配置,保证执行环境一致。

优化字符串处理逻辑

放弃解析格式化输出,直接使用Get-FileHash的对象属性,同时修复SQL注入风险:

gci -af -rec $sourceFolder | Foreach-Object {
    $fileHash = Get-FileHash $_.FullName -Algorithm $algorithm
    $hash = $fileHash.Hash.Trim()
    $aPath = $_.FullName.Replace($sourceFolder, '')
    $aPath = $aPath.Replace('\', '\\').Trim()
    
    # 输出日志
    Write-Output $aPath | Out-File -FilePath C:\Apache24\htdocs\hashlog.log -Append
    Write-Output $algorithm | Out-File -FilePath C:\Apache24\htdocs\hashlog.log -Append
    
    # 转义单引号避免SQL注入
    $safePath = $aPath -replace "'", "''"
    $sql = "INSERT INTO $name (file_name,hash,source) VALUES ('$safePath','$hash',0)"
    Write-Output "mariadb --user=user --password=******* -e `"$sql`" *****_xsw" | Out-File -FilePath C:\Apache24\htdocs\hashlog.log -Append
    
    $answer = & "C:\Program Files\MariaDB\bin\mariadb.exe" --user=user --password=******* -e $sql *****_xsw
    Write-Output $answer | Out-File -FilePath C:\Apache24\htdocs\hashlog.log -Append
}

内容的提问来源于stack exchange,提问作者Monocito

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 18:01:23