Skip to content

81018 adding jea support#185

Open
rcpokorny wants to merge 53 commits into
release-4.0from
81018-Adding_JEA_Support
Open

81018 adding jea support#185
rcpokorny wants to merge 53 commits into
release-4.0from
81018-Adding_JEA_Support

Conversation

@rcpokorny

Copy link
Copy Markdown
Collaborator

No description provided.

Copilot AI review requested due to automatic review settings May 11, 2026 22:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces JEA (Just Enough Administration) support for WinRM-based remote execution by refactoring the extension’s PowerShell surface into installable modules/role capabilities, wiring a new JEAEndpointName job property through the orchestrator, and updating tests/docs to cover the new behavior.

Changes:

  • Add JEAEndpointName support end-to-end (job properties → PSHelper session creation → integration/unit tests).
  • Replace monolithic WinCertScripts.ps1 script injection with modular PowerShell (Keyfactor.WinCert.Common/IIS/SQL) plus JEA .psrc role capability files and a .pssc session configuration template.
  • Update documentation (README + docsource) and integration tests to reflect JEA setup and connection selection.

Reviewed changes

Copilot reviewed 67 out of 68 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
WindowsCertStore.UnitTests/WindowsCertStore.UnitTests.csproj Adds Moq/Newtonsoft.Json; sets xUnit VS runner PrivateAssets metadata.
WindowsCertStore.UnitTests/PSHelperUnitTests.cs Updates script folder name lookup from PowerShellScripts to PowerShell.
WindowsCertStore.UnitTests/PSHelperConfigTests.cs Adds unit tests for PSHelper constructors, script directory discovery, and LocalMachine+JEA guard behavior.
WindowsCertStore.UnitTests/JobPropertiesTests.cs Adds unit tests validating JobProperties defaulting + legacy field tolerance.
WindowsCertStore.IntegrationTests/WinSQLIntegrationTests.cs Adds Integration trait; passes JEAEndpointName; uses SQL-only connection data source.
WindowsCertStore.IntegrationTests/WinIISIntegrationTests.cs Adds Integration trait; passes JEAEndpointName; uses IIS-only connection data source.
WindowsCertStore.IntegrationTests/WinCertIntegrationTests.cs New WinCert E2E integration tests (Add/Inventory/Remove and renewal flow) with JEA support.
WindowsCertStore.IntegrationTests/servers.json Expands server definitions with StoreType + JEA endpoint name.
WindowsCertStore.IntegrationTests/Factories/ConnectionFactory.cs Refactors connection loading, adds store-type filtering and env/appsettings credential sourcing.
WindowsCertStore.IntegrationTests/ClientConnection.cs Adds StoreType and JEAEndpointName to connection model.
README.md Adds detailed JEA documentation and updates WinRM port references (5985/5986).
docsource/content.md Adds detailed JEA documentation for generated docs; notes module install requirements for JEA.
IISU/WindowsCertStore.csproj Updates packaging to include new PowerShell\ module tree + .pssc and legacy scripts.
IISU/RemoteSettings.cs Adds JEAEndpointName to remote settings model.
IISU/PSHelper.cs Adds JEA endpoint support (WinRM ConfigurationName), blocks LocalMachine+JEA, changes script loading strategy, improves Information stream handling.
IISU/Properties/AssemblyInfo.cs Exposes internals to unit/integration test assemblies.
IISU/PowerShellScripts/WinCertScripts.ps1 Removes legacy monolithic script.
IISU/PowerShell/WinADFSScripts.ps1 Adjusts logging to use Information stream “[VERBOSE] …” convention.
IISU/PowerShell/Keyfactor.WinCert.SQL/RoleCapabilities/Keyfactor.WinCert.SQL.psrc New SQL JEA role capability definition.
IISU/PowerShell/Keyfactor.WinCert.SQL/Public/Remove-KeyfactorSQLCertificate.ps1 New SQL unbind function.
IISU/PowerShell/Keyfactor.WinCert.SQL/Public/New-KeyfactorSQLBinding.ps1 New SQL bind function wrapper.
IISU/PowerShell/Keyfactor.WinCert.SQL/Public/Get-KeyfactorSQLInventory.ps1 New SQL inventory function.
IISU/PowerShell/Keyfactor.WinCert.SQL/Private/Set-KeyfactorSQLCertificateBinding.ps1 New SQL bind implementation (registry + ACL + optional restart).
IISU/PowerShell/Keyfactor.WinCert.SQL/Private/Get-KeyfactorSQLServiceUser.ps1 New helper to read SQL service user.
IISU/PowerShell/Keyfactor.WinCert.SQL/Private/Get-KeyfactorSQLServiceName.ps1 New helper to compute SQL service name.
IISU/PowerShell/Keyfactor.WinCert.SQL/Keyfactor.WinCert.SQL.psm1 New SQL module entry point with explicit dot-sourcing + exports.
IISU/PowerShell/Keyfactor.WinCert.IIS/RoleCapabilities/Keyfactor.WinCert.IIS.psrc New IIS JEA role capability definition.
IISU/PowerShell/Keyfactor.WinCert.IIS/Public/Remove-KeyfactorIISSiteBinding.ps1 New IIS binding removal function with IIS drive autodetect.
IISU/PowerShell/Keyfactor.WinCert.IIS/Public/Remove-KeyfactorIISCertificateIfUnused.ps1 New IIS certificate cleanup helper.
IISU/PowerShell/Keyfactor.WinCert.IIS/Public/New-KeyfactorIISSiteBinding.ps1 New IIS binding creation with SSL flags handling and appcmd fallback.
IISU/PowerShell/Keyfactor.WinCert.IIS/Public/Get-KeyfactorIISBoundCertificates.ps1 New IIS inventory function.
IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Test-ValidSslFlags.ps1 New SSL flag validation helper.
IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Test-IISDrive.ps1 New IIS:\ drive availability helper.
IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Get-ValidSslFlagsForSystem.ps1 New OS-build-based SSL flag support helper.
IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Get-IISManagementInfo.ps1 New IIS management mode detection helper.
IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Add-IISBindingWithSSL.ps1 New IIS binding add + SSL attach helper.
IISU/PowerShell/Keyfactor.WinCert.IIS/Keyfactor.WinCert.IIS.psm1 New IIS module entry point with explicit dot-sourcing + exports.
IISU/PowerShell/Keyfactor.WinCert.Common/RoleCapabilities/Keyfactor.WinCert.Common.psrc New common JEA role capability definition.
IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1 New common remove-from-store implementation.
IISU/PowerShell/Keyfactor.WinCert.Common/Public/New-KeyfactorResult.ps1 New common structured result helper.
IISU/PowerShell/Keyfactor.WinCert.Common/Public/New-KeyfactorODKGEnrollment.ps1 New ODKG CSR generation function.
IISU/PowerShell/Keyfactor.WinCert.Common/Public/Import-KeyfactorSignedCertificate.ps1 New signed cert import helper.
IISU/PowerShell/Keyfactor.WinCert.Common/Public/Get-KeyfactorCertificates.ps1 New common inventory function.
IISU/PowerShell/Keyfactor.WinCert.Common/Public/Add-KeyfactorCertificate.ps1 New common add-to-store implementation.
IISU/PowerShell/Keyfactor.WinCert.Common/Private/Validate-CryptoProvider.ps1 New provider validation helper.
IISU/PowerShell/Keyfactor.WinCert.Common/Private/Test-CryptoServiceProvider.ps1 New provider existence helper.
IISU/PowerShell/Keyfactor.WinCert.Common/Private/Get-CryptoProviders.ps1 New CSP discovery helper using certutil.
IISU/PowerShell/Keyfactor.WinCert.Common/Private/Get-CertificateSAN.ps1 New SAN extraction helper.
IISU/PowerShell/Keyfactor.WinCert.Common/Private/Get-CertificateCSP.ps1 New CSP/KSP detection helper (CAPI + CNG).
IISU/PowerShell/Keyfactor.WinCert.Common/Private/Convert-DNSSubject.ps1 New DN subject parsing helper.
IISU/PowerShell/Keyfactor.WinCert.Common/Keyfactor.WinCert.Common.psm1 New Common module entry point with explicit dot-sourcing + exports.
IISU/PowerShell/Build/KeyfactorWinCert.pssc New JEA session configuration template (RestrictedRemoteServer + transcripts + role mapping).
IISU/Models/JobProperties.cs Adds JEAEndpointName job property.
IISU/ImplementedStoreTypes/WinSQL/WinSqlBinding.cs Switches to new SQL module function names.
IISU/ImplementedStoreTypes/WinSQL/Management.cs Wires JEAEndpointName; switches to new module function names.
IISU/ImplementedStoreTypes/WinSQL/Inventory.cs Wires JEAEndpointName; switches to new inventory function name and signature.
IISU/ImplementedStoreTypes/WinIIS/WinIISBinding.cs Switches to new IIS module function names; updates unbind parameter shape and result parsing.
IISU/ImplementedStoreTypes/WinIIS/Management.cs Wires JEAEndpointName; switches to new module function names.
IISU/ImplementedStoreTypes/WinIIS/Inventory.cs Wires JEAEndpointName; switches to new IIS inventory function name.
IISU/ImplementedStoreTypes/WinADFS/Inventory.cs Removes SAN field propagation for ADFS inventory parameters.
IISU/ImplementedStoreTypes/Win/WinInventory.cs Marks unused class obsolete.
IISU/ImplementedStoreTypes/Win/WinCertCertificateInfo.cs Removes SAN field from WinCert cert info model.
IISU/ImplementedStoreTypes/Win/Management.cs Wires JEAEndpointName; switches to new module function names.
IISU/ImplementedStoreTypes/Win/Inventory.cs Wires JEAEndpointName; switches to new inventory function name; removes SAN parameter propagation.
IISU/ClientPSCertStoreReEnrollment.cs Wires JEAEndpointName; switches to new ODKG/import function names; updates log strings.
CHANGELOG.md Adds 4.0.0 entry documenting SAN removal and JEA support.
.vscode/launch.json Adds VS Code launch configuration for PowerShell.
.gitignore Ignores local.runsettings to avoid committing local credentials.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +22 to +29
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true)
.Build();

