PowerShell脚本返回值异常:为何证书指纹附带文件路径?
问题解决:PowerShell脚本返回多余值的原因及修复
问题描述
调用createInstallSSLCertificates.ps1脚本获取证书指纹时,返回值包含了证书文件夹路径和.ext文件路径,而非仅预期的指纹字符串。
根本原因
PowerShell的隐式返回机制:脚本中所有未被捕获或抑制输出的命令结果,都会被自动添加到脚本的输出流中。你的脚本里,创建目录和文件的New-Item命令返回了对应的对象,这些对象被包含在了最终的返回值里。
修复方案
需要将所有不需要作为返回值的命令输出进行抑制,具体操作如下:
1. 抑制New-Item命令的输出
在创建证书目录和.ext文件的New-Item命令末尾添加| Out-Null,阻止其输出进入脚本返回流:
New-item -ItemType Directory $dirname | Out-Null New-Item -Path $ext_file -ItemType File | Out-Null
2. 抑制外部命令(openssl)的输出
将openssl命令的标准输出和错误输出重定向到null,避免混入返回值:
openssl genrsa -des3 -passout pass:$rootpassword -out $rootkey 2048 2>&1 | Out-Null
对所有openssl命令都应用此处理。
3. 确保仅返回预期值
保留脚本末尾的return语句,确保只有指纹或错误信息作为最终返回值。
修改后的完整脚本
param ( [Parameter(Mandatory=$false, HelpMessage="创建证书后是否安装")] [bool] $InstallCerts=$false, [Parameter(Mandatory=$false, HelpMessage="创建EXT文件后是否暂停,以便添加更多DNS名称")] [bool] $PauseOnExtFile=$false, [Parameter(Mandatory=$false, HelpMessage="服务器的SAN、DNS或主机名")] [string] $SAN=$(hostname), [Parameter(Mandatory=$false, HelpMessage="个人签名证书的通用名称/友好名称")] [string] $PersonalCommonName=$(hostname), [Parameter(Mandatory=$false, HelpMessage="CA根证书的通用名称/友好名称")] [string] $RootCommonName="COMPANY123", [Parameter(Mandatory=$false, HelpMessage="(LocalMachine | CurrentUser)")] [string] $user="LocalMachine" ) if (!($user.Contains("LocalMachine")) -and !($user.Contains("CurrentUser"))) { Write-Host "`$user必须是LocalMachine或CurrentUser,而不是'$user'" Exit } ################## 变量定义 ####################### $base = "CAcerts" $certuser = $user $rootpassword = "password" $pfxexportpassword = "password" $country = "CH" $state = "BIOBIO" $city = "Concepcion" $org = "mycompany" $unit = "UNIT" ################ 文件路径与目录创建 ################## $epochseconds = Get-Date (Get-Date).ToUniversalTime() -UFormat %s $epochseconds = $epochseconds.Replace(".", "") $ran = $epochseconds.Substring($epochseconds.Length-4, 4) $cwd = Get-Location $dirname = join-path -Path $cwd -ChildPath "$($base)_certs_$($ran)" $rootkey= $base + "_root_key.key" $rootpem= $base + "_root_pem.pem" $rootcert= $base + "_root_ca.crt" $serverkey= $base + "_server_key.key" $servercsr= $base + "_server_csr.csr" $servercert= $base + "_server_cert.crt" $serverpfx= $base + "_server_pfx.pfx" $ext_file= $base + "_server_ext.ext" $rootkey= join-path $dirname $rootkey $rootpem= join-path $dirname $rootpem $rootcert= join-path $dirname $rootcert $serverkey= join-path $dirname $serverkey $servercsr= join-path $dirname $servercsr $servercert= join-path $dirname $servercert $serverpfx= join-path $dirname $serverpfx $ext_file= join-path $dirname $ext_file New-item -ItemType Directory $dirname | Out-Null New-Item -Path $ext_file -ItemType File | Out-Null ################## 安装OPENSSL ####################### if (!(Get-Command openssl -ErrorAction SilentlyContinue)) { Write-Host "未识别openssl命令,将通过chocolatey安装。" -ForegroundColor Yellow if (!(Get-Command choco -ErrorAction SilentlyContinue)) { Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") } if (!(Get-Command openssl -ErrorAction SilentlyContinue)) { choco install openssl.light -y $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") } } ################## 创建证书 ####################### Write-Host "创建根密钥" openssl genrsa -des3 -passout pass:$rootpassword -out $rootkey 2048 2>&1 | Out-Null if ( !(Test-Path -Path $rootkey -PathType Leaf)) { Write-Host("$rootkey未创建成功") } Write-Host "创建根CA证书" openssl req -x509 -new -nodes -key $rootkey -sha256 -days 3650 -out $rootcert -passin pass:$rootpassword -subj "/C=$country/ST=$state/L=$city/O=$org/OU=$unit/CN=$RootCommonName" 2>&1 | Out-Null if ( !(Test-Path -Path $rootcert -PathType Leaf)) { Write-Host("$rootcert未创建成功") } Write-Host "创建根PEM密钥" openssl req -x509 -new -nodes -key $rootkey -sha512 -days 3650 -out $rootpem -passin pass:$rootpassword -subj "/C=$country/ST=$state/L=$city/O=$org/OU=$unit/CN=$RootCommonName" 2>&1 | Out-Null if ( !(Test-Path -Path $rootpem -PathType Leaf)) { Write-Host("$rootpem未创建成功") } Write-Host "创建服务器私钥" openssl genrsa -out $serverkey 2048 2>&1 | Out-Null if ( !(Test-Path -Path $serverkey -PathType Leaf)) { Write-Host("$serverkey未创建成功") } Write-Host "创建Ext文件" $content = "authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth,clientAuth subjectAltName = @alt_names [ req_ext ] subjectAltName = @alt_names [alt_names] DNS.1 = $SAN" $content | Out-File -FilePath $ext_file -Encoding utf8 if ($pauseOnExtFile) { Write-Host "暂停执行,你可以手动修改EXT文件: '$ext_file' 添加更多DNS名称。" $_pause = Read-Host "按回车键继续" } Write-Host "创建服务器CSR文件" openssl req -new -key $serverkey -out $servercsr -subj "/C=$country/ST=$state/L=$city/O=$org/OU=$unit/CN=$PersonalCommonName" 2>&1 | Out-Null if ( !(Test-Path -Path $servercsr -PathType Leaf)) { Write-Host("$servercsr未创建成功") } Write-Host "创建服务器证书" openssl x509 -req -in $servercsr -CA $rootpem -CAkey $rootkey -CAcreateserial -out $servercert -days 3650 -sha512 -extfile $ext_file -extensions 'req_ext' -passin pass:$rootpassword 2>&1 | Out-Null if ( !(Test-Path -Path $servercert -PathType Leaf)) { Write-Host("$servercert未创建成功") } Write-Host "将证书转换为PFX格式" openssl pkcs12 -export -inkey $serverkey -in $servercert -passout pass:$pfxexportpassword -name $base -out $serverpfx 2>&1 | Out-Null if ( !(Test-Path -Path $serverpfx -PathType Leaf)) { Write-Host("$serverpfx未创建成功") } ################## 安装证书 ####################### if ($InstallCerts) { $pfxexportpassword = ConvertTo-SecureString -String $pfxexportpassword -Force -AsPlainText try { $rootobj = Import-Certificate -FilePath $rootcert -CertStoreLocation "cert:\$certuser\Root" $personalobj = Import-PfxCertificate -FilePath $serverpfx -CertStoreLocation "cert:\$certuser\My" -Password $pfxexportpassword Write-Host "根证书已安装到$certuser\Trust Root CA,名称为$RootCommonName" Write-Host "服务器证书已安装到$certuser\Personal,名称为$PersonalCommonName。指纹: ${personalobj.Thumbprint}" Write-Host "证书创建程序执行成功,前缀为$base。" Write-Host "退出程序..." if ($personalobj -and $rootobj) { Write-Host "根证书指纹: $($rootobj.Thumbprint)`n 个人证书指纹: $($personalobj.Thumbprint)" return $personalobj.Thumbprint } else { return "证书安装出错" } } catch { Write-Host "证书安装失败,请检查权限后重试。" Exit } }
内容的提问来源于stack exchange,提问作者Lacrosse343
相关产品推荐
相关产品推荐

