Windows Server 2019 IIS环境下PHP shell_exec执行失败权限排查
IIS+PHP环境下shell_exec执行cmd打开ppsx权限拒绝问题排查
问题现象
在Windows Server 2019的IIS环境中部署PHP页面,调用shell_exec执行cmd命令打开指定ppsx文件时提示权限拒绝。已配置拥有所有文件、文件夹及cmd.exe完全访问权限的网络管理员账号运行程序,但问题依旧;本地VS Code的PHP开发环境无此异常。
页面功能说明
点击页面按钮后,会临时打开OpenPPT.php页面执行shell_exec,随后关闭该页面并打开下拉框对应的ppsx文件。
相关代码
主页面代码
<!DOCTYPE html> <?php session_start(); require 'Includes/GlobalVariables.php'; require 'Includes/Session.php'; require 'Includes/Conn.php'; require 'Includes/Redirect.php'; ?> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CI Process Program</title> <link rel="shortcut icon" type="image/x-icon" href="icon/Hi-Temp.ico"> <link rel="stylesheet" href="css/styles.css"> </head> <noscript> <p> This page needs JavaScript activated to work properly.<br> Please return here with Javascript enabled in order to open files appropriately. </p> <style> body { display: none; } </style> </noscript> <body> <section class="container2"> <?php if (!$error == ""){echo $error;} ?> <?php include 'Includes/BodyHeader.php'; ?> <form id="CIForm" method="post" target="_blank" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>"> <div class="formContainer"> <div class="formOption"> <select type="text" class="number" name="number" id="number"> <?php foreach ($pdoObj -> query($sql) as $row): $selected=($row['Part Number'] == $entry)? "selected" : ''; echo '<option '.$selected.' value="'.$row["Part Number"].'">'.$row["Part Number"].'</option>';?> <?php endforeach ?> </select> <button type="submit" name="submit" class="button1" onclick="submitForm('OpenPPT.php')">Open PPSX</button> <!--<button type="submit" name="submit" class="button2" onclick="submitForm('OpenVideo.php')">Open Demonstration Video</button> --> </div> </div> </form> <form id="Logout1" method=post action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>"> <button type="submit" name="submit" class="button3 logOnOut" id="Logout" onclick="submitForm2('Logout.php')">Logout</button> </form> <?php include 'Includes/BodyFooter.php'; ?> </section> </body> <script type="text/javascript" src="js\script.js"></script> </html>
OpenPPT.php代码
<?php session_start(); require 'Includes/Redirect.php'; $Part = $_POST['number']; $Part = str_replace('-MS','',$Part); $Part = str_replace('MS','',$Part); $dir = '\\\\server\\share\\Visual Files\\'; $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); foreach ($iterator as $filename => $file) { $path = pathinfo($filename); if ($path['basename'] == $Part.'.ppsx') { $mainPath = $path['dirname']; $ppsxFile = $path['basename']; } } if (isset($ppsxFile)){ echo 'test'; shell_exec('cmd.exe @cmd /C (start "" "'.$mainPath.'\\'.$ppsxFile.'")'); }else{ shell_exec('cmd.exe @cmd /C (msg %username% "File "'.$Part.'.ppsx" Does not exist.")'); }; echo "<script>window.close();</script>"; ?>
补充信息
- 手动在服务器命令行执行对应cmd命令可正常运行,无需提升权限;
- 代码中
echo 'test'可正常输出,说明ppsxFile变量已正确设置,但shell_exec未生效; - 已尝试修改应用池标识为网络管理员、设置IIS文件夹权限等操作,问题仍未解决。
解决方案
1. 开启应用池的用户配置文件加载
Windows服务默认无桌面交互权限,而Office组件启动依赖桌面会话:
- 打开IIS管理器,找到对应应用池 -> 高级设置;
- 将加载用户配置文件设置为
True; - 打开服务器的服务管理器,找到对应应用池的
w3wp服务,在属性的登录标签页勾选允许服务与桌面交互。
2. 调整命令执行方式
原start命令在无桌面会话环境下无法触发Office程序,可改用PowerShell或直接调用Office程序:
// 改用PowerShell启动 shell_exec('powershell.exe -Command "Start-Process \''.$mainPath.'\\'.$ppsxFile.'\'"');
或直接指定PowerPoint路径(需根据实际安装路径调整):
shell_exec('"C:\Program Files\Microsoft Office\root\Office16\POWERPNT.EXE" "'.$mainPath.'\\'.$ppsxFile.'"');
3. 验证共享文件夹权限
除本地权限外,需确保应用池账号对\\server\share\Visual Files\拥有读取和执行权限:
- 右键共享文件夹 -> 属性 -> 共享 -> 高级共享 -> 权限,添加应用池账号并赋予对应权限;
- 切换到安全标签页,同步配置应用池账号的权限。
4. 排查UAC限制
Windows Server的UAC可能限制服务账号操作:
- 打开本地安全策略 -> 本地策略 -> 安全选项,找到用户账户控制:以管理员批准模式运行所有管理员,设置为
禁用(需重启服务器,谨慎操作); - 或在命令中使用
runas指定管理员账号,但需避免硬编码密码。
5. 输出命令日志排查
为shell_exec添加日志输出,定位具体错误:
$cmd = 'cmd.exe @cmd /C (start "" "'.$mainPath.'\\'.$ppsxFile.'") 2>&1'; $output = shell_exec($cmd); file_put_contents('cmd_error_log.txt', $output);
查看生成的cmd_error_log.txt文件,获取详细错误信息。
内容的提问来源于stack exchange,提问作者James Davis
相关产品推荐
相关产品推荐

