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