install-ca.sh
· 3.8 KiB · Bash
Surowy
param(
[string]$CaUrl = "https://10.10.40.53",
[string]$Fingerprint = "5fc8c379cab1119c1a9ac7038225f6bcf3a2ffb0e71b257af796b2bd6c71d594",
[switch]$Force
)
$ErrorActionPreference = "Stop"
function Write-Log {
param([string]$Message)
Write-Host ""
Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $Message"
}
function Fail {
param([string]$Message)
throw $Message
}
function Test-IsAdmin {
$currentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentIdentity)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Require-Command {
param([string]$Name)
if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) {
Fail "Required command not found: $Name"
}
}
function Refresh-Path {
$machinePath = [System.Environment]::GetEnvironmentVariable("Path", "Machine")
$userPath = [System.Environment]::GetEnvironmentVariable("Path", "User")
$env:Path = "$machinePath;$userPath"
}
function Ensure-Step {
if (Get-Command step -ErrorAction SilentlyContinue) {
Write-Log "step CLI already installed"
return
}
Require-Command winget
Write-Log "Installing step CLI with winget"
# Machine-wide install when admin, user install otherwise.
if (Test-IsAdmin) {
winget install --exact --id Smallstep.step --accept-package-agreements --accept-source-agreements --scope machine
} else {
winget install --exact --id Smallstep.step --accept-package-agreements --accept-source-agreements --scope user
}
Refresh-Path
if (-not (Get-Command step -ErrorAction SilentlyContinue)) {
Fail "step CLI installation failed or is not yet on PATH"
}
}
function Reset-StepConfig {
$stepDir = Join-Path $HOME ".step"
if (Test-Path $stepDir) {
Write-Log "Removing previous step configuration"
Remove-Item -Recurse -Force $stepDir
}
}
function Bootstrap-Step {
if ($Force) {
Reset-StepConfig
}
Write-Log "Bootstrapping against $CaUrl"
& step ca bootstrap --ca-url $CaUrl --fingerprint $Fingerprint --install --force
if ($LASTEXITCODE -ne 0) {
Fail "step bootstrap failed"
}
}
function Get-RootCertPath {
$rootCert = Join-Path $HOME ".step\certs\root_ca.crt"
if (-not (Test-Path $rootCert)) {
Fail "Root certificate not found at $rootCert"
}
return $rootCert
}
function Install-TrustStore {
$rootCert = Get-RootCertPath
if (Test-IsAdmin) {
Write-Log "Installing root CA into LocalMachine Root store"
Import-Certificate -FilePath $rootCert -CertStoreLocation "Cert:\LocalMachine\Root" | Out-Null
} else {
Write-Log "Not running as Administrator; installing root CA into CurrentUser Root store"
Import-Certificate -FilePath $rootCert -CertStoreLocation "Cert:\CurrentUser\Root" | Out-Null
}
}
function Verify-Install {
$rootCert = Get-RootCertPath
Write-Log "Installed root CA:"
& step certificate inspect $rootCert --short
if (Test-IsAdmin) {
Write-Log "Verified using LocalMachine Root store"
Get-ChildItem "Cert:\LocalMachine\Root" |
Where-Object { $_.Thumbprint -eq (Get-PfxCertificate $rootCert).Thumbprint } |
Select-Object Subject, Thumbprint |
Format-Table -AutoSize
} else {
Write-Log "Verified using CurrentUser Root store"
Get-ChildItem "Cert:\CurrentUser\Root" |
Where-Object { $_.Thumbprint -eq (Get-PfxCertificate $rootCert).Thumbprint } |
Select-Object Subject, Thumbprint |
Format-Table -AutoSize
}
Write-Host ""
Write-Host "Done."
}
function Main {
Ensure-Step
Bootstrap-Step
Install-TrustStore
Verify-Install
}
Main
| 1 | param( |
| 2 | [string]$CaUrl = "https://10.10.40.53", |
| 3 | [string]$Fingerprint = "5fc8c379cab1119c1a9ac7038225f6bcf3a2ffb0e71b257af796b2bd6c71d594", |
| 4 | [switch]$Force |
| 5 | ) |
| 6 | |
| 7 | $ErrorActionPreference = "Stop" |
| 8 | |
| 9 | function Write-Log { |
| 10 | param([string]$Message) |
| 11 | Write-Host "" |
| 12 | Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $Message" |
| 13 | } |
| 14 | |
| 15 | function Fail { |
| 16 | param([string]$Message) |
| 17 | throw $Message |
| 18 | } |
| 19 | |
| 20 | function Test-IsAdmin { |
| 21 | $currentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent() |
| 22 | $principal = New-Object Security.Principal.WindowsPrincipal($currentIdentity) |
| 23 | return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) |
| 24 | } |
| 25 | |
| 26 | function Require-Command { |
| 27 | param([string]$Name) |
| 28 | if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) { |
| 29 | Fail "Required command not found: $Name" |
| 30 | } |
| 31 | } |
| 32 | |
| 33 | function Refresh-Path { |
| 34 | $machinePath = [System.Environment]::GetEnvironmentVariable("Path", "Machine") |
| 35 | $userPath = [System.Environment]::GetEnvironmentVariable("Path", "User") |
| 36 | $env:Path = "$machinePath;$userPath" |
| 37 | } |
| 38 | |
| 39 | function Ensure-Step { |
| 40 | if (Get-Command step -ErrorAction SilentlyContinue) { |
| 41 | Write-Log "step CLI already installed" |
| 42 | return |
| 43 | } |
| 44 | |
| 45 | Require-Command winget |
| 46 | |
| 47 | Write-Log "Installing step CLI with winget" |
| 48 | # Machine-wide install when admin, user install otherwise. |
| 49 | if (Test-IsAdmin) { |
| 50 | winget install --exact --id Smallstep.step --accept-package-agreements --accept-source-agreements --scope machine |
| 51 | } else { |
| 52 | winget install --exact --id Smallstep.step --accept-package-agreements --accept-source-agreements --scope user |
| 53 | } |
| 54 | |
| 55 | Refresh-Path |
| 56 | |
| 57 | if (-not (Get-Command step -ErrorAction SilentlyContinue)) { |
| 58 | Fail "step CLI installation failed or is not yet on PATH" |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | function Reset-StepConfig { |
| 63 | $stepDir = Join-Path $HOME ".step" |
| 64 | if (Test-Path $stepDir) { |
| 65 | Write-Log "Removing previous step configuration" |
| 66 | Remove-Item -Recurse -Force $stepDir |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | function Bootstrap-Step { |
| 71 | if ($Force) { |
| 72 | Reset-StepConfig |
| 73 | } |
| 74 | |
| 75 | Write-Log "Bootstrapping against $CaUrl" |
| 76 | & step ca bootstrap --ca-url $CaUrl --fingerprint $Fingerprint --install --force |
| 77 | if ($LASTEXITCODE -ne 0) { |
| 78 | Fail "step bootstrap failed" |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | function Get-RootCertPath { |
| 83 | $rootCert = Join-Path $HOME ".step\certs\root_ca.crt" |
| 84 | if (-not (Test-Path $rootCert)) { |
| 85 | Fail "Root certificate not found at $rootCert" |
| 86 | } |
| 87 | return $rootCert |
| 88 | } |
| 89 | |
| 90 | function Install-TrustStore { |
| 91 | $rootCert = Get-RootCertPath |
| 92 | |
| 93 | if (Test-IsAdmin) { |
| 94 | Write-Log "Installing root CA into LocalMachine Root store" |
| 95 | Import-Certificate -FilePath $rootCert -CertStoreLocation "Cert:\LocalMachine\Root" | Out-Null |
| 96 | } else { |
| 97 | Write-Log "Not running as Administrator; installing root CA into CurrentUser Root store" |
| 98 | Import-Certificate -FilePath $rootCert -CertStoreLocation "Cert:\CurrentUser\Root" | Out-Null |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | function Verify-Install { |
| 103 | $rootCert = Get-RootCertPath |
| 104 | |
| 105 | Write-Log "Installed root CA:" |
| 106 | & step certificate inspect $rootCert --short |
| 107 | |
| 108 | if (Test-IsAdmin) { |
| 109 | Write-Log "Verified using LocalMachine Root store" |
| 110 | Get-ChildItem "Cert:\LocalMachine\Root" | |
| 111 | Where-Object { $_.Thumbprint -eq (Get-PfxCertificate $rootCert).Thumbprint } | |
| 112 | Select-Object Subject, Thumbprint | |
| 113 | Format-Table -AutoSize |
| 114 | } else { |
| 115 | Write-Log "Verified using CurrentUser Root store" |
| 116 | Get-ChildItem "Cert:\CurrentUser\Root" | |
| 117 | Where-Object { $_.Thumbprint -eq (Get-PfxCertificate $rootCert).Thumbprint } | |
| 118 | Select-Object Subject, Thumbprint | |
| 119 | Format-Table -AutoSize |
| 120 | } |
| 121 | |
| 122 | Write-Host "" |
| 123 | Write-Host "Done." |
| 124 | } |
| 125 | |
| 126 | function Main { |
| 127 | Ensure-Step |
| 128 | Bootstrap-Step |
| 129 | Install-TrustStore |
| 130 | Verify-Install |
| 131 | } |
| 132 | |
| 133 | Main |