Server 2019证书存储权限配置脚本的DSC执行失败问题
解决DSC执行证书ACL配置脚本失败问题
该脚本在管理员权限的交互模式下可正常运行,但通过DSC(Windows服务器部署流水线配置工具)拉取配置时失败,目标证书已提前添加至证书存储。
原脚本内容
$userName = "domain\user" #example testuser1 $permission = "read" #example read $certStoreLocation = "\LocalMachine\My" #example \LocalMachine\My $certThumbprint = "24235c388df63e20dea2b21e0deadbeefe21c3cd" #example 24235c388df63e20dea2b21e0deadbeefe21c3cd # check if certificate is already installed $certificateInstalled = Get-ChildItem cert:$certStoreLocation | Where thumbprint -eq $certThumbprint Write-Host $certificateInstalled # download & install only if certificate is not already installed on machine if ($certificateInstalled -eq $null) { $message="Certificate with thumbprint:"+$certThumbprint+" does not exist at "+$certStoreLocation Write-Host $message -ForegroundColor Red exit 1; }else { try { $rule = new-object security.accesscontrol.filesystemaccessrule $userName, $permission, allow $root = "c:\programdata\microsoft\crypto\rsa\machinekeys" $l = ls Cert:$certStoreLocation $l = $l |? {$_.thumbprint -like $certThumbprint} $l |%{ $keyname = $_.privatekey.cspkeycontainerinfo.uniquekeycontainername Write-Host "Keyname: $keyname" Write-Host $keyname $p = [io.path]::combine($root, $keyname) if ([io.file]::exists($p)) { $acl = get-acl -path $p $acl.addaccessrule($rule) echo $p set-acl $p $acl Write-Host "Set ACL" } } } catch { Write-Host "Caught an exception:" -ForegroundColor Red Write-Host "$($_.Exception)" -ForegroundColor Red exit 1; } } exit $LASTEXITCODE
错误信息
VERBOSE: [HOSTNAME]: LCM: [ End Set ] [[Script]SSLcertificateRights] in 0.1560 seconds. PowerShell DSC resource MSFT_ScriptResource failed to execute Set-TargetResource functionality with error message: PowerShell Desired State Configuration does not support execution of commands in an interactive mode. Please ensure that the underlying command is not prompting for user input, such as missing mandatory parameter, confirmation prompt etc. + CategoryInfo : InvalidOperation: (:) [], CimException + FullyQualifiedErrorId : ProviderOperationExecutionFailure + PSComputerName : hostname.domain.ext
解决方案
核心问题分析
DSC运行在非交互式环境中,不支持任何需要用户交互的操作,原脚本中的交互式输出命令、潜在的权限提示触发点是失败的主要原因。
修改步骤及优化后的脚本
- 移除
Write-Host、echo等交互式输出命令,改用Write-Verbose输出日志(DSC会捕获verbose日志用于排查) - 避免直接访问证书的
PrivateKey属性(非交互式环境下可能触发隐性权限提示),改用.NET扩展方法获取私钥容器信息 - 替换
exit为throw,让DSC正确捕获错误状态 - 给
Set-Acl添加-Force参数,防止潜在的确认交互 - 简化重复的证书查询逻辑
优化后的脚本:
$userName = "domain\user" $permission = "read" $certStoreLocation = "\LocalMachine\My" $certThumbprint = "24235c388df63e20dea2b21e0deadbeefe21c3cd" # 检查证书是否已安装 $certificateInstalled = Get-ChildItem "cert:$certStoreLocation" | Where-Object { $_.Thumbprint -eq $certThumbprint } if (-not $certificateInstalled) { $message = "证书指纹: $certThumbprint 不存在于 $certStoreLocation" Write-Verbose $message throw $message } else { try { $rule = New-Object System.Security.AccessControl.FileSystemAccessRule( $userName, $permission, [System.Security.AccessControl.AccessControlType]::Allow ) $root = "c:\programdata\microsoft\crypto\rsa\machinekeys" foreach ($cert in $certificateInstalled) { # 使用扩展方法获取私钥容器信息,避免交互提示 $privateKey = [System.Security.Cryptography.X509Certificates.X509Certificate2Extensions]::GetPrivateKey($cert) $keyname = $privateKey.CspKeyContainerInfo.UniqueKeyContainerName Write-Verbose "密钥名称: $keyname" $p = [System.IO.Path]::Combine($root, $keyname) if ([System.IO.File]::Exists($p)) { $acl = Get-Acl -Path $p $acl.AddAccessRule($rule) Set-Acl -Path $p -AclObject $acl -Force Write-Verbose "已设置ACL: $p" } } } catch { $errorMessage = "捕获到异常: $($_.Exception.Message)" Write-Verbose $errorMessage throw $errorMessage } }
内容的提问来源于stack exchange,提问作者BaconBurner
相关产品推荐
相关产品推荐

