diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index eb052c2f..ea2d6a25 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -15,7 +15,7 @@ assignees: '' ``` Operating System: -VenafiTppPS version: +VenafiPS version: PowerShell version: ``` diff --git a/README.md b/README.md index 19efebf0..5c2762f2 100644 --- a/README.md +++ b/README.md @@ -116,9 +116,9 @@ To securely store and retrieve secrets, VenafiPS has added support for the [Powe - `Install-Module Microsoft.PowerShell.SecretStore` or whichever vault you would like to use - `Register-SecretVault -Name VenafiPS -ModuleName Microsoft.PowerShell.SecretStore`. If you are using a different vault type, replace the value for `-ModuleName`. - If using the vault Microsoft.PowerShell.SecretStore, execute `Set-SecretStoreConfiguration -Authentication None -Confirm:$false`. Note, although the vault authentication is set to none, this just turns off the password required to access the vault, it does not mean your secrets are not encrypted. This is required for automation purposes. If using a different vault type, ensure you turn off any features which inhibit automation. -- `Set-Secret -Vault VenafiPS -Name gdb-token -Value $VenafiSession.Token.RefreshToken` will store your refresh token credential in the vault. Ensure you have run `New-VenafiSession` once before running this command. You can also store the access token as opposed to the refresh token. If storing the refresh token a new access token will be obtained each time you create a new session. If using an access token, it will be used as is and expire as configured. -- You can optionally store the server and client id in the secret metadata. If you choose to not store this info, you will need to provide it when calling `New-VenafiSession`. To store the metadata execute `Set-SecretInfo -Vault VenafiPS -Name gdb-token -Metadata @{'Server'='venafi.mycompany.com';'ClientId'='MyApp'}` -- When running `New-VenafiSession` use the `-VaultAccessTokenName` or `-VaultRefreshTokenName` parameters to access the secret. +- Check out the help for `New-VenafiSession` for the many ways you can store and retrieve secrets from the vault, but the easiest way to get started is: + - `New-VenafiSession -Server my.venafi.com -Credential $myCred -ClientId MyApp -Scope $scope -VaultRefreshTokenName tpp-token -VaultMetadata`. This will create a new token based session and store the refresh token in the vault. `-VaultMetadata` will store the server and clientid with the refresh token as metadata. Scope does not need to be stored as it is inherent in the token. + - To create a new session going forward, `New-VenafiSession -VaultRefreshTokenName tpp-token`. This will retrieve the refresh token and associated metadata from the vault, retrieve a new access token based on that refresh token and create a new session. Note, extension vaults are registered to the current logged in user context, and will be available only to that user (unless also registered to other users). diff --git a/VenafiPS/Classes/VenafiSession.ps1 b/VenafiPS/Classes/VenafiSession.ps1 index ed963845..da23a375 100644 --- a/VenafiPS/Classes/VenafiSession.ps1 +++ b/VenafiPS/Classes/VenafiSession.ps1 @@ -135,7 +135,7 @@ class VenafiSession { $params.UseDefaultCredentials = $true } - $response = Invoke-TppRestMethod @params + $response = Invoke-VenafiRestMethod @params $this.Key = [pscustomobject] @{ ApiKey = $response.ApiKey Credential = $Credential diff --git a/VenafiPS/Public/Get-TppAttribute.ps1 b/VenafiPS/Public/Get-TppAttribute.ps1 index 1efcfd7b..73588b28 100644 --- a/VenafiPS/Public/Get-TppAttribute.ps1 +++ b/VenafiPS/Public/Get-TppAttribute.ps1 @@ -17,7 +17,7 @@ Path to the object to retrieve configuration attributes. Just providing DN will To be deprecated; use -Path instead. Object Guid. Just providing Guid will return all attributes. -.PARAMETER AttributeName +.PARAMETER Attribute Only retrieve the value/values for this attribute .PARAMETER Effective @@ -248,7 +248,7 @@ function Get-TppAttribute { $customField = $VenafiSession.CustomField | Where-Object { $_.Guid -eq $thisConfigValue.Name } $thisConfigValue | Add-Member @{ - 'IsCustomField' = $null -ne $customField + 'IsCustomField' = [bool]$customField 'CustomName' = $null } if ( $customField ) { @@ -257,13 +257,7 @@ function Get-TppAttribute { $thisConfigValue } - - # [PSCustomObject] @{ - # Path = $thisPath - # Attribute = $updatedConfigValues - # } } - # } } end { diff --git a/VenafiPS/Public/Get-TppIdentity.ps1 b/VenafiPS/Public/Get-TppIdentity.ps1 index 8a3a9604..f52557bd 100644 --- a/VenafiPS/Public/Get-TppIdentity.ps1 +++ b/VenafiPS/Public/Get-TppIdentity.ps1 @@ -115,7 +115,9 @@ function Get-TppIdentity { $response = Invoke-VenafiRestMethod @params | Select-Object -ExpandProperty ID if ( $IncludeAssociated ) { - $associated = Invoke-VenafiRestMethod @params -UriLeaf 'Identity/GetAssociatedEntries' + $assocParams = $params.Clone() + $assocParams.UriLeaf = 'Identity/GetAssociatedEntries' + $associated = Invoke-VenafiRestMethod @assocParams $response | Add-Member @{ 'Associated' = $associated.Identities } } diff --git a/VenafiPS/Public/Get-TppVersion.ps1 b/VenafiPS/Public/Get-TppVersion.ps1 index 92b9b91c..05e6a10b 100644 --- a/VenafiPS/Public/Get-TppVersion.ps1 +++ b/VenafiPS/Public/Get-TppVersion.ps1 @@ -47,10 +47,9 @@ function Get-TppVersion { } try { - $ver = [Version]((Invoke-TppRestMethod @params).Version) - [Version]::new($ver.Major, $ver.Minor, $ver.Build) + [Version]((Invoke-VenafiRestMethod @params).Version) } catch { Throw ("Getting the version failed with the following error: {0}. This feature was introduced in v18.3." -f $_) } -} \ No newline at end of file +} diff --git a/VenafiPS/Public/Invoke-TppCertificateRenewal.ps1 b/VenafiPS/Public/Invoke-TppCertificateRenewal.ps1 index 891f5243..d74444ed 100644 --- a/VenafiPS/Public/Invoke-TppCertificateRenewal.ps1 +++ b/VenafiPS/Public/Invoke-TppCertificateRenewal.ps1 @@ -8,17 +8,18 @@ immediate renewal. The certificate must not be in error, already being processed configured for Monitoring in order for it be renewable. You must have Write access to the certificate object being renewed. -.PARAMETER InputObject -TppObject which represents a unique object - .PARAMETER Path -Path to the certificate to remove +Path to the certificate to renew + +.PARAMETER Csr +Optional PKCS#10 Certificate Signing Request (CSR). .PARAMETER VenafiSession -Session object created from New-VenafiSession method. The value defaults to the script session object $VenafiSession. +Session object created from New-VenafiSession method. +The value defaults to the script session object $VenafiSession. .INPUTS -InputObject or Path +Path .OUTPUTS PSCustomObject with the following properties: @@ -30,6 +31,10 @@ PSCustomObject with the following properties: .EXAMPLE Invoke-TppCertificateRenewal -Path '\VED\Policy\My folder\app.mycompany.com' +.EXAMPLE +Invoke-TppCertificateRenewal -Path '\VED\Policy\My folder\app.mycompany.com' -Csr '-----BEGIN CERTIFICATE REQUEST-----\nMIIDJDCCAgwCAQAw...-----END CERTIFICATE REQUEST-----' +Renew certificate using a CSR + .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Invoke-TppCertificateRenewal/ @@ -46,10 +51,7 @@ function Invoke-TppCertificateRenewal { [Alias('itcr')] param ( - [Parameter(Mandatory, ParameterSetName = 'ByObject', ValueFromPipeline)] - [TppObject] $InputObject, - - [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByPath')] + [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { @@ -62,6 +64,9 @@ function Invoke-TppCertificateRenewal { [Alias('DN', 'CertificateDN')] [String] $Path, + [Parameter()] + [string] $Csr, + [Parameter()] [VenafiSession] $VenafiSession = $script:VenafiSession ) @@ -71,9 +76,9 @@ function Invoke-TppCertificateRenewal { $params = @{ VenafiSession = $VenafiSession - Method = 'Post' - UriLeaf = 'certificates/renew' - Body = @{ + Method = 'Post' + UriLeaf = 'certificates/renew' + Body = @{ CertificateDN = '' } } @@ -81,15 +86,16 @@ function Invoke-TppCertificateRenewal { process { - if ( $PSBoundParameters.ContainsKey('InputObject') ) { - $path = $InputObject.Path - } - if ( $PSCmdlet.ShouldProcess($Path, 'Renew certificate') ) { write-verbose "Renewing $Path..." $params.Body.CertificateDN = $Path + + if ( $Csr ) { + $params.Body.PKCS10 = $Csr -replace "`n|`r", "" + } + $response = Invoke-TppRestMethod @params $response | Add-Member @{'Path' = $Path } -PassThru diff --git a/VenafiPS/Public/New-TppCertificate.ps1 b/VenafiPS/Public/New-TppCertificate.ps1 index 7f124d15..88438251 100644 --- a/VenafiPS/Public/New-TppCertificate.ps1 +++ b/VenafiPS/Public/New-TppCertificate.ps1 @@ -14,6 +14,10 @@ Name of the certifcate. If not provided, the name will be the same as the subje .PARAMETER CommonName Subject Common Name. If Name isn't provided, CommonName will be used. +.PARAMETER Csr +The PKCS#10 Certificate Signing Request (CSR). +If this value is provided, any Subject DN fields and the KeyBitSize in the request are ignored. + .PARAMETER CertificateType Type of certificate to be created. No value provided will default to X.509 Server Certificate. @@ -43,8 +47,24 @@ Hashtable of custom field(s) to be updated when creating the certificate. This is required when the custom fields are mandatory. The key is the name, not guid, of the custom field. +.PARAMETER NoWorkToDo +Turn off lifecycle processing for this certificate update + +.PARAMETER Device +An array of hashtables for devices to be created. +Available parameters can be found at https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Certificates-request.php. +If provisioning applications as well, those should be provided with the Application parameter. + +.PARAMETER Application +An array of hashtables for applications to be created. +Available parameters can be found at https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Certificates-request-ApplicationsParameter.php. +In addition to the application parameters, a key/value must be provided for the associated device. +The key needs to be 'DeviceName' and the value is the ObjectName from the device. +See the example. + .PARAMETER PassThru Return a TppObject representing the newly created certificate. +If devices and/or applications were created, a 'Device' property will be available as well. .PARAMETER VenafiSession Session object created from New-VenafiSession method. The value defaults to the script session object $VenafiSession. @@ -54,11 +74,16 @@ None .OUTPUTS TppObject, if PassThru is provided +If devices and/or applications were created, a 'Device' property will be available as well. .EXAMPLE New-TppCertificate -Path '\ved\policy\folder' -Name 'mycert.com' -CertificateAuthorityDN '\ved\policy\CA Templates\my template' Create certificate by name +.EXAMPLE +New-TppCertificate -Path '\ved\policy\folder' -CertificateAuthorityDN '\ved\policy\CA Templates\my template' -Csr '-----BEGIN CERTIFICATE REQUEST-----\nMIIDJDCCAgwCAQAw...-----END CERTIFICATE REQUEST-----' +Create certificate using a CSR + .EXAMPLE New-TppCertificate -Path '\ved\policy\folder' -Name 'mycert.com' -CertificateAuthorityDN '\ved\policy\CA Templates\my template' -CustomField @{''=''} Create certificate and update custom fields @@ -71,6 +96,10 @@ Create certificate using common name. Return the created object. New-TppCertificate -Path '\ved\policy\folder' -Name 'mycert.com' -CertificateAuthorityDN '\ved\policy\CA Templates\my template' -SubjectAltName @{'Email'='me@x.com'},@{'IPAddress'='1.2.3.4'} Create certificate including subject alternate names +.EXAMPLE +New-TppCertificate -Path '\ved\policy\folder' -Name 'mycert.com' -Device @{'PolicyDN'=$DevicePath; 'ObjectName'='MyDevice'; 'Host'='1.2.3.4'} -Application @{'DeviceName'='MyDevice'; 'ObjectName'='BasicApp'; 'DriverName'='appbasic'} +Create a new certificate with associated device and app objects + .LINK http://VenafiPS.readthedocs.io/en/latest/functions/New-TppCertificate/ @@ -101,13 +130,19 @@ function New-TppCertificate { [String] $Path, [Parameter(Mandatory, ParameterSetName = 'ByName', ValueFromPipeline)] + [Parameter(Mandatory, ParameterSetName = 'ByNameWithDevice', ValueFromPipeline)] [String] $Name, [Parameter(ParameterSetName = 'ByName')] + [Parameter(ParameterSetName = 'ByNameWithDevice')] [Parameter(Mandatory, ParameterSetName = 'BySubject')] + [Parameter(Mandatory, ParameterSetName = 'BySubjectWithDevice')] [Alias('Subject')] [String] $CommonName, + [Parameter()] + [string] $Csr, + [Parameter()] [String] $CertificateType, @@ -137,6 +172,19 @@ function New-TppCertificate { [Parameter()] [Hashtable] $CustomField, + [Parameter()] + [switch] $NoWorkToDo, + + [Parameter(ParameterSetName = 'ByName')] + [Parameter(Mandatory, ParameterSetName = 'ByNameWithDevice')] + [Parameter(ParameterSetName = 'BySubject')] + [Parameter(Mandatory, ParameterSetName = 'BySubjectWithDevice')] + [hashtable[]] $Device, + + [Parameter(ParameterSetName = 'ByNameWithDevice')] + [Parameter(ParameterSetName = 'BySubjectWithDevice')] + [hashtable[]] $Application, + [Parameter()] [switch] $PassThru, @@ -213,6 +261,7 @@ function New-TppCertificate { 'Value' = 'VenafiPS' } ) + SetWorkToDo = -not $NoWorkToDo } } @@ -231,6 +280,10 @@ function New-TppCertificate { } } + if ( $Csr ) { + $params.Body.Add('PKCS10', $Csr -replace "`n|`r", "") + } + if ( $PSBoundParameters.ContainsKey('CertificateAuthorityPath') ) { $params.Body.Add('CADN', $CertificateAuthorityPath) } @@ -267,6 +320,30 @@ function New-TppCertificate { $params.Body.Add('CustomFields', @($newCf)) } + if ( $Device ) { + # convert apps to array of custom objects to make it easier to search + $appCustom = @($Application | ForEach-Object { [pscustomobject] $_ }) + + # loop through devices and append any apps found + $updatedDevice = foreach ($thisDevice in $Device) { + + $thisApplication = $appCustom | Where-Object { $_.DeviceName -eq $thisDevice.ObjectName } + + if ( $thisApplication ) { + $finalAppList = foreach ($app in $thisApplication | Select-Object -Property * -ExcludeProperty DeviceName) { + $ht = @{} + $app.psobject.properties | ForEach-Object { $ht[$_.Name] = $_.Value } + $ht + } + + $thisDevice.Applications = @($finalAppList) + } + + $thisDevice + } + $params.Body.Add('Devices', @($updatedDevice)) + + } } process { @@ -280,7 +357,14 @@ function New-TppCertificate { Write-Verbose ($response | Out-String) if ( $PassThru ) { - Get-TppObject -Path $response.CertificateDN -VenafiSession $VenafiSession + $newCert = Get-TppObject -Path $response.CertificateDN -VenafiSession $VenafiSession + if ( $Device ) { + $newCert | Add-Member @{ 'Device' = @{'Path' = $response.Devices.DN} } + if ( $Application ) { + $newCert.Device.Application = $response.Devices.Applications.DN + } + } + $newCert } } catch {