为何New-Service无法直接设置服务凭据需使用sc.exe config?
报错核心原因
两种写法的底层调用逻辑、校验规则完全不一样,和密码输入正确性无关:
- 账号名格式解析规则差异:
New-Service传入PSCredential对象创建服务时,最终调用Windows原生的CreateService接口,如果你传入的用户名不带本地账号前缀(.\或者本地主机名\),接口会默认将账号识别为域账号,向当前域控发起身份校验,本地账号自然会被判定为“用户名或密码无效”。而你用sc.exe config时手动给账号加了.\前缀,明确指定是本地机器账号,接口会直接走本地安全账户校验逻辑,不会走域校验流程。 - 校验时机差异:带
Credential参数调用New-Service时,CreateService接口会在创建服务的同一事务内同步完成两项校验:一是账号密码正确性校验,二是账号是否已被授予“作为服务登录”的本地安全权限,任意一项不满足就直接抛出错误。而先用默认LocalSystem账号创建服务、再用sc.exe config修改运行账号时,sc.exe不会在配置阶段校验“作为服务登录”权限,这项校验会延迟到服务首次启动时才执行,哪怕你刚给账号加完权限还没刷新策略缓存,配置步骤也不会报错。
可行修复方式
- 如果你要直接用
New-Service传凭据创建服务,生成PSCredential对象时必须给用户名加上本地前缀,示例如下:
$serviceCred = New-Object System.Management.Automation.PSCredential( ".\$($userAccount.Username)", (ConvertTo-SecureString $userAccount.Password -AsPlainText -Force) ) $params = @{ Name = $service.ServiceName DisplayName = $service.DisplayName BinaryPathName = $binaryFolder StartupType = 'Manual' Credential = $serviceCred } New-Service @params
- 刚给账号配置完“作为服务登录”安全策略后,先执行
gpupdate /force刷新本地安全策略缓存,避免CreateService接口读取到旧的权限配置导致校验失败。 - 从自动化脚本稳定性角度,你当前跑通的「先创建默认权限服务、再用sc.exe修改运行账号」的流程兼容性更好,不需要调整也可以正常使用。
内容的提问来源于stack exchange,提问作者AxD
相关产品推荐
相关产品推荐