// 3. Retrieve connection details from configuration
var vault = new VaultHelper(config);
return (vault.GetSecret("Username"), vault.GetSecret("Password"));
}
Comment thread IISU/PSHelper.cs Outdated
Comment on lines +292 to +311
// Pre-flight: verify Keyfactor modules are installed on the JEA endpoint.
PS.AddCommand("Invoke-Command")
.AddParameter("Session", _PSSession)
.AddParameter("ScriptBlock", ScriptBlock.Create("[bool](Get-Command 'New-KeyfactorResult' -ErrorAction SilentlyContinue)"));
var preFlightResults = PS.Invoke();
PS.Commands.Clear();

bool modulesInstalled = preFlightResults != null &&
preFlightResults.Count > 0 &&
preFlightResults[0]?.BaseObject is bool preFlightBool &&
preFlightBool;

if (!modulesInstalled)
{
throw new Exception(
$"JEA endpoint '{jeaEndpoint}' is reachable but Keyfactor modules are not installed. " +
"Install Keyfactor.WinCert.Common (and any required store-type modules) under " +
"'C:\\Program Files\\WindowsPowerShell\\Modules\\' on the target machine, " +
"re-register the JEA session configuration, and restart WinRM.");
}

try {
Write-Information "Entering PowerShell Script Add-KeyfactorCertificateToStore"
Write-Information "[VERBOSE] Add-KeyfactorCertificateToStore - Received: StoreName: '$StoreName', CryptoServiceProvider: '$CryptoServiceProvider', Base64Cert: '$Base64Cert'"
Comment on lines +77 to +78
Write-Information "[VERBOSE] Running certutil with arguments: $argLine"

Comment on lines +10 to +15
if ($serviceUser) {
return $serviceUser
} else {
Write-Error "SQL Server instance '$SQLInstanceName' not found or no service user associated."
return $null
}
Comment thread CHANGELOG.md
@@ -1,3 +1,7 @@
4.0.0
* As of this version of the extension, SANs will be handled through the ODKG Enrollment page in Command and will no longer use the SAN Entry Parameter. This version, we are removing all support for the SAN Entry Parameter. If you are still using the SAN Entry Parameter, you will need to remove it from your store types and re-run inventory to remove it from your database.
* Adding JEA Support for local PowerShell execution. This will allow for more secure execution of the extension when running in a local PowerShell Runspace. To utilize this feature, you will need to create a JEA endpoint on the target server and specify the endpoint name as a new parameter in the specific Cert Store definition. Refer to the README for more details.
Comment on lines +28 to +34
Write-Information "[VERBOSE] Instance: $instance"
Write-Information "[VERBOSE] Full Instance: $fullInstance"
Write-Information "[VERBOSE] Registry Location: $regLocation"
Write-Information "[VERBOSE] Current Thumbprint: $currentThumbprint"

$currentThumbprint = Get-ItemPropertyValue -Path $regLocation -Name "Certificate" -ErrorAction SilentlyContinue

Comment on lines 286 to 301
_results = _psHelper.ExecutePowerShell("Add-KFCertificateToStore", parameters);
_results = _psHelper.ExecutePowerShell("Add-KeyfactorCertificate", parameters);
_logger.LogTrace("Returned from executing PS function (Add-KFCertificateToStore)");

Comment on lines +269 to +285
_results = _psHelper.ExecutePowerShell("Add-KFCertificateToStore", parameters);
_logger.LogTrace("Returned from executing PS function (Add-KFCertificateToStore)");
_results = _psHelper.ExecutePowerShell("Add-KeyfactorCertificate", parameters);
_logger.LogTrace("Returned from executing PS function (Add-KeyfactorCertificate)");
Comment on lines 149 to 164
_logger.LogTrace("Returned from executing PS function (Add-KFCertificateToStore)");
_results = _psHelper.ExecutePowerShell("Add-KeyfactorCertificate", parameters);
_logger.LogTrace("Returned from executing PS function (Add-KeyfactorCertificate)");

Copilot AI review requested due to automatic review settings May 12, 2026 16:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 72 out of 145 changed files in this pull request and generated 11 comments.

Comment on lines +4 to +8
[string]$StorePath,

[parameter(ParameterSetName = $false)]
[switch]$IsAlias
)
Comment on lines +31 to +33
Set-Location -Path "Cert:\LocalMachine\$StoreName"

