You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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运行在非交互式环境中,不支持任何需要用户交互的操作,原脚本中的交互式输出命令、潜在的权限提示触发点是失败的主要原因。

修改步骤及优化后的脚本

  1. 移除Write-Host、echo等交互式输出命令,改用Write-Verbose输出日志(DSC会捕获verbose日志用于排查)
  2. 避免直接访问证书的PrivateKey属性(非交互式环境下可能触发隐性权限提示),改用.NET扩展方法获取私钥容器信息
  3. 替换exit为throw,让DSC正确捕获错误状态
  4. 给Set-Acl添加-Force参数,防止潜在的确认交互
  5. 简化重复的证书查询逻辑

优化后的脚本:

$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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 20:45:46