diff --git a/CHANGELOG.md b/CHANGELOG.md index 6703ba2..4efa7a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,17 +6,35 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) loos ## Unreleased +## 2026.06.04.1911 + +- Build produced from commit 51bf819c37e5. + +## Unreleased (carried forward) + +## 2026.06.04.1906 + +- Build produced from commit 51bf819c37e5. + +## Unreleased (carried forward) + +- **BREAKING**: Removed the plural-noun discovery cmdlets `Get-InfisicalProjects`, `Get-InfisicalEnvironments`, `Get-InfisicalFolders`, `Get-InfisicalTags`, `Get-InfisicalSecrets`, and `Get-InfisicalCertificates`. Their behavior is now folded into the corresponding singular cmdlets via a `List` (default) / single-record parameter set pair, matching the existing `Get-InfisicalCertificateAuthority` precedent. Callers should drop the trailing `s`; invocation without the identity parameter (`-ProjectId`, `-EnvironmentSlugOrId`, `-FolderNameOrId`, `-TagSlugOrId`, `-SecretName`, `-SerialNumber`) now returns the list, and supplying the identity parameter returns the single record. No back-compat aliases were added. +- Added `Get-InfisicalPkiSubscriber` with `List` (default) and `ByName` parameter sets, backed by new `InfisicalPkiClient.ListPkiSubscribers` and `GetPkiSubscriber` methods, an `InfisicalPkiSubscriber` model, and corresponding DTOs/mapper. Use the emitted `Name` (slug) on `Request-InfisicalCertificate -PkiSubscriberSlug`. +- **Bug fix**: `Request-InfisicalCertificate -PkiSubscriberSlug ...` was returning 404 because the registry's `SignCertificateBySubscriber` endpoint pointed at `/api/v1/pki/pki-subscribers/{subscriberName}/sign-certificate` and `/api/v1/cert-manager/pki-subscribers/...`. Per Infisical's `v1/index.ts`, the subscriber router is mounted at `/pki/subscribers`, so the single correct path is `/api/v1/pki/subscribers/{subscriberName}/sign-certificate`. The redundant `cert-manager` template was removed; the PKI endpoint registry tests were updated to match. +- Updated MAML help in `Module/PSInfisicalAPI/en-US/PSInfisicalAPI.dll-Help.xml`: the six consolidated cmdlets and the new `Get-InfisicalPkiSubscriber` each ship three examples — two straight-line invocations (one per parameter set) plus one `OrderedDictionary` splat example. All in-text references to the removed plural cmdlets across other cmdlets' examples were updated to the singular form. +- `build.ps1`: `CmdletsToExport` and the `Test-ModuleImports` expected cmdlet list were updated to drop the six plural cmdlets and add `Get-InfisicalPkiSubscriber` (total: 34 exported cmdlets). + ## 2026.06.04.1825 - Build produced from commit 19615363e356. -## Unreleased (carried forward) +## Unreleased (carried forward) ## 2026.06.04.1820 - Build produced from commit 19615363e356. -## Unreleased (carried forward) +## Unreleased (carried forward) - `Install-InfisicalCertificate` now routes chain certificates by self-signed status instead of dumping every chain entry into the Intermediate Certification Authorities store. Self-signed roots are installed into `StoreName.Root` (Trusted Root Certification Authorities) and non-self-signed intermediates are installed into `StoreName.CertificateAuthority` (Intermediate Certification Authorities). The leaf continues to use the user-specified `-StoreName`/`-StoreLocation` (default `My`/`CurrentUser`). `Request-InfisicalCertificate` already routed chain certs correctly; the same routing helper is now shared by both cmdlets. - `InfisicalCertificateRequestHelpers` exposes a new public `GetChainCertificateTargetStore(X509Certificate2)` classifier and a new `InstallChain(IEnumerable, StoreLocation, bool, IInfisicalLogger, string)` overload. The existing `InstallChain(InfisicalSignedCertificate, ...)` overload now delegates to the new collection-based overload, so PKI chain-installation routing is centralized in one place. diff --git a/Module/PSInfisicalAPI/PSInfisicalAPI.psd1 b/Module/PSInfisicalAPI/PSInfisicalAPI.psd1 index 5ffa120..20bb1bb 100644 --- a/Module/PSInfisicalAPI/PSInfisicalAPI.psd1 +++ b/Module/PSInfisicalAPI/PSInfisicalAPI.psd1 @@ -1,6 +1,6 @@ @{ RootModule = 'PSInfisicalAPI.psm1' - ModuleVersion = '2026.06.04.1825' + ModuleVersion = '2026.06.04.1911' GUID = 'b8a2f3d4-7c51-4d2f-9e6a-1f0c8b3d4e51' Author = 'Grace Solutions' CompanyName = 'Grace Solutions' @@ -12,7 +12,6 @@ CmdletsToExport = @( 'Connect-Infisical', 'Disconnect-Infisical', - 'Get-InfisicalSecrets', 'Get-InfisicalSecret', 'New-InfisicalSecret', 'Update-InfisicalSecret', @@ -20,29 +19,25 @@ 'Copy-InfisicalSecret', 'ConvertTo-InfisicalSecretDictionary', 'Export-InfisicalSecrets', - 'Get-InfisicalProjects', 'Get-InfisicalProject', 'New-InfisicalProject', 'Update-InfisicalProject', 'Remove-InfisicalProject', - 'Get-InfisicalEnvironments', 'Get-InfisicalEnvironment', 'New-InfisicalEnvironment', 'Update-InfisicalEnvironment', 'Remove-InfisicalEnvironment', - 'Get-InfisicalFolders', 'Get-InfisicalFolder', 'New-InfisicalFolder', 'Update-InfisicalFolder', 'Remove-InfisicalFolder', - 'Get-InfisicalTags', 'Get-InfisicalTag', 'New-InfisicalTag', 'Update-InfisicalTag', 'Remove-InfisicalTag', 'Get-InfisicalCertificateAuthority', + 'Get-InfisicalPkiSubscriber', 'Get-InfisicalCertificate', - 'Get-InfisicalCertificates', 'Search-InfisicalCertificate', 'Request-InfisicalCertificate', 'ConvertTo-InfisicalCertificate', @@ -60,7 +55,7 @@ LicenseUri = 'https://www.gnu.org/licenses/agpl-3.0.html' ProjectUri = 'https://prod.git.gracesolution.info/gsadmin/PSInfisicalAPI' ReleaseNotes = 'See CHANGELOG.md in the project repository for release history.' - CommitHash = '19615363e356' + CommitHash = '51bf819c37e5' } } } \ No newline at end of file diff --git a/Module/PSInfisicalAPI/bin/PSInfisicalAPI.dll b/Module/PSInfisicalAPI/bin/PSInfisicalAPI.dll index 634d6d8..bb515ee 100644 Binary files a/Module/PSInfisicalAPI/bin/PSInfisicalAPI.dll and b/Module/PSInfisicalAPI/bin/PSInfisicalAPI.dll differ diff --git a/Module/PSInfisicalAPI/bin/en-US/PSInfisicalAPI.dll-Help.xml b/Module/PSInfisicalAPI/bin/en-US/PSInfisicalAPI.dll-Help.xml index dc9fb90..8540047 100644 --- a/Module/PSInfisicalAPI/bin/en-US/PSInfisicalAPI.dll-Help.xml +++ b/Module/PSInfisicalAPI/bin/en-US/PSInfisicalAPI.dll-Help.xml @@ -81,77 +81,43 @@ $DisconnectInfisicalResult = Disconnect-Infisical @DisconnectInfisicalParameters Get-InfisicalSecret - Retrieves a single Infisical secret by name from the active session's project and environment. + Lists or retrieves Infisical secrets within a project, environment, and optional folder path. Get InfisicalSecret - Fetches a single secret by name. Project, Environment, SecretPath, and ApiVersion default to the values pinned on the active InfisicalConnection but can be overridden per call. Optional flags request reference-expansion, import inclusion, or a specific historical version. + Default (List parameter set) enumerates secrets under the active session's project and environment, optionally recursing through subfolders and filtering by metadata or tag slugs. When -SecretName is supplied (Single parameter set) the cmdlet returns one secret by name; -Version and -Type tune the single-record fetch. ProjectId, Environment, SecretPath, and ApiVersion default to the values pinned on the active InfisicalConnection in both modes. Notes - The returned InfisicalSecret stores the value as SecureString; call .GetPlainTextValue() to materialize the cleartext value only when strictly required. + Use -Recursive together with -SecretPath to walk an entire folder subtree in List mode. Pipe the result into ConvertTo-InfisicalSecretDictionary for hashtable-style lookup. The returned InfisicalSecret stores the value as SecureString; call .GetPlainTextValue() to materialize the cleartext value only when strictly required. EXAMPLE 1 - Get-InfisicalSecret -SecretName 'DATABASE_URL' - Retrieves the DATABASE_URL secret from the project and environment pinned by Connect-Infisical. - - - EXAMPLE 2 - $GetInfisicalSecretParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalSecretParameters.SecretName = 'DATABASE_URL' -$GetInfisicalSecretParameters.ProjectId = $ConnectInfisicalParameters.ProjectId -$GetInfisicalSecretParameters.Environment = $ConnectInfisicalParameters.Environment -$GetInfisicalSecretParameters.SecretPath = "/Windows/$($CallingScriptPath.BaseName)" -$GetInfisicalSecretParameters.ExpandSecretReferences = $True -$GetInfisicalSecretParameters.IncludeImports = $True -$GetInfisicalSecretParameters.Verbose = $True - -$GetInfisicalSecretResult = Get-InfisicalSecret @GetInfisicalSecretParameters - Retrieves a single secret from a script-specific subpath with secret-reference expansion and folder imports enabled. - - - - - - - Get-InfisicalSecrets - Lists Infisical secrets within a project, environment, and optional folder path. - Get - InfisicalSecrets - - - Enumerates secrets under the active session's project and environment, optionally recursing through subfolders. Supports metadata-based filtering, tag-slug filtering, secret-reference expansion, and personal-override inclusion. - - - Notes - - Use -Recursive together with -SecretPath to walk an entire folder subtree. Pipe the result into ConvertTo-InfisicalSecretDictionary for hashtable-style lookup. - - - - - EXAMPLE 1 - Get-InfisicalSecrets -SecretPath '/Windows' -Recursive + Get-InfisicalSecret -SecretPath '/Windows' -Recursive Lists every secret under /Windows in the active project and environment. EXAMPLE 2 - $GetInfisicalSecretsParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalSecretsParameters.ProjectId = $ConnectInfisicalParameters.ProjectId -$GetInfisicalSecretsParameters.Environment = $ConnectInfisicalParameters.Environment -$GetInfisicalSecretsParameters.SecretPath = "/Windows/$($CallingScriptPath.BaseName)" -$GetInfisicalSecretsParameters.Recursive = $True -$GetInfisicalSecretsParameters.ExpandSecretReferences = $True -$GetInfisicalSecretsParameters.IncludeImports = $True -$GetInfisicalSecretsParameters.IncludePersonalOverrides = $True -$GetInfisicalSecretsParameters.Verbose = $True + Get-InfisicalSecret -SecretName 'DATABASE_URL' + Retrieves the DATABASE_URL secret from the project and environment pinned by Connect-Infisical. + + + EXAMPLE 3 + $GetInfisicalSecretParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) +$GetInfisicalSecretParameters.ProjectId = $ConnectInfisicalParameters.ProjectId +$GetInfisicalSecretParameters.Environment = $ConnectInfisicalParameters.Environment +$GetInfisicalSecretParameters.SecretPath = "/Windows/$($CallingScriptPath.BaseName)" +$GetInfisicalSecretParameters.Recursive = $True +$GetInfisicalSecretParameters.ExpandSecretReferences = $True +$GetInfisicalSecretParameters.IncludeImports = $True +$GetInfisicalSecretParameters.IncludePersonalOverrides = $True +$GetInfisicalSecretParameters.Verbose = $True -$GetInfisicalSecretsResult = Get-InfisicalSecrets @GetInfisicalSecretsParameters +$GetInfisicalSecretResult = Get-InfisicalSecret @GetInfisicalSecretParameters Lists secrets under a script-specific subpath with imports, personal overrides, and reference expansion enabled. @@ -181,7 +147,7 @@ $GetInfisicalSecretsResult = Get-InfisicalSecrets @GetInfisicalSecretsParameters EXAMPLE 2 - $GetInfisicalTagsResult = Get-InfisicalTags -ProjectId $ConnectInfisicalParameters.ProjectId + $GetInfisicalTagResult = Get-InfisicalTag -ProjectId $ConnectInfisicalParameters.ProjectId $NewInfisicalSecretParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) $NewInfisicalSecretParameters.SecretName = 'API_KEY' @@ -190,7 +156,7 @@ $NewInfisicalSecretParameters.SecretComment = 'Issued by deployment pipeline' $NewInfisicalSecretParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $NewInfisicalSecretParameters.Environment = $ConnectInfisicalParameters.Environment $NewInfisicalSecretParameters.SecretPath = "/Windows/$($CallingScriptPath.BaseName)" -$NewInfisicalSecretParameters.TagIds = @($GetInfisicalTagsResult[0].Id) +$NewInfisicalSecretParameters.TagIds = @($GetInfisicalTagResult[0].Id) $NewInfisicalSecretParameters.Verbose = $True $NewInfisicalSecretResult = New-InfisicalSecret @NewInfisicalSecretParameters @@ -286,7 +252,7 @@ $RemoveInfisicalSecretResult = Remove-InfisicalSecret @RemoveInfisicalSecretPara InfisicalSecret - Server-side duplicates an array of secret IDs into a destination environment (and optional destination path), with switches that control whether the value, comment, tags, and metadata are copied. Use Get-InfisicalSecrets followed by selection of the desired Id values to feed -SecretId. + Server-side duplicates an array of secret IDs into a destination environment (and optional destination path), with switches that control whether the value, comment, tags, and metadata are copied. Use Get-InfisicalSecret followed by selection of the desired Id values to feed -SecretId. Notes @@ -297,15 +263,15 @@ $RemoveInfisicalSecretResult = Remove-InfisicalSecret @RemoveInfisicalSecretPara EXAMPLE 1 - Get-InfisicalSecrets | Select-Object -ExpandProperty Id | Copy-InfisicalSecret -DestinationEnvironment 'staging' -CopySecretValue + Get-InfisicalSecret | Select-Object -ExpandProperty Id | Copy-InfisicalSecret -DestinationEnvironment 'staging' -CopySecretValue Copies all secrets from the active environment into 'staging', including their values. EXAMPLE 2 - $GetInfisicalSecretsResult = Get-InfisicalSecrets -SecretPath '/Windows' -Recursive + $GetInfisicalSecretResult = Get-InfisicalSecret -SecretPath '/Windows' -Recursive $CopyInfisicalSecretParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$CopyInfisicalSecretParameters.SecretId = $GetInfisicalSecretsResult.Id +$CopyInfisicalSecretParameters.SecretId = $GetInfisicalSecretResult.Id $CopyInfisicalSecretParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $CopyInfisicalSecretParameters.SourceEnvironment = $ConnectInfisicalParameters.Environment $CopyInfisicalSecretParameters.SourceSecretPath = '/Windows' @@ -343,15 +309,15 @@ $CopyInfisicalSecretResult = Copy-InfisicalSecret @CopyInfisicalSecretParameters EXAMPLE 1 - Get-InfisicalSecrets | ConvertTo-InfisicalSecretDictionary -AsPlainText + Get-InfisicalSecret | ConvertTo-InfisicalSecretDictionary -AsPlainText Builds a plain-text dictionary of every secret in the active environment. EXAMPLE 2 - $GetInfisicalSecretsResult = Get-InfisicalSecrets -SecretPath "/Windows/$($CallingScriptPath.BaseName)" -Recursive + $GetInfisicalSecretResult = Get-InfisicalSecret -SecretPath "/Windows/$($CallingScriptPath.BaseName)" -Recursive $ConvertToInfisicalSecretDictionaryParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$ConvertToInfisicalSecretDictionaryParameters.InputObject = $GetInfisicalSecretsResult +$ConvertToInfisicalSecretDictionaryParameters.InputObject = $GetInfisicalSecretResult $ConvertToInfisicalSecretDictionaryParameters.DuplicateKeyBehavior = 'LastWins' $ConvertToInfisicalSecretDictionaryParameters.AsPlainText = $True $ConvertToInfisicalSecretDictionaryParameters.Verbose = $True @@ -381,15 +347,15 @@ $ConvertToInfisicalSecretDictionaryResult = ConvertTo-InfisicalSecretDictionary EXAMPLE 1 - Get-InfisicalSecrets | Export-InfisicalSecrets -Format DotEnv -Path '.\.env' -Force + Get-InfisicalSecret | Export-InfisicalSecrets -Format DotEnv -Path '.\.env' -Force Writes the active environment's secrets to a .env file. EXAMPLE 2 - $GetInfisicalSecretsResult = Get-InfisicalSecrets -SecretPath "/Windows/$($CallingScriptPath.BaseName)" -Recursive + $GetInfisicalSecretResult = Get-InfisicalSecret -SecretPath "/Windows/$($CallingScriptPath.BaseName)" -Recursive $ExportInfisicalSecretsParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$ExportInfisicalSecretsParameters.InputObject = $GetInfisicalSecretsResult +$ExportInfisicalSecretsParameters.InputObject = $GetInfisicalSecretResult $ExportInfisicalSecretsParameters.Format = 'EnvironmentVariables' $ExportInfisicalSecretsParameters.Scope = 'Process' $ExportInfisicalSecretsParameters.Force = $True @@ -401,71 +367,43 @@ $ExportInfisicalSecretsResult = Export-InfisicalSecrets @ExportInfisicalSecretsP - - - Get-InfisicalProjects - Lists Infisical projects accessible to the current identity. - Get - InfisicalProjects - - - Returns every project the active session can see. The cmdlet requires an active InfisicalConnection but takes no parameters; project visibility is governed by Infisical's role assignments. - - - Notes - - The result is an array of InfisicalProject objects; pipe into Where-Object or Select-Object to filter by Slug, Name, or Id. - - - - - EXAMPLE 1 - Get-InfisicalProjects - Lists every project the current session can see. - - - EXAMPLE 2 - $GetInfisicalProjectsParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalProjectsParameters.Verbose = $True - -$GetInfisicalProjectsResult = Get-InfisicalProjects @GetInfisicalProjectsParameters | Where-Object { $_.Slug -ilike 'platform-*' } - Lists projects and filters down to those whose slug begins with 'platform-'. - - - - Get-InfisicalProject - Retrieves a single Infisical project by its identifier. + Lists or retrieves Infisical projects accessible to the current identity. Get InfisicalProject - Retrieves one project by Id. If -ProjectId is not supplied, the cmdlet falls back to the ProjectId pinned on the active InfisicalConnection. + Default (List parameter set) returns every project the active session can see; project visibility is governed by Infisical's role assignments. When -ProjectId is supplied (Single parameter set) the cmdlet returns the one matching record. Notes - The cmdlet accepts pipeline input by property name; objects emitted by Get-InfisicalProjects can be piped in directly to refresh a single record. + The List-mode result is an array of InfisicalProject objects; pipe into Where-Object or Select-Object to filter by Slug, Name, or Id. The cmdlet accepts pipeline input by property name on -ProjectId. EXAMPLE 1 Get-InfisicalProject - Retrieves the project pinned by the active session. + Lists every project the current session can see. EXAMPLE 2 - $GetInfisicalProjectsResult = Get-InfisicalProjects + Get-InfisicalProject -ProjectId $ConnectInfisicalParameters.ProjectId + Retrieves the canonical record for the project pinned by the active session. + + + EXAMPLE 3 + $GetInfisicalProjectListResult = Get-InfisicalProject | Where-Object { $_.Slug -ilike 'platform-*' } $GetInfisicalProjectParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalProjectParameters.ProjectId = $GetInfisicalProjectsResult[0].Id +$GetInfisicalProjectParameters.ProjectId = $GetInfisicalProjectListResult[0].Id $GetInfisicalProjectParameters.Verbose = $True $GetInfisicalProjectResult = Get-InfisicalProject @GetInfisicalProjectParameters - Looks up the first project in the list and retrieves its full record. + Filters the project list to slugs that begin with 'platform-' and refetches the first match by id. @@ -532,10 +470,10 @@ $NewInfisicalProjectResult = New-InfisicalProject @NewInfisicalProjectParameters EXAMPLE 2 - $GetInfisicalProjectsResult = Get-InfisicalProjects | Where-Object { $_.Slug -eq 'platform-telemetry' } + $GetInfisicalProjectResult = Get-InfisicalProject | Where-Object { $_.Slug -eq 'platform-telemetry' } $UpdateInfisicalProjectParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$UpdateInfisicalProjectParameters.ProjectId = $GetInfisicalProjectsResult.Id +$UpdateInfisicalProjectParameters.ProjectId = $GetInfisicalProjectResult.Id $UpdateInfisicalProjectParameters.Name = 'Platform Telemetry (v2)' $UpdateInfisicalProjectParameters.Description = 'Migrated to v2 pipeline' $UpdateInfisicalProjectParameters.AutoCapitalization = $False @@ -571,10 +509,10 @@ $UpdateInfisicalProjectResult = Update-InfisicalProject @UpdateInfisicalProjectP EXAMPLE 2 - $GetInfisicalProjectsResult = Get-InfisicalProjects | Where-Object { $_.Slug -eq 'sandbox-temp' } + $GetInfisicalProjectResult = Get-InfisicalProject | Where-Object { $_.Slug -eq 'sandbox-temp' } $RemoveInfisicalProjectParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$RemoveInfisicalProjectParameters.ProjectId = $GetInfisicalProjectsResult.Id +$RemoveInfisicalProjectParameters.ProjectId = $GetInfisicalProjectResult.Id $RemoveInfisicalProjectParameters.PassThru = $True $RemoveInfisicalProjectParameters.Confirm = $False $RemoveInfisicalProjectParameters.Verbose = $True @@ -585,75 +523,44 @@ $RemoveInfisicalProjectResult = Remove-InfisicalProject @RemoveInfisicalProjectP - - - Get-InfisicalEnvironments - Lists environments defined on an Infisical project. - Get - InfisicalEnvironments - - - Returns all environments configured on a project. -ProjectId defaults to the session-pinned project id when omitted. - - - Notes - - Each InfisicalEnvironment carries both Id and Slug; downstream cmdlets accept either form on -Environment-like parameters. - - - - - EXAMPLE 1 - Get-InfisicalEnvironments - Lists environments for the session-pinned project. - - - EXAMPLE 2 - $GetInfisicalProjectsResult = Get-InfisicalProjects | Where-Object { $_.Slug -eq 'platform-telemetry' } - -$GetInfisicalEnvironmentsParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalEnvironmentsParameters.ProjectId = $GetInfisicalProjectsResult.Id -$GetInfisicalEnvironmentsParameters.Verbose = $True - -$GetInfisicalEnvironmentsResult = Get-InfisicalEnvironments @GetInfisicalEnvironmentsParameters - Resolves a project by slug and lists every environment defined on it. - - - - Get-InfisicalEnvironment - Retrieves a single Infisical environment by slug or id. + Lists or retrieves Infisical environments defined on a project. Get InfisicalEnvironment - Returns one environment record by slug or id (-EnvironmentSlugOrId). -ProjectId defaults to the session-pinned project when omitted. + Default (List parameter set) returns every environment configured on the session-pinned project. When -EnvironmentSlugOrId is supplied (Single parameter set) the cmdlet returns one environment by slug or id. -ProjectId defaults to the session-pinned project in both modes. Notes - Accepts pipeline input by property name so InfisicalEnvironment objects from Get-InfisicalEnvironments can be refreshed directly. + Each InfisicalEnvironment carries both Id and Slug; downstream cmdlets accept either form on -Environment-like parameters. Accepts pipeline input by property name on -EnvironmentSlugOrId. EXAMPLE 1 + Get-InfisicalEnvironment + Lists every environment defined on the session-pinned project. + + + EXAMPLE 2 Get-InfisicalEnvironment -EnvironmentSlugOrId 'dev' Retrieves the 'dev' environment from the session-pinned project. - EXAMPLE 2 - $GetInfisicalEnvironmentsResult = Get-InfisicalEnvironments | Where-Object { $_.Slug -eq 'dev' } + EXAMPLE 3 + $GetInfisicalProjectResult = Get-InfisicalProject | Where-Object { $_.Slug -eq 'platform-telemetry' } $GetInfisicalEnvironmentParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalEnvironmentParameters.EnvironmentSlugOrId = $GetInfisicalEnvironmentsResult.Slug -$GetInfisicalEnvironmentParameters.ProjectId = $ConnectInfisicalParameters.ProjectId +$GetInfisicalEnvironmentParameters.EnvironmentSlugOrId = 'dev' +$GetInfisicalEnvironmentParameters.ProjectId = $GetInfisicalProjectResult.Id $GetInfisicalEnvironmentParameters.Verbose = $True $GetInfisicalEnvironmentResult = Get-InfisicalEnvironment @GetInfisicalEnvironmentParameters - Looks up the dev environment by slug and re-fetches the canonical record by slug or id. + Resolves a project by slug and re-fetches the dev environment record by slug under that project. @@ -682,10 +589,10 @@ $GetInfisicalEnvironmentResult = Get-InfisicalEnvironment @GetInfisicalEnvironme EXAMPLE 2 - $GetInfisicalProjectsResult = Get-InfisicalProjects | Where-Object { $_.Slug -eq 'platform-telemetry' } + $GetInfisicalProjectResult = Get-InfisicalProject | Where-Object { $_.Slug -eq 'platform-telemetry' } $NewInfisicalEnvironmentParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$NewInfisicalEnvironmentParameters.ProjectId = $GetInfisicalProjectsResult.Id +$NewInfisicalEnvironmentParameters.ProjectId = $GetInfisicalProjectResult.Id $NewInfisicalEnvironmentParameters.Name = 'Staging' $NewInfisicalEnvironmentParameters.Slug = 'staging' $NewInfisicalEnvironmentParameters.Position = 20 @@ -721,10 +628,10 @@ $NewInfisicalEnvironmentResult = New-InfisicalEnvironment @NewInfisicalEnvironme EXAMPLE 2 - $GetInfisicalEnvironmentsResult = Get-InfisicalEnvironments | Where-Object { $_.Slug -eq 'staging' } + $GetInfisicalEnvironmentResult = Get-InfisicalEnvironment | Where-Object { $_.Slug -eq 'staging' } $UpdateInfisicalEnvironmentParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$UpdateInfisicalEnvironmentParameters.EnvironmentId = $GetInfisicalEnvironmentsResult.Id +$UpdateInfisicalEnvironmentParameters.EnvironmentId = $GetInfisicalEnvironmentResult.Id $UpdateInfisicalEnvironmentParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $UpdateInfisicalEnvironmentParameters.Name = 'Pre-Production' $UpdateInfisicalEnvironmentParameters.Slug = 'preprod' @@ -761,10 +668,10 @@ $UpdateInfisicalEnvironmentResult = Update-InfisicalEnvironment @UpdateInfisical EXAMPLE 2 - $GetInfisicalEnvironmentsResult = Get-InfisicalEnvironments | Where-Object { $_.Slug -eq 'sandbox' } + $GetInfisicalEnvironmentResult = Get-InfisicalEnvironment | Where-Object { $_.Slug -eq 'sandbox' } $RemoveInfisicalEnvironmentParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$RemoveInfisicalEnvironmentParameters.EnvironmentId = $GetInfisicalEnvironmentsResult.Id +$RemoveInfisicalEnvironmentParameters.EnvironmentId = $GetInfisicalEnvironmentResult.Id $RemoveInfisicalEnvironmentParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $RemoveInfisicalEnvironmentParameters.PassThru = $True $RemoveInfisicalEnvironmentParameters.Confirm = $False @@ -776,70 +683,39 @@ $RemoveInfisicalEnvironmentResult = Remove-InfisicalEnvironment @RemoveInfisical - - - Get-InfisicalFolders - Lists Infisical folders at a given secret path. - Get - InfisicalFolders - - - Enumerates folders directly under the supplied -Path within the active project and environment. -ProjectId, -Environment, and -Path default to the session-pinned values when omitted. - - - Notes - - This is a non-recursive listing of immediate subfolders. To enumerate secrets across a folder subtree use Get-InfisicalSecrets -Recursive. - - - - - EXAMPLE 1 - Get-InfisicalFolders -Path '/Windows' - Lists every folder directly under /Windows in the active project and environment. - - - EXAMPLE 2 - $GetInfisicalFoldersParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalFoldersParameters.ProjectId = $ConnectInfisicalParameters.ProjectId -$GetInfisicalFoldersParameters.Environment = $ConnectInfisicalParameters.Environment -$GetInfisicalFoldersParameters.Path = "/Windows/$($CallingScriptPath.BaseName)" -$GetInfisicalFoldersParameters.Verbose = $True - -$GetInfisicalFoldersResult = Get-InfisicalFolders @GetInfisicalFoldersParameters - Lists folders under a script-specific subpath using the session-pinned project and environment. - - - - Get-InfisicalFolder - Retrieves a single Infisical folder by name or id. + Lists or retrieves Infisical folders at a given secret path. Get InfisicalFolder - Returns one folder record by name or id (-FolderNameOrId) under the supplied -Path. -ProjectId, -Environment, and -Path default to the session-pinned values when omitted. + Default (List parameter set) enumerates folders directly under the supplied -Path within the active project and environment. When -FolderNameOrId is supplied (Single parameter set) the cmdlet returns one folder by name or id under -Path. -ProjectId, -Environment, and -Path default to the session-pinned values in both modes. Notes - Accepts pipeline input by property name so InfisicalFolder objects from Get-InfisicalFolders can be refreshed directly. + List mode is a non-recursive listing of immediate subfolders. To enumerate secrets across a folder subtree use Get-InfisicalSecret -Recursive. Accepts pipeline input by property name on -FolderNameOrId. EXAMPLE 1 + Get-InfisicalFolder -Path '/Windows' + Lists every folder directly under /Windows in the active project and environment. + + + EXAMPLE 2 Get-InfisicalFolder -FolderNameOrId 'Deployments' -Path '/Windows' Retrieves the Deployments folder under /Windows in the active project and environment. - EXAMPLE 2 - $GetInfisicalFoldersResult = Get-InfisicalFolders -Path '/Windows' | Where-Object { $_.Name -eq 'Deployments' } + EXAMPLE 3 + $GetInfisicalFolderListResult = Get-InfisicalFolder -Path '/Windows' | Where-Object { $_.Name -eq 'Deployments' } $GetInfisicalFolderParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalFolderParameters.FolderNameOrId = $GetInfisicalFoldersResult.Id +$GetInfisicalFolderParameters.FolderNameOrId = $GetInfisicalFolderListResult.Id $GetInfisicalFolderParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $GetInfisicalFolderParameters.Environment = $ConnectInfisicalParameters.Environment $GetInfisicalFolderParameters.Path = '/Windows' @@ -912,10 +788,10 @@ $NewInfisicalFolderResult = New-InfisicalFolder @NewInfisicalFolderParameters EXAMPLE 2 - $GetInfisicalFoldersResult = Get-InfisicalFolders -Path '/Windows' | Where-Object { $_.Name -eq 'Deployments' } + $GetInfisicalFolderResult = Get-InfisicalFolder -Path '/Windows' | Where-Object { $_.Name -eq 'Deployments' } $UpdateInfisicalFolderParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$UpdateInfisicalFolderParameters.FolderId = $GetInfisicalFoldersResult.Id +$UpdateInfisicalFolderParameters.FolderId = $GetInfisicalFolderResult.Id $UpdateInfisicalFolderParameters.Name = 'Deployments-Archive' $UpdateInfisicalFolderParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $UpdateInfisicalFolderParameters.Environment = $ConnectInfisicalParameters.Environment @@ -952,10 +828,10 @@ $UpdateInfisicalFolderResult = Update-InfisicalFolder @UpdateInfisicalFolderPara EXAMPLE 2 - $GetInfisicalFoldersResult = Get-InfisicalFolders -Path '/Windows' | Where-Object { $_.Name -eq $CallingScriptPath.BaseName } + $GetInfisicalFolderResult = Get-InfisicalFolder -Path '/Windows' | Where-Object { $_.Name -eq $CallingScriptPath.BaseName } $RemoveInfisicalFolderParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$RemoveInfisicalFolderParameters.FolderId = $GetInfisicalFoldersResult.Id +$RemoveInfisicalFolderParameters.FolderId = $GetInfisicalFolderResult.Id $RemoveInfisicalFolderParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $RemoveInfisicalFolderParameters.Environment = $ConnectInfisicalParameters.Environment $RemoveInfisicalFolderParameters.Path = '/Windows' @@ -969,75 +845,44 @@ $RemoveInfisicalFolderResult = Remove-InfisicalFolder @RemoveInfisicalFolderPara - - - Get-InfisicalTags - Lists Infisical tags defined on a project. - Get - InfisicalTags - - - Returns every tag configured on a project. -ProjectId defaults to the session-pinned project id when omitted. - - - Notes - - Tag Ids returned here are the values to pass on -TagIds when creating or updating secrets. - - - - - EXAMPLE 1 - Get-InfisicalTags - Lists every tag defined on the session-pinned project. - - - EXAMPLE 2 - $GetInfisicalProjectsResult = Get-InfisicalProjects | Where-Object { $_.Slug -eq 'platform-telemetry' } - -$GetInfisicalTagsParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalTagsParameters.ProjectId = $GetInfisicalProjectsResult.Id -$GetInfisicalTagsParameters.Verbose = $True - -$GetInfisicalTagsResult = Get-InfisicalTags @GetInfisicalTagsParameters - Resolves a project by slug and lists every tag defined on it. - - - - Get-InfisicalTag - Retrieves a single Infisical tag by slug or id. + Lists or retrieves Infisical tags defined on a project. Get InfisicalTag - Returns one tag record by slug or id (-TagSlugOrId). -ProjectId defaults to the session-pinned project when omitted. + Default (List parameter set) returns every tag configured on the project. When -TagSlugOrId is supplied (Single parameter set) the cmdlet returns the one matching record. -ProjectId defaults to the session-pinned project in both modes. Notes - Accepts pipeline input by property name so InfisicalTag objects from Get-InfisicalTags can be refreshed directly. + Tag Ids returned here are the values to pass on -TagIds when creating or updating secrets. Accepts pipeline input by property name on -TagSlugOrId. EXAMPLE 1 + Get-InfisicalTag + Lists every tag defined on the session-pinned project. + + + EXAMPLE 2 Get-InfisicalTag -TagSlugOrId 'critical' Retrieves the 'critical' tag from the session-pinned project. - EXAMPLE 2 - $GetInfisicalTagsResult = Get-InfisicalTags | Where-Object { $_.Slug -eq 'critical' } + EXAMPLE 3 + $GetInfisicalProjectResult = Get-InfisicalProject | Where-Object { $_.Slug -eq 'platform-telemetry' } $GetInfisicalTagParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalTagParameters.TagSlugOrId = $GetInfisicalTagsResult.Slug -$GetInfisicalTagParameters.ProjectId = $ConnectInfisicalParameters.ProjectId +$GetInfisicalTagParameters.TagSlugOrId = 'critical' +$GetInfisicalTagParameters.ProjectId = $GetInfisicalProjectResult.Id $GetInfisicalTagParameters.Verbose = $True $GetInfisicalTagResult = Get-InfisicalTag @GetInfisicalTagParameters - Filters tags to the critical slug and refetches the canonical record. + Resolves a project by slug and refetches the 'critical' tag from that project. @@ -1103,10 +948,10 @@ $NewInfisicalTagResult = New-InfisicalTag @NewInfisicalTagParameters EXAMPLE 2 - $GetInfisicalTagsResult = Get-InfisicalTags | Where-Object { $_.Slug -eq 'critical' } + $GetInfisicalTagResult = Get-InfisicalTag | Where-Object { $_.Slug -eq 'critical' } $UpdateInfisicalTagParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$UpdateInfisicalTagParameters.TagId = $GetInfisicalTagsResult.Id +$UpdateInfisicalTagParameters.TagId = $GetInfisicalTagResult.Id $UpdateInfisicalTagParameters.Slug = 'critical-v2' $UpdateInfisicalTagParameters.Name = 'Critical (v2)' $UpdateInfisicalTagParameters.Color = '#FFA500' @@ -1143,10 +988,10 @@ $UpdateInfisicalTagResult = Update-InfisicalTag @UpdateInfisicalTagParameters EXAMPLE 2 - $GetInfisicalTagsResult = Get-InfisicalTags | Where-Object { $_.Slug -eq 'critical-v2' } + $GetInfisicalTagResult = Get-InfisicalTag | Where-Object { $_.Slug -eq 'critical-v2' } $RemoveInfisicalTagParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$RemoveInfisicalTagParameters.TagId = $GetInfisicalTagsResult.Id +$RemoveInfisicalTagParameters.TagId = $GetInfisicalTagResult.Id $RemoveInfisicalTagParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $RemoveInfisicalTagParameters.PassThru = $True $RemoveInfisicalTagParameters.Confirm = $False @@ -1197,40 +1042,45 @@ $GetInfisicalCertificateAuthorityResult = Get-InfisicalCertificateAuthority @Get - Get-InfisicalCertificates - Lists Infisical certificates in a project, with optional filters and automatic paging. + Get-InfisicalCertificate + Lists or retrieves Infisical certificates in a project, with optional filters and automatic paging. Get - InfisicalCertificates + InfisicalCertificate - Enumerates certificates with optional filters for -CommonName, -FriendlyName, -Status, and -CaId. -Limit and -Offset drive a single page; pages are walked automatically until exhausted unless -NoAutoPage is supplied. -ProjectId defaults to the session-pinned project when omitted. + Default (List parameter set) enumerates certificates with optional filters for -CommonName, -FriendlyName, -Status, and -CaId; -Limit and -Offset drive a single page and pages are walked automatically until exhausted unless -NoAutoPage is supplied. When -SerialNumber is supplied (Single parameter set) the cmdlet returns one certificate record. -ProjectId defaults to the session-pinned project in both modes. Notes - For advanced filtering (validity window, key algorithm, extended key usage, etc.) use Search-InfisicalCertificate instead. + For advanced filtering (validity window, key algorithm, extended key usage, etc.) use Search-InfisicalCertificate instead. Single mode returns metadata only; to obtain certificate and chain PEM material use ConvertTo-InfisicalCertificate or Export-InfisicalCertificate. Accepts pipeline input by property name on -SerialNumber. EXAMPLE 1 - Get-InfisicalCertificates -Status 'active' + Get-InfisicalCertificate -Status 'active' Lists every active certificate in the session-pinned project. EXAMPLE 2 + Get-InfisicalCertificate -SerialNumber '7A:F2:1B:...:9E' + Retrieves the certificate record for the supplied serial number. + + + EXAMPLE 3 $GetInfisicalCertificateAuthorityListResult = Get-InfisicalCertificateAuthority | Where-Object { $_.FriendlyName -eq 'Issuing CA - Platform' } -$GetInfisicalCertificatesParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalCertificatesParameters.ProjectId = $ConnectInfisicalParameters.ProjectId -$GetInfisicalCertificatesParameters.CommonName = $env:COMPUTERNAME -$GetInfisicalCertificatesParameters.FriendlyName = 'web-tier' -$GetInfisicalCertificatesParameters.Status = 'active' -$GetInfisicalCertificatesParameters.CaId = @($GetInfisicalCertificateAuthorityListResult.Id) -$GetInfisicalCertificatesParameters.Limit = 100 -$GetInfisicalCertificatesParameters.Verbose = $True +$GetInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) +$GetInfisicalCertificateParameters.ProjectId = $ConnectInfisicalParameters.ProjectId +$GetInfisicalCertificateParameters.CommonName = $env:COMPUTERNAME +$GetInfisicalCertificateParameters.FriendlyName = 'web-tier' +$GetInfisicalCertificateParameters.Status = 'active' +$GetInfisicalCertificateParameters.CaId = @($GetInfisicalCertificateAuthorityListResult.Id) +$GetInfisicalCertificateParameters.Limit = 100 +$GetInfisicalCertificateParameters.Verbose = $True -$GetInfisicalCertificatesResult = Get-InfisicalCertificates @GetInfisicalCertificatesParameters +$GetInfisicalCertificateListResult = Get-InfisicalCertificate @GetInfisicalCertificateParameters Resolves the issuing CA, then lists active certificates scoped to that CA, the local hostname, and the 'web-tier' friendly name. @@ -1238,36 +1088,42 @@ $GetInfisicalCertificatesResult = Get-InfisicalCertificates @GetInfisicalCertifi - Get-InfisicalCertificate - Retrieves a single Infisical certificate by serial number. + Get-InfisicalPkiSubscriber + Lists or retrieves Infisical PKI subscribers in a project. Get - InfisicalCertificate + InfisicalPkiSubscriber - Returns one certificate record by -SerialNumber. Accepts pipeline input by property name so InfisicalCertificate objects from list/search cmdlets can be re-fetched directly. + Default (List parameter set) returns every PKI subscriber configured on the project. When -Name is supplied (ByName parameter set) the cmdlet returns one subscriber by its slug. -ProjectId defaults to the session-pinned project in both modes. Notes - This returns metadata only. To obtain certificate and chain PEM material use ConvertTo-InfisicalCertificate or Export-InfisicalCertificate. + The -Name parameter is the subscriber slug; aliases SubscriberName and Slug are accepted. Pass the slug returned here on -PkiSubscriberSlug when calling Request-InfisicalCertificate. Accepts pipeline input by property name on -Name. EXAMPLE 1 - Get-InfisicalCertificate -SerialNumber '7A:F2:1B:...:9E' - Retrieves the certificate record for the supplied serial number. + Get-InfisicalPkiSubscriber + Lists every PKI subscriber defined on the session-pinned project. EXAMPLE 2 - $GetInfisicalCertificatesResult = Get-InfisicalCertificates -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } + Get-InfisicalPkiSubscriber -Name 'mecm' + Retrieves the 'mecm' PKI subscriber from the session-pinned project. + + + EXAMPLE 3 + $GetInfisicalPkiSubscriberListResult = Get-InfisicalPkiSubscriber | Where-Object { $_.Name -ilike 'mecm*' } -$GetInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificatesResult[0].SerialNumber -$GetInfisicalCertificateParameters.Verbose = $True +$GetInfisicalPkiSubscriberParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) +$GetInfisicalPkiSubscriberParameters.Name = $GetInfisicalPkiSubscriberListResult[0].Name +$GetInfisicalPkiSubscriberParameters.ProjectId = $ConnectInfisicalParameters.ProjectId +$GetInfisicalPkiSubscriberParameters.Verbose = $True -$GetInfisicalCertificateResult = Get-InfisicalCertificate @GetInfisicalCertificateParameters - Selects the active certificate whose common name matches the host and refetches its canonical record. +$GetInfisicalPkiSubscriberResult = Get-InfisicalPkiSubscriber @GetInfisicalPkiSubscriberParameters + Filters subscribers whose name starts with 'mecm' and refetches the canonical record for the first match. @@ -1388,10 +1244,10 @@ $RequestInfisicalCertificateResult = Request-InfisicalCertificate @RequestInfisi EXAMPLE 2 - $GetInfisicalCertificatesResult = Get-InfisicalCertificates -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } + $GetInfisicalCertificateResult = Get-InfisicalCertificate -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } $ConvertToInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$ConvertToInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificatesResult[0].SerialNumber +$ConvertToInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificateResult[0].SerialNumber $ConvertToInfisicalCertificateParameters.NoPrivateKey = $False $ConvertToInfisicalCertificateParameters.IncludeChain = $True $ConvertToInfisicalCertificateParameters.KeyStorageFlags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable @@ -1427,10 +1283,10 @@ $ConvertToInfisicalCertificateResult = ConvertTo-InfisicalCertificate @ConvertTo EXAMPLE 2 - $GetInfisicalCertificatesResult = Get-InfisicalCertificates -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } + $GetInfisicalCertificateResult = Get-InfisicalCertificate -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } $ExportInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$ExportInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificatesResult[0].SerialNumber +$ExportInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificateResult[0].SerialNumber $ExportInfisicalCertificateParameters.Path = "C:\Temp\$($env:COMPUTERNAME).pfx" $ExportInfisicalCertificateParameters.Format = 'Pfx' $ExportInfisicalCertificateParameters.Password = (Read-Host -AsSecureString -Prompt 'PFX password') @@ -1468,10 +1324,10 @@ $ExportInfisicalCertificateResult = Export-InfisicalCertificate @ExportInfisical EXAMPLE 2 - $GetInfisicalCertificatesResult = Get-InfisicalCertificates -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } + $GetInfisicalCertificateResult = Get-InfisicalCertificate -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } $InstallInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$InstallInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificatesResult[0].SerialNumber +$InstallInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificateResult[0].SerialNumber $InstallInfisicalCertificateParameters.StoreName = 'My' $InstallInfisicalCertificateParameters.StoreLocation = 'LocalMachine' $InstallInfisicalCertificateParameters.KeyStorageFlags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet @@ -1510,10 +1366,10 @@ $InstallInfisicalCertificateResult = Install-InfisicalCertificate @InstallInfisi EXAMPLE 2 - $GetInfisicalCertificatesResult = Get-InfisicalCertificates -Status 'revoked' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } + $GetInfisicalCertificateResult = Get-InfisicalCertificate -Status 'revoked' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } $UninstallInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$UninstallInfisicalCertificateParameters.InfisicalCertificate = $GetInfisicalCertificatesResult[0] +$UninstallInfisicalCertificateParameters.InfisicalCertificate = $GetInfisicalCertificateResult[0] $UninstallInfisicalCertificateParameters.StoreName = 'My' $UninstallInfisicalCertificateParameters.StoreLocation = 'LocalMachine' $UninstallInfisicalCertificateParameters.Force = $True diff --git a/Module/PSInfisicalAPI/en-US/PSInfisicalAPI.dll-Help.xml b/Module/PSInfisicalAPI/en-US/PSInfisicalAPI.dll-Help.xml index dc9fb90..8540047 100644 --- a/Module/PSInfisicalAPI/en-US/PSInfisicalAPI.dll-Help.xml +++ b/Module/PSInfisicalAPI/en-US/PSInfisicalAPI.dll-Help.xml @@ -81,77 +81,43 @@ $DisconnectInfisicalResult = Disconnect-Infisical @DisconnectInfisicalParameters Get-InfisicalSecret - Retrieves a single Infisical secret by name from the active session's project and environment. + Lists or retrieves Infisical secrets within a project, environment, and optional folder path. Get InfisicalSecret - Fetches a single secret by name. Project, Environment, SecretPath, and ApiVersion default to the values pinned on the active InfisicalConnection but can be overridden per call. Optional flags request reference-expansion, import inclusion, or a specific historical version. + Default (List parameter set) enumerates secrets under the active session's project and environment, optionally recursing through subfolders and filtering by metadata or tag slugs. When -SecretName is supplied (Single parameter set) the cmdlet returns one secret by name; -Version and -Type tune the single-record fetch. ProjectId, Environment, SecretPath, and ApiVersion default to the values pinned on the active InfisicalConnection in both modes. Notes - The returned InfisicalSecret stores the value as SecureString; call .GetPlainTextValue() to materialize the cleartext value only when strictly required. + Use -Recursive together with -SecretPath to walk an entire folder subtree in List mode. Pipe the result into ConvertTo-InfisicalSecretDictionary for hashtable-style lookup. The returned InfisicalSecret stores the value as SecureString; call .GetPlainTextValue() to materialize the cleartext value only when strictly required. EXAMPLE 1 - Get-InfisicalSecret -SecretName 'DATABASE_URL' - Retrieves the DATABASE_URL secret from the project and environment pinned by Connect-Infisical. - - - EXAMPLE 2 - $GetInfisicalSecretParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalSecretParameters.SecretName = 'DATABASE_URL' -$GetInfisicalSecretParameters.ProjectId = $ConnectInfisicalParameters.ProjectId -$GetInfisicalSecretParameters.Environment = $ConnectInfisicalParameters.Environment -$GetInfisicalSecretParameters.SecretPath = "/Windows/$($CallingScriptPath.BaseName)" -$GetInfisicalSecretParameters.ExpandSecretReferences = $True -$GetInfisicalSecretParameters.IncludeImports = $True -$GetInfisicalSecretParameters.Verbose = $True - -$GetInfisicalSecretResult = Get-InfisicalSecret @GetInfisicalSecretParameters - Retrieves a single secret from a script-specific subpath with secret-reference expansion and folder imports enabled. - - - - - - - Get-InfisicalSecrets - Lists Infisical secrets within a project, environment, and optional folder path. - Get - InfisicalSecrets - - - Enumerates secrets under the active session's project and environment, optionally recursing through subfolders. Supports metadata-based filtering, tag-slug filtering, secret-reference expansion, and personal-override inclusion. - - - Notes - - Use -Recursive together with -SecretPath to walk an entire folder subtree. Pipe the result into ConvertTo-InfisicalSecretDictionary for hashtable-style lookup. - - - - - EXAMPLE 1 - Get-InfisicalSecrets -SecretPath '/Windows' -Recursive + Get-InfisicalSecret -SecretPath '/Windows' -Recursive Lists every secret under /Windows in the active project and environment. EXAMPLE 2 - $GetInfisicalSecretsParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalSecretsParameters.ProjectId = $ConnectInfisicalParameters.ProjectId -$GetInfisicalSecretsParameters.Environment = $ConnectInfisicalParameters.Environment -$GetInfisicalSecretsParameters.SecretPath = "/Windows/$($CallingScriptPath.BaseName)" -$GetInfisicalSecretsParameters.Recursive = $True -$GetInfisicalSecretsParameters.ExpandSecretReferences = $True -$GetInfisicalSecretsParameters.IncludeImports = $True -$GetInfisicalSecretsParameters.IncludePersonalOverrides = $True -$GetInfisicalSecretsParameters.Verbose = $True + Get-InfisicalSecret -SecretName 'DATABASE_URL' + Retrieves the DATABASE_URL secret from the project and environment pinned by Connect-Infisical. + + + EXAMPLE 3 + $GetInfisicalSecretParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) +$GetInfisicalSecretParameters.ProjectId = $ConnectInfisicalParameters.ProjectId +$GetInfisicalSecretParameters.Environment = $ConnectInfisicalParameters.Environment +$GetInfisicalSecretParameters.SecretPath = "/Windows/$($CallingScriptPath.BaseName)" +$GetInfisicalSecretParameters.Recursive = $True +$GetInfisicalSecretParameters.ExpandSecretReferences = $True +$GetInfisicalSecretParameters.IncludeImports = $True +$GetInfisicalSecretParameters.IncludePersonalOverrides = $True +$GetInfisicalSecretParameters.Verbose = $True -$GetInfisicalSecretsResult = Get-InfisicalSecrets @GetInfisicalSecretsParameters +$GetInfisicalSecretResult = Get-InfisicalSecret @GetInfisicalSecretParameters Lists secrets under a script-specific subpath with imports, personal overrides, and reference expansion enabled. @@ -181,7 +147,7 @@ $GetInfisicalSecretsResult = Get-InfisicalSecrets @GetInfisicalSecretsParameters EXAMPLE 2 - $GetInfisicalTagsResult = Get-InfisicalTags -ProjectId $ConnectInfisicalParameters.ProjectId + $GetInfisicalTagResult = Get-InfisicalTag -ProjectId $ConnectInfisicalParameters.ProjectId $NewInfisicalSecretParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) $NewInfisicalSecretParameters.SecretName = 'API_KEY' @@ -190,7 +156,7 @@ $NewInfisicalSecretParameters.SecretComment = 'Issued by deployment pipeline' $NewInfisicalSecretParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $NewInfisicalSecretParameters.Environment = $ConnectInfisicalParameters.Environment $NewInfisicalSecretParameters.SecretPath = "/Windows/$($CallingScriptPath.BaseName)" -$NewInfisicalSecretParameters.TagIds = @($GetInfisicalTagsResult[0].Id) +$NewInfisicalSecretParameters.TagIds = @($GetInfisicalTagResult[0].Id) $NewInfisicalSecretParameters.Verbose = $True $NewInfisicalSecretResult = New-InfisicalSecret @NewInfisicalSecretParameters @@ -286,7 +252,7 @@ $RemoveInfisicalSecretResult = Remove-InfisicalSecret @RemoveInfisicalSecretPara InfisicalSecret - Server-side duplicates an array of secret IDs into a destination environment (and optional destination path), with switches that control whether the value, comment, tags, and metadata are copied. Use Get-InfisicalSecrets followed by selection of the desired Id values to feed -SecretId. + Server-side duplicates an array of secret IDs into a destination environment (and optional destination path), with switches that control whether the value, comment, tags, and metadata are copied. Use Get-InfisicalSecret followed by selection of the desired Id values to feed -SecretId. Notes @@ -297,15 +263,15 @@ $RemoveInfisicalSecretResult = Remove-InfisicalSecret @RemoveInfisicalSecretPara EXAMPLE 1 - Get-InfisicalSecrets | Select-Object -ExpandProperty Id | Copy-InfisicalSecret -DestinationEnvironment 'staging' -CopySecretValue + Get-InfisicalSecret | Select-Object -ExpandProperty Id | Copy-InfisicalSecret -DestinationEnvironment 'staging' -CopySecretValue Copies all secrets from the active environment into 'staging', including their values. EXAMPLE 2 - $GetInfisicalSecretsResult = Get-InfisicalSecrets -SecretPath '/Windows' -Recursive + $GetInfisicalSecretResult = Get-InfisicalSecret -SecretPath '/Windows' -Recursive $CopyInfisicalSecretParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$CopyInfisicalSecretParameters.SecretId = $GetInfisicalSecretsResult.Id +$CopyInfisicalSecretParameters.SecretId = $GetInfisicalSecretResult.Id $CopyInfisicalSecretParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $CopyInfisicalSecretParameters.SourceEnvironment = $ConnectInfisicalParameters.Environment $CopyInfisicalSecretParameters.SourceSecretPath = '/Windows' @@ -343,15 +309,15 @@ $CopyInfisicalSecretResult = Copy-InfisicalSecret @CopyInfisicalSecretParameters EXAMPLE 1 - Get-InfisicalSecrets | ConvertTo-InfisicalSecretDictionary -AsPlainText + Get-InfisicalSecret | ConvertTo-InfisicalSecretDictionary -AsPlainText Builds a plain-text dictionary of every secret in the active environment. EXAMPLE 2 - $GetInfisicalSecretsResult = Get-InfisicalSecrets -SecretPath "/Windows/$($CallingScriptPath.BaseName)" -Recursive + $GetInfisicalSecretResult = Get-InfisicalSecret -SecretPath "/Windows/$($CallingScriptPath.BaseName)" -Recursive $ConvertToInfisicalSecretDictionaryParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$ConvertToInfisicalSecretDictionaryParameters.InputObject = $GetInfisicalSecretsResult +$ConvertToInfisicalSecretDictionaryParameters.InputObject = $GetInfisicalSecretResult $ConvertToInfisicalSecretDictionaryParameters.DuplicateKeyBehavior = 'LastWins' $ConvertToInfisicalSecretDictionaryParameters.AsPlainText = $True $ConvertToInfisicalSecretDictionaryParameters.Verbose = $True @@ -381,15 +347,15 @@ $ConvertToInfisicalSecretDictionaryResult = ConvertTo-InfisicalSecretDictionary EXAMPLE 1 - Get-InfisicalSecrets | Export-InfisicalSecrets -Format DotEnv -Path '.\.env' -Force + Get-InfisicalSecret | Export-InfisicalSecrets -Format DotEnv -Path '.\.env' -Force Writes the active environment's secrets to a .env file. EXAMPLE 2 - $GetInfisicalSecretsResult = Get-InfisicalSecrets -SecretPath "/Windows/$($CallingScriptPath.BaseName)" -Recursive + $GetInfisicalSecretResult = Get-InfisicalSecret -SecretPath "/Windows/$($CallingScriptPath.BaseName)" -Recursive $ExportInfisicalSecretsParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$ExportInfisicalSecretsParameters.InputObject = $GetInfisicalSecretsResult +$ExportInfisicalSecretsParameters.InputObject = $GetInfisicalSecretResult $ExportInfisicalSecretsParameters.Format = 'EnvironmentVariables' $ExportInfisicalSecretsParameters.Scope = 'Process' $ExportInfisicalSecretsParameters.Force = $True @@ -401,71 +367,43 @@ $ExportInfisicalSecretsResult = Export-InfisicalSecrets @ExportInfisicalSecretsP - - - Get-InfisicalProjects - Lists Infisical projects accessible to the current identity. - Get - InfisicalProjects - - - Returns every project the active session can see. The cmdlet requires an active InfisicalConnection but takes no parameters; project visibility is governed by Infisical's role assignments. - - - Notes - - The result is an array of InfisicalProject objects; pipe into Where-Object or Select-Object to filter by Slug, Name, or Id. - - - - - EXAMPLE 1 - Get-InfisicalProjects - Lists every project the current session can see. - - - EXAMPLE 2 - $GetInfisicalProjectsParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalProjectsParameters.Verbose = $True - -$GetInfisicalProjectsResult = Get-InfisicalProjects @GetInfisicalProjectsParameters | Where-Object { $_.Slug -ilike 'platform-*' } - Lists projects and filters down to those whose slug begins with 'platform-'. - - - - Get-InfisicalProject - Retrieves a single Infisical project by its identifier. + Lists or retrieves Infisical projects accessible to the current identity. Get InfisicalProject - Retrieves one project by Id. If -ProjectId is not supplied, the cmdlet falls back to the ProjectId pinned on the active InfisicalConnection. + Default (List parameter set) returns every project the active session can see; project visibility is governed by Infisical's role assignments. When -ProjectId is supplied (Single parameter set) the cmdlet returns the one matching record. Notes - The cmdlet accepts pipeline input by property name; objects emitted by Get-InfisicalProjects can be piped in directly to refresh a single record. + The List-mode result is an array of InfisicalProject objects; pipe into Where-Object or Select-Object to filter by Slug, Name, or Id. The cmdlet accepts pipeline input by property name on -ProjectId. EXAMPLE 1 Get-InfisicalProject - Retrieves the project pinned by the active session. + Lists every project the current session can see. EXAMPLE 2 - $GetInfisicalProjectsResult = Get-InfisicalProjects + Get-InfisicalProject -ProjectId $ConnectInfisicalParameters.ProjectId + Retrieves the canonical record for the project pinned by the active session. + + + EXAMPLE 3 + $GetInfisicalProjectListResult = Get-InfisicalProject | Where-Object { $_.Slug -ilike 'platform-*' } $GetInfisicalProjectParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalProjectParameters.ProjectId = $GetInfisicalProjectsResult[0].Id +$GetInfisicalProjectParameters.ProjectId = $GetInfisicalProjectListResult[0].Id $GetInfisicalProjectParameters.Verbose = $True $GetInfisicalProjectResult = Get-InfisicalProject @GetInfisicalProjectParameters - Looks up the first project in the list and retrieves its full record. + Filters the project list to slugs that begin with 'platform-' and refetches the first match by id. @@ -532,10 +470,10 @@ $NewInfisicalProjectResult = New-InfisicalProject @NewInfisicalProjectParameters EXAMPLE 2 - $GetInfisicalProjectsResult = Get-InfisicalProjects | Where-Object { $_.Slug -eq 'platform-telemetry' } + $GetInfisicalProjectResult = Get-InfisicalProject | Where-Object { $_.Slug -eq 'platform-telemetry' } $UpdateInfisicalProjectParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$UpdateInfisicalProjectParameters.ProjectId = $GetInfisicalProjectsResult.Id +$UpdateInfisicalProjectParameters.ProjectId = $GetInfisicalProjectResult.Id $UpdateInfisicalProjectParameters.Name = 'Platform Telemetry (v2)' $UpdateInfisicalProjectParameters.Description = 'Migrated to v2 pipeline' $UpdateInfisicalProjectParameters.AutoCapitalization = $False @@ -571,10 +509,10 @@ $UpdateInfisicalProjectResult = Update-InfisicalProject @UpdateInfisicalProjectP EXAMPLE 2 - $GetInfisicalProjectsResult = Get-InfisicalProjects | Where-Object { $_.Slug -eq 'sandbox-temp' } + $GetInfisicalProjectResult = Get-InfisicalProject | Where-Object { $_.Slug -eq 'sandbox-temp' } $RemoveInfisicalProjectParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$RemoveInfisicalProjectParameters.ProjectId = $GetInfisicalProjectsResult.Id +$RemoveInfisicalProjectParameters.ProjectId = $GetInfisicalProjectResult.Id $RemoveInfisicalProjectParameters.PassThru = $True $RemoveInfisicalProjectParameters.Confirm = $False $RemoveInfisicalProjectParameters.Verbose = $True @@ -585,75 +523,44 @@ $RemoveInfisicalProjectResult = Remove-InfisicalProject @RemoveInfisicalProjectP - - - Get-InfisicalEnvironments - Lists environments defined on an Infisical project. - Get - InfisicalEnvironments - - - Returns all environments configured on a project. -ProjectId defaults to the session-pinned project id when omitted. - - - Notes - - Each InfisicalEnvironment carries both Id and Slug; downstream cmdlets accept either form on -Environment-like parameters. - - - - - EXAMPLE 1 - Get-InfisicalEnvironments - Lists environments for the session-pinned project. - - - EXAMPLE 2 - $GetInfisicalProjectsResult = Get-InfisicalProjects | Where-Object { $_.Slug -eq 'platform-telemetry' } - -$GetInfisicalEnvironmentsParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalEnvironmentsParameters.ProjectId = $GetInfisicalProjectsResult.Id -$GetInfisicalEnvironmentsParameters.Verbose = $True - -$GetInfisicalEnvironmentsResult = Get-InfisicalEnvironments @GetInfisicalEnvironmentsParameters - Resolves a project by slug and lists every environment defined on it. - - - - Get-InfisicalEnvironment - Retrieves a single Infisical environment by slug or id. + Lists or retrieves Infisical environments defined on a project. Get InfisicalEnvironment - Returns one environment record by slug or id (-EnvironmentSlugOrId). -ProjectId defaults to the session-pinned project when omitted. + Default (List parameter set) returns every environment configured on the session-pinned project. When -EnvironmentSlugOrId is supplied (Single parameter set) the cmdlet returns one environment by slug or id. -ProjectId defaults to the session-pinned project in both modes. Notes - Accepts pipeline input by property name so InfisicalEnvironment objects from Get-InfisicalEnvironments can be refreshed directly. + Each InfisicalEnvironment carries both Id and Slug; downstream cmdlets accept either form on -Environment-like parameters. Accepts pipeline input by property name on -EnvironmentSlugOrId. EXAMPLE 1 + Get-InfisicalEnvironment + Lists every environment defined on the session-pinned project. + + + EXAMPLE 2 Get-InfisicalEnvironment -EnvironmentSlugOrId 'dev' Retrieves the 'dev' environment from the session-pinned project. - EXAMPLE 2 - $GetInfisicalEnvironmentsResult = Get-InfisicalEnvironments | Where-Object { $_.Slug -eq 'dev' } + EXAMPLE 3 + $GetInfisicalProjectResult = Get-InfisicalProject | Where-Object { $_.Slug -eq 'platform-telemetry' } $GetInfisicalEnvironmentParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalEnvironmentParameters.EnvironmentSlugOrId = $GetInfisicalEnvironmentsResult.Slug -$GetInfisicalEnvironmentParameters.ProjectId = $ConnectInfisicalParameters.ProjectId +$GetInfisicalEnvironmentParameters.EnvironmentSlugOrId = 'dev' +$GetInfisicalEnvironmentParameters.ProjectId = $GetInfisicalProjectResult.Id $GetInfisicalEnvironmentParameters.Verbose = $True $GetInfisicalEnvironmentResult = Get-InfisicalEnvironment @GetInfisicalEnvironmentParameters - Looks up the dev environment by slug and re-fetches the canonical record by slug or id. + Resolves a project by slug and re-fetches the dev environment record by slug under that project. @@ -682,10 +589,10 @@ $GetInfisicalEnvironmentResult = Get-InfisicalEnvironment @GetInfisicalEnvironme EXAMPLE 2 - $GetInfisicalProjectsResult = Get-InfisicalProjects | Where-Object { $_.Slug -eq 'platform-telemetry' } + $GetInfisicalProjectResult = Get-InfisicalProject | Where-Object { $_.Slug -eq 'platform-telemetry' } $NewInfisicalEnvironmentParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$NewInfisicalEnvironmentParameters.ProjectId = $GetInfisicalProjectsResult.Id +$NewInfisicalEnvironmentParameters.ProjectId = $GetInfisicalProjectResult.Id $NewInfisicalEnvironmentParameters.Name = 'Staging' $NewInfisicalEnvironmentParameters.Slug = 'staging' $NewInfisicalEnvironmentParameters.Position = 20 @@ -721,10 +628,10 @@ $NewInfisicalEnvironmentResult = New-InfisicalEnvironment @NewInfisicalEnvironme EXAMPLE 2 - $GetInfisicalEnvironmentsResult = Get-InfisicalEnvironments | Where-Object { $_.Slug -eq 'staging' } + $GetInfisicalEnvironmentResult = Get-InfisicalEnvironment | Where-Object { $_.Slug -eq 'staging' } $UpdateInfisicalEnvironmentParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$UpdateInfisicalEnvironmentParameters.EnvironmentId = $GetInfisicalEnvironmentsResult.Id +$UpdateInfisicalEnvironmentParameters.EnvironmentId = $GetInfisicalEnvironmentResult.Id $UpdateInfisicalEnvironmentParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $UpdateInfisicalEnvironmentParameters.Name = 'Pre-Production' $UpdateInfisicalEnvironmentParameters.Slug = 'preprod' @@ -761,10 +668,10 @@ $UpdateInfisicalEnvironmentResult = Update-InfisicalEnvironment @UpdateInfisical EXAMPLE 2 - $GetInfisicalEnvironmentsResult = Get-InfisicalEnvironments | Where-Object { $_.Slug -eq 'sandbox' } + $GetInfisicalEnvironmentResult = Get-InfisicalEnvironment | Where-Object { $_.Slug -eq 'sandbox' } $RemoveInfisicalEnvironmentParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$RemoveInfisicalEnvironmentParameters.EnvironmentId = $GetInfisicalEnvironmentsResult.Id +$RemoveInfisicalEnvironmentParameters.EnvironmentId = $GetInfisicalEnvironmentResult.Id $RemoveInfisicalEnvironmentParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $RemoveInfisicalEnvironmentParameters.PassThru = $True $RemoveInfisicalEnvironmentParameters.Confirm = $False @@ -776,70 +683,39 @@ $RemoveInfisicalEnvironmentResult = Remove-InfisicalEnvironment @RemoveInfisical - - - Get-InfisicalFolders - Lists Infisical folders at a given secret path. - Get - InfisicalFolders - - - Enumerates folders directly under the supplied -Path within the active project and environment. -ProjectId, -Environment, and -Path default to the session-pinned values when omitted. - - - Notes - - This is a non-recursive listing of immediate subfolders. To enumerate secrets across a folder subtree use Get-InfisicalSecrets -Recursive. - - - - - EXAMPLE 1 - Get-InfisicalFolders -Path '/Windows' - Lists every folder directly under /Windows in the active project and environment. - - - EXAMPLE 2 - $GetInfisicalFoldersParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalFoldersParameters.ProjectId = $ConnectInfisicalParameters.ProjectId -$GetInfisicalFoldersParameters.Environment = $ConnectInfisicalParameters.Environment -$GetInfisicalFoldersParameters.Path = "/Windows/$($CallingScriptPath.BaseName)" -$GetInfisicalFoldersParameters.Verbose = $True - -$GetInfisicalFoldersResult = Get-InfisicalFolders @GetInfisicalFoldersParameters - Lists folders under a script-specific subpath using the session-pinned project and environment. - - - - Get-InfisicalFolder - Retrieves a single Infisical folder by name or id. + Lists or retrieves Infisical folders at a given secret path. Get InfisicalFolder - Returns one folder record by name or id (-FolderNameOrId) under the supplied -Path. -ProjectId, -Environment, and -Path default to the session-pinned values when omitted. + Default (List parameter set) enumerates folders directly under the supplied -Path within the active project and environment. When -FolderNameOrId is supplied (Single parameter set) the cmdlet returns one folder by name or id under -Path. -ProjectId, -Environment, and -Path default to the session-pinned values in both modes. Notes - Accepts pipeline input by property name so InfisicalFolder objects from Get-InfisicalFolders can be refreshed directly. + List mode is a non-recursive listing of immediate subfolders. To enumerate secrets across a folder subtree use Get-InfisicalSecret -Recursive. Accepts pipeline input by property name on -FolderNameOrId. EXAMPLE 1 + Get-InfisicalFolder -Path '/Windows' + Lists every folder directly under /Windows in the active project and environment. + + + EXAMPLE 2 Get-InfisicalFolder -FolderNameOrId 'Deployments' -Path '/Windows' Retrieves the Deployments folder under /Windows in the active project and environment. - EXAMPLE 2 - $GetInfisicalFoldersResult = Get-InfisicalFolders -Path '/Windows' | Where-Object { $_.Name -eq 'Deployments' } + EXAMPLE 3 + $GetInfisicalFolderListResult = Get-InfisicalFolder -Path '/Windows' | Where-Object { $_.Name -eq 'Deployments' } $GetInfisicalFolderParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalFolderParameters.FolderNameOrId = $GetInfisicalFoldersResult.Id +$GetInfisicalFolderParameters.FolderNameOrId = $GetInfisicalFolderListResult.Id $GetInfisicalFolderParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $GetInfisicalFolderParameters.Environment = $ConnectInfisicalParameters.Environment $GetInfisicalFolderParameters.Path = '/Windows' @@ -912,10 +788,10 @@ $NewInfisicalFolderResult = New-InfisicalFolder @NewInfisicalFolderParameters EXAMPLE 2 - $GetInfisicalFoldersResult = Get-InfisicalFolders -Path '/Windows' | Where-Object { $_.Name -eq 'Deployments' } + $GetInfisicalFolderResult = Get-InfisicalFolder -Path '/Windows' | Where-Object { $_.Name -eq 'Deployments' } $UpdateInfisicalFolderParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$UpdateInfisicalFolderParameters.FolderId = $GetInfisicalFoldersResult.Id +$UpdateInfisicalFolderParameters.FolderId = $GetInfisicalFolderResult.Id $UpdateInfisicalFolderParameters.Name = 'Deployments-Archive' $UpdateInfisicalFolderParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $UpdateInfisicalFolderParameters.Environment = $ConnectInfisicalParameters.Environment @@ -952,10 +828,10 @@ $UpdateInfisicalFolderResult = Update-InfisicalFolder @UpdateInfisicalFolderPara EXAMPLE 2 - $GetInfisicalFoldersResult = Get-InfisicalFolders -Path '/Windows' | Where-Object { $_.Name -eq $CallingScriptPath.BaseName } + $GetInfisicalFolderResult = Get-InfisicalFolder -Path '/Windows' | Where-Object { $_.Name -eq $CallingScriptPath.BaseName } $RemoveInfisicalFolderParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$RemoveInfisicalFolderParameters.FolderId = $GetInfisicalFoldersResult.Id +$RemoveInfisicalFolderParameters.FolderId = $GetInfisicalFolderResult.Id $RemoveInfisicalFolderParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $RemoveInfisicalFolderParameters.Environment = $ConnectInfisicalParameters.Environment $RemoveInfisicalFolderParameters.Path = '/Windows' @@ -969,75 +845,44 @@ $RemoveInfisicalFolderResult = Remove-InfisicalFolder @RemoveInfisicalFolderPara - - - Get-InfisicalTags - Lists Infisical tags defined on a project. - Get - InfisicalTags - - - Returns every tag configured on a project. -ProjectId defaults to the session-pinned project id when omitted. - - - Notes - - Tag Ids returned here are the values to pass on -TagIds when creating or updating secrets. - - - - - EXAMPLE 1 - Get-InfisicalTags - Lists every tag defined on the session-pinned project. - - - EXAMPLE 2 - $GetInfisicalProjectsResult = Get-InfisicalProjects | Where-Object { $_.Slug -eq 'platform-telemetry' } - -$GetInfisicalTagsParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalTagsParameters.ProjectId = $GetInfisicalProjectsResult.Id -$GetInfisicalTagsParameters.Verbose = $True - -$GetInfisicalTagsResult = Get-InfisicalTags @GetInfisicalTagsParameters - Resolves a project by slug and lists every tag defined on it. - - - - Get-InfisicalTag - Retrieves a single Infisical tag by slug or id. + Lists or retrieves Infisical tags defined on a project. Get InfisicalTag - Returns one tag record by slug or id (-TagSlugOrId). -ProjectId defaults to the session-pinned project when omitted. + Default (List parameter set) returns every tag configured on the project. When -TagSlugOrId is supplied (Single parameter set) the cmdlet returns the one matching record. -ProjectId defaults to the session-pinned project in both modes. Notes - Accepts pipeline input by property name so InfisicalTag objects from Get-InfisicalTags can be refreshed directly. + Tag Ids returned here are the values to pass on -TagIds when creating or updating secrets. Accepts pipeline input by property name on -TagSlugOrId. EXAMPLE 1 + Get-InfisicalTag + Lists every tag defined on the session-pinned project. + + + EXAMPLE 2 Get-InfisicalTag -TagSlugOrId 'critical' Retrieves the 'critical' tag from the session-pinned project. - EXAMPLE 2 - $GetInfisicalTagsResult = Get-InfisicalTags | Where-Object { $_.Slug -eq 'critical' } + EXAMPLE 3 + $GetInfisicalProjectResult = Get-InfisicalProject | Where-Object { $_.Slug -eq 'platform-telemetry' } $GetInfisicalTagParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalTagParameters.TagSlugOrId = $GetInfisicalTagsResult.Slug -$GetInfisicalTagParameters.ProjectId = $ConnectInfisicalParameters.ProjectId +$GetInfisicalTagParameters.TagSlugOrId = 'critical' +$GetInfisicalTagParameters.ProjectId = $GetInfisicalProjectResult.Id $GetInfisicalTagParameters.Verbose = $True $GetInfisicalTagResult = Get-InfisicalTag @GetInfisicalTagParameters - Filters tags to the critical slug and refetches the canonical record. + Resolves a project by slug and refetches the 'critical' tag from that project. @@ -1103,10 +948,10 @@ $NewInfisicalTagResult = New-InfisicalTag @NewInfisicalTagParameters EXAMPLE 2 - $GetInfisicalTagsResult = Get-InfisicalTags | Where-Object { $_.Slug -eq 'critical' } + $GetInfisicalTagResult = Get-InfisicalTag | Where-Object { $_.Slug -eq 'critical' } $UpdateInfisicalTagParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$UpdateInfisicalTagParameters.TagId = $GetInfisicalTagsResult.Id +$UpdateInfisicalTagParameters.TagId = $GetInfisicalTagResult.Id $UpdateInfisicalTagParameters.Slug = 'critical-v2' $UpdateInfisicalTagParameters.Name = 'Critical (v2)' $UpdateInfisicalTagParameters.Color = '#FFA500' @@ -1143,10 +988,10 @@ $UpdateInfisicalTagResult = Update-InfisicalTag @UpdateInfisicalTagParameters EXAMPLE 2 - $GetInfisicalTagsResult = Get-InfisicalTags | Where-Object { $_.Slug -eq 'critical-v2' } + $GetInfisicalTagResult = Get-InfisicalTag | Where-Object { $_.Slug -eq 'critical-v2' } $RemoveInfisicalTagParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$RemoveInfisicalTagParameters.TagId = $GetInfisicalTagsResult.Id +$RemoveInfisicalTagParameters.TagId = $GetInfisicalTagResult.Id $RemoveInfisicalTagParameters.ProjectId = $ConnectInfisicalParameters.ProjectId $RemoveInfisicalTagParameters.PassThru = $True $RemoveInfisicalTagParameters.Confirm = $False @@ -1197,40 +1042,45 @@ $GetInfisicalCertificateAuthorityResult = Get-InfisicalCertificateAuthority @Get - Get-InfisicalCertificates - Lists Infisical certificates in a project, with optional filters and automatic paging. + Get-InfisicalCertificate + Lists or retrieves Infisical certificates in a project, with optional filters and automatic paging. Get - InfisicalCertificates + InfisicalCertificate - Enumerates certificates with optional filters for -CommonName, -FriendlyName, -Status, and -CaId. -Limit and -Offset drive a single page; pages are walked automatically until exhausted unless -NoAutoPage is supplied. -ProjectId defaults to the session-pinned project when omitted. + Default (List parameter set) enumerates certificates with optional filters for -CommonName, -FriendlyName, -Status, and -CaId; -Limit and -Offset drive a single page and pages are walked automatically until exhausted unless -NoAutoPage is supplied. When -SerialNumber is supplied (Single parameter set) the cmdlet returns one certificate record. -ProjectId defaults to the session-pinned project in both modes. Notes - For advanced filtering (validity window, key algorithm, extended key usage, etc.) use Search-InfisicalCertificate instead. + For advanced filtering (validity window, key algorithm, extended key usage, etc.) use Search-InfisicalCertificate instead. Single mode returns metadata only; to obtain certificate and chain PEM material use ConvertTo-InfisicalCertificate or Export-InfisicalCertificate. Accepts pipeline input by property name on -SerialNumber. EXAMPLE 1 - Get-InfisicalCertificates -Status 'active' + Get-InfisicalCertificate -Status 'active' Lists every active certificate in the session-pinned project. EXAMPLE 2 + Get-InfisicalCertificate -SerialNumber '7A:F2:1B:...:9E' + Retrieves the certificate record for the supplied serial number. + + + EXAMPLE 3 $GetInfisicalCertificateAuthorityListResult = Get-InfisicalCertificateAuthority | Where-Object { $_.FriendlyName -eq 'Issuing CA - Platform' } -$GetInfisicalCertificatesParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalCertificatesParameters.ProjectId = $ConnectInfisicalParameters.ProjectId -$GetInfisicalCertificatesParameters.CommonName = $env:COMPUTERNAME -$GetInfisicalCertificatesParameters.FriendlyName = 'web-tier' -$GetInfisicalCertificatesParameters.Status = 'active' -$GetInfisicalCertificatesParameters.CaId = @($GetInfisicalCertificateAuthorityListResult.Id) -$GetInfisicalCertificatesParameters.Limit = 100 -$GetInfisicalCertificatesParameters.Verbose = $True +$GetInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) +$GetInfisicalCertificateParameters.ProjectId = $ConnectInfisicalParameters.ProjectId +$GetInfisicalCertificateParameters.CommonName = $env:COMPUTERNAME +$GetInfisicalCertificateParameters.FriendlyName = 'web-tier' +$GetInfisicalCertificateParameters.Status = 'active' +$GetInfisicalCertificateParameters.CaId = @($GetInfisicalCertificateAuthorityListResult.Id) +$GetInfisicalCertificateParameters.Limit = 100 +$GetInfisicalCertificateParameters.Verbose = $True -$GetInfisicalCertificatesResult = Get-InfisicalCertificates @GetInfisicalCertificatesParameters +$GetInfisicalCertificateListResult = Get-InfisicalCertificate @GetInfisicalCertificateParameters Resolves the issuing CA, then lists active certificates scoped to that CA, the local hostname, and the 'web-tier' friendly name. @@ -1238,36 +1088,42 @@ $GetInfisicalCertificatesResult = Get-InfisicalCertificates @GetInfisicalCertifi - Get-InfisicalCertificate - Retrieves a single Infisical certificate by serial number. + Get-InfisicalPkiSubscriber + Lists or retrieves Infisical PKI subscribers in a project. Get - InfisicalCertificate + InfisicalPkiSubscriber - Returns one certificate record by -SerialNumber. Accepts pipeline input by property name so InfisicalCertificate objects from list/search cmdlets can be re-fetched directly. + Default (List parameter set) returns every PKI subscriber configured on the project. When -Name is supplied (ByName parameter set) the cmdlet returns one subscriber by its slug. -ProjectId defaults to the session-pinned project in both modes. Notes - This returns metadata only. To obtain certificate and chain PEM material use ConvertTo-InfisicalCertificate or Export-InfisicalCertificate. + The -Name parameter is the subscriber slug; aliases SubscriberName and Slug are accepted. Pass the slug returned here on -PkiSubscriberSlug when calling Request-InfisicalCertificate. Accepts pipeline input by property name on -Name. EXAMPLE 1 - Get-InfisicalCertificate -SerialNumber '7A:F2:1B:...:9E' - Retrieves the certificate record for the supplied serial number. + Get-InfisicalPkiSubscriber + Lists every PKI subscriber defined on the session-pinned project. EXAMPLE 2 - $GetInfisicalCertificatesResult = Get-InfisicalCertificates -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } + Get-InfisicalPkiSubscriber -Name 'mecm' + Retrieves the 'mecm' PKI subscriber from the session-pinned project. + + + EXAMPLE 3 + $GetInfisicalPkiSubscriberListResult = Get-InfisicalPkiSubscriber | Where-Object { $_.Name -ilike 'mecm*' } -$GetInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$GetInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificatesResult[0].SerialNumber -$GetInfisicalCertificateParameters.Verbose = $True +$GetInfisicalPkiSubscriberParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) +$GetInfisicalPkiSubscriberParameters.Name = $GetInfisicalPkiSubscriberListResult[0].Name +$GetInfisicalPkiSubscriberParameters.ProjectId = $ConnectInfisicalParameters.ProjectId +$GetInfisicalPkiSubscriberParameters.Verbose = $True -$GetInfisicalCertificateResult = Get-InfisicalCertificate @GetInfisicalCertificateParameters - Selects the active certificate whose common name matches the host and refetches its canonical record. +$GetInfisicalPkiSubscriberResult = Get-InfisicalPkiSubscriber @GetInfisicalPkiSubscriberParameters + Filters subscribers whose name starts with 'mecm' and refetches the canonical record for the first match. @@ -1388,10 +1244,10 @@ $RequestInfisicalCertificateResult = Request-InfisicalCertificate @RequestInfisi EXAMPLE 2 - $GetInfisicalCertificatesResult = Get-InfisicalCertificates -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } + $GetInfisicalCertificateResult = Get-InfisicalCertificate -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } $ConvertToInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$ConvertToInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificatesResult[0].SerialNumber +$ConvertToInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificateResult[0].SerialNumber $ConvertToInfisicalCertificateParameters.NoPrivateKey = $False $ConvertToInfisicalCertificateParameters.IncludeChain = $True $ConvertToInfisicalCertificateParameters.KeyStorageFlags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable @@ -1427,10 +1283,10 @@ $ConvertToInfisicalCertificateResult = ConvertTo-InfisicalCertificate @ConvertTo EXAMPLE 2 - $GetInfisicalCertificatesResult = Get-InfisicalCertificates -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } + $GetInfisicalCertificateResult = Get-InfisicalCertificate -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } $ExportInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$ExportInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificatesResult[0].SerialNumber +$ExportInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificateResult[0].SerialNumber $ExportInfisicalCertificateParameters.Path = "C:\Temp\$($env:COMPUTERNAME).pfx" $ExportInfisicalCertificateParameters.Format = 'Pfx' $ExportInfisicalCertificateParameters.Password = (Read-Host -AsSecureString -Prompt 'PFX password') @@ -1468,10 +1324,10 @@ $ExportInfisicalCertificateResult = Export-InfisicalCertificate @ExportInfisical EXAMPLE 2 - $GetInfisicalCertificatesResult = Get-InfisicalCertificates -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } + $GetInfisicalCertificateResult = Get-InfisicalCertificate -Status 'active' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } $InstallInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$InstallInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificatesResult[0].SerialNumber +$InstallInfisicalCertificateParameters.SerialNumber = $GetInfisicalCertificateResult[0].SerialNumber $InstallInfisicalCertificateParameters.StoreName = 'My' $InstallInfisicalCertificateParameters.StoreLocation = 'LocalMachine' $InstallInfisicalCertificateParameters.KeyStorageFlags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet @@ -1510,10 +1366,10 @@ $InstallInfisicalCertificateResult = Install-InfisicalCertificate @InstallInfisi EXAMPLE 2 - $GetInfisicalCertificatesResult = Get-InfisicalCertificates -Status 'revoked' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } + $GetInfisicalCertificateResult = Get-InfisicalCertificate -Status 'revoked' | Where-Object { $_.CommonName -eq $env:COMPUTERNAME } $UninstallInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) -$UninstallInfisicalCertificateParameters.InfisicalCertificate = $GetInfisicalCertificatesResult[0] +$UninstallInfisicalCertificateParameters.InfisicalCertificate = $GetInfisicalCertificateResult[0] $UninstallInfisicalCertificateParameters.StoreName = 'My' $UninstallInfisicalCertificateParameters.StoreLocation = 'LocalMachine' $UninstallInfisicalCertificateParameters.Force = $True diff --git a/README.md b/README.md index 835c2b5..01b3b5b 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,17 @@ Import-Module -Name .\Module\PSInfisicalAPI ## Cmdlets -| Cmdlet | Purpose | -| ------------------------------------- | -------------------------------------------------------------------------- | -| `Connect-Infisical` | Establish a session using Universal Auth or a pre-issued access token. | -| `Disconnect-Infisical` | Clear the current session. | -| `Get-InfisicalSecrets` | List secrets at a given path / environment. | -| `Get-InfisicalSecret` | Retrieve a single secret by name. | -| `ConvertTo-InfisicalSecretDictionary` | Convert secret objects into a `Hashtable` keyed by `SecretKey`. | -| `Export-InfisicalSecrets` | Export secrets to JSON, YAML, XML, or `.env` format. | +The module exports 34 cmdlets. Discovery cmdlets (`Get-Infisical*`) use a `List` (default) / single-record parameter-set pair: invoking without the identity parameter returns the collection, supplying the identity parameter returns one record. + +| Area | Cmdlets | +| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Session | `Connect-Infisical`, `Disconnect-Infisical` | +| Secrets | `Get-InfisicalSecret`, `New-InfisicalSecret`, `Update-InfisicalSecret`, `Remove-InfisicalSecret`, `Copy-InfisicalSecret`, `ConvertTo-InfisicalSecretDictionary`, `Export-InfisicalSecrets` | +| Projects | `Get-InfisicalProject`, `New-InfisicalProject`, `Update-InfisicalProject`, `Remove-InfisicalProject` | +| Environments | `Get-InfisicalEnvironment`, `New-InfisicalEnvironment`, `Update-InfisicalEnvironment`, `Remove-InfisicalEnvironment` | +| Folders | `Get-InfisicalFolder`, `New-InfisicalFolder`, `Update-InfisicalFolder`, `Remove-InfisicalFolder` | +| Tags | `Get-InfisicalTag`, `New-InfisicalTag`, `Update-InfisicalTag`, `Remove-InfisicalTag` | +| PKI | `Get-InfisicalCertificateAuthority`, `Get-InfisicalPkiSubscriber`, `Get-InfisicalCertificate`, `Search-InfisicalCertificate`, `Request-InfisicalCertificate`, `ConvertTo-InfisicalCertificate`, `Install-InfisicalCertificate`, `Uninstall-InfisicalCertificate`, `Export-InfisicalCertificate` | Use `Get-Help -Full` for parameter details and `Get-Help about_PSInfisicalAPI` for the module overview. @@ -51,7 +54,7 @@ $connection = Connect-Infisical ` -ClientSecret $secureSecret ` -PassThru -Get-InfisicalSecrets -SecretPath '/' +Get-InfisicalSecret -SecretPath '/' Disconnect-Infisical ``` @@ -96,7 +99,7 @@ Sensitive values (`ClientSecret`, `AccessToken`) are read directly into a read-o [Environment]::SetEnvironmentVariable('INFISICAL_CLIENT_SECRET', 'super-secret-value', 'User') Connect-Infisical -Get-InfisicalSecrets +Get-InfisicalSecret ``` ### Mixed example (explicit values override discovery) @@ -119,6 +122,55 @@ pwsh -NoProfile -ExecutionPolicy Bypass -File .\build.ps1 -RunTests The script builds the binary, runs unit tests, publishes binaries into `Module/PSInfisicalAPI/bin/`, regenerates the manifest, and validates that the module imports. +## Extending the module + +### Adding a new API endpoint + +All HTTP routes live in two files under `src/PSInfisicalAPI/Endpoints/`: + +- `InfisicalEndpointNames.cs` declares a `const string` identifier for each endpoint. +- `InfisicalEndpointRegistry.cs` maps each identifier to one or more `InfisicalEndpointDefinition` records grouped by resource (`RegisterAuthentication`, `RegisterSecrets`, `RegisterPki`, etc.). + +To add a route: + +1. Add a constant in `InfisicalEndpointNames.cs` (e.g., `public const string ListPkiSubscribers = "ListPkiSubscribers";`). +2. In the matching `Register` method, call `Add(map, new InfisicalEndpointDefinition { ... })` with `Name`, `Resource`, `Version`, `Method`, `Template`, and the `RequiresAuthorization` / `ContainsSecretMaterialInRequest` / `ContainsSecretMaterialInResponse` flags. Use `{placeholder}` tokens in `Template`; they are substituted from the `pathParameters` dictionary passed by the caller. +3. If the same logical operation has more than one upstream path (legacy + current), register both definitions under the same `Name` — `InvokeWithCandidateFallback` tries each in order until one succeeds. +4. Invoke the endpoint from the appropriate client (`InfisicalPkiClient`, `InfisicalSecretsClient`, etc.) via `_invoker.InvokeWithCandidateFallback(connection, InfisicalEndpointNames.XYZ, "XYZ", pathParameters, query, body)`. + +### 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: + +```csharp +[Cmdlet(VerbsCommon.Get, "InfisicalPkiSubscriber", DefaultParameterSetName = "List")] +[OutputType(typeof(InfisicalPkiSubscriber))] +public sealed class GetInfisicalPkiSubscriberCmdlet : InfisicalCmdletBase +{ + [Parameter(ParameterSetName = "ByName", Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)] + [Alias("SubscriberName", "Slug")] + public string Name { get; set; } + + [Parameter] public string ProjectId { get; set; } + + protected override void ProcessRecord() { /* dispatch on ParameterSetName */ } +} +``` + +After adding (or removing) a cmdlet: + +1. Update `build.ps1` in **two** places — the `CmdletsToExport` array inside the generated manifest block, and the `$expectedCmds` array used by `Test-ModuleImports`. Both must list the same cmdlets; the build fails fast if they drift. +2. Add a `` entry in `Module/PSInfisicalAPI/en-US/PSInfisicalAPI.dll-Help.xml`. Each entry must include a non-empty `` synopsis (do not let it start with the cmdlet name — the validation gate rejects PowerShell's auto-generated fallback), a non-empty `` body, and at least one `` with a non-empty `` block. +3. For consolidated `List` / single-record cmdlets, ship **three examples**: two straight-line invocations (one per parameter set) and one `OrderedDictionary` splat. The splat must construct the dictionary with `OrdinalIgnoreCase` so parameter names round-trip case-insensitively: + + ```powershell + $Params = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase) + $Params.ProjectId = (Get-InfisicalProject | 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**). +5. Run `./build.ps1 -RunTests`. The script enforces the cmdlet list, runs the xUnit suite, and verifies that every exported cmdlet has a valid synopsis, description, and at least one non-empty example. + ## Continuous integration `.gitea/workflows/publish-psgallery.yml` publishes the module to the PowerShell Gallery whenever a pull request is merged into `main`. The workflow expects a repository secret named `PSGALLERY_API_KEY` containing a valid Gallery API key. diff --git a/build.ps1 b/build.ps1 index b928622..26088be 100644 --- a/build.ps1 +++ b/build.ps1 @@ -100,7 +100,6 @@ function Write-Manifest { CmdletsToExport = @( 'Connect-Infisical', 'Disconnect-Infisical', - 'Get-InfisicalSecrets', 'Get-InfisicalSecret', 'New-InfisicalSecret', 'Update-InfisicalSecret', @@ -108,29 +107,25 @@ function Write-Manifest { 'Copy-InfisicalSecret', 'ConvertTo-InfisicalSecretDictionary', 'Export-InfisicalSecrets', - 'Get-InfisicalProjects', 'Get-InfisicalProject', 'New-InfisicalProject', 'Update-InfisicalProject', 'Remove-InfisicalProject', - 'Get-InfisicalEnvironments', 'Get-InfisicalEnvironment', 'New-InfisicalEnvironment', 'Update-InfisicalEnvironment', 'Remove-InfisicalEnvironment', - 'Get-InfisicalFolders', 'Get-InfisicalFolder', 'New-InfisicalFolder', 'Update-InfisicalFolder', 'Remove-InfisicalFolder', - 'Get-InfisicalTags', 'Get-InfisicalTag', 'New-InfisicalTag', 'Update-InfisicalTag', 'Remove-InfisicalTag', 'Get-InfisicalCertificateAuthority', + 'Get-InfisicalPkiSubscriber', 'Get-InfisicalCertificate', - 'Get-InfisicalCertificates', 'Search-InfisicalCertificate', 'Request-InfisicalCertificate', 'ConvertTo-InfisicalCertificate', @@ -201,7 +196,7 @@ if (`$cmds.Count -eq 0) { throw "No cmdlets were exported by the PSInfisicalAPI module." } -`$expectedCmds = @('Connect-Infisical','Disconnect-Infisical','Get-InfisicalSecrets','Get-InfisicalSecret','New-InfisicalSecret','Update-InfisicalSecret','Remove-InfisicalSecret','Copy-InfisicalSecret','ConvertTo-InfisicalSecretDictionary','Export-InfisicalSecrets','Get-InfisicalProjects','Get-InfisicalProject','New-InfisicalProject','Update-InfisicalProject','Remove-InfisicalProject','Get-InfisicalEnvironments','Get-InfisicalEnvironment','New-InfisicalEnvironment','Update-InfisicalEnvironment','Remove-InfisicalEnvironment','Get-InfisicalFolders','Get-InfisicalFolder','New-InfisicalFolder','Update-InfisicalFolder','Remove-InfisicalFolder','Get-InfisicalTags','Get-InfisicalTag','New-InfisicalTag','Update-InfisicalTag','Remove-InfisicalTag','Get-InfisicalCertificateAuthority','Get-InfisicalCertificate','Get-InfisicalCertificates','Search-InfisicalCertificate','Request-InfisicalCertificate','ConvertTo-InfisicalCertificate','Install-InfisicalCertificate','Uninstall-InfisicalCertificate','Export-InfisicalCertificate') +`$expectedCmds = @('Connect-Infisical','Disconnect-Infisical','Get-InfisicalSecret','New-InfisicalSecret','Update-InfisicalSecret','Remove-InfisicalSecret','Copy-InfisicalSecret','ConvertTo-InfisicalSecretDictionary','Export-InfisicalSecrets','Get-InfisicalProject','New-InfisicalProject','Update-InfisicalProject','Remove-InfisicalProject','Get-InfisicalEnvironment','New-InfisicalEnvironment','Update-InfisicalEnvironment','Remove-InfisicalEnvironment','Get-InfisicalFolder','New-InfisicalFolder','Update-InfisicalFolder','Remove-InfisicalFolder','Get-InfisicalTag','New-InfisicalTag','Update-InfisicalTag','Remove-InfisicalTag','Get-InfisicalCertificateAuthority','Get-InfisicalPkiSubscriber','Get-InfisicalCertificate','Search-InfisicalCertificate','Request-InfisicalCertificate','ConvertTo-InfisicalCertificate','Install-InfisicalCertificate','Uninstall-InfisicalCertificate','Export-InfisicalCertificate') foreach (`$expected in `$expectedCmds) { if (-not (Get-Command -Name `$expected -Module PSInfisicalAPI -ErrorAction SilentlyContinue)) { throw "Cmdlet not found: `$expected" diff --git a/src/PSInfisicalAPI.Tests/CsrAndRequestCmdletTests.cs b/src/PSInfisicalAPI.Tests/CsrAndRequestCmdletTests.cs index e048a6a..95c8232 100644 --- a/src/PSInfisicalAPI.Tests/CsrAndRequestCmdletTests.cs +++ b/src/PSInfisicalAPI.Tests/CsrAndRequestCmdletTests.cs @@ -115,17 +115,15 @@ namespace PSInfisicalAPI.Tests } [Fact] - public void Candidates_For_SignCertificateBySubscriber_Include_Pki_And_CertManager() + public void SignCertificateBySubscriber_Uses_Pki_Subscribers_Template() { IReadOnlyList candidates = InfisicalEndpointRegistry.GetCandidates(InfisicalEndpointNames.SignCertificateBySubscriber); - Assert.Contains(candidates, c => c.Template == "/api/v1/pki/pki-subscribers/{subscriberName}/sign-certificate"); - Assert.Contains(candidates, c => c.Template == "/api/v1/cert-manager/pki-subscribers/{subscriberName}/sign-certificate"); - foreach (InfisicalEndpointDefinition candidate in candidates) - { - Assert.Equal("POST", candidate.Method); - Assert.True(candidate.RequiresAuthorization); - Assert.True(candidate.ContainsSecretMaterialInResponse); - } + Assert.Single(candidates); + InfisicalEndpointDefinition only = candidates[0]; + Assert.Equal("/api/v1/pki/subscribers/{subscriberName}/sign-certificate", only.Template); + Assert.Equal("POST", only.Method); + Assert.True(only.RequiresAuthorization); + Assert.True(only.ContainsSecretMaterialInResponse); } [Fact] diff --git a/src/PSInfisicalAPI.Tests/PkiEndpointRegistryTests.cs b/src/PSInfisicalAPI.Tests/PkiEndpointRegistryTests.cs index 9ecd5c9..dae7d4b 100644 --- a/src/PSInfisicalAPI.Tests/PkiEndpointRegistryTests.cs +++ b/src/PSInfisicalAPI.Tests/PkiEndpointRegistryTests.cs @@ -12,7 +12,7 @@ namespace PSInfisicalAPI.Tests private static readonly Assembly ModuleAssembly = typeof(PSInfisicalAPI.Connections.InfisicalConnection).Assembly; [Fact] - public void GetInfisicalCertificate_Cmdlet_Is_Singular_With_Mandatory_SerialNumber() + public void GetInfisicalCertificate_Cmdlet_Is_Singular_With_SerialNumber_In_Single_ParameterSet() { Type cmdletType = ModuleAssembly.GetType("PSInfisicalAPI.Cmdlets.GetInfisicalCertificateCmdlet", true); Assert.True(typeof(PSInfisicalAPI.Cmdlets.InfisicalCmdletBase).IsAssignableFrom(cmdletType)); @@ -27,6 +27,13 @@ namespace PSInfisicalAPI.Tests Assert.Equal(VerbsCommon.Get, cmdletData.ConstructorArguments[0].Value); Assert.Equal("InfisicalCertificate", cmdletData.ConstructorArguments[1].Value); + string defaultParameterSetName = null; + foreach (CustomAttributeNamedArgument named in cmdletData.NamedArguments) + { + if (named.MemberName == "DefaultParameterSetName") { defaultParameterSetName = (string)named.TypedValue.Value; break; } + } + Assert.Equal("List", defaultParameterSetName); + PropertyInfo serialProp = cmdletType.GetProperty("SerialNumber"); Assert.NotNull(serialProp); @@ -38,33 +45,27 @@ namespace PSInfisicalAPI.Tests Assert.NotNull(parameterAttr); bool mandatory = false; + string parameterSetName = null; foreach (CustomAttributeNamedArgument named in parameterAttr.NamedArguments) { - if (named.MemberName == "Mandatory") { mandatory = (bool)named.TypedValue.Value; break; } + if (named.MemberName == "Mandatory") { mandatory = (bool)named.TypedValue.Value; } + else if (named.MemberName == "ParameterSetName") { parameterSetName = (string)named.TypedValue.Value; } } Assert.True(mandatory); + Assert.Equal("Single", parameterSetName); } [Fact] - public void GetInfisicalCertificates_Cmdlet_Is_Registered_For_Listing() + public void GetInfisicalCertificate_Cmdlet_Exposes_List_Filter_Properties() { - Type cmdletType = ModuleAssembly.GetType("PSInfisicalAPI.Cmdlets.GetInfisicalCertificatesCmdlet", true); - Assert.True(typeof(PSInfisicalAPI.Cmdlets.InfisicalCmdletBase).IsAssignableFrom(cmdletType)); - - CustomAttributeData cmdletData = null; - foreach (CustomAttributeData candidate in cmdletType.GetCustomAttributesData()) - { - if (candidate.AttributeType == typeof(CmdletAttribute)) { cmdletData = candidate; break; } - } - Assert.NotNull(cmdletData); - Assert.Equal(VerbsCommon.Get, cmdletData.ConstructorArguments[0].Value); - Assert.Equal("InfisicalCertificates", cmdletData.ConstructorArguments[1].Value); - + Type cmdletType = ModuleAssembly.GetType("PSInfisicalAPI.Cmdlets.GetInfisicalCertificateCmdlet", true); Assert.NotNull(cmdletType.GetProperty("CommonName")); Assert.NotNull(cmdletType.GetProperty("FriendlyName")); Assert.NotNull(cmdletType.GetProperty("CaId")); Assert.NotNull(cmdletType.GetProperty("Limit")); Assert.NotNull(cmdletType.GetProperty("Offset")); + Assert.NotNull(cmdletType.GetProperty("NoAutoPage")); + Assert.NotNull(cmdletType.GetProperty("List")); } [Fact] diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalCertificateCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalCertificateCmdlet.cs index df5970c..91a91e8 100644 --- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalCertificateCmdlet.cs +++ b/src/PSInfisicalAPI/Cmdlets/GetInfisicalCertificateCmdlet.cs @@ -6,14 +6,24 @@ using PSInfisicalAPI.Pki; namespace PSInfisicalAPI.Cmdlets { - [Cmdlet(VerbsCommon.Get, "InfisicalCertificate")] + [Cmdlet(VerbsCommon.Get, "InfisicalCertificate", DefaultParameterSetName = "List")] [OutputType(typeof(InfisicalCertificate))] public sealed class GetInfisicalCertificateCmdlet : InfisicalCmdletBase { - [Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)] + [Parameter(ParameterSetName = "Single", Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)] [Alias("Id", "Identifier")] public string SerialNumber { get; set; } + [Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; } + [Parameter(ParameterSetName = "List")] public string ProjectId { get; set; } + [Parameter(ParameterSetName = "List")] public string CommonName { get; set; } + [Parameter(ParameterSetName = "List")] public string FriendlyName { get; set; } + [Parameter(ParameterSetName = "List")] public string Status { get; set; } + [Parameter(ParameterSetName = "List")] public string[] CaId { get; set; } + [Parameter(ParameterSetName = "List")] public int? Limit { get; set; } + [Parameter(ParameterSetName = "List")] public int? Offset { get; set; } + [Parameter(ParameterSetName = "List")] public SwitchParameter NoAutoPage { get; set; } + protected override void ProcessRecord() { try @@ -21,10 +31,57 @@ namespace PSInfisicalAPI.Cmdlets InfisicalConnection connection = InfisicalSessionManager.RequireCurrent(); InfisicalPkiClient client = new InfisicalPkiClient(HttpClient, Logger); - InfisicalCertificate cert = client.RetrieveCertificate(connection, SerialNumber); - if (cert != null) + if (string.Equals(ParameterSetName, "Single", StringComparison.Ordinal)) { - WriteObject(cert); + InfisicalCertificate cert = client.RetrieveCertificate(connection, SerialNumber); + if (cert != null) + { + WriteObject(cert); + } + + return; + } + + string resolvedProjectId = ResolveProjectId(connection, ProjectId); + + InfisicalCertificateSearchQuery query = new InfisicalCertificateSearchQuery + { + ProjectId = resolvedProjectId, + CommonName = CommonName, + FriendlyName = FriendlyName, + Status = Status, + CaIds = CaId, + Limit = Limit ?? 100, + Offset = Offset ?? 0 + }; + + int requestedLimit = query.Limit ?? 100; + int emitted = 0; + while (true) + { + InfisicalCertificateSearchResult page = client.SearchCertificates(connection, query); + if (page == null || page.Certificates == null || page.Certificates.Length == 0) + { + break; + } + + foreach (InfisicalCertificate cert in page.Certificates) + { + WriteObject(cert); + emitted++; + } + + if (NoAutoPage.IsPresent || page.Certificates.Length < requestedLimit) + { + break; + } + + if (page.TotalCount > 0 && emitted >= page.TotalCount) + { + break; + } + + query.Offset = (query.Offset ?? 0) + page.Certificates.Length; } } catch (Exception exception) diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalCertificatesCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalCertificatesCmdlet.cs deleted file mode 100644 index 7c90278..0000000 --- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalCertificatesCmdlet.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Management.Automation; -using PSInfisicalAPI.Connections; -using PSInfisicalAPI.Models; -using PSInfisicalAPI.Pki; - -namespace PSInfisicalAPI.Cmdlets -{ - [Cmdlet(VerbsCommon.Get, "InfisicalCertificates")] - [OutputType(typeof(InfisicalCertificate))] - public sealed class GetInfisicalCertificatesCmdlet : InfisicalCmdletBase - { - [Parameter] public string ProjectId { get; set; } - [Parameter] public string CommonName { get; set; } - [Parameter] public string FriendlyName { get; set; } - [Parameter] public string Status { get; set; } - [Parameter] public string[] CaId { get; set; } - [Parameter] public int? Limit { get; set; } - [Parameter] public int? Offset { get; set; } - [Parameter] public SwitchParameter NoAutoPage { get; set; } - - protected override void ProcessRecord() - { - try - { - InfisicalConnection connection = InfisicalSessionManager.RequireCurrent(); - InfisicalPkiClient client = new InfisicalPkiClient(HttpClient, Logger); - string resolvedProjectId = ResolveProjectId(connection, ProjectId); - - InfisicalCertificateSearchQuery query = new InfisicalCertificateSearchQuery - { - ProjectId = resolvedProjectId, - CommonName = CommonName, - FriendlyName = FriendlyName, - Status = Status, - CaIds = CaId, - Limit = Limit ?? 100, - Offset = Offset ?? 0 - }; - - int requestedLimit = query.Limit ?? 100; - int emitted = 0; - while (true) - { - InfisicalCertificateSearchResult page = client.SearchCertificates(connection, query); - if (page == null || page.Certificates == null || page.Certificates.Length == 0) - { - break; - } - - foreach (InfisicalCertificate cert in page.Certificates) - { - WriteObject(cert); - emitted++; - } - - if (NoAutoPage.IsPresent || page.Certificates.Length < requestedLimit) - { - break; - } - - if (page.TotalCount > 0 && emitted >= page.TotalCount) - { - break; - } - - query.Offset = (query.Offset ?? 0) + page.Certificates.Length; - } - } - catch (Exception exception) - { - ThrowTerminatingForException("GetInfisicalCertificatesCmdlet", "GetCertificates", exception); - } - } - } -} diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalEnvironmentCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalEnvironmentCmdlet.cs index 728ec32..a871c16 100644 --- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalEnvironmentCmdlet.cs +++ b/src/PSInfisicalAPI/Cmdlets/GetInfisicalEnvironmentCmdlet.cs @@ -6,16 +6,18 @@ using PSInfisicalAPI.Models; namespace PSInfisicalAPI.Cmdlets { - [Cmdlet(VerbsCommon.Get, "InfisicalEnvironment")] + [Cmdlet(VerbsCommon.Get, "InfisicalEnvironment", DefaultParameterSetName = "List")] [OutputType(typeof(InfisicalEnvironment))] public sealed class GetInfisicalEnvironmentCmdlet : InfisicalCmdletBase { - [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, Position = 0)] + [Parameter(ParameterSetName = "Single", Mandatory = true, ValueFromPipelineByPropertyName = true, Position = 0)] [Alias("Slug", "Id", "Environment")] public string EnvironmentSlugOrId { get; set; } [Parameter] public string ProjectId { get; set; } + [Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; } + protected override void ProcessRecord() { try @@ -23,15 +25,27 @@ namespace PSInfisicalAPI.Cmdlets InfisicalConnection connection = InfisicalSessionManager.RequireCurrent(); string resolvedProjectId = ResolveProjectId(connection, ProjectId); InfisicalEnvironmentClient client = new InfisicalEnvironmentClient(HttpClient, Logger); - InfisicalEnvironment env = client.Retrieve(connection, resolvedProjectId, EnvironmentSlugOrId); - if (env != null) + + if (string.Equals(ParameterSetName, "Single", StringComparison.Ordinal)) + { + InfisicalEnvironment env = client.Retrieve(connection, resolvedProjectId, EnvironmentSlugOrId); + if (env != null) + { + WriteObject(env); + } + + return; + } + + InfisicalEnvironment[] envs = client.List(connection, resolvedProjectId); + foreach (InfisicalEnvironment env in envs) { WriteObject(env); } } catch (Exception exception) { - ThrowTerminatingForException("GetInfisicalEnvironmentCmdlet", "RetrieveEnvironment", exception); + ThrowTerminatingForException("GetInfisicalEnvironmentCmdlet", "GetEnvironment", exception); } } } diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalEnvironmentsCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalEnvironmentsCmdlet.cs deleted file mode 100644 index 2128cda..0000000 --- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalEnvironmentsCmdlet.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Management.Automation; -using PSInfisicalAPI.Connections; -using PSInfisicalAPI.Environments; -using PSInfisicalAPI.Models; - -namespace PSInfisicalAPI.Cmdlets -{ - [Cmdlet(VerbsCommon.Get, "InfisicalEnvironments")] - [OutputType(typeof(InfisicalEnvironment))] - public sealed class GetInfisicalEnvironmentsCmdlet : InfisicalCmdletBase - { - [Parameter] public string ProjectId { get; set; } - - protected override void ProcessRecord() - { - try - { - InfisicalConnection connection = InfisicalSessionManager.RequireCurrent(); - string resolvedProjectId = ResolveProjectId(connection, ProjectId); - InfisicalEnvironmentClient client = new InfisicalEnvironmentClient(HttpClient, Logger); - InfisicalEnvironment[] envs = client.List(connection, resolvedProjectId); - foreach (InfisicalEnvironment env in envs) - { - WriteObject(env); - } - } - catch (Exception exception) - { - ThrowTerminatingForException("GetInfisicalEnvironmentsCmdlet", "ListEnvironments", exception); - } - } - } -} diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalFolderCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalFolderCmdlet.cs index 22ff5ee..8a1e644 100644 --- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalFolderCmdlet.cs +++ b/src/PSInfisicalAPI/Cmdlets/GetInfisicalFolderCmdlet.cs @@ -6,11 +6,11 @@ using PSInfisicalAPI.Models; namespace PSInfisicalAPI.Cmdlets { - [Cmdlet(VerbsCommon.Get, "InfisicalFolder")] + [Cmdlet(VerbsCommon.Get, "InfisicalFolder", DefaultParameterSetName = "List")] [OutputType(typeof(InfisicalFolder))] public sealed class GetInfisicalFolderCmdlet : InfisicalCmdletBase { - [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, Position = 0)] + [Parameter(ParameterSetName = "Single", Mandatory = true, ValueFromPipelineByPropertyName = true, Position = 0)] [Alias("Name", "Id")] public string FolderNameOrId { get; set; } @@ -18,6 +18,8 @@ namespace PSInfisicalAPI.Cmdlets [Parameter] public string Environment { get; set; } [Parameter] public string Path { get; set; } + [Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; } + protected override void ProcessRecord() { try @@ -27,15 +29,27 @@ namespace PSInfisicalAPI.Cmdlets string resolvedEnvironment = ResolveEnvironment(connection, Environment); string resolvedPath = ResolveSecretPath(connection, Path); InfisicalFolderClient client = new InfisicalFolderClient(HttpClient, Logger); - InfisicalFolder folder = client.Retrieve(connection, resolvedProjectId, resolvedEnvironment, resolvedPath, FolderNameOrId); - if (folder != null) + + if (string.Equals(ParameterSetName, "Single", StringComparison.Ordinal)) + { + InfisicalFolder folder = client.Retrieve(connection, resolvedProjectId, resolvedEnvironment, resolvedPath, FolderNameOrId); + if (folder != null) + { + WriteObject(folder); + } + + return; + } + + InfisicalFolder[] folders = client.List(connection, resolvedProjectId, resolvedEnvironment, resolvedPath); + foreach (InfisicalFolder folder in folders) { WriteObject(folder); } } catch (Exception exception) { - ThrowTerminatingForException("GetInfisicalFolderCmdlet", "RetrieveFolder", exception); + ThrowTerminatingForException("GetInfisicalFolderCmdlet", "GetFolder", exception); } } } diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalFoldersCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalFoldersCmdlet.cs deleted file mode 100644 index 4c3b2a6..0000000 --- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalFoldersCmdlet.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Management.Automation; -using PSInfisicalAPI.Connections; -using PSInfisicalAPI.Folders; -using PSInfisicalAPI.Models; - -namespace PSInfisicalAPI.Cmdlets -{ - [Cmdlet(VerbsCommon.Get, "InfisicalFolders")] - [OutputType(typeof(InfisicalFolder))] - public sealed class GetInfisicalFoldersCmdlet : InfisicalCmdletBase - { - [Parameter] public string ProjectId { get; set; } - [Parameter] public string Environment { get; set; } - [Parameter] public string Path { get; set; } - - protected override void ProcessRecord() - { - try - { - InfisicalConnection connection = InfisicalSessionManager.RequireCurrent(); - string resolvedProjectId = ResolveProjectId(connection, ProjectId); - string resolvedEnvironment = ResolveEnvironment(connection, Environment); - string resolvedPath = ResolveSecretPath(connection, Path); - InfisicalFolderClient client = new InfisicalFolderClient(HttpClient, Logger); - InfisicalFolder[] folders = client.List(connection, resolvedProjectId, resolvedEnvironment, resolvedPath); - foreach (InfisicalFolder folder in folders) - { - WriteObject(folder); - } - } - catch (Exception exception) - { - ThrowTerminatingForException("GetInfisicalFoldersCmdlet", "ListFolders", exception); - } - } - } -} diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalPkiSubscriberCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalPkiSubscriberCmdlet.cs new file mode 100644 index 0000000..bcd2eab --- /dev/null +++ b/src/PSInfisicalAPI/Cmdlets/GetInfisicalPkiSubscriberCmdlet.cs @@ -0,0 +1,50 @@ +using System; +using System.Management.Automation; +using PSInfisicalAPI.Connections; +using PSInfisicalAPI.Models; +using PSInfisicalAPI.Pki; + +namespace PSInfisicalAPI.Cmdlets +{ + [Cmdlet(VerbsCommon.Get, "InfisicalPkiSubscriber", DefaultParameterSetName = "List")] + [OutputType(typeof(InfisicalPkiSubscriber))] + public sealed class GetInfisicalPkiSubscriberCmdlet : InfisicalCmdletBase + { + [Parameter(ParameterSetName = "ByName", Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)] + [Alias("SubscriberName", "Slug")] + public string Name { get; set; } + + [Parameter] public string ProjectId { get; set; } + + protected override void ProcessRecord() + { + try + { + InfisicalConnection connection = InfisicalSessionManager.RequireCurrent(); + InfisicalPkiClient client = new InfisicalPkiClient(HttpClient, Logger); + string resolvedProjectId = ResolveProjectId(connection, ProjectId); + + if (string.Equals(ParameterSetName, "ByName", StringComparison.Ordinal)) + { + InfisicalPkiSubscriber subscriber = client.GetPkiSubscriber(connection, Name, resolvedProjectId); + if (subscriber != null) + { + WriteObject(subscriber); + } + + return; + } + + InfisicalPkiSubscriber[] all = client.ListPkiSubscribers(connection, resolvedProjectId); + foreach (InfisicalPkiSubscriber subscriber in all) + { + WriteObject(subscriber); + } + } + catch (Exception exception) + { + ThrowTerminatingForException("GetInfisicalPkiSubscriberCmdlet", "GetPkiSubscriber", exception); + } + } + } +} diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalProjectCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalProjectCmdlet.cs index 93ec71e..fa251fc 100644 --- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalProjectCmdlet.cs +++ b/src/PSInfisicalAPI/Cmdlets/GetInfisicalProjectCmdlet.cs @@ -6,30 +6,44 @@ using PSInfisicalAPI.Projects; namespace PSInfisicalAPI.Cmdlets { - [Cmdlet(VerbsCommon.Get, "InfisicalProject")] + [Cmdlet(VerbsCommon.Get, "InfisicalProject", DefaultParameterSetName = "List")] [OutputType(typeof(InfisicalProject))] public sealed class GetInfisicalProjectCmdlet : InfisicalCmdletBase { - [Parameter(ValueFromPipelineByPropertyName = true, Position = 0)] + [Parameter(ParameterSetName = "Single", Mandatory = true, ValueFromPipelineByPropertyName = true, Position = 0)] [Alias("Id")] public string ProjectId { get; set; } + [Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; } + protected override void ProcessRecord() { try { InfisicalConnection connection = InfisicalSessionManager.RequireCurrent(); - string resolvedProjectId = ResolveProjectId(connection, ProjectId); InfisicalProjectClient client = new InfisicalProjectClient(HttpClient, Logger); - InfisicalProject project = client.Retrieve(connection, resolvedProjectId); - if (project != null) + + if (string.Equals(ParameterSetName, "Single", StringComparison.Ordinal)) + { + string resolvedProjectId = ResolveProjectId(connection, ProjectId); + InfisicalProject project = client.Retrieve(connection, resolvedProjectId); + if (project != null) + { + WriteObject(project); + } + + return; + } + + InfisicalProject[] projects = client.List(connection); + foreach (InfisicalProject project in projects) { WriteObject(project); } } catch (Exception exception) { - ThrowTerminatingForException("GetInfisicalProjectCmdlet", "RetrieveProject", exception); + ThrowTerminatingForException("GetInfisicalProjectCmdlet", "GetProject", exception); } } } diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalProjectsCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalProjectsCmdlet.cs deleted file mode 100644 index fa6150a..0000000 --- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalProjectsCmdlet.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Management.Automation; -using PSInfisicalAPI.Connections; -using PSInfisicalAPI.Models; -using PSInfisicalAPI.Projects; - -namespace PSInfisicalAPI.Cmdlets -{ - [Cmdlet(VerbsCommon.Get, "InfisicalProjects")] - [OutputType(typeof(InfisicalProject))] - public sealed class GetInfisicalProjectsCmdlet : InfisicalCmdletBase - { - protected override void ProcessRecord() - { - try - { - InfisicalConnection connection = InfisicalSessionManager.RequireCurrent(); - InfisicalProjectClient client = new InfisicalProjectClient(HttpClient, Logger); - InfisicalProject[] projects = client.List(connection); - - foreach (InfisicalProject project in projects) - { - WriteObject(project); - } - } - catch (Exception exception) - { - ThrowTerminatingForException("GetInfisicalProjectsCmdlet", "ListProjects", exception); - } - } - } -} diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalSecretCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalSecretCmdlet.cs index 2493296..49eee51 100644 --- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalSecretCmdlet.cs +++ b/src/PSInfisicalAPI/Cmdlets/GetInfisicalSecretCmdlet.cs @@ -1,4 +1,6 @@ using System; +using System.Collections; +using System.Collections.Generic; using System.Management.Automation; using PSInfisicalAPI.Connections; using PSInfisicalAPI.Models; @@ -6,55 +8,101 @@ using PSInfisicalAPI.Secrets; namespace PSInfisicalAPI.Cmdlets { - [Cmdlet(VerbsCommon.Get, "InfisicalSecret")] + [Cmdlet(VerbsCommon.Get, "InfisicalSecret", DefaultParameterSetName = "List")] [OutputType(typeof(InfisicalSecret))] public sealed class GetInfisicalSecretCmdlet : InfisicalCmdletBase { - [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, Position = 0)] + [Parameter(ParameterSetName = "Single", Mandatory = true, ValueFromPipelineByPropertyName = true, Position = 0)] public string SecretName { get; set; } [Parameter] public string ProjectId { get; set; } [Parameter] public string Environment { get; set; } [Parameter] public string SecretPath { get; set; } [Parameter] public string ApiVersion { get; set; } - [Parameter] public int? Version { get; set; } - [Parameter] public InfisicalSecretType Type { get; set; } = InfisicalSecretType.Shared; [Parameter] public SwitchParameter ViewSecretValue { get; set; } = SwitchParameter.Present; [Parameter] public SwitchParameter ExpandSecretReferences { get; set; } [Parameter] public SwitchParameter IncludeImports { get; set; } + [Parameter(ParameterSetName = "Single")] public int? Version { get; set; } + [Parameter(ParameterSetName = "Single")] public InfisicalSecretType Type { get; set; } = InfisicalSecretType.Shared; + + [Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; } + [Parameter(ParameterSetName = "List")] public SwitchParameter Recursive { get; set; } + [Parameter(ParameterSetName = "List")] public SwitchParameter IncludePersonalOverrides { get; set; } + [Parameter(ParameterSetName = "List")] public Hashtable MetadataFilter { get; set; } + [Parameter(ParameterSetName = "List")] public string[] TagSlugs { get; set; } + protected override void ProcessRecord() { try { InfisicalConnection connection = InfisicalSessionManager.RequireCurrent(); + InfisicalSecretsClient client = new InfisicalSecretsClient(HttpClient, Logger); - InfisicalRetrieveSecretQuery query = new InfisicalRetrieveSecretQuery + if (string.Equals(ParameterSetName, "Single", StringComparison.Ordinal)) + { + InfisicalRetrieveSecretQuery query = new InfisicalRetrieveSecretQuery + { + SecretName = SecretName, + ProjectId = ResolveProjectId(connection, ProjectId), + Environment = ResolveEnvironment(connection, Environment), + SecretPath = ResolveSecretPath(connection, SecretPath), + ApiVersion = ResolveApiVersion(connection, ApiVersion), + Version = Version, + Type = Type.ToString(), + ViewSecretValue = ViewSecretValue.IsPresent, + ExpandSecretReferences = ExpandSecretReferences.IsPresent, + IncludeImports = IncludeImports.IsPresent + }; + + InfisicalSecret secret = client.Retrieve(connection, query); + if (secret != null) + { + WriteObject(secret); + } + + return; + } + + InfisicalListSecretsQuery listQuery = new InfisicalListSecretsQuery { - SecretName = SecretName, ProjectId = ResolveProjectId(connection, ProjectId), Environment = ResolveEnvironment(connection, Environment), SecretPath = ResolveSecretPath(connection, SecretPath), ApiVersion = ResolveApiVersion(connection, ApiVersion), - Version = Version, - Type = Type.ToString(), - ViewSecretValue = ViewSecretValue.IsPresent, + Recursive = Recursive.IsPresent, + IncludeImports = IncludeImports.IsPresent, + IncludePersonalOverrides = IncludePersonalOverrides.IsPresent, ExpandSecretReferences = ExpandSecretReferences.IsPresent, - IncludeImports = IncludeImports.IsPresent + ViewSecretValue = ViewSecretValue.IsPresent, + MetadataFilter = ToStringDictionary(MetadataFilter), + TagSlugs = TagSlugs }; - InfisicalSecretsClient client = new InfisicalSecretsClient(HttpClient, Logger); - InfisicalSecret secret = client.Retrieve(connection, query); - - if (secret != null) + InfisicalSecret[] secrets = client.List(connection, listQuery); + foreach (InfisicalSecret secret in secrets) { WriteObject(secret); } } catch (Exception exception) { - ThrowTerminatingForException("GetInfisicalSecretCmdlet", "RetrieveSecret", exception); + ThrowTerminatingForException("GetInfisicalSecretCmdlet", "GetSecret", exception); } } + + private static Dictionary ToStringDictionary(Hashtable hashtable) + { + if (hashtable == null) { return null; } + + Dictionary result = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (DictionaryEntry entry in hashtable) + { + if (entry.Key == null) { continue; } + result[entry.Key.ToString()] = entry.Value != null ? entry.Value.ToString() : null; + } + + return result; + } } } diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalSecretsCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalSecretsCmdlet.cs deleted file mode 100644 index 599b8a9..0000000 --- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalSecretsCmdlet.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Management.Automation; -using PSInfisicalAPI.Connections; -using PSInfisicalAPI.Models; -using PSInfisicalAPI.Secrets; - -namespace PSInfisicalAPI.Cmdlets -{ - [Cmdlet(VerbsCommon.Get, "InfisicalSecrets")] - [OutputType(typeof(InfisicalSecret))] - public sealed class GetInfisicalSecretsCmdlet : InfisicalCmdletBase - { - [Parameter] public string ProjectId { get; set; } - [Parameter] public string Environment { get; set; } - [Parameter] public string SecretPath { get; set; } - [Parameter] public string ApiVersion { get; set; } - [Parameter] public SwitchParameter Recursive { get; set; } - [Parameter] public SwitchParameter IncludeImports { get; set; } - [Parameter] public SwitchParameter IncludePersonalOverrides { get; set; } - [Parameter] public SwitchParameter ExpandSecretReferences { get; set; } - [Parameter] public SwitchParameter ViewSecretValue { get; set; } = SwitchParameter.Present; - [Parameter] public Hashtable MetadataFilter { get; set; } - [Parameter] public string[] TagSlugs { get; set; } - - protected override void ProcessRecord() - { - try - { - InfisicalConnection connection = InfisicalSessionManager.RequireCurrent(); - - InfisicalListSecretsQuery query = new InfisicalListSecretsQuery - { - ProjectId = ResolveProjectId(connection, ProjectId), - Environment = ResolveEnvironment(connection, Environment), - SecretPath = ResolveSecretPath(connection, SecretPath), - ApiVersion = ResolveApiVersion(connection, ApiVersion), - Recursive = Recursive.IsPresent, - IncludeImports = IncludeImports.IsPresent, - IncludePersonalOverrides = IncludePersonalOverrides.IsPresent, - ExpandSecretReferences = ExpandSecretReferences.IsPresent, - ViewSecretValue = ViewSecretValue.IsPresent, - MetadataFilter = ToStringDictionary(MetadataFilter), - TagSlugs = TagSlugs - }; - - InfisicalSecretsClient client = new InfisicalSecretsClient(HttpClient, Logger); - InfisicalSecret[] secrets = client.List(connection, query); - - foreach (InfisicalSecret secret in secrets) - { - WriteObject(secret); - } - } - catch (Exception exception) - { - ThrowTerminatingForException("GetInfisicalSecretsCmdlet", "RetrieveSecrets", exception); - } - } - - private static Dictionary ToStringDictionary(Hashtable hashtable) - { - if (hashtable == null) { return null; } - - Dictionary result = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (DictionaryEntry entry in hashtable) - { - if (entry.Key == null) { continue; } - result[entry.Key.ToString()] = entry.Value != null ? entry.Value.ToString() : null; - } - - return result; - } - } -} diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalTagCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalTagCmdlet.cs index 8c7837f..60ce541 100644 --- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalTagCmdlet.cs +++ b/src/PSInfisicalAPI/Cmdlets/GetInfisicalTagCmdlet.cs @@ -6,16 +6,18 @@ using PSInfisicalAPI.Tags; namespace PSInfisicalAPI.Cmdlets { - [Cmdlet(VerbsCommon.Get, "InfisicalTag")] + [Cmdlet(VerbsCommon.Get, "InfisicalTag", DefaultParameterSetName = "List")] [OutputType(typeof(InfisicalTag))] public sealed class GetInfisicalTagCmdlet : InfisicalCmdletBase { - [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, Position = 0)] + [Parameter(ParameterSetName = "Single", Mandatory = true, ValueFromPipelineByPropertyName = true, Position = 0)] [Alias("Slug", "Id")] public string TagSlugOrId { get; set; } [Parameter] public string ProjectId { get; set; } + [Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; } + protected override void ProcessRecord() { try @@ -23,15 +25,27 @@ namespace PSInfisicalAPI.Cmdlets InfisicalConnection connection = InfisicalSessionManager.RequireCurrent(); string resolvedProjectId = ResolveProjectId(connection, ProjectId); InfisicalTagClient client = new InfisicalTagClient(HttpClient, Logger); - InfisicalTag tag = client.Retrieve(connection, resolvedProjectId, TagSlugOrId); - if (tag != null) + + if (string.Equals(ParameterSetName, "Single", StringComparison.Ordinal)) + { + InfisicalTag tag = client.Retrieve(connection, resolvedProjectId, TagSlugOrId); + if (tag != null) + { + WriteObject(tag); + } + + return; + } + + InfisicalTag[] tags = client.List(connection, resolvedProjectId); + foreach (InfisicalTag tag in tags) { WriteObject(tag); } } catch (Exception exception) { - ThrowTerminatingForException("GetInfisicalTagCmdlet", "RetrieveTag", exception); + ThrowTerminatingForException("GetInfisicalTagCmdlet", "GetTag", exception); } } } diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalTagsCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalTagsCmdlet.cs deleted file mode 100644 index a4b736c..0000000 --- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalTagsCmdlet.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Management.Automation; -using PSInfisicalAPI.Connections; -using PSInfisicalAPI.Models; -using PSInfisicalAPI.Tags; - -namespace PSInfisicalAPI.Cmdlets -{ - [Cmdlet(VerbsCommon.Get, "InfisicalTags")] - [OutputType(typeof(InfisicalTag))] - public sealed class GetInfisicalTagsCmdlet : InfisicalCmdletBase - { - [Parameter] public string ProjectId { get; set; } - - protected override void ProcessRecord() - { - try - { - InfisicalConnection connection = InfisicalSessionManager.RequireCurrent(); - string resolvedProjectId = ResolveProjectId(connection, ProjectId); - InfisicalTagClient client = new InfisicalTagClient(HttpClient, Logger); - InfisicalTag[] tags = client.List(connection, resolvedProjectId); - foreach (InfisicalTag tag in tags) - { - WriteObject(tag); - } - } - catch (Exception exception) - { - ThrowTerminatingForException("GetInfisicalTagsCmdlet", "ListTags", exception); - } - } - } -} diff --git a/src/PSInfisicalAPI/Endpoints/InfisicalEndpointNames.cs b/src/PSInfisicalAPI/Endpoints/InfisicalEndpointNames.cs index 22f08bf..a4b70de 100644 --- a/src/PSInfisicalAPI/Endpoints/InfisicalEndpointNames.cs +++ b/src/PSInfisicalAPI/Endpoints/InfisicalEndpointNames.cs @@ -51,5 +51,8 @@ namespace PSInfisicalAPI.Endpoints public const string GetCertificateBundle = "GetCertificateBundle"; public const string SignCertificateBySubscriber = "SignCertificateBySubscriber"; public const string SignCertificateByCa = "SignCertificateByCa"; + + public const string ListPkiSubscribers = "ListPkiSubscribers"; + public const string GetPkiSubscriber = "GetPkiSubscriber"; } } diff --git a/src/PSInfisicalAPI/Endpoints/InfisicalEndpointRegistry.cs b/src/PSInfisicalAPI/Endpoints/InfisicalEndpointRegistry.cs index 2bd0f58..24d9131 100644 --- a/src/PSInfisicalAPI/Endpoints/InfisicalEndpointRegistry.cs +++ b/src/PSInfisicalAPI/Endpoints/InfisicalEndpointRegistry.cs @@ -596,18 +596,7 @@ namespace PSInfisicalAPI.Endpoints Resource = "Pki", Version = "v1", Method = "POST", - Template = "/api/v1/pki/pki-subscribers/{subscriberName}/sign-certificate", - RequiresAuthorization = true, - ContainsSecretMaterialInResponse = true - }); - - Add(map, new InfisicalEndpointDefinition - { - Name = InfisicalEndpointNames.SignCertificateBySubscriber, - Resource = "Pki", - Version = "v1", - Method = "POST", - Template = "/api/v1/cert-manager/pki-subscribers/{subscriberName}/sign-certificate", + Template = "/api/v1/pki/subscribers/{subscriberName}/sign-certificate", RequiresAuthorization = true, ContainsSecretMaterialInResponse = true }); @@ -633,6 +622,26 @@ namespace PSInfisicalAPI.Endpoints RequiresAuthorization = true, ContainsSecretMaterialInResponse = true }); + + Add(map, new InfisicalEndpointDefinition + { + Name = InfisicalEndpointNames.ListPkiSubscribers, + Resource = "Pki", + Version = "v1", + Method = "GET", + Template = "/api/v1/projects/{projectId}/pki-subscribers", + RequiresAuthorization = true + }); + + Add(map, new InfisicalEndpointDefinition + { + Name = InfisicalEndpointNames.GetPkiSubscriber, + Resource = "Pki", + Version = "v1", + Method = "GET", + Template = "/api/v1/pki/subscribers/{subscriberName}", + RequiresAuthorization = true + }); } public static InfisicalEndpointDefinition Get(string name) diff --git a/src/PSInfisicalAPI/Models/InfisicalPkiSubscriber.cs b/src/PSInfisicalAPI/Models/InfisicalPkiSubscriber.cs new file mode 100644 index 0000000..66a1953 --- /dev/null +++ b/src/PSInfisicalAPI/Models/InfisicalPkiSubscriber.cs @@ -0,0 +1,37 @@ +using System; + +namespace PSInfisicalAPI.Models +{ + public sealed class InfisicalPkiSubscriber + { + public string Id { get; set; } + public string ProjectId { get; set; } + public string CaId { get; set; } + public string Name { get; set; } + public string CommonName { get; set; } + public string Status { get; set; } + public string Ttl { get; set; } + public string[] SubjectAlternativeNames { get; set; } + public string[] KeyUsages { get; set; } + public string[] ExtendedKeyUsages { get; set; } + public bool? EnableAutoRenewal { get; set; } + public int? AutoRenewalPeriodInDays { get; set; } + public string LastOperationStatus { get; set; } + public string LastOperationMessage { get; set; } + public DateTimeOffset? LastOperationAtUtc { get; set; } + public DateTimeOffset? CreatedAtUtc { get; set; } + public DateTimeOffset? UpdatedAtUtc { get; set; } + public InfisicalPkiSubscriberProperties Properties { get; set; } + } + + public sealed class InfisicalPkiSubscriberProperties + { + public string AzureTemplateType { get; set; } + public string Organization { get; set; } + public string OrganizationalUnit { get; set; } + public string Country { get; set; } + public string State { get; set; } + public string Locality { get; set; } + public string EmailAddress { get; set; } + } +} diff --git a/src/PSInfisicalAPI/Pki/InfisicalPkiClient.cs b/src/PSInfisicalAPI/Pki/InfisicalPkiClient.cs index ff8de17..a098cf0 100644 --- a/src/PSInfisicalAPI/Pki/InfisicalPkiClient.cs +++ b/src/PSInfisicalAPI/Pki/InfisicalPkiClient.cs @@ -270,6 +270,74 @@ namespace PSInfisicalAPI.Pki }; } + public InfisicalPkiSubscriber[] ListPkiSubscribers(InfisicalConnection connection, string projectId) + { + if (connection == null) { throw new ArgumentNullException(nameof(connection)); } + string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId); + if (string.IsNullOrEmpty(resolvedProjectId)) { throw new InfisicalConfigurationException("ProjectId is required."); } + + Dictionary pathParameters = new Dictionary { { "projectId", resolvedProjectId } }; + + try + { + _logger.Information(Component, "Attempting to list Infisical PKI subscribers. Please Wait..."); + InfisicalHttpResponse response = _invoker.InvokeWithCandidateFallback(connection, InfisicalEndpointNames.ListPkiSubscribers, "ListPkiSubscribers", pathParameters, null, null); + string body = response.Body; + response.Clear(); + + List source = ParsePkiSubscriberListBody(body); + InfisicalPkiSubscriber[] mapped = InfisicalPkiSubscriberMapper.MapMany(source, resolvedProjectId); + _logger.Information(Component, "Infisical PKI subscriber list retrieval was successful."); + return mapped; + } + catch (Exception) + { + _logger.Error(Component, "Infisical PKI subscriber list retrieval failed."); + throw; + } + } + + public InfisicalPkiSubscriber GetPkiSubscriber(InfisicalConnection connection, string subscriberName, string projectId) + { + if (connection == null) { throw new ArgumentNullException(nameof(connection)); } + if (string.IsNullOrEmpty(subscriberName)) { throw new InfisicalConfigurationException("SubscriberName is required."); } + string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId); + if (string.IsNullOrEmpty(resolvedProjectId)) { throw new InfisicalConfigurationException("ProjectId is required."); } + + Dictionary pathParameters = new Dictionary { { "subscriberName", subscriberName } }; + List> query = new List> { new KeyValuePair("projectId", resolvedProjectId) }; + + try + { + _logger.Information(Component, string.Concat("Attempting to retrieve Infisical PKI subscriber '", subscriberName, "'. Please Wait...")); + InfisicalHttpResponse response = _invoker.InvokeWithCandidateFallback(connection, InfisicalEndpointNames.GetPkiSubscriber, "GetPkiSubscriber", pathParameters, query, null); + InfisicalPkiSubscriberResponseDto dto = _serializer.Deserialize(response.Body); + response.Clear(); + + InfisicalPkiSubscriber mapped = InfisicalPkiSubscriberMapper.Map(dto, resolvedProjectId); + _logger.Information(Component, "Infisical PKI subscriber retrieval was successful."); + return mapped; + } + catch (Exception) + { + _logger.Error(Component, "Infisical PKI subscriber retrieval failed."); + throw; + } + } + + private List ParsePkiSubscriberListBody(string body) + { + if (string.IsNullOrEmpty(body)) { return null; } + JToken token = JToken.Parse(body); + if (token.Type == JTokenType.Array) + { + return token.ToObject>(); + } + + InfisicalPkiSubscriberListResponseDto wrapper = token.ToObject(); + return wrapper != null ? wrapper.Subscribers : null; + } + public InfisicalCertificateBundle GetCertificateBundle(InfisicalConnection connection, string serialNumber) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } diff --git a/src/PSInfisicalAPI/Pki/InfisicalPkiSubscriberDtos.cs b/src/PSInfisicalAPI/Pki/InfisicalPkiSubscriberDtos.cs new file mode 100644 index 0000000..b424535 --- /dev/null +++ b/src/PSInfisicalAPI/Pki/InfisicalPkiSubscriberDtos.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace PSInfisicalAPI.Pki +{ + internal sealed class InfisicalPkiSubscriberResponseDto + { + [JsonProperty("id")] public string Id { get; set; } + [JsonProperty("projectId")] public string ProjectId { get; set; } + [JsonProperty("caId")] public string CaId { get; set; } + [JsonProperty("name")] public string Name { get; set; } + [JsonProperty("commonName")] public string CommonName { get; set; } + [JsonProperty("status")] public string Status { get; set; } + [JsonProperty("ttl")] public string Ttl { get; set; } + [JsonProperty("subjectAlternativeNames")] public List SubjectAlternativeNames { get; set; } + [JsonProperty("keyUsages")] public List KeyUsages { get; set; } + [JsonProperty("extendedKeyUsages")] public List ExtendedKeyUsages { get; set; } + [JsonProperty("enableAutoRenewal")] public bool? EnableAutoRenewal { get; set; } + [JsonProperty("autoRenewalPeriodInDays")] public int? AutoRenewalPeriodInDays { get; set; } + [JsonProperty("lastOperationStatus")] public string LastOperationStatus { get; set; } + [JsonProperty("lastOperationMessage")] public string LastOperationMessage { get; set; } + [JsonProperty("lastOperationAt")] public string LastOperationAt { get; set; } + [JsonProperty("createdAt")] public string CreatedAt { get; set; } + [JsonProperty("updatedAt")] public string UpdatedAt { get; set; } + [JsonProperty("properties")] public InfisicalPkiSubscriberPropertiesDto Properties { get; set; } + } + + internal sealed class InfisicalPkiSubscriberPropertiesDto + { + [JsonProperty("azureTemplateType")] public string AzureTemplateType { get; set; } + [JsonProperty("organization")] public string Organization { get; set; } + [JsonProperty("organizationalUnit")] public string OrganizationalUnit { get; set; } + [JsonProperty("country")] public string Country { get; set; } + [JsonProperty("state")] public string State { get; set; } + [JsonProperty("locality")] public string Locality { get; set; } + [JsonProperty("emailAddress")] public string EmailAddress { get; set; } + } + + internal sealed class InfisicalPkiSubscriberListResponseDto + { + [JsonProperty("subscribers")] public List Subscribers { get; set; } + } +} diff --git a/src/PSInfisicalAPI/Pki/InfisicalPkiSubscriberMapper.cs b/src/PSInfisicalAPI/Pki/InfisicalPkiSubscriberMapper.cs new file mode 100644 index 0000000..1e0284c --- /dev/null +++ b/src/PSInfisicalAPI/Pki/InfisicalPkiSubscriberMapper.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using PSInfisicalAPI.Models; + +namespace PSInfisicalAPI.Pki +{ + internal static class InfisicalPkiSubscriberMapper + { + public static InfisicalPkiSubscriber Map(InfisicalPkiSubscriberResponseDto dto, string fallbackProjectId) + { + if (dto == null) + { + return null; + } + + return new InfisicalPkiSubscriber + { + Id = dto.Id, + ProjectId = !string.IsNullOrEmpty(dto.ProjectId) ? dto.ProjectId : fallbackProjectId, + CaId = dto.CaId, + Name = dto.Name, + CommonName = dto.CommonName, + Status = dto.Status, + Ttl = dto.Ttl, + SubjectAlternativeNames = dto.SubjectAlternativeNames != null ? dto.SubjectAlternativeNames.ToArray() : null, + KeyUsages = dto.KeyUsages != null ? dto.KeyUsages.ToArray() : null, + ExtendedKeyUsages = dto.ExtendedKeyUsages != null ? dto.ExtendedKeyUsages.ToArray() : null, + EnableAutoRenewal = dto.EnableAutoRenewal, + AutoRenewalPeriodInDays = dto.AutoRenewalPeriodInDays, + LastOperationStatus = dto.LastOperationStatus, + LastOperationMessage = dto.LastOperationMessage, + LastOperationAtUtc = ParseTimestamp(dto.LastOperationAt), + CreatedAtUtc = ParseTimestamp(dto.CreatedAt), + UpdatedAtUtc = ParseTimestamp(dto.UpdatedAt), + Properties = MapProperties(dto.Properties) + }; + } + + public static InfisicalPkiSubscriber[] MapMany(IEnumerable items, string fallbackProjectId) + { + if (items == null) + { + return Array.Empty(); + } + + List results = new List(); + foreach (InfisicalPkiSubscriberResponseDto dto in items) + { + InfisicalPkiSubscriber mapped = Map(dto, fallbackProjectId); + if (mapped != null) + { + results.Add(mapped); + } + } + + return results.ToArray(); + } + + private static InfisicalPkiSubscriberProperties MapProperties(InfisicalPkiSubscriberPropertiesDto dto) + { + if (dto == null) + { + return null; + } + + return new InfisicalPkiSubscriberProperties + { + AzureTemplateType = dto.AzureTemplateType, + Organization = dto.Organization, + OrganizationalUnit = dto.OrganizationalUnit, + Country = dto.Country, + State = dto.State, + Locality = dto.Locality, + EmailAddress = dto.EmailAddress + }; + } + + private static DateTimeOffset? ParseTimestamp(string value) + { + if (string.IsNullOrEmpty(value)) + { + return null; + } + + DateTimeOffset parsed; + if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out parsed)) + { + return parsed; + } + + return null; + } + } +}