$importResult = Import-Certificate -FilePath $cerFilename
Comment on lines +28 to +36
Write-Information "[VERBOSE] Instance: $instance"
Write-Information "[VERBOSE] Full Instance: $fullInstance"
Write-Information "[VERBOSE] Registry Location: $regLocation"
Write-Information "[VERBOSE] Current Thumbprint: $currentThumbprint"

$currentThumbprint = Get-ItemPropertyValue -Path $regLocation -Name "Certificate" -ErrorAction SilentlyContinue

if ($RenewalThumbprint -and $RenewalThumbprint -contains $currentThumbprint) {
Write-Information "Renewal thumbprint matches for instance: $fullInstance"
Comment on lines +35 to +46
if ($RenewalThumbprint -and $RenewalThumbprint -contains $currentThumbprint) {
Write-Information "Renewal thumbprint matches for instance: $fullInstance"
$result = Set-KeyfactorSQLCertificateBinding -InstanceName $instance -NewThumbprint $NewThumbprint -RestartService:$RestartService
} elseif (-not $RenewalThumbprint) {
Write-Information "No renewal thumbprint provided. Binding certificate to instance: $fullInstance"
$result = Set-KeyfactorSQLCertificateBinding -InstanceName $instance -NewThumbprint $NewThumbprint -RestartService:$RestartService
}

if (-not $result) {
Write-Error "Failed to bind certificate for instance: $instance"
$bindingSuccess = $false
}
Comment on lines +11 to +15
return $serviceUser
} else {
Write-Error "SQL Server instance '$SQLInstanceName' not found or no service user associated."
return $null
}
Comment on lines +41 to +44
var (username, password) = GetCredentials();
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
yield break;

