Bring the README examples in line with optional -ProjectId and add renewal
Several examples still passed -ProjectId ($Project.Id) from a project lookup the walkthrough no longer performs, so they read as though the parameter were still required. Removed from the profile, policy, subscriber, and certificate authority examples, and from the offline-fallback snippet. The end-to-end example loses the site-specific application name, and the profile selection collapses to one line. Its "Example output" section still showed the project and certificate authority records the example stopped fetching, so it now matches what the script actually emits, including the project-resolution line. Adds a renewal example directly beneath, reusing the parameters built above so the difference is visible as two added keys rather than a second wall of setup. It notes that the call is safe to repeat, that reuse is matched on the issuing profile and the SAN set so a changed profile or added name reissues, and that -Force ignores both. Also drops the note about $CertificateProfile versus the $Profile automatic variable, which explained a naming choice the reader has no reason to care about, and points the extension docs at ResolveCertManagerProjectId rather than the ResolveProjectId name that no longer exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -161,11 +161,9 @@ $ConnectInfisicalParameters = New-Object -TypeName 'System.Collections.Specializ
|
||||
|
||||
$Connection = Connect-Infisical @ConnectInfisicalParameters
|
||||
|
||||
$Application = Get-InfisicalCertificateApplication | Where-Object {($_.Name -ieq '2pint')}
|
||||
$Application = Get-InfisicalCertificateApplication | Where-Object {($_.Name -ieq 'platform')}
|
||||
|
||||
$CertificateProfile = Get-InfisicalCertificateProfile -ApplicationId ($Application.Id) -IncludeConfigs |
|
||||
Where-Object {($_.EnrollmentType -ieq 'api') -and ($_.Slug -imatch 'server')} |
|
||||
Select-Object -First 1
|
||||
$CertificateProfile = Get-InfisicalCertificateProfile -ApplicationId ($Application.Id) -IncludeConfigs | Where-Object {($_.EnrollmentType -ieq 'api') -and ($_.Slug -imatch 'server')} | Select-Object -First 1
|
||||
|
||||
$SanList = Get-InfisicalSANList
|
||||
|
||||
@@ -188,10 +186,30 @@ $Null = Disconnect-Infisical -Verbose
|
||||
|
||||
Four calls: find the application, pick its profile, gather SANs, request. No project lookup — `-ProjectId` resolves itself — and no CA lookup, because the profile already binds its issuing CA and `-InstallChain` installs the whole chain regardless.
|
||||
|
||||
Note `$CertificateProfile` rather than `$Profile`: `$Profile` is an automatic variable in PowerShell (the path to the current profile script), and assigning to it works but shadows something the host relies on.
|
||||
|
||||
`-StoreName`/`-StoreLocation` are omitted deliberately — see [Where certificates get installed](#where-certificates-get-installed).
|
||||
|
||||
## Renewing that certificate
|
||||
|
||||
Run the same request again with `-AllowRenewal`. Nothing else changes — the parameters below are the ones built above, so this is the shape to put on a schedule:
|
||||
|
||||
```powershell
|
||||
$RequestInfisicalCertificateParameters.AllowRenewal = $True
|
||||
$RequestInfisicalCertificateParameters.RenewalThresholdDays = 30
|
||||
|
||||
$Certificate = Request-InfisicalCertificate @RequestInfisicalCertificateParameters
|
||||
```
|
||||
|
||||
The call is safe to repeat. Outside the renewal window it finds the installed certificate and returns it untouched; inside the window it issues a replacement and installs it:
|
||||
|
||||
```text
|
||||
VERBOSE: Reuse search for CN=WEB01 scoped to certificate profile 'a42f8446-...' returned 1 active certificate(s).
|
||||
VERBOSE: Reusing existing certificate (Thumbprint=F480A920..., NotAfter=2026-10-28 19:36:49Z).
|
||||
```
|
||||
|
||||
Reuse is matched on the issuing profile *and* the requested SAN set, so the same script issues a new certificate — rather than silently returning the old one — whenever the profile changes or a name is added to `-DnsName`. `-Force` issues unconditionally, ignoring both the renewal window and any existing certificate.
|
||||
|
||||
Run it daily and it does nothing until the certificate is within 30 days of expiry, then rotates it. Nothing to gate it with, and no state to keep.
|
||||
|
||||
### Project scoping
|
||||
|
||||
Opening **Certificate Manager** in the Infisical console never asks which project to use. The project is in the URL — `/organizations/{orgId}/projects/cert-manager/{projectId}/applications` — but it is chosen for you, and everything below it is presented as **applications**. That is because Infisical's own resolver takes the single Certificate Manager project when an organization has exactly one:
|
||||
@@ -256,12 +274,12 @@ The two are different levels, which is worth keeping straight when reading outpu
|
||||
| **Project** | The Certificate Manager project itself. One per organization in most setups. | `Get-InfisicalProject -Type cert-manager` |
|
||||
| **Application** | A grouping of profiles, members, and certificates inside that project. | `Get-InfisicalCertificateApplication` |
|
||||
|
||||
So a project named `mecm` can contain applications named `2pint` and `microsoft-endpoint-configuration-manager`; listing projects returns only `mecm`, because the others are not projects. Every application carries the `ProjectId` it belongs to.
|
||||
So a project named `pki` can contain applications named `platform` and `endpoint-management`; listing projects returns only `pki`, because the others are not projects. Every application carries the `ProjectId` it belongs to, which is why that field is real rather than vestigial.
|
||||
|
||||
Profiles can be filtered to an application, matching how the console groups them:
|
||||
|
||||
```powershell
|
||||
$Application = Get-InfisicalCertificateApplication | Where-Object {($_.Name -eq '2pint')}
|
||||
$Application = Get-InfisicalCertificateApplication | Where-Object {($_.Name -ieq 'platform')}
|
||||
Get-InfisicalCertificateProfile -ApplicationId $Application.Id -IncludeConfigs
|
||||
Get-InfisicalCertificate -ApplicationId $Application.Id
|
||||
```
|
||||
@@ -269,32 +287,15 @@ Get-InfisicalCertificate -ApplicationId $Application.Id
|
||||
### Example output
|
||||
|
||||
```text
|
||||
Id : 00000000-0000-0000-0000-000000000000
|
||||
Name : Microsoft Endpoint Configuration Manager
|
||||
Slug : mecm
|
||||
Description :
|
||||
OrganizationId : 11111111-1111-1111-1111-111111111111
|
||||
Type : cert-manager
|
||||
AutoCapitalization : False
|
||||
EnvironmentSlugs : {dev, staging, prod}
|
||||
CreatedAtUtc : 3/12/2026 8:32:52 PM +00:00
|
||||
UpdatedAtUtc : 6/21/2026 7:00:28 PM +00:00
|
||||
|
||||
Name : root-ca
|
||||
CommonName : Contoso Root Certificate Authority
|
||||
Type : internal
|
||||
Status : active
|
||||
KeyAlgorithm : RSA_2048
|
||||
NotAfter : 03/25/2036 00:00:00
|
||||
Id : 22222222-2222-2222-2222-222222222222
|
||||
|
||||
Name : intermediate-ca
|
||||
CommonName : Contoso Intermediate Certificate Authority
|
||||
Type : internal
|
||||
Status : active
|
||||
KeyAlgorithm : RSA_2048
|
||||
NotAfter : 03/25/2031 00:00:00
|
||||
Id : 33333333-3333-3333-3333-333333333333
|
||||
Id : 11111111-1111-1111-1111-111111111111
|
||||
ProjectId : 00000000-0000-0000-0000-000000000000
|
||||
Name : platform
|
||||
Description :
|
||||
ProfileCount : 3
|
||||
MemberCount : 2
|
||||
CertificateCount : 0
|
||||
CreatedAtUtc : 7/30/2026 10:05:37 PM +00:00
|
||||
UpdatedAtUtc : 7/30/2026 10:05:37 PM +00:00
|
||||
|
||||
Id : 44444444-4444-4444-4444-444444444444
|
||||
ProjectId : 00000000-0000-0000-0000-000000000000
|
||||
@@ -321,6 +322,7 @@ WEB01.contoso.com
|
||||
127.0.0.1
|
||||
::1
|
||||
|
||||
VERBOSE: [...] - [Information] - [GetInfisicalCertificateApplicationCmdlet] - -ProjectId was not supplied; resolved the organization's only Certificate Manager project 'Platform PKI' (00000000-0000-0000-0000-000000000000).
|
||||
VERBOSE: [...] - [Information] - [PkiClient] - Attempting to search Infisical certificates. Please Wait...
|
||||
VERBOSE: [...] - [Verbose] - [HttpClient] - Attempting HTTP POST to https://infisical.contoso.com/api/v1/projects/00000000-0000-0000-0000-000000000000/certificates/search. Please Wait...
|
||||
VERBOSE: [...] - [Verbose] - [HttpClient] - HTTP POST completed with status 200.
|
||||
@@ -467,8 +469,8 @@ Request-InfisicalCertificate @RequestInfisicalCertificateParameters -WhatIf
|
||||
A certificate profile binds a CA to a certificate policy. The policy constrains the subject, key usages, and extended key usages with `allowed`/`required`/`denied` lists, so the common name still varies per request while staying inside guardrails.
|
||||
|
||||
```powershell
|
||||
Get-InfisicalCertificateProfile -ProjectId ($Project.Id) | Format-Table Id, Name, CaId
|
||||
Get-InfisicalCertificatePolicy -ProjectId ($Project.Id) | Format-Table Id, Name
|
||||
Get-InfisicalCertificateProfile | Format-Table Id, Slug, CaId, EnrollmentType
|
||||
Get-InfisicalCertificatePolicy | Format-Table Id, Name
|
||||
```
|
||||
|
||||
Profile issuance is the only path that does **not** consult the CA's direct-issuance flag — the service short-circuits it:
|
||||
@@ -482,7 +484,7 @@ So a profile issues successfully against a CA whose `EnableDirectIssuance` is `F
|
||||
#### Discovering subscribers
|
||||
|
||||
```powershell
|
||||
Get-InfisicalPkiSubscriber -ProjectId ($Project.Id) |
|
||||
Get-InfisicalPkiSubscriber |
|
||||
Format-Table Name, CommonName, Status, Ttl, CaId
|
||||
```
|
||||
|
||||
@@ -515,10 +517,10 @@ const ca = await certificateAuthorityDAL.create({ projectId, name: resolvedCaNam
|
||||
So **every CA created through the API or UI has direct issuance disabled**, and nothing can turn it on afterwards. Use a certificate profile, which ignores the flag entirely.
|
||||
|
||||
```powershell
|
||||
Get-InfisicalCertificateAuthority -ProjectId ($Project.Id) -Kind Internal |
|
||||
Get-InfisicalCertificateAuthority -Kind Internal |
|
||||
Format-Table Name, CommonName, Status, EnableDirectIssuance
|
||||
|
||||
$Ca = Get-InfisicalCertificateAuthority -ProjectId ($Project.Id) -Kind Internal |
|
||||
$Ca = Get-InfisicalCertificateAuthority -Kind Internal |
|
||||
Where-Object {($_.EnableDirectIssuance -eq $True)} |
|
||||
Select-Object -First 1
|
||||
|
||||
@@ -574,7 +576,7 @@ A failing item does not abort the batch:
|
||||
|
||||
```powershell
|
||||
'web01', 'does-not-exist', 'web02' |
|
||||
ForEach-Object { Get-InfisicalPkiSubscriber -ProjectId $ProjectId -Name $_ -ErrorAction SilentlyContinue }
|
||||
ForEach-Object { Get-InfisicalPkiSubscriber -Name $_ -ErrorAction SilentlyContinue }
|
||||
# emits web01 and web02; the failure is available in $Error
|
||||
```
|
||||
|
||||
@@ -674,7 +676,7 @@ To add a route:
|
||||
|
||||
### Adding a new cmdlet
|
||||
|
||||
Cmdlets live in `src/PSInfisicalAPI/Cmdlets/` and derive from `InfisicalCmdletBase`, which exposes `HttpClient`, `Logger`, `ResolveProjectId`, and `ThrowTerminatingForException`. Follow the consolidated discovery pattern when the cmdlet supports both list and single-record retrieval:
|
||||
Cmdlets live in `src/PSInfisicalAPI/Cmdlets/` and derive from `InfisicalCmdletBase`, which exposes `HttpClient`, `Logger`, `ResolveCertManagerProjectId`, and `ThrowTerminatingForException`. Follow the consolidated discovery pattern when the cmdlet supports both list and single-record retrieval:
|
||||
|
||||
```csharp
|
||||
[Cmdlet(VerbsCommon.Get, "InfisicalPkiSubscriber", DefaultParameterSetName = "List")]
|
||||
@@ -699,7 +701,7 @@ After adding (or removing) a cmdlet:
|
||||
|
||||
```powershell
|
||||
$Params = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase)
|
||||
$Params.ProjectId = (Get-InfisicalProject | Select-Object -First 1).Id
|
||||
$Params.ProjectId = (Get-InfisicalProject -Type cert-manager | Select-Object -First 1).Id
|
||||
$Result = Get-InfisicalPkiSubscriber @Params
|
||||
```
|
||||
4. Add a `## Unreleased` entry to `CHANGELOG.md` describing the change (mark removals of public cmdlets or parameters as **BREAKING**).
|
||||
|
||||
Reference in New Issue
Block a user