从C#服务运行PowerShell脚本时Copy-Item无法生效
核心原因是domain\SYSTEM账户默认没有访问网络文件共享的权限:手动运行时用的是交互式用户账户(自带共享访问权限),而SYSTEM作为本地系统账户,访问网络共享的身份验证逻辑和普通用户不同——即使脚本日志显示执行了Copy-Item步骤,实际会因权限不足导致文件未复制,且原脚本未配置错误捕获,所以日志里没有异常提示。
无需更换凭据的解决办法:
授予SYSTEM账户共享与NTFS权限
在文件共享服务器上,将domain\SYSTEM账户添加到目标共享的共享权限中,设置所需权限(如读取/修改);同时在共享文件夹的NTFS权限里也添加该账户,赋予对应的访问权限。这是最直接的方案,确保SYSTEM账户有权限访问目标共享。增强脚本的错误捕获能力
修改脚本中的Copy-Item命令,添加错误终止参数,让权限问题能被日志记录:Copy-Item -force -path $UpdateFromPath -destination $CopyTo -ErrorAction Stop这样如果复制失败,会抛出终止错误,转录文件或输出日志中会显示具体错误信息,方便后续排查验证。
调整C#启动PowerShell的参数
原代码中UseShellExecute = true和Verb = "runas"的组合可能导致SYSTEM账户的运行上下文异常,尝试修改为:psi = new ProcessStartInfo(psPath, "-executionpolicy bypass -file c:\\temp\\HeartBeatScript.ps1 -verbose"); psi.CreateNoWindow = true; psi.UseShellExecute = false; psi.WindowStyle = ProcessWindowStyle.Hidden; Process.Start(psi);UseShellExecute = false会直接启动PowerShell进程,避免依赖shell的身份验证上下文,可能解决共享访问的身份传递问题。启用Kerberos约束委派(需AD管理员配合)
如果环境是域环境,可要求AD管理员为运行C#服务的服务器(SYSTEM账户所在主机)配置针对文件共享服务器的Kerberos约束委派,让SYSTEM账户能通过Kerberos验证访问共享资源。此方案无需修改脚本或运行凭据,但需要域管理员操作。
内容的提问来源于stack exchange,提问作者Nottoc