Comment on lines +299 to 301
_results = _psHelper.ExecutePowerShell("Add-KeyfactorCertificate", parameters);
_logger.LogTrace("Returned from executing PS function (Add-KFCertificateToStore)");

Comment on lines 164 to 168
case "Skipped":
psResult = OrchestratorJobStatusJobResult.Failure;
failureMessage = ($"PowerShell function New-KFIISSiteBinding failed on step: {step} - message:\n {errorMessage}");
failureMessage = ($"PowerShell function New-KeyfactorIISSiteBinding failed on step: {step} - message:\n {errorMessage}");
_logger.LogDebug(failureMessage);
break;
Comment on lines +4 to 6
Write-Host "Creating store type: WinCert"
kfutil store-types create WinCert

Comment on lines +1 to +8
#!/bin/bash
# Store Type creation script using kfutil
# Generated by Doctool

# Creates all 4 store types using kfutil.
# kfutil reads definitions from the Keyfactor integration catalog.
#
# Auth environment variables (first matching method is used):
# OAuth access token: KEYFACTOR_AUTH_ACCESS_TOKEN
# OAuth client creds: KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET
# + KEYFACTOR_AUTH_TOKEN_URL
# Basic auth (AD): KEYFACTOR_HOSTNAME + KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD
# + KEYFACTOR_DOMAIN
#
# Auto-generated by doctool generate-store-type-scripts — do not edit by hand.
set -e

if ! command -v kfutil &> /dev/null; then
echo "kfutil could not be found. Please install kfutil"
echo "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
fi
echo "Creating store type: WinCert"
kfutil store-types create WinCert
Copilot AI review requested due to automatic review settings May 12, 2026 16:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 72 out of 145 changed files in this pull request and generated 12 comments.

Comment on lines +8 to +14
$serviceUser = (Get-CimInstance -ClassName Win32_Service -Filter "Name='$SQLServiceName'").StartName

