通过任务计划程序运行时Get-ChildItem命令失效问题
我之前也碰到过一模一样的情况——脚本手动跑完全正常,放到计划任务里就“偷懒”只执行了注册表部分,文件扫描和CSV导出完全没动静。结合你的场景,咱们一步步排查解决:
先搞清楚到底哪里出问题:加日志!
计划任务运行时看不到控制台输出,根本不知道脚本卡在哪了。先给脚本加日志,或者在计划任务的执行命令里重定向输出:
方法1:修改计划任务命令
把原来的执行命令改成:
Powershell.exe -ExecutionPolicy Bypass -File "\\server1\share1\PST_Discovery_Script.ps1" 2>&1 >> c:\PST_Discovery_Log.txt
这样所有的输出(包括错误)都会写到c:\PST_Discovery_Log.txt里,你就能看到脚本执行到哪一步挂了。
方法2:给脚本加错误捕获和日志
直接修改脚本,把每一步的执行情况都记录下来,方便精准排查:
$logPath = "c:\PST_Discovery_Log.txt" $registryPath = 'HKLM:\Software\CC\PST_Discovery_Script\Already_Run' try { Add-Content -Path $logPath -Value "[$(Get-Date)] 脚本启动" if (!(Test-Path -Path $registryPath)) { Add-Content -Path $logPath -Value "[$(Get-Date)] 未检测到注册表标记,开始扫描PST文件" $dir = "c:\Users" $ext = "pst" Add-Content -Path $logPath -Value "[$(Get-Date)] 开始遍历目录: $dir" # 强制捕获错误,避免脚本悄悄中断 $pstFiles = Get-ChildItem -Path "$dir" -Filter "*$ext" -Recurse -ErrorAction Stop Add-Content -Path $logPath -Value "[$(Get-Date)] 共找到 $($pstFiles.Count) 个PST文件" $outputPath = "c:\PST_Discovery.csv" $pstFiles | Select-Object FullName,LastAccessTime,LastWriteTime,CreationTime, @{N='Owner';E={$_.GetAccessControl().Owner}}, @{Name="MegaBytes"; Expression={"{0:F2}" -f ($_.Length / 1MB)}}, @{N='Hostname';E={$env:computername}} | Export-Csv -Path $outputPath -Append -NoTypeInformation -ErrorAction Stop Add-Content -Path $logPath -Value "[$(Get-Date)] CSV已导出到: $outputPath" New-Item -Path HKLM:\Software\CC\PST_Discovery_Script -Name Already_Run –Force -ErrorAction Stop Add-Content -Path $logPath -Value "[$(Get-Date)] 注册表标记已创建" } else { Add-Content -Path $logPath -Value "[$(Get-Date)] 已存在注册表标记,跳过扫描" } } catch { Add-Content -Path $logPath -Value "[$(Get-Date)] 执行出错: $_" }
修正PowerShell执行命令的关键参数
你原来的命令少了一个非常重要的参数:-File!如果不加-File,PowerShell会把脚本路径当作命令字符串解析,很容易出问题(尤其是路径里有特殊字符或者共享路径的时候)。正确的命令应该是:
Powershell.exe -ExecutionPolicy Bypass -File "\\server1\share1\PST_Discovery_Script.ps1"
注意共享路径要用双反斜杠\\,单斜杠会被解析成错误路径。
检查计划任务的权限配置
即使是域管理员账号,计划任务也可能受UAC限制:
- 打开计划任务的「常规」选项卡,务必勾选**「运行最高权限」**(Run with highest privileges),这能绕过UAC的权限限制;
- 确认「操作」选项卡中的「程序或脚本」是
powershell.exe,「添加参数」里的路径完全正确; - 检查共享文件夹
\\server1\share1的权限:确保域管理员账号有读取权限(共享权限和NTFS权限都要设置)。
排查文件扫描的权限问题
Get-ChildItem遍历c:\Users时,可能遇到某些用户文件夹权限严格(比如加密文件夹、私人用户目录),导致脚本报错中断。这时候注册表项已经创建了,但扫描和导出步骤没完成——这也是为啥手动运行没问题(手动登录时你的会话有访问这些文件夹的权限,计划任务的会话可能没有)。
通过上面的日志你就能看到是不是这个问题,如果是的话,可以给Get-ChildItem加-ErrorAction SilentlyContinue跳过无权限的文件夹,或者在脚本里处理权限异常。
测试脚本的执行上下文
手动用域管理员账号登录客户端,打开PowerShell,直接运行计划任务里的命令:
Powershell.exe -ExecutionPolicy Bypass -File "\\server1\share1\PST_Discovery_Script.ps1"
如果这时候能正常执行,说明是计划任务的配置问题;如果也报错,那就是脚本本身或者权限的问题,看日志就能定位。
内容的提问来源于stack exchange,提问作者Aziz