if ($serviceUser) {
return $serviceUser
} else {
Write-Error "SQL Server instance '$SQLInstanceName' not found or no service user associated."
return $null
Comment on lines +29 to +35
Write-Information "[VERBOSE] Full Instance: $fullInstance"
Write-Information "[VERBOSE] Registry Location: $regLocation"
Write-Information "[VERBOSE] Current Thumbprint: $currentThumbprint"

$currentThumbprint = Get-ItemPropertyValue -Path $regLocation -Name "Certificate" -ErrorAction SilentlyContinue

if ($RenewalThumbprint -and $RenewalThumbprint -contains $currentThumbprint) {
Comment on lines +24 to +26
Write-Information "Entering PowerShell Script: New-KFIISSiteBinding" -InformationAction SilentlyContinue
Write-Information "[VERBOSE] Parameters: $(($PSBoundParameters.GetEnumerator() | ForEach-Object { "$($_.Key): '$($_.Value)'" }) -join ', ')"

Comment on lines +113 to +117
catch {
$errorMessage = "Unexpected error in New-KFIISSiteBinding: $($_.Exception.Message)"
Write-Error $errorMessage
return New-KeyfactorResult -Status Error -Code 999 -Step UnexpectedError -ErrorMessage $errorMessage
}
Comment on lines +12 to +16
if ($build -ge 20348) {
# Windows Server 2022+ (IIS 10.0.20348+)
Write-Information "[VERBOSE] Detected Windows Server 2022 or later (Build: $build)"
return @(1, 4, 8, 16, 32, 64) # Include unknowns for testing
}
Comment on lines +5 to +8

[parameter(ParameterSetName = $false)]
[switch]$IsAlias
)
Comment on lines +31 to +33
Set-Location -Path "Cert:\LocalMachine\$StoreName"

$importResult = Import-Certificate -FilePath $cerFilename
Comment on lines +2 to +6
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "" },
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "{SQL-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "" },
{ "Machine": "{SQL-JEA-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "192.168.230.139", "StoreType": "WinCert", "JEAEndpointName": "" },
Comment on lines +1 to +8
#!/bin/bash
# Store Type creation script using kfutil
# Generated by Doctool

# Creates all 4 store types using kfutil.
# kfutil reads definitions from the Keyfactor integration catalog.
#
# Auth environment variables (first matching method is used):
# OAuth access token: KEYFACTOR_AUTH_ACCESS_TOKEN
# OAuth client creds: KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET
# + KEYFACTOR_AUTH_TOKEN_URL
# Basic auth (AD): KEYFACTOR_HOSTNAME + KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD
# + KEYFACTOR_DOMAIN
#
# Auto-generated by doctool generate-store-type-scripts — do not edit by hand.
set -e

if ! command -v kfutil &> /dev/null; then
echo "kfutil could not be found. Please install kfutil"
echo "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
fi
echo "Creating store type: WinCert"
kfutil store-types create WinCert
Comment on lines +1 to +8
# Store Type creation script using kfutil
# Generated by Doctool

# Uncomment if kfutil is not in your PATH
# Set-Alias -Name kfutil -Value 'C:\Program Files\Keyfactor\kfutil\kfutil.exe'
Write-Host "Creating store type: WinCert"
kfutil store-types create WinCert

if ($null -eq (Get-Command "kfutil" -ErrorAction SilentlyContinue)) {
Write-Host "kfutil could not be found. Please install kfutil"
Write-Host "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
}
Write-Host "Creating store type: IISU"
kfutil store-types create IISU
Copilot AI review requested due to automatic review settings July 6, 2026 20:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 81 out of 161 changed files in this pull request and generated 13 comments.

Comment on lines +1 to +3
using Keyfactor.Extensions.Orchestrator.WindowsCertStore;

namespace WindowsCertStore.UnitTests
Comment on lines +1 to +5
using Keyfactor.Extensions.Orchestrator.WindowsCertStore;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace WindowsCertStore.UnitTests
Comment on lines 81 to +84
// Assert
Assert.Equal("dns=legacy.example.com&dns=old.example.com", result);
//Assert.Equal(legacySan, result);

// Assert
Comment on lines +5 to +8

[parameter(ParameterSetName = $false)]
[switch]$IsAlias
)
Comment on lines +25 to +33
if ($cert) {
# Remove the certificate from the store
Write-Information "Attempting to remove certificate from store '$StorePath' with the thumbprint: $Thumbprint"
$store.Remove($cert)
Write-Information "Certificate removed successfully from store '$StorePath'"

# Mark success
$isSuccessful = $true
} else {
Comment on lines +1 to 6
#!/bin/bash
# Store Type creation script using kfutil
# Generated by Doctool

# Creates all 4 store types using kfutil.
# kfutil reads definitions from the Keyfactor integration catalog.
#
# Auth environment variables (first matching method is used):
# OAuth access token: KEYFACTOR_AUTH_ACCESS_TOKEN
# OAuth client creds: KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET
# + KEYFACTOR_AUTH_TOKEN_URL
# Basic auth (AD): KEYFACTOR_HOSTNAME + KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD
# + KEYFACTOR_DOMAIN
#
# Auto-generated by doctool generate-store-type-scripts — do not edit by hand.
set -e

Comment on lines +1 to 3
# Store Type creation script using kfutil
# Generated by Doctool

Comment on lines +2 to +7
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "" },
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "{SQL-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "" },
{ "Machine": "{SQL-JEA-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "192.168.230.139", "StoreType": "WinCert", "JEAEndpointName": "" },
{ "Machine": "192.168.230.139", "StoreType": "WinCert", "JEAEndpointName": "keyfactor.wincert" }
Comment on lines +29 to +34
# Step 4: Import the certificate into the specified store
Write-Verbose "Importing the certificate to the store: Cert:\LocalMachine\$StoreName"
Set-Location -Path "Cert:\LocalMachine\$StoreName"

$importResult = Import-Certificate -FilePath $cerFilename
if ($importResult) {
Comment on lines +51 to +56
# Path to temporary INF file
$infFile = [System.IO.Path]::GetTempFileName() + ".inf"
$csrOutputFile = [System.IO.Path]::GetTempFileName() + ".csr"

Set-Content -Path $infFile -Value $infContent
Write-Information "Generated INF file at: $infFile"
Copilot AI review requested due to automatic review settings July 6, 2026 20:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 81 out of 161 changed files in this pull request and generated 11 comments.

Comment on lines 1 to 7
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

Comment on lines +41 to +43
var (username, password) = GetCredentials();
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
yield break;
Comment on lines +2 to +7
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "" },
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "{SQL-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "" },
{ "Machine": "{SQL-JEA-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "192.168.230.139", "StoreType": "WinCert", "JEAEndpointName": "" },
{ "Machine": "192.168.230.139", "StoreType": "WinCert", "JEAEndpointName": "keyfactor.wincert" }
Comment on lines +28 to +46
Write-Information "[VERBOSE] Instance: $instance"
Write-Information "[VERBOSE] Full Instance: $fullInstance"
Write-Information "[VERBOSE] Registry Location: $regLocation"
Write-Information "[VERBOSE] Current Thumbprint: $currentThumbprint"

$currentThumbprint = Get-ItemPropertyValue -Path $regLocation -Name "Certificate" -ErrorAction SilentlyContinue

if ($RenewalThumbprint -and $RenewalThumbprint -contains $currentThumbprint) {
Write-Information "Renewal thumbprint matches for instance: $fullInstance"
$result = Set-KeyfactorSQLCertificateBinding -InstanceName $instance -NewThumbprint $NewThumbprint -RestartService:$RestartService
} elseif (-not $RenewalThumbprint) {
Write-Information "No renewal thumbprint provided. Binding certificate to instance: $fullInstance"
$result = Set-KeyfactorSQLCertificateBinding -InstanceName $instance -NewThumbprint $NewThumbprint -RestartService:$RestartService
}

if (-not $result) {
Write-Error "Failed to bind certificate for instance: $instance"
$bindingSuccess = $false
}
Comment on lines +48 to +51
$sqlSettingsDict = @{
InstanceName = $instanceNames
ProviderName = $cert.PrivateKey.CspKeyContainerInfo.ProviderName
}
Comment on lines +12 to +16
if ($build -ge 20348) {
# Windows Server 2022+ (IIS 10.0.20348+)
Write-Information "[VERBOSE] Detected Windows Server 2022 or later (Build: $build)"
return @(1, 4, 8, 16, 32, 64) # Include unknowns for testing
}
Comment on lines +1 to 6
# Store Type creation script using kfutil
# Generated by Doctool

# Uncomment if kfutil is not in your PATH
# Set-Alias -Name kfutil -Value 'C:\Program Files\Keyfactor\kfutil\kfutil.exe'
Write-Host "Creating store type: WinCert"
kfutil store-types create WinCert

Comment on lines +1 to 9
#!/bin/bash
# Store Type creation script using kfutil
# Generated by Doctool

# Creates all 4 store types using kfutil.
# kfutil reads definitions from the Keyfactor integration catalog.
#
# Auth environment variables (first matching method is used):
# OAuth access token: KEYFACTOR_AUTH_ACCESS_TOKEN
# OAuth client creds: KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET
# + KEYFACTOR_AUTH_TOKEN_URL
# Basic auth (AD): KEYFACTOR_HOSTNAME + KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD
# + KEYFACTOR_DOMAIN
#
# Auto-generated by doctool generate-store-type-scripts — do not edit by hand.
set -e

if ! command -v kfutil &> /dev/null; then
echo "kfutil could not be found. Please install kfutil"
echo "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
fi
echo "Creating store type: WinCert"
kfutil store-types create WinCert

[InlineData("dns=legacy.example.com&dns=old.example.com")]
[InlineData("")]
[InlineData(null)]
public void ResolveSanString_UsesLegacySAN_WhenConfigSANsMissing(string legacySan)
Comment on lines 81 to +96
// Assert
Assert.Equal("dns=legacy.example.com&dns=old.example.com", result);
//Assert.Equal(legacySan, result);

// Assert
if (legacySan == null)
{
Assert.Equal(string.Empty, result);
}
else if (legacySan == string.Empty)
{
Assert.Equal(string.Empty, result);
}
else
{
Assert.Equal(legacySan, result);
}
Bob Pokorny added 2 commits July 6, 2026 15:57
…upport for JEA (Just Enough Administration) environments. Added a new documentation file for setting up an SSH development environment.
Copilot AI review requested due to automatic review settings July 14, 2026 23:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 82 out of 162 changed files in this pull request and generated 14 comments.

Comment on lines +28 to +46
Write-Information "[VERBOSE] Instance: $instance"
Write-Information "[VERBOSE] Full Instance: $fullInstance"
Write-Information "[VERBOSE] Registry Location: $regLocation"
Write-Information "[VERBOSE] Current Thumbprint: $currentThumbprint"

$currentThumbprint = Get-ItemPropertyValue -Path $regLocation -Name "Certificate" -ErrorAction SilentlyContinue

if ($RenewalThumbprint -and $RenewalThumbprint -contains $currentThumbprint) {
Write-Information "Renewal thumbprint matches for instance: $fullInstance"
$result = Set-KeyfactorSQLCertificateBinding -InstanceName $instance -NewThumbprint $NewThumbprint -RestartService:$RestartService
} elseif (-not $RenewalThumbprint) {
Write-Information "No renewal thumbprint provided. Binding certificate to instance: $fullInstance"
$result = Set-KeyfactorSQLCertificateBinding -InstanceName $instance -NewThumbprint $NewThumbprint -RestartService:$RestartService
}

if (-not $result) {
Write-Error "Failed to bind certificate for instance: $instance"
$bindingSuccess = $false
}
Comment on lines +15 to +17
# Resolve full instance name from registry
$fullInstance = Get-ItemPropertyValue "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL" -Name $instance
$regPath = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$fullInstance\MSSQLServer\SuperSocketNetLib"
Comment on lines +25 to +39
# Instead of deleting, set to an empty string to prevent SQL startup issues
Set-ItemProperty -Path $regPath -Name "Certificate" -Value ""

Write-Information "Successfully unbound certificate from SQL Server instance: $instance."
} else {
Write-Warning "No certificate bound to SQL Server instance: $instance."
}

# Restart service if required
if ($RestartService) {
$serviceName = Get-KeyfactorSQLServiceName -InstanceName $instance
Write-Information "Restarting SQL Server service: $serviceName..."
Restart-Service -Name $serviceName -Force
Write-Information "SQL Server service restarted successfully."
}
Comment on lines +5 to +8

[parameter(ParameterSetName = $false)]
[switch]$IsAlias
)
Comment on lines +25 to +33
if ($cert) {
# Remove the certificate from the store
Write-Information "Attempting to remove certificate from store '$StorePath' with the thumbprint: $Thumbprint"
$store.Remove($cert)
Write-Information "Certificate removed successfully from store '$StorePath'"

# Mark success
$isSuccessful = $true
} else {
Comment on lines +1 to +8
#!/bin/bash
# Store Type creation script using kfutil
# Generated by Doctool

# Creates all 4 store types using kfutil.
# kfutil reads definitions from the Keyfactor integration catalog.
#
# Auth environment variables (first matching method is used):
# OAuth access token: KEYFACTOR_AUTH_ACCESS_TOKEN
# OAuth client creds: KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET
# + KEYFACTOR_AUTH_TOKEN_URL
# Basic auth (AD): KEYFACTOR_HOSTNAME + KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD
# + KEYFACTOR_DOMAIN
#
# Auto-generated by doctool generate-store-type-scripts — do not edit by hand.
set -e

if ! command -v kfutil &> /dev/null; then
echo "kfutil could not be found. Please install kfutil"
echo "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
fi
echo "Creating store type: WinCert"
kfutil store-types create WinCert
Comment on lines +1 to 6
# Store Type creation script using kfutil
# Generated by Doctool

# Uncomment if kfutil is not in your PATH
# Set-Alias -Name kfutil -Value 'C:\Program Files\Keyfactor\kfutil\kfutil.exe'
Write-Host "Creating store type: WinCert"
kfutil store-types create WinCert

Comment on lines +2 to +7
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "" },
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "{SQL-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "" },
{ "Machine": "{SQL-JEA-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "192.168.230.139", "StoreType": "WinCert", "JEAEndpointName": "" },
{ "Machine": "192.168.230.139", "StoreType": "WinCert", "JEAEndpointName": "keyfactor.wincert" }
Comment on lines +556 to 559
catch (Exception)
{
throw;
}
Comment on lines 86 to 88
_logger.LogTrace($"Attempting to read bound SQL Server certificates from cert store: {storePath}");
inventoryItems = QuerySQLCertificates(settings, storePath);
inventoryItems = QuerySQLCertificates(settings);

Copilot AI review requested due to automatic review settings July 14, 2026 23:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 82 out of 162 changed files in this pull request and generated 10 comments.

Comment on lines +28 to +41
Write-Information "[VERBOSE] Instance: $instance"
Write-Information "[VERBOSE] Full Instance: $fullInstance"
Write-Information "[VERBOSE] Registry Location: $regLocation"
Write-Information "[VERBOSE] Current Thumbprint: $currentThumbprint"

$currentThumbprint = Get-ItemPropertyValue -Path $regLocation -Name "Certificate" -ErrorAction SilentlyContinue

if ($RenewalThumbprint -and $RenewalThumbprint -contains $currentThumbprint) {
Write-Information "Renewal thumbprint matches for instance: $fullInstance"
$result = Set-KeyfactorSQLCertificateBinding -InstanceName $instance -NewThumbprint $NewThumbprint -RestartService:$RestartService
} elseif (-not $RenewalThumbprint) {
Write-Information "No renewal thumbprint provided. Binding certificate to instance: $fullInstance"
$result = Set-KeyfactorSQLCertificateBinding -InstanceName $instance -NewThumbprint $NewThumbprint -RestartService:$RestartService
}
Comment on lines +48 to +51
$sqlSettingsDict = @{
InstanceName = $instanceNames
ProviderName = $cert.PrivateKey.CspKeyContainerInfo.ProviderName
}
Comment on lines +14 to +19
if (Test-Path -LiteralPath $regPath) {
$cspInfoList = @(
Get-ChildItem -LiteralPath $regPath -ErrorAction Stop |
Select-Object -ExpandProperty PSChildName
)
}
[string]$Thumbprint,
[string]$StorePath,

[parameter(ParameterSetName = $false)]
Comment on lines +26 to +29
# Remove the certificate from the store
Write-Information "Attempting to remove certificate from store '$StorePath' with the thumbprint: $Thumbprint"
$store.Remove($cert)
Write-Information "Certificate removed successfully from store '$StorePath'"
Comment on lines +2 to +7
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "" },
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "{SQL-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "" },
{ "Machine": "{SQL-JEA-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "192.168.230.139", "StoreType": "WinCert", "JEAEndpointName": "" },
{ "Machine": "192.168.230.139", "StoreType": "WinCert", "JEAEndpointName": "keyfactor.wincert" }
Comment on lines +4 to +8
Write-Host "Creating store type: WinCert"
kfutil store-types create WinCert

if ($null -eq (Get-Command "kfutil" -ErrorAction SilentlyContinue)) {
Write-Host "kfutil could not be found. Please install kfutil"
Write-Host "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
}
Write-Host "Creating store type: IISU"
kfutil store-types create IISU
Comment on lines +5 to 12
set -e

if ! command -v kfutil &> /dev/null; then
echo "kfutil could not be found. Please install kfutil"
echo "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
fi
echo "Creating store type: WinCert"
kfutil store-types create WinCert

if [ -z "$KEYFACTOR_HOSTNAME" ]; then
echo "KEYFACTOR_HOSTNAME not set — launching kfutil login"
kfutil login
fi
echo "Creating store type: IISU"
kfutil store-types create IISU

Comment on lines 81 to +96
// Assert
Assert.Equal("dns=legacy.example.com&dns=old.example.com", result);
//Assert.Equal(legacySan, result);

// Assert
if (legacySan == null)
{
Assert.Equal(string.Empty, result);
}
else if (legacySan == string.Empty)
{
Assert.Equal(string.Empty, result);
}
else
{
Assert.Equal(legacySan, result);
}
Comment on lines +12 to +16
if ($build -ge 20348) {
# Windows Server 2022+ (IIS 10.0.20348+)
Write-Information "[VERBOSE] Detected Windows Server 2022 or later (Build: $build)"
return @(1, 4, 8, 16, 32, 64) # Include unknowns for testing
}
	modified:   IISU/ImplementedStoreTypes/WinIIS/Management.cs
	modified:   IISU/PowerShell/Keyfactor.WinCert.Common/Keyfactor.WinCert.Common.psm1
	new file:   IISU/PowerShell/Keyfactor.WinCert.Common/Private/Test-KeyfactorAdminRights.ps1
	modified:   IISU/PowerShell/Keyfactor.WinCert.Common/Public/New-KeyfactorResult.ps1
	modified:   IISU/PowerShell/Keyfactor.WinCert.Common/RoleCapabilities/Keyfactor.WinCert.Common.psrc
	modified:   IISU/PowerShell/Keyfactor.WinCert.IIS/Public/Get-KeyfactorIISBoundCertificates.ps1
	modified:   IISU/PowerShell/Keyfactor.WinCert.IIS/Public/New-KeyfactorIISSiteBinding.ps1
	modified:   IISU/PowerShell/Keyfactor.WinCert.IIS/Public/Remove-KeyfactorIISCertificateIfUnused.ps1
	modified:   IISU/PowerShell/Keyfactor.WinCert.IIS/Public/Remove-KeyfactorIISSiteBinding.ps1
Copilot AI review requested due to automatic review settings July 15, 2026 15:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 83 out of 163 changed files in this pull request and generated 6 comments.

Comment on lines +4 to +7
[string]$StorePath,

[parameter(ParameterSetName = $false)]
[switch]$IsAlias
Comment on lines +28 to +46
Write-Information "[VERBOSE] Instance: $instance"
Write-Information "[VERBOSE] Full Instance: $fullInstance"
Write-Information "[VERBOSE] Registry Location: $regLocation"
Write-Information "[VERBOSE] Current Thumbprint: $currentThumbprint"

$currentThumbprint = Get-ItemPropertyValue -Path $regLocation -Name "Certificate" -ErrorAction SilentlyContinue

if ($RenewalThumbprint -and $RenewalThumbprint -contains $currentThumbprint) {
Write-Information "Renewal thumbprint matches for instance: $fullInstance"
$result = Set-KeyfactorSQLCertificateBinding -InstanceName $instance -NewThumbprint $NewThumbprint -RestartService:$RestartService
} elseif (-not $RenewalThumbprint) {
Write-Information "No renewal thumbprint provided. Binding certificate to instance: $fullInstance"
$result = Set-KeyfactorSQLCertificateBinding -InstanceName $instance -NewThumbprint $NewThumbprint -RestartService:$RestartService
}

if (-not $result) {
Write-Error "Failed to bind certificate for instance: $instance"
$bindingSuccess = $false
}
Comment on lines +29 to +33
# Step 4: Import the certificate into the specified store
Write-Verbose "Importing the certificate to the store: Cert:\LocalMachine\$StoreName"
Set-Location -Path "Cert:\LocalMachine\$StoreName"

$importResult = Import-Certificate -FilePath $cerFilename
Comment on lines +1 to +8
# Store Type creation script using kfutil
# Generated by Doctool

# Uncomment if kfutil is not in your PATH
# Set-Alias -Name kfutil -Value 'C:\Program Files\Keyfactor\kfutil\kfutil.exe'
Write-Host "Creating store type: WinCert"
kfutil store-types create WinCert

if ($null -eq (Get-Command "kfutil" -ErrorAction SilentlyContinue)) {
Write-Host "kfutil could not be found. Please install kfutil"
Write-Host "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
}
Write-Host "Creating store type: IISU"
kfutil store-types create IISU
Comment on lines +1 to +8
#!/bin/bash
# Store Type creation script using kfutil
# Generated by Doctool

# Creates all 4 store types using kfutil.
# kfutil reads definitions from the Keyfactor integration catalog.
#
# Auth environment variables (first matching method is used):
# OAuth access token: KEYFACTOR_AUTH_ACCESS_TOKEN
# OAuth client creds: KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET
# + KEYFACTOR_AUTH_TOKEN_URL
# Basic auth (AD): KEYFACTOR_HOSTNAME + KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD
# + KEYFACTOR_DOMAIN
#
# Auto-generated by doctool generate-store-type-scripts — do not edit by hand.
set -e

if ! command -v kfutil &> /dev/null; then
echo "kfutil could not be found. Please install kfutil"
echo "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
fi
echo "Creating store type: WinCert"
kfutil store-types create WinCert
Comment on lines +2 to +7
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "" },
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "{SQL-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "" },
{ "Machine": "{SQL-JEA-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "192.168.230.139", "StoreType": "WinCert", "JEAEndpointName": "" },
{ "Machine": "192.168.230.139", "StoreType": "WinCert", "JEAEndpointName": "keyfactor.wincert" }
Copilot AI review requested due to automatic review settings July 16, 2026 20:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 83 out of 163 changed files in this pull request and generated 7 comments.

Comment thread WindowsCertStore.UnitTests/SANsUnitTests.cs
Comment thread WindowsCertStore.IntegrationTests/servers.json
Comment thread scripts/store_types/bash/kfutil_create_store_types.sh
Copilot AI review requested due to automatic review settings July 20, 2026 23:53
Fixed tempfile left behind when using ssh

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 83 out of 163 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (5)

IISU/PowerShell/Keyfactor.WinCert.SQL/Public/New-KeyfactorSQLBinding.ps1:41

  • $currentThumbprint is logged before it’s assigned, and the renewal check uses -contains against a string. This makes the renewal path always evaluate false and can incorrectly mark binding as failed when RenewalThumbprint is provided.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1:8
  • [parameter(ParameterSetName = $false)] is not a valid attribute value (ParameterSetName must be a string). This will cause a parse error when importing the module.
    WindowsCertStore.IntegrationTests/servers.json:7
  • servers.json now contains a hard-coded private IP (192.168.230.139). This is environment-specific and can leak internal network details; it also makes the sample file less reusable for other environments. Prefer placeholders or documentation-reserved example IPs.
    scripts/store_types/bash/kfutil_create_store_types.sh:17
  • The script no longer checks whether kfutil is installed or whether the user is logged in; it will now fail with a less actionable error when prerequisites aren’t met. Also, #!/bin/bash is less portable than #!/usr/bin/env bash.
    scripts/store_types/powershell/kfutil_create_store_types.ps1:14
  • The script no longer checks whether kfutil is installed or whether the user is logged in. Without these guards, failures are harder to diagnose in automation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet