VenafiPS.psm1
#Region './Enum/TppCertificateStage.ps1' -1 enum TppCertificateStage { CheckStore = 100 CreateConfigureStore = 200 CreateKey = 300 CreateCSR = 400 PostCSR = 500 ApproveRequest = 600 RetrieveCertificate = 700 InstallCertificate = 800 CheckConfiguration = 900 ConfigureApplication = 1000 RestartApplication = 1100 EndProcessing = 1200 Revocation = 1400 UpdateTrustStore = 1500 EndTrustStoreProcessing = 1600 } #EndRegion './Enum/TppCertificateStage.ps1' 18 #Region './Enum/TppEventSeverity.ps1' -1 enum TppEventSeverity { Emergency = 1 Alert = 2 Critical = 3 Error = 4 Warning = 5 Notice = 6 Info = 7 Debug = 8 } #EndRegion './Enum/TppEventSeverity.ps1' 11 #Region './Enum/TppIdentityType.ps1' -1 enum TppIdentityType { User = 1 SecurityGroups = 2 DistributionGroups = 8 } #EndRegion './Enum/TppIdentityType.ps1' 6 #Region './Enum/TppManagementType.ps1' -1 enum TppManagementType { Unassigned Monitoring Enrollment Provisioning } #EndRegion './Enum/TppManagementType.ps1' 7 #Region './Enum/TppMetadataResult.ps1' -1 enum TppMetadataResult { Success = 0 InvalidConfigObject = 1 InvalidDN = 2 InvalidName = 3 InvalidItem = 4 InvalidClass = 5 InvalidMetadataObject = 6 InvalidRights = 7 ItemIsNull = 8 ItemAlreadyExists = 9 ItemTypeUnknown = 10 ConfigCreateFailed = 11 ConfigWriteFailed = 12 ConfigDeleteFailed = 13 MetadataInUse = 14 NoAllowedValues = 15 AllowedValueDoesNotExist = 16 ValueNotInAllowedList = 17 ItemNotValidForClass = 18 NameTooLong = 19 TooManyContainers = 20 ConfigDnNotContainer = 21 InvalidPolicyState = 22 ConfigLockFailed = 23 ConfigReadFailed = 24 RemoteError = 25 } #EndRegion './Enum/TppMetadataResult.ps1' 29 #Region './Enum/TppSecretStoreResult.ps1' -1 enum TppSecretStoreResult { Success = 0 InvalidCallingAssembly = 1 CreateDatabaseError = 2 UseDatabaseError = 3 CreateTableError = 4 CreateIndexError = 5 ConnectionError = 6 TransactionError = 7 InvalidVaultID = 8 InvalidParams = 9 InsufficientPermissions = 10 CryptoFailure = 11 DeleteSecretFailed = 12 AddSecretFailed = 13 RetrieveSecretFailed = 14 RetrieveSecretTypeFailed = 15 GetNextVaultIDFailed = 16 DisassociateFailed = 17 OwnerLookupFailed = 18 AssociateDataFailed = 19 LookupFailed = 20 InvalidKey = 21 QueryError = 22 SecurityGroupNotImplemented = 23 RemoteError = 24 VaultIdAlreadyExists = 25 OutOfMemory = 26 AssociationAlreadyExists = 27 VaultIdExceedsIntegerCapacity = 28 AssociationLookupFailed = 29 AddRevocationStateFailed = 30 CertificateMigrationStateNotFound = 31 TodoManagerError = 32 } #EndRegion './Enum/TppSecretStoreResult.ps1' 36 #Region './Enum/TppWorkflowResult.ps1' -1 enum TppWorkflowResult { Success = 1 GenericFailure = 2 TicketDoesNotExist = 3 InsufficientPrivileges = 4 BadArguments = 5 ObjectDoesNotExist = 6 RemoteError = 7 WorkflowObjectDoesNotExist = 8 } #EndRegion './Enum/TppWorkflowResult.ps1' 11 #Region './Classes/TppPermission.ps1' -1 class TppPermission { [bool] $IsAssociateAllowed [bool] $IsCreateAllowed [bool] $IsDeleteAllowed [bool] $IsManagePermissionsAllowed [bool] $IsPolicyWriteAllowed [bool] $IsPrivateKeyReadAllowed [bool] $IsPrivateKeyWriteAllowed [bool] $IsReadAllowed [bool] $IsRenameAllowed [bool] $IsRevokeAllowed [bool] $IsViewAllowed [bool] $IsWriteAllowed TppPermission () { $this.IsAssociateAllowed = $false $this.IsCreateAllowed = $false $this.IsDeleteAllowed = $false $this.IsManagePermissionsAllowed = $false $this.IsPolicyWriteAllowed = $false $this.IsPrivateKeyReadAllowed = $false $this.IsPrivateKeyWriteAllowed = $false $this.IsReadAllowed = $false $this.IsRenameAllowed = $false $this.IsRevokeAllowed = $false $this.IsViewAllowed = $false $this.IsWriteAllowed = $false } TppPermission ([pscustomobject] $InputObject) { $this.IsAssociateAllowed = $InputObject.IsAssociateAllowed $this.IsCreateAllowed = $InputObject.IsCreateAllowed $this.IsDeleteAllowed = $InputObject.IsDeleteAllowed $this.IsManagePermissionsAllowed = $InputObject.IsManagePermissionsAllowed $this.IsPolicyWriteAllowed = $InputObject.IsPolicyWriteAllowed $this.IsPrivateKeyReadAllowed = $InputObject.IsPrivateKeyReadAllowed $this.IsPrivateKeyWriteAllowed = $InputObject.IsPrivateKeyWriteAllowed $this.IsReadAllowed = $InputObject.IsReadAllowed $this.IsRenameAllowed = $InputObject.IsRenameAllowed $this.IsRevokeAllowed = $InputObject.IsRevokeAllowed $this.IsViewAllowed = $InputObject.IsViewAllowed $this.IsWriteAllowed = $InputObject.IsWriteAllowed } [HashTable] ToHashtable() { $hash = @{} $propNames = $this | Get-Member | Where-Object { $_.MemberType -eq 'Property' } | Select-Object -ExpandProperty Name foreach ($prop in $propNames) { if ($this.GetType().GetProperty($prop)) { $hash.Add($prop, $this.$prop) } } return $hash } } #EndRegion './Classes/TppPermission.ps1' 61 #Region './Private/ConvertTo-PlaintextString.ps1' -1 function ConvertTo-PlaintextString { <# .SYNOPSIS Convert a SecureString or PSCredential to a plaintext string/password. .EXAMPLE ConvertTo-PlaintextString -InputObject $mySecureString #> [Cmdletbinding()] [OutputType([string])] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, Position = 0)] [psobject] $InputObject ) process { if ( $InputObject -is [string] ) { $InputObject } elseif ($InputObject -is [securestring]) { # use this workaround to support both v5 and v7 (New-Object System.Management.Automation.PSCredential(0, $InputObject)).GetNetworkCredential().password } elseif ($InputObject -is [pscredential]) { $InputObject.GetNetworkCredential().Password } else { throw 'Unsupported type for -InputObject. Provide either a String, SecureString, or PSCredential.' } } } #EndRegion './Private/ConvertTo-PlaintextString.ps1' 31 #Region './Private/ConvertTo-UtcIso8601.ps1' -1 <# .SYNOPSIS Convert datetime to UTC ISO 8601 format .DESCRIPTION Convert datetime to UTC ISO 8601 format .PARAMETER InputObject DateTime object .INPUTS InputObject .OUTPUTS System.String .EXAMPLE (get-date) | ConvertTo-UtcIso8601 #> function ConvertTo-UtcIso8601 { [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline)] [ValidateNotNullOrEmpty()] [DateTime] $InputObject ) begin { } process { $InputObject.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ") } } #EndRegion './Private/ConvertTo-UtcIso8601.ps1' 38 #Region './Private/ConvertTo-VcTeam.ps1' -1 function ConvertTo-VcTeam { <# .SYNOPSIS Convert vaas team to standard format .DESCRIPTION Convert vaas team to standard format .PARAMETER InputObject Team object .INPUTS InputObject .OUTPUTS PSCustomObject .EXAMPLE $teamObj | ConvertTo-VcTeam #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline)] [AllowNull()] [PSCustomObject[]] $InputObject ) begin { } process { $InputObject | Select-Object -Property ` @{ n = 'teamId' e = { $_.id } }, * -ExcludeProperty id } } #EndRegion './Private/ConvertTo-VcTeam.ps1' 42 #Region './Private/ConvertTo-VdcFullPath.ps1' -1 function ConvertTo-VdcFullPath { [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline)] [string] $Path ) begin { } process { if ( $Path.ToLower() -notlike '\ved*') { "\VED\Policy\$Path" } else { $Path } } end { } } #EndRegion './Private/ConvertTo-VdcFullPath.ps1' 25 #Region './Private/ConvertTo-VdcIdentity.ps1' -1 function ConvertTo-VdcIdentity { <# .SYNOPSIS Convert identity to standard format .DESCRIPTION Convert identity to standard format .PARAMETER InputObject Identity object .INPUTS InputObject .OUTPUTS PSCustomObject .EXAMPLE $identityObj | ConvertTo-VdcIdentity #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline)] [AllowNull()] [PSCustomObject[]] $InputObject ) begin { } process { $InputObject | Select-Object -Property ` @{ n = 'Name' e = { $_.Name } }, @{ n = 'ID' e = { $_.PrefixedUniversal } }, @{ n = 'Path' e = { $_.FullName } }, @{ n = 'FullName' e = { $_.PrefixedName } }, @{ n = 'IsGroup' e = { $_.Type -ne 1 } }, * -ExcludeProperty PrefixedUniversal, FullName, Prefix, PrefixedName, Type, Universal, IsGroup, Name } } #EndRegion './Private/ConvertTo-VdcIdentity.ps1' 58 #Region './Private/ConvertTo-VdcObject.ps1' -1 function ConvertTo-VdcObject { [CmdletBinding(DefaultParameterSetName = 'Path')] param ( [Parameter(Mandatory, ParameterSetName = 'ByObject', ValueFromPipeline)] [pscustomobject] $InputObject, [Parameter(Mandatory, ParameterSetName = 'Path', ValueFromPipeline)] [Parameter(Mandatory, ParameterSetName = 'All')] [string] $Path, [Parameter(Mandatory, ParameterSetName = 'Guid', ValueFromPipeline)] [Parameter(Mandatory, ParameterSetName = 'All')] [guid] $Guid, [Parameter(ParameterSetName = 'Path')] [Parameter(ParameterSetName = 'Guid')] [Parameter(Mandatory, ParameterSetName = 'All')] [string] $TypeName ) begin { } process { switch ($PSCmdlet.ParameterSetName) { 'ByObject' { $thisPath = $InputObject.Path $thisGuid = $InputObject.Guid $thisTypeName = $InputObject.TypeName } 'Path' { $thisPath = $Path $info = $Path | ConvertTo-VdcGuid -IncludeType $thisGuid = $info.Guid $thisTypeName = $info.TypeName } 'Guid' { $thisGuid = $Guid $info = ConvertTo-VdcPath -Guid $Guid -IncludeType $thisPath = $info.Path $thisTypeName = $info.TypeName } Default { $thisPath = $Path $thisGuid = $Guid $thisTypeName = $TypeName } } $out = [pscustomobject]@{ Path = $thisPath.Replace('\\', '\') TypeName = $thisTypeName Guid = $thisGuid Name = $thisPath.Split('\')[-1] } $out | Add-Member @{'ParentPath' = $out.Path.Substring(0, $out.Path.LastIndexOf("\$($out.Name)")) } $out | Add-Member -MemberType ScriptMethod -Name ToString -Value { $out.Path } -Force $out } } #EndRegion './Private/ConvertTo-VdcObject.ps1' 68 #Region './Private/Find-VcObject.ps1' -1 function Find-VcObject { <# .SYNOPSIS Find different objects on TLSPC .DESCRIPTION Find objects of type ActivityLog, Machine, MachineIdentity, CertificateRequest, CertificateInstance on TLSPC. Supports -First for page size; the max page size is 1000. To find certificate objects, use Find-VcCertificate. .PARAMETER Type Type of object to retrieve, either Certificate, ActivityLog, Machine, MachineIdentity, CertificateRequest, or CertificateInstance. .PARAMETER Name Case sensitive name to search for. The field to be searched is different for each object type. .PARAMETER Filter Array or multidimensional array of fields and values to filter on. Each array should be of the format @('operator', @(field, comparison operator, value), @(field2, comparison operator2, value2)). Nested filters are supported. For a complete list of comparison operators, see https://docs.venafi.cloud/api/about-api-search-operators/. .PARAMETER Order Array of fields to order on. For each item in the array, you can provide a field name by itself; this will default to ascending. You can also provide a hashtable with the field name as the key and either asc or desc as the value. .PARAMETER First Only retrieve this many records .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .OUTPUTS PSCustomObject .EXAMPLE Find-VcObject -Type CertificateInstance Get all records .EXAMPLE Find-VcObject -Type CertificateInstance -First 50 Get first 50 records .EXAMPLE Find-VcObject -Type ActivityLog -Filter @('activityType', 'eq', 'Notifications') -First 10 Retrieve 10 records matching the field name .EXAMPLE Find-VcObject -Type Certificate -Name searchme Get all certificates where the name has 'searchme' in it .EXAMPLE Find-VcObject -type Certificate -filter @('selfSigned','eq','True') Get all self signed certificates .EXAMPLE Find-VcObject -Type ActivityLog -Filter @('activityType', 'eq', 'Notifications') -First 10 -Order @{'activityDate'='desc'} Retrieve the most recent 10 records matching the field name .EXAMPLE Find-VcObject -Filter @('and', @('activityDate', 'gt', (get-date).AddMonths(-1)), @('or', @('userId', 'eq', 'ab0feb46-8df7-47e7-8da9-f47ab314f26a'), @('userId', 'eq', '933c28de-6352-46f3-bc12-bd96077e8eae'))) Advanced filtering of results. This filter will find log entries by 1 of 2 people within the last month. .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Find-VcObject/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Find-VcObject.ps1 #> [CmdletBinding(DefaultParameterSetName = 'All')] param ( [Parameter(Mandatory)] [ValidateSet('Certificate', 'ActivityLog', 'Machine', 'MachineIdentity', 'CertificateRequest', 'CertificateInstance')] [string] $Type, [Parameter(ParameterSetName = 'All')] [string] $Name, [Parameter(Mandatory, ParameterSetName = 'Filter')] [System.Collections.Generic.List[object]] $Filter, # [System.Collections.ArrayList] $Filter, [Parameter(ParameterSetName = 'All')] [Parameter(ParameterSetName = 'Filter')] [psobject[]] $Order, [parameter(Mandatory, ParameterSetName = 'SavedSearch')] [string] $SavedSearchName, [Parameter()] [int] $First, [Parameter()] [psobject] $VenafiSession ) Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $objectData = @{ 'Certificate' = @{ 'uriroot' = 'outagedetection/v1' 'urileaf' = 'certificatesearch' 'property' = 'certificates' 'filter' = @{ Property = @{'n' = 'certificateId'; 'e' = { $_.Id } } ExcludeProperty = 'id' } 'name' = 'certificateName' } 'CertificateRequest' = @{ 'uriroot' = 'outagedetection/v1' 'urileaf' = 'certificaterequestssearch' 'property' = 'certificaterequests' 'filter' = @{ Property = @{'n' = 'certificateRequestId'; 'e' = { $_.Id } } ExcludeProperty = 'id' } 'name' = 'subjectDN' } 'CertificateInstance' = @{ 'uriroot' = 'outagedetection/v1' 'urileaf' = 'certificateinstancesearch' 'property' = 'instances' 'filter' = '' 'name' = 'hostname' } 'Machine' = @{ 'uriroot' = 'v1' 'urileaf' = 'machinesearch' 'property' = 'machines' 'filter' = @{ Property = @{'n' = 'machineId'; 'e' = { $_.Id } } ExcludeProperty = 'id' } 'name' = 'machineName' } 'MachineIdentity' = @{ 'uriroot' = 'v1' 'urileaf' = 'machineidentitysearch' 'property' = 'machineidentities' 'filter' = @{ Property = @{'n' = 'machineIdentityId'; 'e' = { $_.Id } } ExcludeProperty = 'id' } 'name' = 'certificateName' } 'ActivityLog' = @{ 'uriroot' = 'v1' 'urileaf' = 'activitylogsearch' 'property' = 'activityLogEntries' 'filter' = @{ Property = @{'n' = 'activityLogId'; 'e' = { $_.Id } } ExcludeProperty = 'id' } 'name' = 'activityName' } } $queryParams = @{ Filter = $Filter Order = $Order First = $First } if ($Name) { $queryParams.Filter = @($objectData.$Type.name, 'FIND', $Name) } $body = New-VcSearchQuery @queryParams if ( $PSBoundParameters.ContainsKey('SavedSearchName') ) { # get saved search data and update payload $thisSavedSearch = Invoke-VenafiRestMethod -UriRoot 'outagedetection/v1' -UriLeaf 'savedsearches' | Select-Object -ExpandProperty savedSearchInfo | Where-Object { $_.name -eq $SavedSearchName } if ( $thisSavedSearch ) { $body.expression = $thisSavedSearch.searchDetails.expression $body.ordering = $thisSavedSearch.searchDetails.ordering } else { throw "The saved search name $SavedSearchName could not be found" } } $params = @{ Method = 'Post' Body = $body Header = @{'Accept' = 'application/json' } } $params.UriRoot = $objectData.$Type.uriroot $params.UriLeaf = $objectData.$Type.urileaf $params.UriLeaf += '?ownershipTree=true' $allObjects = [System.Collections.Generic.List[object]]::new() do { $response = Invoke-VenafiRestMethod @params if ( -not $response ) { continue } $thisObjects = $response | Select-Object -ExpandProperty $objectData.$Type.property if ( -not $thisObjects ) { break } $allObjects.AddRange(@($thisObjects)) if ( $thisObjects.Count -lt $params.Body.paging.pageSize ) { break } if ( $First ) { # break out if we have all the objects we asked for if ( $allObjects.Count -eq $First ) { break } else { $params.Body.paging.pageSize = [System.Math]::Min($First - $allObjects.Count, 1000) } } $params.body.paging.pageNumber += 1 } while ( $true ) if ( $objectData.$Type.filter ) { $allObjects | Select-Object -Property $objectData.$Type.filter.Property, * -ExcludeProperty $objectData.$Type.filter.ExcludeProperty } else { $allObjects } } #EndRegion './Private/Find-VcObject.ps1' 244 #Region './Private/Get-EnumValues.ps1' -1 function Get-EnumValues { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '')] param ( [Parameter(Mandatory, ValueFromPipeline)] [ValidateNotNullOrEmpty()] [string] $EnumName ) process { [enum]::GetValues([type]$EnumName).ForEach{ @{$_ = $_.value__} } } } #EndRegion './Private/Get-EnumValues.ps1' 18 #Region './Private/Get-VcData.ps1' -1 function Get-VcData { <# .SYNOPSIS Helper function to get data from Venafi Cloud #> [CmdletBinding(DefaultParameterSetName = 'ID')] param ( [parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ID', Position = '0')] [parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'Name', Position = '0')] [parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'Object', Position = '0')] [AllowEmptyString()] [string] $InputObject, [parameter(Mandatory)] [ValidateSet('Application', 'MachineType', 'VSatellite', 'Certificate', 'IssuingTemplate', 'Team', 'Machine', 'Tag')] [string] $Type, # [parameter()] # [ValidateSet('InputObject', 'Name', 'Object', 'First')] # [string] $OutType = 'InputObject', [parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'Name')] [switch] $Name, [parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'Object')] [switch] $Object, [parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'First')] [switch] $First, [parameter()] [switch] $FailOnMultiple, [parameter()] [switch] $FailOnNotFound ) begin { } process { # if we already have a guid, just return it if ( $PSCmdlet.ParameterSetName -eq 'ID' -and (Test-IsGuid($InputObject)) ) { return $InputObject } switch ($Type) { 'Application' { # if ( -not $script:vcApplication ) { # $script:vcApplication = Get-VcApplication -All | Sort-Object -Property name # } # $allObject = $script:vcApplication # $thisObject = $script:vcApplication | Where-Object { $InputObject -in $_.name, $_.applicationId } $allObject = Get-VcApplication -All | Sort-Object -Property name $thisObject = $allObject | Where-Object { $InputObject -in $_.name, $_.applicationId } } 'VSatellite' { # if ( -not $script:vcVSatellite ) { # $script:vcVSatellite = Get-VcSatellite -All | Sort-Object -Property name # } # $allObject = $script:vcVSatellite # $thisObject = $script:vcVSatellite | Where-Object { $InputObject -in $_.name, $_.vsatelliteId } $allObject = Get-VcSatellite -All | Where-Object { $_.edgeStatus -eq 'ACTIVE' } | Sort-Object -Property name $thisObject = $allObject | Where-Object { $InputObject -in $_.name, $_.vsatelliteId } } 'IssuingTemplate' { # if ( -not $script:vcIssuingTemplate ) { # $script:vcIssuingTemplate = Get-VcIssuingTemplate -All | Sort-Object -Property name # } # $allObject = $script:vcIssuingTemplate # $thisObject = $script:vcIssuingTemplate | Where-Object { $InputObject -in $_.name, $_.issuingTemplateId } $allObject = Get-VcIssuingTemplate -All | Sort-Object -Property name $thisObject = $allObject | Where-Object { $InputObject -in $_.name, $_.issuingTemplateId } } 'Team' { # if ( -not $script:vcTeam ) { # $script:vcTeam = Get-VcTeam -All | Sort-Object -Property name # } # $allObject = $script:vcTeam # $thisObject = $script:vcTeam | Where-Object { $InputObject -in $_.name, $_.teamId } $allObject = Get-VcTeam -All | Sort-Object -Property name $thisObject = $allObject | Where-Object { $InputObject -in $_.name, $_.teamId } } 'MachineType' { # if ( -not $script:vcMachineType ) { # $script:vcMachineType = Invoke-VenafiRestMethod -UriLeaf 'machinetypes' | # Select-Object -ExpandProperty machineTypes | # Select-Object -Property @{'n' = 'machineTypeId'; 'e' = { $_.Id } }, * -ExcludeProperty id | # Sort-Object -Property machineType # } # $allObject = $script:vcMachineType # $thisObject = $script:vcMachineType | Where-Object { $InputObject -in $_.machineType, $_.machineTypeId } $allObject = Invoke-VenafiRestMethod -UriLeaf 'machinetypes' | Select-Object -ExpandProperty machineTypes | Select-Object -Property @{'n' = 'machineTypeId'; 'e' = { $_.Id } }, * -ExcludeProperty id | Sort-Object -Property machineType $thisObject = $allObject | Where-Object { $InputObject -in $_.machineType, $_.machineTypeId } } 'Certificate' { $thisObject = Find-VcCertificate -Name $InputObject } 'Machine' { $thisObject = Find-VcMachine -Name $InputObject } 'Tag' { try { if ( $InputObject.Contains(':') ) { $tagName, $tagValue = $InputObject.Split(':') } else { $tagName = $InputObject } $tag = Invoke-VenafiRestMethod -UriLeaf "tags/$tagName" | Select-Object -Property @{'n' = 'tagId'; 'e' = { $_.Id } }, @{'n' = 'values'; 'e' = { $null } }, * -ExcludeProperty id if ( $tag ) { $values = Invoke-VenafiRestMethod -UriLeaf "tags/$($tag.name)/values" if ( $values.values ) { $tag.values = ($values.values | Select-Object id, @{'n' = 'name'; 'e' = { $_.value } }) # make sure the value, if provided, is valid if ( $tagValue -and $tagValue -notin $tag.values.name ) { $tag = $null } } else { if ( $tagValue ) { # the tag name exists, but the value does not $tag = $null } } } $thisObject = $tag } catch { $thisObject = $null } } } if ( $FailOnMultiple -and @($thisObject).Count -gt 1 ) { throw "Multiple $Type found" } if ( $FailOnNotFound -and -not $thisObject ) { throw "'$InputObject' of type $Type not found" } switch ($PSCmdlet.ParameterSetName) { 'ID' { if ( $thisObject ) { $thisObject."$("$Type")id" } else { return $null } } 'Name' { switch ($Type) { 'Tag' { $InputObject } } } 'Object' { $thisObject } 'First' { $allObject | Select-Object -First 1 } } } end { } } #EndRegion './Private/Get-VcData.ps1' 204 #Region './Private/Initialize-PSSodium.ps1' -1 function Initialize-PSSodium { [CmdletBinding()] param ( ) # Check if the module is already loaded if ( Get-Module PSSodium ) { return } # Check if the module is installed if ( -not (Get-Module PSSodium -ListAvailable) ) { throw 'The PSSodium module is not installed. Run `Install-Module -Name PSSodium` to install.' } try { Import-Module PSSodium -Force } catch { throw "Sodium encryption could not be loaded. Ensure you are running PowerShell v7+ and if on Windows, install the latest Visual C++ Runtime. $_" } } #EndRegion './Private/Initialize-PSSodium.ps1' 24 #Region './Private/Invoke-VenafiParallel.ps1' -1 function Invoke-VenafiParallel { <# .SYNOPSIS Helper function to execute a scriptblock in parallel .DESCRIPTION Execute a scriptblock in parallel. For PS v5, the ThreadJob module is required. .PARAMETER InputObject List of items to iterate over .PARAMETER ScriptBlock Scriptblock to execute against the list of items .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER ProgressTitle Message displayed on the progress bar .PARAMETER VenafiSession Authentication for the function. .EXAMPLE Invoke-VenafiParallel -InputObject $myObjects -ScriptBlock { Do-Something $PSItem } Execute in parallel. Reference each item in the scriptblock as $PSItem or $_. .EXAMPLE Invoke-VenafiParallel -InputObject $myObjects -ScriptBlock { Do-Something $PSItem } -ThrottleLimit 5 Only run 5 threads at a time instead of the default of 100. .EXAMPLE $ProgressPreference = 'SilentlyContinue' Invoke-VenafiParallel -InputObject $myObjects -ScriptBlock { Do-Something $PSItem } Execute in parallel with no progress bar. .NOTES In your ScriptBlock: - Use either $PSItem or $_ to reference the current input object - Remember hashtables are reference types so be sure to clone if 'using' from parent #> [CmdletBinding()] param ( [Parameter(Mandatory)] [AllowNull()] [psobject] $InputObject, [Parameter(Mandatory)] [scriptblock] $ScriptBlock, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [string] $ProgressTitle = 'Performing action', [Parameter()] [psobject] $VenafiSession ) begin { if (-not $InputObject) { return } # if ThreadJob module is not available, throttle to 1 so multithreading isn't used if ( $PSVersionTable.PSVersion.Major -eq 5 ) { if ( -not $script:ThreadJobAvailable ) { $ThrottleLimit = 1 } } if ( $script:VenafiSession ) { $VenafiSession = $script:VenafiSession } elseif ($script:VenafiSessionNested) { $VenafiSession = $script:VenafiSessionNested } elseif ( $env:VDC_TOKEN ) { $VenafiSession = $env:VDC_TOKEN } elseif ( $env:VC_KEY ) { $VenafiSession = $env:VC_KEY } } process { } end { if (-not $InputObject) { return } # throttle to 1 = no parallel if ( $ThrottleLimit -le 1 ) { # ensure no $using: vars given not threaded and not needed $InputObject | ForEach-Object -Process ([ScriptBlock]::Create(($ScriptBlock.ToString() -ireplace [regex]::Escape('$using:'), '$'))) return } # parallel processing from here down $starterSb = { # need to import module until https://github.com/PowerShell/PowerShell/issues/12240 is complete # import via path instead of just module name to support non-standard paths, eg. development work # ParallelImportPath is set during module import Import-Module $using:script:ParallelImportPath -Force # bring in the venafi session from the calling ps session $script:VenafiSession = $using:VenafiSession # bring in verbose preference from calling ps session $VerbosePreference = $using:VerbosePreference } if ( $PSVersionTable.PSVersion.Major -eq 5 ) { # Start-ThreadJob does not have any child jobs for some reason so there will be no progress and just exist $sb = ([ScriptBlock]::Create($starterSb.ToString() + '$using:InputObject | % { ' + $ScriptBlock.ToString() + '}')) return Start-ThreadJob -ScriptBlock $sb -ThrottleLimit $ThrottleLimit | Receive-Job -Wait -AutoRemoveJob } else { $sb = ([ScriptBlock]::Create($starterSb.ToString() + $ScriptBlock.ToString())) # no progress, arguably faster if ( $ProgressPreference -ne 'Continue' ) { return $InputObject | Foreach-Object -AsJob -ThrottleLimit $ThrottleLimit -Parallel $sb | Receive-Job -Wait -AutoRemoveJob } } Write-Progress -Activity $ProgressTitle -Status "Initializing..." $job = $InputObject | Foreach-Object -AsJob -ThrottleLimit $ThrottleLimit -Parallel $sb if ( -not $job.ChildJobs ) { return } do { # let threads run Start-Sleep -Seconds 0.1 $completedJobsCount = $job.ChildJobs.Where({ $_.State -notin 'NotStarted', 'Running' }).Count # get latest job info $job | Receive-Job [int] $percent = ($completedJobsCount / $job.ChildJobs.Count) * 100 Write-Progress -Activity $ProgressTitle -Status "$percent% complete" -PercentComplete $percent } while ($completedJobsCount -lt $job.ChildJobs.Count) Write-Progress -Completed -Activity 'done' } } #EndRegion './Private/Invoke-VenafiParallel.ps1' 168 #Region './Private/New-HttpQueryString.ps1' -1 <# .SYNOPSIS Generate http query string .LINK https://powershellmagazine.com/2019/06/14/pstip-a-better-way-to-generate-http-query-strings-in-powershell/ #> function New-HttpQueryString { [System.Diagnostics.CodeAnalysis.SuppressMessage('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'No state is actually changing')] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [String] $Uri, [Parameter(Mandatory = $true)] [Hashtable] $QueryParameter ) # Add System.Web Add-Type -AssemblyName System.Web # Create a http name value collection from an empty string $nvCollection = [System.Web.HttpUtility]::ParseQueryString([String]::Empty) foreach ($key in $QueryParameter.Keys) { $nvCollection.Add($key, $QueryParameter.$key) } # Build the uri $uriRequest = [System.UriBuilder]$uri $uriRequest.Query = $nvCollection.ToString() return $uriRequest.Uri.OriginalString } #EndRegion './Private/New-HttpQueryString.ps1' 37 #Region './Private/New-VcSearchQuery.ps1' -1 function New-VcSearchQuery { <# .SYNOPSIS Build body for various vaas api calls .DESCRIPTION Build body for various api calls, typically for searching, eg. certificates, logs. .PARAMETER Filter Array or multidimensional array of fields and values to filter on. Each array should be of the format @('operator', @(field, comparison operator, value), @(field2, comparison operator2, value2)). Nested filters are supported. For a complete list of comparison operators, see https://docs.venafi.cloud/api/about-api-search-operators/. .PARAMETER Order Array or multidimensional array of fields to Order on. Each array should be of the format @(field, asc/desc). If just the field name is provided, ascending will be used. .EXAMPLE New-VcSearchQuery -Filter @('authenticationType', 'eq', 'NONE') Filter log results .OUTPUTS Hashtable #> [System.Diagnostics.CodeAnalysis.SuppressMessage('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'No state is actually changing')] [CmdletBinding()] [OutputType([Hashtable])] param( [parameter()] [System.Collections.Generic.List[object]] $Filter, [parameter()] [psobject[]] $Order, [Parameter()] [int] $First ) begin { $operators = 'EQ', 'FIND', 'GT', 'GTE', 'IN', 'LT', 'LTE', 'MATCH' $query = @{ 'expression' = @{} 'ordering' = @{} 'paging' = @{} } $vaasPageSizeLimit = 1000 if ( $First -le 0 ) { $First = $vaasPageSizeLimit } $query.paging.Add('pageSize', [Math]::Min($First, $vaasPageSizeLimit)) $query.paging.Add('pageNumber', 0) function New-VaasExpression { [CmdletBinding()] param ( [parameter()] [System.Collections.Generic.List[object]] $Filter ) $loopFilter = $Filter $operator = $null # first item may be the operator or a filter # if so, pull it off the list and process the rest if ($Filter[0] -is 'String' -and $Filter[0] -in 'AND', 'OR') { $operator = $Filter[0].ToUpper() $loopFilter = $Filter | Select-Object -Skip 1 $loopFilter = @(, $loopFilter) } $operands = foreach ($thisItem in $loopFilter) { if ( $thisItem.count -eq 3 ) { # handle nested expressions if ( $thisItem[2] -is 'Object[]' -and $thisItem[2][1] -in $operators ) { New-VaasExpression -Filter $thisItem } # vaas fields are case sensitive, get the proper case if we're aware of the field $thisField = $thisItem[0] $thisFieldCased = $vaasFields | Where-Object { $_.ToLower() -eq $thisField.ToLower() } $newOperand = @{ 'field' = if ($thisFieldCased) { $thisFieldCased } else { $thisField } 'operator' = $thisItem[1].ToUpper() } # handle different value types # note the use of property 'values' for an array, eg. when the operator is find, in, match switch ($thisItem[2].GetType().Name) { 'DateTime' { $newOperand.Add('value', ($thisItem[2] | ConvertTo-UtcIso8601)) } 'String' { $newValue = $thisItem[2] # these values should be upper case, fix in case not provided that way if ( $newOperand.field.ToLower() -in $vaasValuesToUpper.ToLower() ) { $newValue = $thisItem[2].ToUpper() } $newOperand.Add('value', $newValue) } Default { # we have a list $newOperand.Add('values', $thisItem[2]) } } $newOperand } else { New-VaasExpression -Filter $thisItem } } if ( $operator ) { @{ 'operator' = $operator 'operands' = @($operands) } } else { $operands } } } process { if ( $Filter ) { $thisFilter = $Filter # if we have a basic filter of field, operator, value, force it to be a 1 item array intead of 3 items if ( $Filter.Count -eq 3 -and -not ($Filter | Where-Object { $_ -isnot [string] })) { $thisFilter = @(, $Filter) } $query.expression = New-VaasExpression -Filter $thisFilter } if ( $Order ) { $query.ordering.Add('orders', @()) # @($Order) | ForEach-Object { foreach ($thisOrder in $Order) { # $thisOrder = $_ switch ($thisOrder.GetType().Name) { 'String' { $thisOrderCased = $vaasFields | Where-Object { $_.ToLower() -eq $thisOrder.ToLower() } $query.ordering.orders += @{ 'field' = if ($thisOrderCased) { $thisOrderCased } else { $thisOrder } 'direction' = 'ASC' } } 'HashTable' { if ( $thisOrder.Values[0] -notin 'asc', 'desc' ) { throw ('Invalid order direction, {0}. Provide either ''asc'' or ''desc''' -f $thisOrder.Values[0]) } $thisOrderCased = $vaasFields | Where-Object { $_.ToLower() -eq $thisOrder.Keys[0].ToLower() } $query.ordering.orders += @{ 'field' = if ($thisOrderCased) { $thisOrderCased } else { $thisOrder.Keys[0] } 'direction' = $thisOrder.Values[0].ToUpper() } } Default { throw 'Invalid format for Order' } } } } $query } } #EndRegion './Private/New-VcSearchQuery.ps1' 191 #Region './Private/Select-VenBatch.ps1' -1 function Select-VenBatch { <# .SYNOPSIS Batches pipeline input. .DESCRIPTION Batches up pipeline input into consistently sized List[T]s of objects. Used to ensure that processing occurs in specific sized batches. Useful for not recieving API timouts due to sending more objects than can be processed in the connection timeout period. .PARAMETER InputObject The pipeline input objects binds to this parameter one by one. Do not use it directly. .PARAMETER BatchSize The size of the batches to separate the pipeline input into. .PARAMETER BatchType Type of object to group things into. Defaults to a Powershell custom object Valid Values: "pscustomobject", "string", "int", "guid" .PARAMETER TotalCount The total number of items in the pipeline. Used to calculate progress. If you do not provide this value or ProgressPreference is set to 'SilentlyContinue', no progress will be displayed. .OUTPUTS System.Collections.Generic.List[T] .EXAMPLE 1..6000 | Select-VenBatch -batchsize 1000 -BatchType string #> [CmdletBinding(PositionalBinding = $false)] param ( [Parameter(ValueFromPipeline)] $InputObject, [Parameter(Mandatory)] [int] $BatchSize, [Parameter(Mandatory, Position = 0)] [ValidateSet("pscustomobject", "string", "int", "guid")] [string] $BatchType = "pscustomobject", [Parameter()] [int] $TotalCount, [Parameter()] [string] $Activity = 'Processing batches' ) Begin { switch ($BatchType) { 'string' { $Batch = [System.Collections.Generic.Queue[string]]::new($BatchSize) } 'int' { $Batch = [System.Collections.Generic.Queue[int]]::new($BatchSize) } 'guid' { $Batch = [System.Collections.Generic.Queue[guid]]::new($BatchSize) } 'pscustomobject' { $Batch = [System.Collections.Generic.Queue[pscustomobject]]::new($BatchSize) } } $count = 0 If ($TotalCount) { $progressParams = @{ Activity = $Activity Status = 'Initializing' PercentComplete = -1 } Write-Progress @progressParams } } Process { $count++ $Batch.Enqueue($_) if ($Batch.Count -eq $BatchSize) { If ($TotalCount) { $progressParams.Status = 'Batch {0}, items {1}-{2}' -f ($count / $BatchSize), ($count - $BatchSize + 1), $count [int] $percent = ($count / $TotalCount) * 100 $progressParams.PercentComplete = $percent Write-Progress @progressParams } 'Processing batch {0}, items {1}-{2}' -f ($count / $BatchSize), ($count - $BatchSize + 1), $count | Write-Verbose , ($Batch) $Batch.Clear() # start next batch } } end { # process any remaining items, eg. we didn't have a full batch if ( $Batch.Count ) { $batchNum = [math]::Ceiling($count / $BatchSize) If ($TotalCount) { $progressParams.Status = 'Batch {0}, items {1}-{2}' -f $batchNum, ((($batchNum - 1) * $BatchSize) + 1), $count [int] $percent = ($count / $TotalCount) * 100 $progressParams.PercentComplete = $percent Write-Progress @progressParams } 'Processing batch {0}, items {1}-{2}' -f $batchNum, ((($batchNum - 1) * $BatchSize) + 1), $count | Write-Verbose , ($Batch) $Batch.Clear() Remove-Variable Batch If ($TotalCount) { Write-Progress -Activity 'Completed' -Completed } } } } #EndRegion './Private/Select-VenBatch.ps1' 125 #Region './Private/Split-CertificateData.ps1' -1 function Split-CertificateData { [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [String] $CertificateData ) begin { $allCerts = [System.Collections.Generic.List[hashtable]]::new() } process { $pemLines = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($CertificateData)).Split("`n") $certPem = @() for ($i = 0; $i -lt $pemLines.Count; $i++) { if ($pemLines[$i].Contains('-----BEGIN')) { $iStart = $i continue } if ($pemLines[$i].Contains('-----END')) { $thisPemLines = $pemLines[$iStart..$i] if ( $pemLines[$i].Contains('KEY-----')) { $keyPem = ($thisPemLines -join "`n") -replace "`r" } else { $certPem += ($thisPemLines -join "`n") -replace "`r" } continue } } $allCerts.Add( @{ CertPem = $certPem[0] KeyPem = $keyPem ChainPem = $certPem[1..($certPem.Count - 1)] } ) } end { $allCerts } } #EndRegion './Private/Split-CertificateData.ps1' 48 #Region './Private/Test-IsGuid.ps1' -1 function Test-IsGuid { <# .SYNOPSIS Validates a given input string and checks string is a valid GUID .DESCRIPTION Validates a given input string and checks string is a valid GUID by using the .NET method Guid.TryParse .EXAMPLE Test-Guid -InputObject "3363e9e1-00d8-45a1-9c0c-b93ee03f8c13" .NOTES Uses .NET method [guid]::TryParse() #> [Cmdletbinding()] [OutputType([bool])] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, Position = 0)] [AllowEmptyString()] [string] $InputObject ) process { return [guid]::TryParse($InputObject, $([ref][guid]::Empty)) } } #EndRegion './Private/Test-IsGuid.ps1' 24 #Region './Private/Test-TppDnPath.ps1' -1 function Test-TppDnPath { [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline)] [ValidateNotNullOrEmpty()] [string] $Path, [Parameter()] [bool] $AllowRoot = $true ) process { if ( $AllowRoot ) { $Path -imatch '^[\\|\\\\]+ved([\\|\\\\]+.+)*$' } else { $Path -imatch '^[\\|\\\\]+ved([\\|\\\\]+.+)+$' } } } #EndRegion './Private/Test-TppDnPath.ps1' 21 #Region './Private/Test-VdcIdentityFormat.ps1' -1 function Test-VdcIdentityFormat { <# .SYNOPSIS Validate identity formats .DESCRIPTION Validate the format for identities prefixed name, prefixed universal, and local. As these formats are often interchangeable with api calls, you can validate multiple formats at once. By default, prefixed name and prefixed universal will be validated. .PARAMETER Identity The identity string to be validated .PARAMETER Format Format to validate, Name, Universal, and/or Local. .EXAMPLE Test-VdcIdentityFormat -ID "AD+BigSur:cypher" Test the identity against all formats. This would succeed for Name, but fail on Universal .EXAMPLE Test-VdcIdentityFormat -ID "AD+BigSur:cypher" -Format Name Test the identity against a specific format. #> [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $ID, [Parameter()] [ValidateSet('Name', 'Universal', 'Domain', 'Local')] [string] $Format ) begin { $domainProviderRegex = '(?im)^(AD|LDAP)\+.+:' $localProviderRegex = '(?im)^local:' $nameRegex = '.+$' $universalRegex = '\{?([0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12})\}?$' } process { switch ( $Format ) { 'Name' { $ID -match ($domainProviderRegex + $nameRegex) -or $ID -match ($localProviderRegex + $nameRegex) } 'Universal' { $ID -match ($domainProviderRegex + $universalRegex) -or $ID -match ($localProviderRegex + $universalRegex) } 'Domain' { $ID -match ($domainProviderRegex + $universalRegex) -or $ID -match ($domainProviderRegex + $nameRegex) } 'Local' { $ID -match ($localProviderRegex + $universalRegex) -or $ID -match ($localProviderRegex + $nameRegex) } default { $ID -match ($domainProviderRegex + $universalRegex) -or $ID -match ($domainProviderRegex + $nameRegex) -or $ID -match ($localProviderRegex + $universalRegex) -or $ID -match ($localProviderRegex + $nameRegex) } } } } #EndRegion './Private/Test-VdcIdentityFormat.ps1' 68 #Region './Private/Test-VenafiSession.ps1' -1 function Test-VenafiSession { <# .SYNOPSIS Validate authentication session/key/token .DESCRIPTION Validate authentication session from New-VenafiSession, a TLSPC key, or TLSPDC token. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token or TLSPC key can also provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .PARAMETER Platform Platform, either TLSPDC or Vaas, to validate VenafiSession against. .PARAMETER PassThru Provide the determined platform from VenafiSession .OUTPUTS String - if PassThru provided .EXAMPLE Test-VenafiSession -VenafiSession $VenafiSession Test a session .EXAMPLE Test-VenafiSession -VenafiSession $VenafiSession -PassThru Test a session and return the platform type found .EXAMPLE Test-VenafiSession -VenafiSession $key Test a TLSPC key .EXAMPLE Test-VenafiSession -VenafiSession $VenafiSession -Platform TLSPDC Test session ensuring the platform is TLSPDC #> [CmdletBinding(DefaultParameterSetName = 'All')] param ( [Parameter(Mandatory, ValueFromPipeline)] [AllowNull()] [Alias('Key', 'AccessToken')] [psobject] $VenafiSession, [Parameter(Mandatory, ParameterSetName = 'Platform')] [string] $Platform ) process { if ( (Get-PSCallStack).Count -gt 3 -and -not $VenafiSession ) { # nested function, no need to continue testing session since it was already done return } if ( -not $VenafiSession ) { if ( $env:VDC_TOKEN ) { $VenafiSession = $env:VDC_TOKEN } elseif ( $env:VC_KEY ) { $VenafiSession = $env:VC_KEY } elseif ( $script:VenafiSession ) { $VenafiSession = $script:VenafiSession } else { throw 'Please run New-VenafiSession or provide a TLSPC key or TLSPDC token.' } } switch ($VenafiSession.GetType().Name) { 'PSCustomObject' { if ( -not $VenafiSession.Key -and -not $VenafiSession.Token ) { throw "You must first connect to either TLSPC or a TLSPDC server with New-VenafiSession" } # make sure the auth type and url we have match # this keeps folks from calling a vaas function with a token and vice versa if ( $Platform -and $Platform -ne $VenafiSession.Platform ) { throw "This function is only accessible for $Platform" } if ( $Platform -eq 'VDC' ) { if ( $VenafiSession.Token.Expires -and $VenafiSession.Token.Expires -lt (Get-Date).ToUniversalTime() ) { throw 'TLSPDC token has expired. Execute New-VenafiSession and rerun your command.' } } # don't perform .Validate as we do above since this # isn't the class, it's a converted pscustomobject # for Invoke-VenafiParallel usage break } 'String' { if ( Test-IsGuid($VenafiSession) ) { Write-Verbose 'Session is VC key' if ( $Platform -and $Platform -notmatch '^VC$' ) { throw "This function or parameter set is only accessible for $Platform" } } else { # TLSPDC access token Write-Verbose 'Session is VDC token' if ( $Platform -and $Platform -notmatch '^VDC' ) { throw "This function or parameter set is only accessible for $Platform" } # get server from environment variable if ( -not $env:VDC_SERVER ) { throw 'TLSPDC token provided, but VDC_SERVER environment variable was not found' } } } Default { throw "Unknown session '$VenafiSession'. Please run New-VenafiSession or provide a TLSPC key or TLSPDC access token." } } # at entry function call, not nested, set the temp variables # if ( $script:VenafiSessionNested ) { # # append/update existing # ($script:VenafiSessionNested).$($VenafiSession.Platform) = $VenafiSession # } # else { # $script:VenafiSessionNested = @{ # $($VenafiSession.Platform) = $VenafiSession # } # } $script:VenafiSessionNested = $VenafiSession $script:PlatformNested = $Platform } } #EndRegion './Private/Test-VenafiSession.ps1' 144 #Region './Private/Write-VerboseWithSecret.ps1' -1 <# .SYNOPSIS Remove sensitive information when writing verbose info .DESCRIPTION Remove sensitive information when writing verbose info .PARAMETER InputObject JSON string or other object .PARAMETER SecretName Name of secret(s) to hide their values. Default value is 'Password', 'AccessToken', 'RefreshToken', 'access_token', 'refresh_token', 'Authorization', 'KeystorePassword', 'tppl-api-key', 'CertficateData' .INPUTS InputObject .OUTPUTS None .EXAMPLE @{'password'='foobar'} | Write-VerboseWithSecret Hide password value from hashtable .EXAMPLE $jsonString | Write-VerboseWithSecret Hide value(s) from JSON string #> function Write-VerboseWithSecret { [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline)] [AllowNull()] [AllowEmptyString()] [psobject] $InputObject, [Parameter()] [string[]] $PropertyName = @('AccessToken', 'Password', 'RefreshToken', 'access_token', 'refresh_token', 'Authorization', 'KeystorePassword', 'tppl-api-key', 'CertificateData', 'certificate') ) begin { } process { if ( -not $InputObject -or [System.Management.Automation.ActionPreference]::SilentlyContinue -eq $VerbosePreference ) { return } Write-Debug ('Write-VerboseWithSecret input type: {0}' -f $InputObject.GetType().FullName) # default to json string $processMe = $InputObject if ($InputObject.GetType().FullName -ne 'System.String') { # if hashtable or other object, convert to json first $processMe = $InputObject | ConvertTo-Json -Depth 5 -Compress } foreach ($prop in $PropertyName) { # look for values in json string, eg. "Body": "{"Password":"MyPass"}" or {\"Password\":\"MyPass\"} if ( $processMe -match "\\?""$prop\\?"":\\?""(.*?)\\?""" ) { $processMe = $processMe.replace($matches[1], '***hidden***') } } Write-Verbose $processMe } } #EndRegion './Private/Write-VerboseWithSecret.ps1' 73 #Region './Public/Add-VcCertificateAssociation.ps1' -1 function Add-VcCertificateAssociation { <# .SYNOPSIS Associate certificates with applications .DESCRIPTION Associate one or more certificates with one or more applications. The associated applications can either replace or be added to existing. By default, applications will be replaced. .PARAMETER Certificate Certificate ID or name to be associated. If a name is provided and multiple certificates are found, they will all be associated. Tab completion can be used for a list of certificate names to choose from. Type 3 or more characters for tab completion to work. .PARAMETER Application One or more application IDs or names. Tab completion can be used for a list of application names. .PARAMETER NoOverwrite Append to existing applications as opposed to overwriting .PARAMETER PassThru Return the newly updated certificate object(s) .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS Certificate .OUTPUTS PSCustomObject .EXAMPLE Add-VcCertificateAssociation -Certificate '7ac56ec0-2017-11ee-9417-a17dd25b82f9' -Application '96fc9310-67ec-11eb-a8a7-794fe75a8e6f' Associate a certificate to an application .EXAMPLE Add-VcCertificateAssociation -Certificate '7ac56ec0-2017-11ee-9417-a17dd25b82f9' -Application '96fc9310-67ec-11eb-a8a7-794fe75a8e6f', 'a05013bd-921d-440c-bc22-c9ead5c8d548' Associate a certificate to multiple applications .EXAMPLE Find-VcCertificate -First 5 | Add-VcCertificateAssociation -Application 'My Awesome App' Associate multiple certificates to 1 application by name .EXAMPLE Add-VcCertificateAssociation -Certificate 'www.barron.com' -Application '96fc9310-67ec-11eb-a8a7-794fe75a8e6f' -NoOverwrite Associate a certificate, by name, to another application, keeping the existing #> [CmdletBinding()] [Alias('Set-VaasCertificateAssignment')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('certificateID')] [string] $Certificate, [Parameter(Mandatory)] [Alias('ApplicationID')] [string[]] $Application, [Parameter()] [switch] $NoOverwrite, [Parameter()] [switch] $PassThru, [Parameter()] [Alias('Key')] [psobject] $VenafiSession ) begin { Write-Warning 'This function will soon be deprecated. Use Set-VcCertificate instead.' Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $apps = $Application | Get-VcData -Type 'Application' $params = @{ Method = 'Patch' UriRoot = 'outagedetection/v1' UriLeaf = 'applications/certificates' Body = @{ action = 'REPLACE' targetedApplicationIds = @($apps) } } if ( $NoOverwrite ) { $params.Body.action = 'ADD' } $allCerts = [System.Collections.Generic.List[string]]::new() } process { if ( Test-IsGuid($Certificate) ) { $allCerts.Add($Certificate) } else { # search by name $certIDs = Get-VcData -InputObject $Certificate -Type 'Certificate' foreach ($certID in @($certIDs)) { $allCerts.Add($certID) } } } end { $params.Body.certificateIds = $allCerts $response = Invoke-VenafiRestMethod @params if ( $PassThru ) { $response.certificates } } } #EndRegion './Public/Add-VcCertificateAssociation.ps1' 132 #Region './Public/Add-VcTeamMember.ps1' -1 function Add-VcTeamMember { <# .SYNOPSIS Add members to a team .DESCRIPTION Add members to a TLSPC team .PARAMETER ID Team ID to add to .PARAMETER Member 1 or more members to add to the team. This is the unique guid obtained from Get-VcIdentity. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Add-VcTeamMember -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Member @('ca7ff555-88d2-4bfc-9efa-2630ac44c1f3', 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f4') Add members to a TLSPC team .EXAMPLE Add-VcTeamMember -ID 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e6}' -Member 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e7}' Add members to a TLSPDC team .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html#/Teams/addMember #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('PrefixedUniversal', 'Guid')] [string] $ID, [Parameter(Mandatory)] [string[]] $Member, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { $params.Method = 'Post' $params.UriLeaf = "teams/$ID/members" $params.Body = @{ 'members' = @($Member) } $null = Invoke-VenafiRestMethod @params } } #EndRegion './Public/Add-VcTeamMember.ps1' 67 #Region './Public/Add-VcTeamOwner.ps1' -1 function Add-VcTeamOwner { <# .SYNOPSIS Add owners to a team .DESCRIPTION Add owners to a TLSPC team .PARAMETER Team Team ID or name .PARAMETER Owner 1 or more owners to add to the team This is the unique guid obtained from Get-VcIdentity. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS Team .EXAMPLE Add-VcTeamOwner -Team 'DevOps' -Owner @('ca7ff555-88d2-4bfc-9efa-2630ac44c1f3', 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f4') Add owners .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html#/Teams/addOwner #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('ID')] [string] $Team, [Parameter(Mandatory)] [string[]] $Owner, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $params = @{ Method = 'Post' Body = @{ 'owners' = @($Owner) } } } process { $params.UriLeaf = 'teams/{0}/owners' -f (Get-VcData -InputObject $Team -Type 'Team') $null = Invoke-VenafiRestMethod @params } } #EndRegion './Public/Add-VcTeamOwner.ps1' 65 #Region './Public/Add-VdcAdaptableHash.ps1' -1 function Add-VdcAdaptableHash { <# .SYNOPSIS Adds or updates the hash value for an adaptable script .DESCRIPTION TLSPDC stores a base64 encoded hash of the file contents of an adaptable script in the Secret Store. This is referenced by the Attribute 'PowerShell Script Hash Vault Id' on the DN of the adaptable script. This script retrieves the hash (if present) from the Secret Store and compares it to the hash of the file in one of the scripts directories. It then adds a new or updated hash if required. When updating an existing hash, it removes the old one from the Secret Store. .PARAMETER Path Required. Path to the object to add or update the hash. Note: For an adaptable app or an onboard discovery, 'Path' must always be a policy folder as this is where the hash is saved. .PARAMETER Keyname The name of the Secret Encryption Key (SEK) to used when encrypting this item. Default is "Software:Default" .PARAMETER FilePath Required. The full path to the adaptable script file. This should normally be in a '<drive>:\Program Files\Venafi\Scripts\<subdir>' directory for TLSPDC to recognize the script. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS None .OUTPUTS None .EXAMPLE Add-VdcAdaptableHash -Path $Path -FilePath 'C:\Program Files\Venafi\Scripts\AdaptableApp\AppDriver.ps1' Update the hash on an adaptable app object. Note: For an adaptable app or an onboard discovery, 'Path' must always be a policy folder as this is where the hash is saved. .EXAMPLE Add-VdcAdaptableHash -Path $Path -FilePath 'C:\Program Files\Venafi\Scripts\AdaptableLog\Generic-LogDriver.ps1' Update the hash on an adaptable log object. .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Add-VdcAdaptableHash/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Add-VdcAdaptableHash.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Secretstore-add.php .LINK https://docs.venafi.com/Docs/currentSDK/TopNav/Content/SDK/WebSDK/r-SDK-POST-Secretstore-ownerdelete.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Secretstore-retrieve.php #> [CmdletBinding(SupportsShouldProcess)] [Alias('Add-TppAdaptableHash')] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('DN')] [String] $Path, [Parameter()] [string] $Keyname = "Software:Default", [Parameter(Mandatory)] [Alias('File')] [string] $FilePath, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' } $TypeName = (Get-VdcObject -Path $Path).TypeName if ( $TypeName -eq 'Policy' ) { $retrieveVaultID = ( Get-VdcAttribute -Path $Path -Class 'Adaptable App' -Attribute 'PowerShell Script Hash Vault Id' ).'PowerShell Script Hash Vault Id' } else { $retrieveVaultID = ( Get-VdcAttribute -Path $Path -Attribute 'PowerShell Script Hash Vault Id' ).'PowerShell Script Hash Vault Id' } $bytes = [Text.Encoding]::UTF32.GetBytes([IO.File]::ReadAllText($FilePath)) $hash = Get-FileHash -InputStream ([System.IO.MemoryStream]::New($bytes)) $base64data = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($hash.hash.ToLower())) } process { if ( -not $PSCmdlet.ShouldProcess($Path) ) { continue } if ( $retrieveVaultID ) { $paramsretrieve = $params.Clone() $paramsretrieve.UriLeaf = 'SecretStore/retrieve' $paramsretrieve.Body = @{ VaultID = $retrieveVaultID } $retrieveResponse = Invoke-VenafiRestMethod @paramsretrieve if ( $retrieveResponse.Result -ne [TppSecretStoreResult]::Success ) { Write-Error ("Error retrieving VaultID: {0}" -f [enum]::GetName([TppSecretStoreResult], $retrieveResponse.Result)) -ErrorAction Stop } if($null -ne $retrieveResponse.Base64Data) { $retrieveBase64 = $retrieveResponse.Base64Data } } if ( $base64data -eq $retrieveBase64 ){ Write-Verbose "PowerShell Script Hash Vault Id unchanged for $($Path)." continue } else { $paramsadd = $params.Clone() $paramsadd.UriLeaf = 'SecretStore/Add' $paramsadd.Body = @{ VaultType = '128' Keyname = $Keyname Base64Data = $Base64Data Namespace = 'Config' Owner = $Path } $addresponse = Invoke-VenafiRestMethod @paramsadd if ( $addresponse.Result -ne [TppSecretStoreResult]::Success ) { Write-Error ("Error adding VaultID: {0}" -f [enum]::GetName([TppSecretStoreResult], $addResponse.Result)) -ErrorAction Stop } if ( $TypeName -eq 'Policy' ) { Set-VdcAttribute -Path $Path -PolicyClass 'Adaptable App' -Attribute @{ 'PowerShell Script Hash Vault Id' = [string]$addresponse.VaultID } -Lock -ErrorAction Stop } else { Set-VdcAttribute -Path $Path -Attribute @{ 'PowerShell Script Hash Vault Id' = [string]$addresponse.VaultID } -ErrorAction Stop } Write-Verbose "PowerShell Script Hash Vault Id for $($Path) set to $($addresponse.VaultID)." } if (( $retrieveBase64 ) -and ( $addresponse.VaultID )) { $paramsdelete = $params.Clone() $paramsdelete.UriLeaf = 'SecretStore/OwnerDelete' $paramsdelete.Body = @{ Namespace = 'Config' Owner = $Path VaultID = $retrieveVaultID } $deleteResponse = Invoke-VenafiRestMethod @paramsdelete if ( $deleteResponse.Result -ne [TppSecretStoreResult]::Success ) { Write-Error ("Error removing VaultID: {0}" -f [enum]::GetName([TppSecretStoreResult], $deleteResponse.Result)) -ErrorAction Stop } } } } #EndRegion './Public/Add-VdcAdaptableHash.ps1' 181 #Region './Public/Add-VdcCertificateAssociation.ps1' -1 function Add-VdcCertificateAssociation { <# .SYNOPSIS Add certificate association .DESCRIPTION Associates one or more Application objects to an existing certificate. Optionally, you can push the certificate once the association is complete. .PARAMETER InputObject TppObject which represents a certificate .PARAMETER CertificatePath Path to the certificate. Required if InputObject not provided. .PARAMETER ApplicationPath List of application object paths to associate .PARAMETER PushCertificate Push the certificate after associating it to the Application objects. This will only be successful if the certificate management type is Provisioning and is not disabled, in error, or a push is already in process. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS None .EXAMPLE Add-VdcCertificateAssociation -CertificatePath '\ved\policy\my cert' -ApplicationPath '\ved\policy\my capi' Add a single application object association .EXAMPLE Add-VdcCertificateAssociation -Path '\ved\policy\my cert' -ApplicationPath '\ved\policy\my capi' -PushCertificate Add the association and push the certificate .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Add-VdcCertificateAssociation/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Add-VdcCertificateAssociation.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/API_Reference/r-SDK-POST-Certificates-Associate.php .NOTES You must have: - Write permission to the Certificate object. - Write or Associate and Delete permission to Application objects that are associated with the certificate #> [CmdletBinding(SupportsShouldProcess)] [Alias('Add-TppCertificateAssociation')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('DN', 'CertificateDN', 'Path')] [String] $CertificatePath, [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [String[]] $ApplicationPath, [Parameter()] [Alias('ProvisionCertificate')] [switch] $PushCertificate, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' UriLeaf = 'Certificates/Associate' Body = @{ CertificateDN = '' ApplicationDN = '' } } if ( $PSBoundParameters.ContainsKey('PushCertificate') ) { $params.Body.Add('PushToNew', 'true') } } process { $params.Body.CertificateDN = $CertificatePath $params.Body.ApplicationDN = @($ApplicationPath) if ( $PSCmdlet.ShouldProcess($CertificatePath, 'Add association') ) { $null = Invoke-VenafiRestMethod @params } } } #EndRegion './Public/Add-VdcCertificateAssociation.ps1' 121 #Region './Public/Add-VdcEngineFolder.ps1' -1 function Add-VdcEngineFolder { <# .SYNOPSIS Add policy folder assignments to a TLSPDC processing engine .DESCRIPTION Add one or more policy folder assignments to a TLSPDC processing engine. .PARAMETER EnginePath The full DN path to a TLSPDC processing engine. .PARAMETER EngineObject TPPObject belonging to the 'Venafi Platform' class. .PARAMETER FolderPath The full DN path to one or more policy folders (string array). .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided, but this requires an environment variable VDC_SERVER to be set. .INPUTS EnginePath or EngineObject, FolderPath[] .OUTPUTS None .EXAMPLE Add-VdcEngineFolder -EnginePath '\VED\Engines\MYVENAFI01' -FolderPath '\VED\Policy\Certificates\Web Team' Add processing engine MYVENAFI01 to the policy folders '\VED\Policy\Certificates\Web Team'. .EXAMPLE Add-VdcEngineFolder -EnginePath '\VED\Engines\MYVENAFI01' -FolderPath @('\VED\Policy\Certificates\Web Team','\VED\Policy\Certificates\Database Team') Add processing engine MYVENAFI01 to the policy folders '\VED\Policy\Certificates\Web Team' and '\VED\Policy\Certificates\Database Team'. .EXAMPLE $EngineObjects | Add-VdcEngineFolder -FolderPath @('\VED\Policy\Certificates\Web Team','\VED\Policy\Certificates\Database Team') -Confirm:$false Add one or more processing engines via the pipeline to multiple policy folders. Suppress the confirmation prompt. .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Add-VdcEngineFolder/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Add-VdcEngineFolder.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-ProcessingEngines-Engine-eguid.php #> [CmdletBinding(SupportsShouldProcess)] [Alias('Add-TppEngineFolder')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('EngineDN', 'Engine', 'Path')] [String] $EnginePath, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('FolderDN', 'Folder')] [String[]] $FolderPath, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' Body = @{ FolderGuids = '' } } } process { if ( -not ($PSBoundParameters.ContainsKey('EngineObject')) ) { $EngineObject = Get-VdcObject -Path $EnginePath if ($EngineObject.TypeName -ne 'Venafi Platform') { throw ("DN/Path '$($EngineObject.Path)' is not a processing engine") } } $FolderGuids = [System.Collections.Generic.List[string]]::new() $params.UriLeaf = "ProcessingEngines/Engine/{$($EngineObject.Guid)}" foreach ($path in $FolderPath) { try { $folder = Get-VdcObject -Path $path } catch { Write-Warning ("TLSPDC object '$($path)' does not exist") Continue } if ($folder.TypeName -ne 'Policy') { Write-Warning ("TLSPDC object '$($folder.Path)' is not a policy folder") Continue } $lastFolder = $folder.Path $FolderGuids += "{$($folder.guid)}" } $params.Body.FolderGuids = @($FolderGuids) if ($FolderGuids.Count -gt 1) { $shouldProcessAction = "Add $($FolderGuids.Count) policy folders" } else { $shouldProcessAction = "Add $($lastFolder)" } if ($PSCmdlet.ShouldProcess($EngineObject.Name, $shouldProcessAction)) { $response = Invoke-VenafiRestMethod @params if ($response.AddedCount -ne $FolderGuids.Count) { $errorMessage = "Added $($response.AddedCount) folder(s), but requested $($FolderGuids.Count)" if ($response.Errors) { $errorMessage += ": $($response.Errors)" } Write-Warning ($errorMessage) } else { Write-Verbose ("Added $($response.AddedCount) folder(s) to $($EngineObject.Name)") } } } } #EndRegion './Public/Add-VdcEngineFolder.ps1' 126 #Region './Public/Add-VdcTeamMember.ps1' -1 function Add-VdcTeamMember { <# .SYNOPSIS Add members to a team .DESCRIPTION Add members to a TLSPDC team .PARAMETER ID Team ID from Find-VdcIdentity or Get-VdcTeam. .PARAMETER Member 1 or more members to add to the team. The identity ID property from Find-VdcIdentity or Get-VdcIdentity. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS ID .EXAMPLE Add-VdcTeamMember -ID 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e6}' -Member 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e7}' Add members to a TLSPDC team .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-PUT-Teams-AddTeamMembers.php #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('PrefixedUniversal', 'Guid')] [string] $ID, [Parameter(Mandatory)] [string[]] $Member, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { $teamName = Get-VdcIdentity -ID $ID | Select-Object -ExpandProperty FullName $members = foreach ($thisMember in $Member) { if ( $thisMember.StartsWith('local') ) { $memberIdentity = Get-VdcIdentity -ID $thisMember @{ 'PrefixedName' = $memberIdentity.FullName 'PrefixedUniversal' = $memberIdentity.ID } } else { @{'PrefixedUniversal' = $thisMember } } } $params = @{ Method = 'Put' UriLeaf = 'Teams/AddTeamMembers' Body = @{ 'Team' = @{'PrefixedName' = $teamName } 'Members' = @($members) } } $null = Invoke-VenafiRestMethod @params } } #EndRegion './Public/Add-VdcTeamMember.ps1' 81 #Region './Public/Add-VdcTeamOwner.ps1' -1 function Add-VdcTeamOwner { <# .SYNOPSIS Add owners to a team .DESCRIPTION Add owners to a TLSPDC team .PARAMETER ID Team ID, this is the ID property from Find-VdcIdentity or Get-VdcTeam. .PARAMETER Owner 1 or more owners to add to the team This is the identity ID property from Find-VdcIdentity or Get-VdcIdentity. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS ID .EXAMPLE Add-VdcTeamOwner -ID 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e6}' -Owner 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e7}' Add owners .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-PUT-Teams-AddTeamOwners.php #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('PrefixedUniversal', 'Guid')] [string] $ID, [Parameter(Mandatory)] [string[]] $Owner, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { $teamName = Get-VdcIdentity -ID $ID | Select-Object -ExpandProperty FullName $owners = foreach ($thisOwner in $Owner) { if ( $thisOwner.StartsWith('local') ) { $ownerIdentity = Get-VdcIdentity -ID $thisOwner @{ 'PrefixedName' = $ownerIdentity.FullName 'PrefixedUniversal' = $ownerIdentity.ID } } else { @{'PrefixedUniversal' = $thisOwner } } } $params = @{ Method = 'Put' UriLeaf = 'Teams/AddTeamOwners' Body = @{ 'Team' = @{'PrefixedName' = $teamName } 'Owners' = @($owners) } } $null = Invoke-VenafiRestMethod @params } } #EndRegion './Public/Add-VdcTeamOwner.ps1' 80 #Region './Public/Convert-VdcObject.ps1' -1 function Convert-VdcObject { <# .SYNOPSIS Change the class/object type of an existing object .DESCRIPTION Change the class/object type of an existing object. Please note, changing the class does NOT change any attributes and must be done separately. Using -PassThru will allow you to pass the input to other functions including Set-VdcAttribute; see the examples. .PARAMETER Path Path to the object .PARAMETER Class New class/type .PARAMETER PassThru Return a TppObject representing the newly converted object .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS TppObject, if -PassThru provided .EXAMPLE Convert-VdcObject -Path '\ved\policy\' -Class 'X509 Device Certificate' Convert an object to a different type .EXAMPLE Convert-VdcObject -Path '\ved\policy\device\app' -Class 'CAPI' -PassThru | Set-VdcAttribute -Attribute @{'Driver Name'='appcapi'} Convert an object to a different type, return the updated object and update attributes .EXAMPLE Find-VdcObject -Class Basic | Convert-VdcObject -Class 'capi' -PassThru | Set-VdcAttribute -Attribute @{'Driver Name'='appcapi'} Convert multiple objects to a different type, return the updated objects and update attributes .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Convert-VdcObject.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-mutateobject.php #> [CmdletBinding(SupportsShouldProcess)] [Alias('Convert-TppObject')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid path" } })] [String] $Path, [Parameter(Mandatory)] [String] $Class, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' UriLeaf = 'config/MutateObject' Body = @{ Class = $Class } } } process { $params.Body.ObjectDN = $Path if ( $PSCmdlet.ShouldProcess($Path, "Convert to type $Class") ) { $response = Invoke-VenafiRestMethod @params if ( $response.Result -eq 1 ) { if ( $PassThru ) { ConvertTo-VdcObject -Path $Path } } else { Write-Error $response.Error } } } } #EndRegion './Public/Convert-VdcObject.ps1' 110 #Region './Public/ConvertTo-VdcGuid.ps1' -1 function ConvertTo-VdcGuid { <# .SYNOPSIS Convert DN path to GUID .DESCRIPTION Convert DN path to GUID .PARAMETER Path DN path representing an object .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS Guid .EXAMPLE ConvertTo-VdcGuid -Path '\ved\policy\convertme' #> [CmdletBinding()] [Alias('ConvertTo-TppGuid')] [OutputType([System.Guid])] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('DN')] [String] $Path, [Parameter()] [switch] $IncludeType, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' UriLeaf = 'config/DnToGuid' Body = @{ ObjectDN = '' } } } process { $params.Body.ObjectDN = $Path $response = Invoke-VenafiRestMethod @params switch ($response.Result) { 1 { # success if ( $IncludeType ) { [PSCustomObject] @{ Guid = [Guid] $response.Guid TypeName = $response.ClassName } } else { [Guid] $response.Guid } } 7 { throw [System.UnauthorizedAccessException]::new($response.Error) } 400 { throw [System.Management.Automation.ItemNotFoundException]::new($response.Error) } Default { throw $response.Error } } } } #EndRegion './Public/ConvertTo-VdcGuid.ps1' 100 #Region './Public/ConvertTo-VdcPath.ps1' -1 function ConvertTo-VdcPath { <# .SYNOPSIS Convert GUID to Path .DESCRIPTION Convert GUID to Path .PARAMETER Guid Guid type, [guid] 'xyxyxyxy-xyxy-xyxy-xyxy-xyxyxyxyxyxy' .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Guid .OUTPUTS String representing the Path .EXAMPLE ConvertTo-VdcPath -Guid [guid]'xyxyxyxy-xyxy-xyxy-xyxy-xyxyxyxyxyxy' #> [CmdletBinding()] [Alias('ConvertTo-TppPath')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Guid] $Guid, [Parameter()] [switch] $IncludeType, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' UriLeaf = 'config/GuidToDN' Body = @{ ObjectGUID = '' } } } process { $params.Body.ObjectGUID = "{$Guid}" $response = Invoke-VenafiRestMethod @params if ( $response.Result -eq 1 ) { if ( $PSBoundParameters.ContainsKey('IncludeType') ) { [PSCustomObject] @{ Path = $response.ObjectDN TypeName = $response.ClassName } } else { $response.ObjectDN } } else { throw $response.Error } } } #EndRegion './Public/ConvertTo-VdcPath.ps1' 78 #Region './Public/Export-VcCertificate.ps1' -1 function Export-VcCertificate { <# .SYNOPSIS Export certificate data from TLSPC .DESCRIPTION Export certificate data in PEM format. You can retrieve the certificate, chain, and key. You can also save the certificate and private key in PEM or PKCS12 format. .PARAMETER ID Certificate ID, also known as uuid. Use Find-VcCertificate or Get-VcCertificate to determine the ID. You can pipe those functions as well. .PARAMETER PrivateKeyPassword Password required to include the private key. You can either provide a String, SecureString, or PSCredential. Requires PowerShell v7.0+. .PARAMETER IncludeChain Include the certificate chain with the exported or saved PEM certificate data. .PARAMETER OutPath Folder path to save the certificate to. The name of the file will be determined automatically. For each certificate a directory will be created in this folder with the format Name-ID. In the case of PKCS12, the file will be saved to the root of the folder. .PARAMETER PKCS12 Export the certificate and private key in PKCS12 format. Requires PowerShell v7.1+. .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .OUTPUTS PSCustomObject .EXAMPLE $certId | Export-VcCertificate Export certificate data .EXAMPLE $certId | Export-VcCertificate -PrivateKeyPassword 'myPassw0rd!' Export certificate and private key data .EXAMPLE $certId | Export-VcCertificate -PrivateKeyPassword 'myPassw0rd!' -PKCS12 -OutPath '~/temp' Export certificate and private key in PKCS12 format .EXAMPLE $cert | Export-VcCertificate -OutPath '~/temp' Get certificate data and save to a file .EXAMPLE $cert | Export-VcCertificate -IncludeChain Get certificate data with the certificate chain included. .NOTES This function requires the use of sodium encryption. PS v7.1+ is required. On Windows, the latest Visual C++ redist must be installed. See https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist. #> [CmdletBinding(DefaultParameterSetName = 'PEM')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('certificateId')] [string] $ID, [Parameter(ParameterSetName = 'PEM')] [Parameter(ParameterSetName = 'PKCS12', Mandatory)] [ValidateScript( { if ($PSVersionTable.PSVersion -lt [version]'7.0') { throw 'Exporting private keys is only supported on PowerShell v7.0+' } if ( $_ -is [string] -or $_ -is [securestring] -or $_ -is [pscredential] ) { $true } else { throw 'Unsupported type. Provide either a String, SecureString, or PSCredential.' } } )] [psobject] $PrivateKeyPassword, [Parameter(ParameterSetName = 'PEM')] [switch] $IncludeChain, [Parameter(ParameterSetName = 'PEM')] [Parameter(ParameterSetName = 'PKCS12', Mandatory)] [ValidateNotNullOrEmpty()] [ValidateScript( { if (Test-Path $_ -PathType Container) { $true } else { Throw "Output path '$_' does not exist" } })] [String] $OutPath, [Parameter(ParameterSetName = 'PKCS12', Mandatory)] [ValidateScript( { if ($PSVersionTable.PSVersion -lt [version]'7.1') { throw 'Exporting in PKCS#12 foramt is only supported on PowerShell v7.1+' } $true } )] [switch] $PKCS12, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allCerts = [System.Collections.Generic.List[string]]::new() # set up the scriptblocks to be executed via invoke-venafiparallel if ( $PrivateKeyPassword ) { $pkPassString = $PrivateKeyPassword | ConvertTo-PlaintextString $sb = { $id = $PSItem $pkPassString = $using:pkPassString $params = @{ Method = 'Post' Header = @{ 'accept' = 'application/octet-stream' } UriRoot = 'outagedetection/v1' UriLeaf = 'certificates/{0}/keystore' -f $id Body = @{ 'exportFormat' = 'PEM' 'encryptedKeystorePassphrase' = '' 'certificateLabel' = '' } FullResponse = $true } $out = [pscustomobject] @{ certificateId = $id error = '' } $thisCert = Get-VcCertificate -id $id if ( -not $thisCert ) { $out.error = 'Certificate not found' return $out } if ( -not $thisCert.dekHash ) { $out.error = 'Private key not found' return $out } # build the encrypted private key password Import-Module PSSodium -Force $publicKey = Invoke-VenafiRestMethod -UriLeaf "edgeencryptionkeys/$($thisCert.dekHash)" | Select-Object -ExpandProperty key $privateKeyPasswordEnc = ConvertTo-SodiumEncryptedString -Text $pkPassString -PublicKey $publicKey $params.Body.encryptedPrivateKeyPassphrase = $privateKeyPasswordEnc $innerResponse = Invoke-VenafiRestMethod @params if ($innerResponse.StatusCode -notin 200, 201, 202) { $out.error = $innerResponse.StatusDescription return $out } if ( -not $innerResponse.Content ) { $out.error = 'No certificate data received' return $out } $zipFile = '{0}.zip' -f (New-TemporaryFile) $unzipPath = Join-Path -Path (Split-Path -Path $zipFile -Parent) -ChildPath $id try { # always save the zip file then decide to copy to the final destination or return contents [IO.File]::WriteAllBytes($zipFile, $innerResponse.Content) Write-Verbose ('Expanding {0} to {1}' -f $zipFile, $unzipPath) Expand-Archive -Path $zipFile -DestinationPath $unzipPath $unzipFiles = Get-ChildItem -Path $unzipPath if ( $using:OutPath ) { if ( $using:PKCS12 ) { $keyFile = Get-ChildItem -Path $unzipPath -Filter '*.key' if ( $keyFile.Count -ne 1 ) { $out.error = 'Private key not found' return $out } $keyPath = $keyFile.FullName $crtPath = $keyPath.Replace('.key', '.crt') $cert = [System.Security.Cryptography.X509Certificates.x509Certificate2]::CreateFromEncryptedPemFile($crtPath, $pkPassString, $keyPath) # export content type of 3 is for pfx $cert.Export(3, $pkPassString) | Set-Content -Path (Join-Path -Path $using:OutPath -ChildPath ('{0}.pfx' -f $keyFile.BaseName)) -AsByteStream } else { # copy files to final desination $dest = Join-Path -Path (Resolve-Path -Path $using:OutPath) -ChildPath ('{0}-{1}' -f $thisCert.certificateName, $thisCert.certificateId) $null = New-Item -Path $dest -ItemType Directory -Force $unzipFiles | Copy-Item -Destination $dest -Force $out | Add-Member @{'outPath' = $dest } } } else { # pull in the contents so we can provide them switch ($unzipFiles) { { $_.Name.EndsWith('.key') } { $out | Add-Member @{'KeyPem' = Get-Content -Path $_.FullName -Raw } } { $_.Name.EndsWith('root-last.pem') } { $certPem = @() $pemLines = Get-Content -Path $_.FullName for ($i = 0; $i -lt $pemLines.Count; $i++) { if ($pemLines[$i].Contains('-----BEGIN')) { $iStart = $i continue } if ($pemLines[$i].Contains('-----END')) { $thisPemLines = $pemLines[$iStart..$i] $certPem += $thisPemLines -join "`n" continue } } $out | Add-Member @{'CertPem' = $certPem[0] } if ( $using:IncludeChain ) { $out | Add-Member @{'ChainPem' = $certPem[1..($certPem.Count - 1)] } } } } } $out } finally { Remove-Item -Path $unzipPath -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path $zipFile -Force -ErrorAction SilentlyContinue } } } else { # no need to get the entire keystore if just getting cert/chain # cert/chain only, no private key. different api call, better performance. $sb = { $params = @{ UriRoot = 'outagedetection/v1' UriLeaf = 'certificates/{0}/contents' -f $PSItem Body = @{ format = 'PEM' } FullResponse = $true } if ( $using:IncludeChain ) { $params.Body.chainOrder = 'EE_FIRST' } else { $params.Body.chainOrder = 'EE_ONLY' } $out = [pscustomobject] @{ certificateId = $PSItem error = if ($innerResponse.StatusCode -notin 200, 201, 202) { $innerResponse.StatusDescription } } $thisCert = Get-VcCertificate -id $PSItem if ( -not $thisCert ) { $out.error = 'Certificate not found' return $out } $innerResponse = Invoke-VenafiRestMethod @params $certificateData = $innerResponse.Content if ( $certificateData ) { if ( $using:OutPath ) { $dest = Join-Path -Path (Resolve-Path -Path $using:OutPath) -ChildPath ('{0}-{1}' -f $thisCert.certificateName, $thisCert.certificateId) $null = New-Item -Path $dest -ItemType Directory -Force $outFile = Join-Path -Path $dest -ChildPath ('{0}.{1}' -f $PSItem, $params.Body.format) try { $sw = [IO.StreamWriter]::new($outFile, $false, [Text.Encoding]::ASCII) $sw.WriteLine($certificateData) Write-Verbose "Saved $outFile" } finally { if ($null -ne $sw) { $sw.Close() } } $out | Add-Member @{'outPath' = $dest } } else { $out | Add-Member @{'certificateData' = $certificateData } } } $out } } Initialize-PSSodium } process { $allCerts.Add($ID) } end { $invokeParams = @{ InputObject = $allCerts ScriptBlock = $sb ThrottleLimit = $ThrottleLimit ProgressTitle = 'Exporting certificates' } Invoke-VenafiParallel @invokeParams } } #EndRegion './Public/Export-VcCertificate.ps1' 352 #Region './Public/Export-VdcCertificate.ps1' -1 function Export-VdcCertificate { <# .SYNOPSIS Export certificate data from TLSPDC .DESCRIPTION Export certificate data .PARAMETER Path Full path to the certificate .PARAMETER Base64 Provide output in Base64 format. This is the default if no format is provided. .PARAMETER Pkcs7 Provide output in PKCS #7 format .PARAMETER Pkcs8 Provide output in PKCS #8 format .PARAMETER Der Provide output in DER format .PARAMETER Pkcs12 Provide output in PKCS #12 format. Requires a value for PrivateKeyPassword. .PARAMETER Jks Provide output in JKS format. Requires a value for FriendlyName. .PARAMETER OutPath Folder path to save the certificate/key to. The name of the file will be determined automatically. .PARAMETER IncludeChain Include the certificate chain with the exported certificate. The end entity will be first and the root last. .PARAMETER FriendlyName Label or alias to use. Permitted with Base64 and PKCS #12 formats. Required when exporting JKS. .PARAMETER PrivateKeyPassword Password required to include the private key. You can either provide a String, SecureString, or PSCredential. You must adhere to the following rules: - Password is at least 12 characters. - Comprised of at least three of the following: - Uppercase alphabetic letters - Lowercase alphabetic letters - Numeric characters - Special characters .PARAMETER KeystorePassword Password required to retrieve the certificate in JKS format. You can either provide a String, SecureString, or PSCredential. You must adhere to the following rules: - Password is at least 12 characters. - Comprised of at least three of the following: - Uppercase alphabetic letters - Lowercase alphabetic letters - Numeric characters - Special characters .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS PSCustomObject .EXAMPLE Export-VdcCertificate -Path '\ved\policy\mycert.com' Get certificate data in Base64 format, the default .EXAMPLE $cert | Export-VdcCertificate -'PKCS7' -OutPath 'c:\temp' Get certificate data in a specific format and save to a file .EXAMPLE $cert | Export-VdcCertificate -'PKCS7' -IncludeChain Get one or more certificates with the certificate chain included .EXAMPLE $cert | Export-VdcCertificate -'PKCS12' -PrivateKeyPassword 'mySecretPassword!' Get one or more certificates with private key included .EXAMPLE $cert | Export-VdcCertificate -'PKCS8' -PrivateKeyPassword 'mySecretPassword!' -OutPath '~/temp' Save certificate info to a file. PKCS8 with private key will save 3 files, .pem (cert+key), .pem.cer (cert only), and .pem.key (key only) .EXAMPLE $cert | Export-VdcCertificate -Jks -FriendlyName 'MyFriendlyName' -KeystorePassword $cred.password Get certificates in JKS format. #> [CmdletBinding(DefaultParameterSetName = 'Base64')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('id')] [string] $Path, [Parameter(ParameterSetName = 'Base64')] [switch] $Base64, [Parameter(Mandatory, ParameterSetName = 'Pkcs7')] [switch] $Pkcs7, [Parameter(Mandatory, ParameterSetName = 'Pkcs8')] [switch] $Pkcs8, [Parameter(Mandatory, ParameterSetName = 'Der')] [switch] $Der, [Parameter(Mandatory, ParameterSetName = 'Pkcs12')] [switch] $Pkcs12, [Parameter(Mandatory, ParameterSetName = 'Jks')] [switch] $Jks, [Parameter(ParameterSetName = 'Pkcs8')] [Parameter(Mandatory, ParameterSetName = 'Pkcs12')] [Parameter(ParameterSetName = 'Jks')] [ValidateScript( { if ( $_ -is [string] -or $_ -is [securestring] -or $_ -is [pscredential] ) { $true } else { throw 'Unsupported type. Provide either a String, SecureString, or PSCredential.' } } )] [Alias('SecurePassword')] [psobject] $PrivateKeyPassword, [Parameter(ParameterSetName = 'Base64')] [Parameter(ParameterSetName = 'Pkcs7')] [Parameter(ParameterSetName = 'Pkcs8')] [Parameter(ParameterSetName = 'Pkcs12')] [Parameter(ParameterSetName = 'Jks')] [switch] $IncludeChain, [Parameter(ParameterSetName = 'Base64')] [Parameter(ParameterSetName = 'Pkcs12')] [Parameter(Mandatory, ParameterSetName = 'Jks')] [string] $FriendlyName, [Parameter(Mandatory, ParameterSetName = 'Jks')] [ValidateScript( { if ( $_ -is [string] -or $_ -is [securestring] -or $_ -is [pscredential] ) { $true } else { throw 'Unsupported type. Provide either a String, SecureString, or PSCredential.' } } )] [psobject] $KeystorePassword, [Parameter()] [ValidateNotNullOrEmpty()] [ValidateScript( { if (Test-Path $_ -PathType Container) { $true } else { Throw "Output path '$_' does not exist" } })] [String] $OutPath, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $allCerts = [System.Collections.Generic.List[hashtable]]::new() $body = @{ Format = 'Base64' } switch ($PSCmdlet.ParameterSetName) { 'Pkcs7' { $body.Format = 'PKCS #7' } 'Pkcs8' { $body.Format = 'Base64 (PKCS#8)' } 'Pkcs12' { $body.Format = 'PKCS #12' } 'Der' { $body.Format = 'DER' } 'Jks' { $body.Format = 'JKS' } } $body.IncludePrivateKey = $PSBoundParameters.ContainsKey('PrivateKeyPassword') if ( $body.IncludePrivateKey ) { $body.Password = $PrivateKeyPassword | ConvertTo-PlaintextString } if ( $PSBoundParameters.ContainsKey('KeystorePassword') ) { $body.Format = 'JKS' $body.KeystorePassword = $KeystorePassword | ConvertTo-PlaintextString } if ( $PSBoundParameters.ContainsKey('FriendlyName') ) { $body.FriendlyName = $FriendlyName } if ($IncludeChain) { $body.IncludeChain = $true } $body | Write-VerboseWithSecret } process { $body.CertificateDN = ($Path | ConvertTo-VdcFullPath) $allCerts.Add($body.Clone()) } end { Invoke-VenafiParallel -InputObject $allCerts -ScriptBlock { $thisBody = $PSItem try { $innerResponse = Invoke-VenafiRestMethod -Method 'Post' -UriLeaf 'certificates/retrieve' -Body $thisBody } catch { try { # key not available, get just the cert if ( $_.ToString() -like '*failed to lookup private key*') { # we can't have a p12 without a private key if ( $thisBody.Format -eq 'PKCS #12' ) { throw $_ } $thisBody.IncludePrivateKey = $false $thisBody.Password = $null $innerResponse = Invoke-VenafiRestMethod -Method 'Post' -UriLeaf 'certificates/retrieve' -Body $thisBody } } catch { return [pscustomobject]@{ 'Path' = $thisBody.CertificateDN 'Error' = $_ 'CertificateData' = $null } } } $out = $innerResponse | Select-Object Filename, Format, @{ n = 'Path' e = { $thisBody.CertificateDN } }, @{ n = 'Error' e = { $_.Status } }, CertificateData if ( $innerResponse.CertificateData ) { if ( $thisBody.Format -in 'Base64', 'Base64 (PKCS#8)' ) { $splitData = Split-CertificateData -CertificateData $innerResponse.CertificateData } if ( $using:OutPath ) { $out = $out | Select-Object -Property * -ExcludeProperty CertificateData # write the file with the filename provided $outFile = Join-Path -Path (Resolve-Path -Path $using:OutPath) -ChildPath ($innerResponse.FileName.Trim('"')) $bytes = [Convert]::FromBase64String($innerResponse.CertificateData) [IO.File]::WriteAllBytes($outFile, $bytes) Write-Verbose "Saved $outFile" $out | Add-Member @{'OutFile' = @($outFile) } if ( $thisBody.Format -in 'Base64 (PKCS#8)' -and $thisBody.IncludePrivateKey) { # outFile will be .pem with cert and key # write out the individual files as well try { $crtFile = $outFile.Replace('.pem', '.crt') $sw = [IO.StreamWriter]::new($crtFile, $false, [Text.Encoding]::ASCII) $sw.WriteLine($splitData.CertPem) Write-Verbose "Saved $crtFile" $out.OutFile += $crtFile } finally { if ($null -ne $sw) { $sw.Close() } } if ( $thisBody.IncludePrivateKey ) { try { $keyFile = $outFile.Replace('.pem', '.key') $sw = [IO.StreamWriter]::new($keyFile, $false, [Text.Encoding]::ASCII) $sw.WriteLine($splitData.KeyPem) Write-Verbose "Saved $keyFile" $out.OutFile += $keyFile } finally { if ($null -ne $sw) { $sw.Close() } } } } } else { if ( $thisBody.Format -in 'Base64', 'Base64 (PKCS#8)' ) { $out | Add-Member @{'CertPem' = $splitData.CertPem } if ( $thisBody.IncludePrivateKey ) { $out | Add-Member @{'KeyPem' = $splitData.KeyPem } } if ( $thisBody.IncludeChain -and $splitData.ChainPem ) { $out | Add-Member @{'ChainPem' = $splitData.ChainPem } } } } } $out } -ThrottleLimit $ThrottleLimit -ProgressTitle 'Exporting certificates' } } #EndRegion './Public/Export-VdcCertificate.ps1' 353 #Region './Public/Export-VdcVaultObject.ps1' -1 function Export-VdcVaultObject { <# .SYNOPSIS Export an object from the vault .DESCRIPTION Export different object types from the vault. The currently supported types are certificate, key, and PKCS12. If the type is not supported, the base64 data will be returned as is. .PARAMETER ID ID of the vault object to export .PARAMETER OutPath Folder path to save the certificate/key to. The name of the file will be determined automatically. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS ID .OUTPUTS PSCustomObject if unhandled type, otherwise saves the object to a file .EXAMPLE Export-VdcVaultObject -ID 12345 -OutPath 'c:\temp' Get vault object and save to a file #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('VaultId')] [int] $ID, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateScript( { if (Test-Path $_ -PathType Container) { $true } else { Throw "Output path '$_' does not exist" } })] [String] $OutPath, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { $response = Invoke-VenafiRestMethod -Method 'Post' -UriLeaf 'SecretStore/Retrieve' -Body @{ 'VaultID' = $ID } if ( $response.Result -ne 0 ) { Write-Error "Failed to retrieve vault object with a result code of $($response.Result). Look up this code at https://docs.venafi.com/Docs/currentSDK/TopNav/Content/SDK/WebSDK/r-SDK-SecretStore-ResultCodes.php." return } $ext = $null switch ( $response.VaultType ) { { $_ -in 2, 1073741826 } { # certificate $ext = 'cer' } { $_ -in 4, 1073741828 } { # PKCS12 $ext = 'p12' } { $_ -in 256, 1073742080 } { # PKCS8 $ext = 'key' } } if ( $ext ) { $outFile = Join-Path -Path (Resolve-Path -Path $OutPath) -ChildPath ('{0}.{1}' -f $ID, $ext) $bytes = [Convert]::FromBase64String($response.Base64Data) [IO.File]::WriteAllBytes($outFile, $bytes) Write-Verbose "Saved $outFile" } else { # unhandled type, send data as is Write-Verbose "Unhandled vault type $($response.VaultType), returning data as is" $response | Select-Object -Property *, @{'n' = 'VaultID'; 'e' = { $ID } } -ExcludeProperty Result } } } #EndRegion './Public/Export-VdcVaultObject.ps1' 106 #Region './Public/Find-VcCertificate.ps1' -1 function Find-VcCertificate { <# .SYNOPSIS Find certificates in TLSPC .DESCRIPTION Find certificates based on various attributes. .PARAMETER Name Search for certificates with the name matching part or all of the value .PARAMETER KeyLength Search by certificate key length .PARAMETER Serial Search by serial number .PARAMETER Fingerprint Search by fingerprint .PARAMETER IsSelfSigned Search for only self signed certificates .PARAMETER Status Search by one or more certificate statuses. Valid values include ACTIVE, RETIRED, and DELETED. .PARAMETER ExpireBefore Search for certificates expiring before a certain date. Use with -ExpireAfter for a defined start and end. .PARAMETER ExpireAfter Search for certificates expiring after a certain date. Use with -ExpireBefore for a defined start and end. .PARAMETER Version Search by version type. Valid values include CURRENT and OLD. .PARAMETER SanDns Search for certificates with SAN DNS matching part or all of the value .PARAMETER Application Application ID or name that this certificate is associated with .PARAMETER Tag One or more tags associated with the certificate. You can specify either just a tag name or name:value. .PARAMETER CN Search for certificates where the subject CN matches all of part of the value .PARAMETER Issuer Search by issuer name .PARAMETER Filter Array or multidimensional array of fields and values to filter on. Each array should be of the format @(field, comparison operator, value). To combine filters, use the format @('operator', @(field, comparison operator, value), @(field2, comparison operator2, value2)). Nested filters are supported. Field names and values are case sensitive, but VenafiPS will try and convert to the proper case if able. Available operators are: Operator | Name | Description and Usage ----------------------------------------------------------------------------------- EQ Equal operator The search result is equal to the specified value. Valid for numeric or Boolean fields. FIND Find operator The search result is based on the value of all or part of one or more strings. You can also use Regular Expressions (regex). GT Greater than The search result has a higher numeric value than the specified value. GTE Greater than or equal to The search result is equal or has a higher numeric value than the specified value. IN In clause The search result matches one of the values in an array. LT Less Than The search result has a lower value than the specified value. LTE Less than or equal to The search result is equal or less than the specified value. MATCH Match operator The search result includes a string value from the supplied list. You can also use regex for your search. For more info comparison operators, see https://docs.venafi.cloud/api/about-api-search-operators/. .PARAMETER Order 1 or more fields to order on. For each item in the array, you can provide a field name by itself; this will default to ascending. You can also provide a hashtable with the field name as the key and either asc or desc as the value. .PARAMETER SavedSearchName Find certificates based on a saved search, see https://docs.venafi.cloud/vaas/certificates/saving-certificate-filters .PARAMETER First Only retrieve this many records .PARAMETER ApplicationDetail Retrieve detailed application info. This will cause additional api calls to be made and take longer. .PARAMETER OwnerDetail Retrieve detailed user/team owner info. This will cause additional api calls to be made and take longer. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS None .OUTPUTS PSCustomObject .EXAMPLE Find-VcCertificate Find all certificates .EXAMPLE Find-VcCertificate -First 500 Find the first 500 certificates .EXAMPLE Find-VcCertificate -Name 'mycert.company.com' Find certificates matching all of part of the name .EXAMPLE Find-VcCertificate -Fingerprint '075C43428E70BCF941039F54B8ED78DE4FACA87F' Find certificates matching a single value .EXAMPLE Find-VcCertificate -ExpireAfter (get-date) -ExpireBefore (get-date).AddDays(30) Find certificates matching multiple values. In this case, find all certificates expiring in the next 30 days. .EXAMPLE Find-VcCertificate -ExpireAfter (get-date) -ExpireBefore (get-date).AddDays(30)| Invoke-VcCertificateAction -Renew Find all certificates expiring in the next 30 days and renew them .EXAMPLE Find-VcCertificate -Filter @('subjectDN', 'FIND', 'www.barron.com') Find via a filter instead of using built-in function properties .EXAMPLE Find-VcCertificate -ApplicatonDetail Include application details, not just the ID. This will make additional api calls and will increase the response time. .EXAMPLE Find-VcCertificate -OwnerDetail Include user/team owner details, not just the ID. This will make additional api calls and will increase the response time. #> [CmdletBinding(DefaultParameterSetName = 'All')] param ( [Parameter(ParameterSetName = 'All')] [string] $Name, [Parameter(ParameterSetName = 'All')] [int32] $KeyLength, [Parameter(ParameterSetName = 'All')] [string] $Serial, [Parameter(ParameterSetName = 'All')] [string] $Fingerprint, [Parameter(ParameterSetName = 'All')] [switch] $IsSelfSigned, [Parameter(ParameterSetName = 'All')] [ValidateSet('ACTIVE', 'RETIRED', 'DELETED')] [string[]] $Status, [Parameter(ParameterSetName = 'All')] [datetime] $ExpireBefore, [Parameter(ParameterSetName = 'All')] [datetime] $ExpireAfter, [Parameter(ParameterSetName = 'All')] [ValidateSet('CURRENT', 'OLD')] [string] $Version, [Parameter(ParameterSetName = 'All')] [string] $SanDns, [Parameter(ParameterSetName = 'All')] [string] $Application, [Parameter(ParameterSetName = 'All')] [string[]] $Tag, [Parameter(ParameterSetName = 'All')] [string] $CN, [Parameter(ParameterSetName = 'All')] [string] $Issuer, [Parameter(Mandatory, ParameterSetName = 'Filter')] [System.Collections.ArrayList] $Filter, [Parameter(ParameterSetName = 'All')] [Parameter(ParameterSetName = 'Filter')] [psobject[]] $Order, [parameter(Mandatory, ParameterSetName = 'SavedSearch')] [string] $SavedSearchName, [Parameter()] [switch] $ApplicationDetail, [Parameter()] [Alias('IncludeVaasOwner')] [switch] $OwnerDetail, [Parameter()] [int] $First, [Parameter()] [psobject] $VenafiSession ) Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $apps = [System.Collections.Generic.List[object]]::new() $appOwners = [System.Collections.Generic.List[object]]::new() $params = @{ Type = 'Certificate' First = $First } if ( $Order ) { $params.Order = $Order } switch ($PSCmdlet.ParameterSetName) { 'Filter' { $params.Filter = $Filter } 'All' { $newFilter = [System.Collections.Generic.List[object]]::new() $newFilter.Add('AND') switch ($PSBoundParameters.Keys) { 'Name' { $null = $newFilter.Add(@('certificateName', 'FIND', $Name)) } 'KeyLength' { $null = $newFilter.Add(@('keyStrength', 'EQ', $KeyLength.ToString())) } 'Serial' { $null = $newFilter.Add(@('serialNumber', 'EQ', $Serial)) } 'Fingerprint' { $null = $newFilter.Add(@('fingerprint', 'EQ', $Fingerprint)) } 'IsSelfSigned' { $null = $newFilter.Add(@('selfSigned', 'EQ', $IsSelfSigned.IsPresent.ToString())) } 'Version' { $null = $newFilter.Add(@('versionType', 'EQ', $Version)) } 'Status' { $null = $newFilter.Add(@('certificateStatus', 'MATCH', $Status.ToUpper())) } 'ExpireBefore' { $null = $newFilter.Add(@('validityEnd', 'LTE', $ExpireBefore)) } 'ExpireAfter' { $null = $newFilter.Add(@('validityEnd', 'GTE', $ExpireAfter)) } 'SanDns' { $null = $newFilter.Add(@('subjectAlternativeNameDns', 'FIND', $SanDns)) } 'CN' { $null = $newFilter.Add(@('subjectCN', 'FIND', $CN)) } 'Issuer' { $null = $newFilter.Add(@('issuerCN', 'FIND', $Issuer)) } 'Application' { $appId = Get-VcData -InputObject $Application -Type 'Application' if ( -not $appId ) { throw "Application '$Application' does not exist" } $newFilter.Add(@('applicationIds', 'MATCH', $appId )) } 'Tag' { $null = $newFilter.Add(@('tags', 'MATCH', $Tag)) } } if ( $newFilter.Count -gt 1 ) { $params.Filter = $newFilter } } 'SavedSearch' { $params.SavedSearchName = $SavedSearchName } } $response = Find-VcObject @params $response | Select-Object *, @{ 'n' = 'application' 'e' = { if ( $ApplicationDetail ) { foreach ($thisAppId in $_.applicationIds) { $thisApp = $apps | Where-Object { $_.applicationId -eq $thisAppId } if ( -not $thisApp ) { $thisApp = Get-VcApplication -ID $thisAppId | Select-Object -Property * -ExcludeProperty ownerIdsAndTypes, ownership $apps.Add($thisApp) } $thisApp } } else { $_.applicationIds } } }, @{ 'n' = 'owner' 'e' = { if ( $OwnerDetail ) { # this scriptblock requires ?ownershipTree=true be part of the url foreach ( $thisOwner in $_.ownership.owningContainers.owningUsers ) { $thisOwnerDetail = $appOwners | Where-Object { $_.id -eq $thisOwner } if ( -not $thisOwnerDetail ) { $thisOwnerDetail = Get-VcIdentity -ID $thisOwner | Select-Object firstName, lastName, emailAddress, @{ 'n' = 'status' 'e' = { $_.userStatus } }, @{ 'n' = 'role' 'e' = { $_.systemRoles } }, @{ 'n' = 'type' 'e' = { 'USER' } }, @{ 'n' = 'userId' 'e' = { $_.id } } $appOwners.Add($thisOwnerDetail) } $thisOwnerDetail } foreach ($thisOwner in $_.ownership.owningContainers.owningTeams) { $thisOwnerDetail = $appOwners | Where-Object { $_.id -eq $thisOwner } if ( -not $thisOwnerDetail ) { $thisOwnerDetail = Get-VcTeam -ID $thisOwner | Select-Object name, role, members, @{ 'n' = 'type' 'e' = { 'TEAM' } }, @{ 'n' = 'teamId' 'e' = { $_.id } } $appOwners.Add($thisOwnerDetail) } $thisOwnerDetail } } else { $_.ownership.owningContainers | Select-Object owningUsers, owningTeams } } }, @{ 'n' = 'instance' 'e' = { $_.instances } }, @{ 'n' = 'issuerCN' 'e' = { $_.issuerCN[0] } }, @{ 'n' = 'issuerOU' 'e' = { $_.issuerOU[0] } } -ExcludeProperty applicationIds, instances, totalInstanceCount, ownership, issuerCN, issuerOU } #EndRegion './Public/Find-VcCertificate.ps1' 372 #Region './Public/Find-VcCertificateInstance.ps1' -1 function Find-VcCertificateInstance { <# .SYNOPSIS Find certificate requests .DESCRIPTION Find certificate requests .PARAMETER Filter Array or multidimensional array of fields and values to filter on. Each array should be of the format @('operator', @(field, comparison operator, value), @(field2, comparison operator2, value2)). Nested filters are supported. For a complete list of comparison operators, see https://docs.venafi.cloud/api/about-api-search-operators/. To see which fields you can search on, execute Find-VcCertificateInstance -First 1. .PARAMETER Order Array of fields to order on. For each item in the array, you can provide a field name by itself; this will default to ascending. You can also provide a hashtable with the field name as the key and either asc or desc as the value. .PARAMETER HostName Hostname to find via regex match .PARAMETER IpAddress Machine IP Address .PARAMETER Port Machine port .PARAMETER Status Instance status, either IN_USE or SUPERSEDED .PARAMETER First Only retrieve this many records .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .OUTPUTS #> [CmdletBinding(DefaultParameterSetName = 'All')] param ( [Parameter(ParameterSetName = 'All')] [string] $HostName, [Parameter(ParameterSetName = 'All')] [ipaddress] $IpAddress, [Parameter(ParameterSetName = 'All')] [int] $Port, [Parameter(ParameterSetName = 'All')] [ValidateSet('IN_USE', 'SUPERSEDED')] [string] $Status, [Parameter(Mandatory, ParameterSetName = 'Filter')] [System.Collections.ArrayList] $Filter, [parameter()] [psobject[]] $Order, [Parameter()] [int] $First, [Parameter()] [psobject] $VenafiSession ) Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $params = @{ Type = 'CertificateInstance' First = $First } if ( $Order ) { $params.Order = $Order } if ( $PSCmdlet.ParameterSetName -eq 'Filter' ) { $params.Filter = $Filter } else { $newFilter = [System.Collections.Generic.List[object]]::new() $newFilter.Add('AND') switch ($PSBoundParameters.Keys) { 'HostName' { $null = $newFilter.Add(@('hostname', 'FIND', $HostName)) } 'IpAddress' { $null = $newFilter.Add(@('ipAddress', 'EQ', $IpAddress.IPAddressToString)) } 'Port' { $null = $newFilter.Add(@('port', 'EQ', $Port.ToString())) } 'Status' { $null = $newFilter.Add(@('deploymentStatus', 'EQ', $Status.ToUpper())) } } if ( $newFilter.Count -gt 1 ) { $params.Filter = $newFilter } } Find-VcObject @params } #EndRegion './Public/Find-VcCertificateInstance.ps1' 103 #Region './Public/Find-VcCertificateRequest.ps1' -1 function Find-VcCertificateRequest { <# .SYNOPSIS Find certificate requests .DESCRIPTION Find certificate requests .PARAMETER Filter Array or multidimensional array of fields and values to filter on. Each array should be of the format @('operator', @(field, comparison operator, value), @(field2, comparison operator2, value2)). Nested filters are supported. For a complete list of comparison operators, see https://docs.venafi.cloud/api/about-api-search-operators/. .PARAMETER Order Array of fields to order on. For each item in the array, you can provide a field name by itself; this will default to ascending. You can also provide a hashtable with the field name as the key and either asc or desc as the value. .PARAMETER Status Request status, either ISSUED or FAILED .PARAMETER KeyLength Certificate key length .PARAMETER First Only retrieve this many records .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .OUTPUTS #> [CmdletBinding(DefaultParameterSetName = 'All')] param ( [Parameter(ParameterSetName = 'All')] [ValidateSet('ISSUED', 'FAILED')] [string] $Status, [Parameter(ParameterSetName = 'All')] [int] $KeyLength, [Parameter(Mandatory, ParameterSetName = 'Filter')] [System.Collections.ArrayList] $Filter, [parameter()] [psobject[]] $Order, [Parameter()] [int] $First, [Parameter()] [psobject] $VenafiSession ) Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $params = @{ Type = 'CertificateRequest' First = $First } if ( $Order ) { $params.Order = $Order } if ( $PSCmdlet.ParameterSetName -eq 'Filter' ) { $params.Filter = $Filter } else { $newFilter = [System.Collections.Generic.List[object]]::new() $newFilter.Add('AND') switch ($PSBoundParameters.Keys) { 'Status' { $null = $newFilter.Add(@('status', 'EQ', $Status.ToUpper())) } 'KeyLength' { $null = $newFilter.Add(@('keyLength', 'EQ', $KeyLength.ToString())) } } if ( $newFilter.Count -gt 1 ) { $params.Filter = $newFilter } } Find-VcObject @params } #EndRegion './Public/Find-VcCertificateRequest.ps1' 89 #Region './Public/Find-VcLog.ps1' -1 function Find-VcLog { <# .SYNOPSIS Find log entries on TLSPC .DESCRIPTION Find log entries .PARAMETER Filter Array or multidimensional array of fields and values to filter on. Each array should be of the format @('operator', @(field, comparison operator, value), @(field2, comparison operator2, value2)). Nested filters are supported. For a complete list of comparison operators, see https://docs.venafi.cloud/api/about-api-search-operators/. .PARAMETER Order Array of fields to order on. For each item in the array, you can provide a field name by itself; this will default to ascending. You can also provide a hashtable with the field name as the key and either asc or desc as the value. .PARAMETER Name Activity name to find via regex match .PARAMETER Type Activity type .PARAMETER Message Look anywhere in the message for the string provided .PARAMETER First Only retrieve this many records .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .OUTPUTS PSCustomObject activityLogId activityDate activityType activityName criticality message payload companyId .EXAMPLE Find-VcLog -First 10 Get the most recent 10 log items .EXAMPLE Find-VcLog -Type 'Authentication' Filter log results by specific value .EXAMPLE Find-VcLog -Filter @('and', @('activityDate', 'gt', (get-date).AddMonths(-1)), @('or', @('message', 'find', 'greg@venafi.com'), @('message', 'find', 'bob@venafi.com')), @('activityType','eq','Authentication')) Advanced filtering of results. This filter will find authentication log entries by 1 of 2 people within the last month. .EXAMPLE Find-VcLog -Type 'Authentication' -Order 'activityDate' Filter log results and order them. By default, order will be ascending. .EXAMPLE Find-VcLog -Type 'Authentication' -Order @{'activityDate'='desc'} Filter log results and order them descending .EXAMPLE Find-VcLog -Type 'Authentication' -Order @{'activityDate'='desc'}, 'criticality' Filter log results and order them by multiple fields .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html?configUrl=/v3/api-docs/swagger-config#/Activity%20Logs/activitylogs_getByExpression #> [CmdletBinding(DefaultParameterSetName = 'All')] param ( [Parameter(ParameterSetName = 'All')] [string] $Name, [Parameter(ParameterSetName = 'All')] [string] $Type, [Parameter(ParameterSetName = 'All')] [string] $Message, [Parameter(Mandatory, ParameterSetName = 'Filter')] [System.Collections.ArrayList] $Filter, [parameter()] [psobject[]] $Order, [Parameter()] [int] $First, [Parameter()] [psobject] $VenafiSession ) Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $params = @{ Type = 'ActivityLog' First = $First } if ( $Order ) { $params.Order = $Order } if ( $PSCmdlet.ParameterSetName -eq 'Filter' ) { $params.Filter = $Filter } else { $newFilter = [System.Collections.Generic.List[object]]::new() $newFilter.Add('AND') switch ($PSBoundParameters.Keys) { 'Name' { $null = $newFilter.Add(@('activityName', 'FIND', $Name)) } 'Type' { $null = $newFilter.Add(@('activityType', 'EQ', $Type)) } 'Message' { $null = $newFilter.Add(@('message', 'FIND', $Message)) } } if ( $newFilter.Count -gt 1 ) { $params.Filter = $newFilter } } Find-VcObject @params } #EndRegion './Public/Find-VcLog.ps1' 138 #Region './Public/Find-VcMachine.ps1' -1 function Find-VcMachine { <# .SYNOPSIS Find machines .DESCRIPTION Find machines .PARAMETER Filter Array or multidimensional array of fields and values to filter on. Each array should be of the format @('operator', @(field, comparison operator, value), @(field2, comparison operator2, value2)). Nested filters are supported. For a complete list of comparison operators, see https://docs.venafi.cloud/api/about-api-search-operators/. .PARAMETER Order Array of fields to order on. For each item in the array, you can provide a field name by itself; this will default to ascending. You can also provide a hashtable with the field name as the key and either asc or desc as the value. .PARAMETER Name Machine name to find via regex match .PARAMETER MachineType Machine type. You can use tab-ahead autocompletion for a list. .PARAMETER Status Machine status, either DRAFT, VERIFIED, OR UNVERIFIED. .PARAMETER First Only retrieve this many records .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .OUTPUTS #> [CmdletBinding(DefaultParameterSetName = 'All')] param ( [Parameter(ParameterSetName = 'All')] [string] $Name, [Parameter(ParameterSetName = 'All')] [Alias('Type')] [string] $MachineType, [Parameter(ParameterSetName = 'All')] [ValidateSet('DRAFT', 'VERIFIED', 'UNVERIFIED')] [string] $Status, [Parameter(Mandatory, ParameterSetName = 'Filter')] [System.Collections.ArrayList] $Filter, [Parameter()] [psobject[]] $Order, [Parameter()] [int] $First, [Parameter()] [psobject] $VenafiSession ) Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $params = @{ Type = 'Machine' First = $First } if ( $Order ) { $params.Order = $Order } if ( $PSCmdlet.ParameterSetName -eq 'Filter' ) { $params.Filter = $Filter } else { $newFilter = [System.Collections.Generic.List[object]]::new() $newFilter.Add('AND') switch ($PSBoundParameters.Keys) { 'Name' { $null = $newFilter.Add(@('machineName', 'FIND', $Name)) } 'Type' { $null = $newFilter.Add(@('machineType', 'EQ', $Type)) } 'Status' { $null = $newFilter.Add(@('status', 'EQ', $Status.ToUpper())) } } if ( $newFilter.Count -gt 1 ) { $params.Filter = $newFilter } } Find-VcObject @params } #EndRegion './Public/Find-VcMachine.ps1' 97 #Region './Public/Find-VcMachineIdentity.ps1' -1 function Find-VcMachineIdentity { <# .SYNOPSIS Find machine identities .DESCRIPTION Find machine identities .PARAMETER Status Search by one or more statuses. Valid values are DISCOVERED, VALIDATED, and INSTALLED .PARAMETER Filter Array or multidimensional array of fields and values to filter on. Each array should be of the format @('operator', @(field, comparison operator, value), @(field2, comparison operator2, value2)). Nested filters are supported. For a complete list of comparison operators, see https://docs.venafi.cloud/api/about-api-search-operators/. .PARAMETER Order Array of fields to order on. For each item in the array, you can provide a field name by itself; this will default to ascending. You can also provide a hashtable with the field name as the key and either asc or desc as the value. .PARAMETER First Only retrieve this many records .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .OUTPUTS pscustomobject #> [CmdletBinding(DefaultParameterSetName = 'All')] param ( [Parameter(ParameterSetName = 'All')] [ValidateSet('DISCOVERED', 'VALIDATED', 'INSTALLED')] [string[]] $Status, [Parameter(Mandatory, ParameterSetName = 'Filter')] [System.Collections.ArrayList] $Filter, [parameter()] [psobject[]] $Order, [Parameter()] [int] $First, [Parameter()] [psobject] $VenafiSession ) Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $params = @{ Type = 'MachineIdentity' First = $First } if ( $Order ) { $params.Order = $Order } if ( $PSCmdlet.ParameterSetName -eq 'Filter' ) { $params.Filter = $Filter } else { $newFilter = [System.Collections.Generic.List[object]]::new() $newFilter.Add('AND') switch ($PSBoundParameters.Keys) { 'Status' { $newFilter.Add(@('status', 'MATCH', $Status.ToUpper())) } } if ( $newFilter.Count -gt 1 ) { $params.Filter = $newFilter } } Find-VcObject @params } #EndRegion './Public/Find-VcMachineIdentity.ps1' 82 #Region './Public/Find-VdcCertificate.ps1' -1 function Find-VdcCertificate { <# .SYNOPSIS Find certificates in TLSPDC based on various attributes .DESCRIPTION Find certificates based on various attributes. Supports standard PS paging parameters First and Skip. If -First not provided, the default return is 1000 records. .PARAMETER Path Starting path to search from. If not provided, the default is \ved\policy. .PARAMETER Guid Guid which represents a starting path. .PARAMETER Recursive Search recursively starting from the search path. .PARAMETER Country Find certificates by Country attribute of Subject DN. .PARAMETER CommonName Find certificates by Common name attribute of Subject DN. .PARAMETER Issuer Find certificates by issuer. Use the CN, O, L, S, and C values from the certificate request. .PARAMETER KeyAlgorithm Find certificates by algorithm for the public key. .PARAMETER KeySize Find certificates by public key size. .PARAMETER KeySizeGreaterThan Find certificates with a key size greater than the specified value. .PARAMETER KeySizeLessThan Find certificates with a key size less than the specified value. .PARAMETER Locale Find certificates by Locality/City attribute of Subject Distinguished Name (DN). .PARAMETER Organization Find certificates by Organization attribute of Subject DN. .PARAMETER OrganizationUnit Find certificates by Organization Unit (OU). .PARAMETER State Find certificates by State/Province attribute of Subject DN. .PARAMETER SanDns Find certificates by Subject Alternate Name (SAN) Distinguished Name Server (DNS). .PARAMETER SanEmail Find certificates by SAN Email RFC822. .PARAMETER SanIP Find certificates by SAN IP Address. .PARAMETER SanUpn Find certificates by SAN User Principal Name (UPN) or OtherName. .PARAMETER SanUri Find certificates by SAN Uniform Resource Identifier (URI). .PARAMETER SerialNumber Find certificates by Serial number. .PARAMETER SignatureAlgorithm Find certificates by the algorithm used to sign the certificate (e.g. SHA1RSA). .PARAMETER Thumbprint Find certificates by one or more SHA-1 thumbprints. .PARAMETER IssueDate Find certificates by the date of issue. .PARAMETER ExpireDate Find certificates by expiration date. .PARAMETER ExpireAfter Find certificates that expire after a certain date. .PARAMETER ExpireBefore Find certificates that expire before a certain date. .PARAMETER Enabled Include only certificates that are enabled or disabled. .PARAMETER InError Only include certificates in an error state. .PARAMETER IsSelfSigned Only include self-signed certificates .PARAMETER IsWildcard Only include wilcard certificates .PARAMETER NetworkValidationEnabled Only include certificates with network validation enabled or disabled. .PARAMETER CreatedDate Find certificates that were created at an exact date and time. .PARAMETER CreatedAfter Find certificate created after this date and time. .PARAMETER CreatedBefore Find certificate created before this date and time. .PARAMETER CertificateType Find certificate by category of usage. Use CodeSigning, Device, Server, and/or User. .PARAMETER ManagementType Find certificates with a Management type of Unassigned, Monitoring, Enrollment, or Provisioning. .PARAMETER PendingWorkflow Only include certificates that have a pending workflow resolution (have an outstanding workflow ticket). .PARAMETER Stage Find certificates by one or more stages in the certificate lifecycle. .PARAMETER StageGreaterThan Find certificates with a stage greater than the specified stage (does not include specified stage). .PARAMETER StageLessThan Find certificates with a stage less than the specified stage (does not include specified stage). .PARAMETER ValidationEnabled Only include certificates with validation enabled or disabled. .PARAMETER ValidationState Find certificates with a validation state of Blank, Success, or Failure. .PARAMETER CountOnly Return the count of certificates found from the query as opposed to the certificates themselves .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS TppObject, Int when CountOnly provided .EXAMPLE Find-VdcCertificate Find first 1000 certificates .EXAMPLE Find-VdcCertificate -ExpireBefore [datetime]'2018-01-01' Find certificates expiring before a certain date .EXAMPLE Find-VdcCertificate -ExpireBefore "2018-01-01" -First 5 Find 5 certificates expiring before a certain date .EXAMPLE Find-VdcCertificate -ExpireBefore "2018-01-01" -First 5 -Skip 2 Find 5 certificates expiring before a certain date, starting at the 3rd certificate found. .EXAMPLE Find-VdcCertificate -Path '\VED\Policy\My Policy' Find certificates in a specific path .EXAMPLE Find-VdcCertificate -Issuer 'CN=Example Root CA, O=Venafi,Inc., L=Salt Lake City, S=Utah, C=US' Find certificates by issuer .EXAMPLE Find-VdcCertificate -Path '\VED\Policy\My Policy' -Recursive Find certificates in a specific path and all subfolders .EXAMPLE Find-VdcCertificate | Get-VdcCertificate Get detailed certificate info .EXAMPLE Find-VdcCertificate -ExpireBefore "2019-09-01" | Invoke-VdcCertificateAction -Renew Renew all certificates expiring before a certain date .EXAMPLE Find-VdcCertificate -First 500 Find the first 500 certificates .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-Certificates.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-Certificates-guid.php .LINK https://msdn.microsoft.com/en-us/library/system.web.httputility(v=vs.110).aspx #> [CmdletBinding(SupportsPaging)] param ( [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Alias('DN')] [String] $Path = '\ved\policy', [Parameter()] [ValidateNotNullOrEmpty()] [guid] $Guid, [Parameter()] [Switch] $Recursive, # [Parameter()] # [int] $Limit = 1000, # [Parameter()] # [int] $Offset, [Parameter()] [Alias('C')] [String] $Country, [Parameter()] [Alias('CN')] [String] $CommonName, [Parameter()] [String] $Issuer, [Parameter()] [String[]] $KeyAlgorithm, [Parameter()] [Int[]] $KeySize, [Parameter()] [Int] $KeySizeGreaterThan, [Parameter()] [Int] $KeySizeLessThan, [Parameter()] [Alias('L')] [String[]] $Locale, [Parameter()] [Alias('O')] [String[]] $Organization, [Parameter()] [Alias('OU')] [String[]] $OrganizationUnit, [Parameter()] [Alias('S')] [String[]] $State, [Parameter()] [String] $SanDns, [Parameter()] [String] $SanEmail, [Parameter()] [String] $SanIP, [Parameter()] [String] $SanUpn, [Parameter()] [String] $SanUri, [Parameter()] [String] $SerialNumber, [Parameter()] [String] $SignatureAlgorithm, [Parameter()] [String] $Thumbprint, [Parameter()] [Alias('ValidFrom')] [DateTime] $IssueDate, [Parameter()] [Alias('ValidFromGreater')] [DateTime] $IssueDateAfter, [Parameter()] [Alias('ValidFromLess')] [DateTime] $IssueDateBefore, [Parameter()] [Alias('ValidTo')] [DateTime] $ExpireDate, [Parameter()] [Alias('ValidToGreater')] [DateTime] $ExpireAfter, [Parameter()] [Alias('ValidToLess')] [DateTime] $ExpireBefore, [Parameter()] [Switch] $Enabled, [Parameter()] [switch] $InError, [Parameter()] [switch] $IsSelfSigned, [Parameter()] [switch] $IsWildcard, [Parameter()] [bool] $NetworkValidationEnabled, [Parameter()] [Alias('CreatedOn')] [datetime] $CreatedDate, [Parameter()] [Alias('CreatedOnGreater')] [datetime] $CreatedAfter, [Parameter()] [Alias('CreatedOnLess')] [datetime] $CreatedBefore, [Parameter()] [ValidateSet('CodeSigning', 'Device', 'Server', 'User')] [String[]] $CertificateType, [Parameter()] [TppManagementType[]] $ManagementType, [Parameter()] [Switch] $PendingWorkflow, [Parameter()] [TppCertificateStage[]] $Stage, [Parameter()] [Alias('StageGreater')] [TppCertificateStage] $StageGreaterThan, [Parameter()] [Alias('StageLess')] [TppCertificateStage] $StageLessThan, [Parameter()] [Switch] $ValidationEnabled, [Parameter()] [ValidateSet('Blank', 'Success', 'Failure')] [String[]] $ValidationState, [Parameter()] [Switch] $CountOnly, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Get' UriLeaf = 'certificates/' Body = @{ Limit = 1000 Offset = 0 } FullResponse = $true } if ($PSCmdlet.PagingParameters.First -ne [uint64]::MaxValue -and $PSCmdlet.PagingParameters.First -le 1000) { $params.Body.Limit = $PSCmdlet.PagingParameters.First } if ($PSCmdlet.PagingParameters.Skip) { $params.Body.Offset = $PSCmdlet.PagingParameters.Skip } if ( $CountOnly.IsPresent ) { $params.Method = 'Head' } switch ($PSBoundParameters.Keys) { 'CreatedDate' { $params.Body.Add( 'CreatedOn', ($CreatedDate | ConvertTo-UtcIso8601) ) } 'CreatedBefore' { $params.Body.Add( 'CreatedOnLess', ($CreatedBefore | ConvertTo-UtcIso8601) ) } 'CreatedAfter' { $params.Body.Add( 'CreatedOnGreater', ($CreatedAfter | ConvertTo-UtcIso8601) ) } 'CertificateType' { $params.Body.Add( 'CertificateType', $CertificateType -join ',' ) } 'Country' { $params.Body.Add( 'C', $Country ) } 'CommonName' { $params.Body.Add( 'CN', $CommonName ) } 'Issuer' { $params.Body.Add( 'Issuer', '"{0}"' -f $Issuer ) } 'KeyAlgorithm' { $params.Body.Add( 'KeyAlgorithm', $KeyAlgorithm -join ',' ) } 'KeySize' { $params.Body.Add( 'KeySize', $KeySize -join ',' ) } 'KeySizeGreaterThan' { $params.Body.Add( 'KeySizeGreater', $KeySizeGreaterThan ) } 'KeySizeLessThan' { $params.Body.Add( 'KeySizeLess', $KeySizeLessThan ) } 'Locale' { $params.Body.Add( 'L', $Locale -join ',' ) } 'Organization' { $params.Body.Add( 'O', $Organization -join ',' ) } 'OrganizationUnit' { $params.Body.Add( 'OU', $OrganizationUnit -join ',' ) } 'State' { $params.Body.Add( 'S', $State -join ',' ) } 'SanDns' { $params.Body.Add( 'SAN-DNS', $SanDns ) } 'SanEmail' { $params.Body.Add( 'SAN-Email', $SanEmail ) } 'SanIP' { $params.Body.Add( 'SAN-IP', $SanIP ) } 'SanUpn' { $params.Body.Add( 'SAN-UPN', $SanUpn ) } 'SanUri' { $params.Body.Add( 'SAN-URI', $SanUri ) } 'SerialNumber' { $params.Body.Add( 'Serial', $SerialNumber ) } 'SignatureAlgorithm' { $params.Body.Add( 'SignatureAlgorithm', $SignatureAlgorithm -join ',' ) } 'Thumbprint' { $params.Body.Add( 'Thumbprint', $Thumbprint ) } 'IssueDateAfter' { $params.Body.Add( 'ValidFromGreater', ($IssueDateAfter | ConvertTo-UtcIso8601) ) } 'IssueDateBefore' { $params.Body.Add( 'ValidFromLess', ($IssueDateBefore | ConvertTo-UtcIso8601) ) } 'IssueDate' { $params.Body.Add( 'ValidFrom', ($IssueDate | ConvertTo-UtcIso8601) ) } 'ExpireDate' { $params.Body.Add( 'ValidTo', ($ExpireDate | ConvertTo-UtcIso8601) ) } 'ExpireAfter' { $params.Body.Add( 'ValidToGreater', ($ExpireAfter | ConvertTo-UtcIso8601) ) } 'ExpireBefore' { $params.Body.Add( 'ValidToLess', ($ExpireBefore | ConvertTo-UtcIso8601) ) } 'Enabled' { $params.Body.Add( 'Disabled', [int] (-not $Enabled) ) } 'InError' { $params.Body.Add( 'InError', [int]$InError.IsPresent ) } 'IsSelfSigned' { $params.Body.Add( 'IsSelfSigned', [int] $IsSelfSigned.IsPresent ) } 'IsWildcard' { $params.Body.Add( 'IsWildcard', [int] $IsWildcard.IsPresent ) } 'NetworkValidationEnabled' { $params.Body.Add( 'NetworkValidationDisabled', [int] (-not $NetworkValidationEnabled) ) } 'ManagementType' { $params.Body.Add( 'ManagementType', $ManagementType -join ',' ) } 'PendingWorkflow' { $params.Body.Add( 'PendingWorkflow', '') } 'Stage' { $params.Body.Add( 'Stage', ($Stage | ForEach-Object { [TppCertificateStage]::$_.value__ }) -join ',' ) } 'StageGreaterThan' { $params.Body.Add( 'StageGreater', [TppCertificateStage]::$StageGreaterThan.value__ ) } 'StageLessThan' { $params.Body.Add( 'StageLess', [TppCertificateStage]::$StageLessThan.value__ ) } 'ValidationEnabled' { $params.Body.Add( 'ValidationDisabled', [int] (-not $ValidationEnabled) ) } 'ValidationState' { $params.Body.Add( 'ValidationState', $ValidationState -join ',' ) } # } } } process { if ( $PSBoundParameters.ContainsKey('Path') ) { $thisPath = $Path | ConvertTo-VdcFullPath } elseif ( $PSBoundParameters.ContainsKey('Guid') ) { # guid provided, get path $thisPath = $Guid | ConvertTo-VdcPath } if ( $thisPath ) { if ( $Recursive.IsPresent ) { $params.Body.ParentDnRecursive = $thisPath } else { $params.Body.ParentDn = $thisPath } } $response = Invoke-VenafiRestMethod @params $totalRecordCount = 0 if ($PSVersionTable.PSVersion.Major -lt 6) { $totalRecordCount = [int]$response.Headers.'X-Record-Count' } else { $totalRecordCount = [int]($response.Headers.'X-Record-Count'[0]) } if ( $CountOnly ) { return $totalRecordCount } Write-Verbose "Total number of records for this query: $totalRecordCount" $content = $response.content | ConvertFrom-Json $content.Certificates.ForEach{ ConvertTo-VdcObject -Path $_.DN -Guid $_.Guid -TypeName $_.SchemaClass } if ($PSBoundParameters.ContainsKey('First')) { $totalRecordCount = $PSCmdlet.PagingParameters.First } $setPoint = $params.Body.Offset + $params.Body.Limit while ($totalRecordCount -gt $setPoint) { # up the offset so we get the next set of records $params.Body.Offset += $params.Body.Limit $setPoint = $params.Body.Offset + $params.Body.Limit $end = if ( $totalRecordCount -lt $setPoint ) { $totalRecordCount } else { $setPoint } Write-Verbose ('getting {0}-{1} of {2}' -f ($params.Body.Offset + 1), $end, $totalRecordCount) try { $response = Invoke-VenafiRestMethod @params -Verbose:$false } catch { $ProgressPreference = $oldProgressPreference throw $_ } $content = $response.content | ConvertFrom-Json $content.Certificates.ForEach{ ConvertTo-VdcObject -Path $_.DN -Guid $_.Guid -TypeName $_.SchemaClass } } } } #EndRegion './Public/Find-VdcCertificate.ps1' 612 #Region './Public/Find-VdcClient.ps1' -1 function Find-VdcClient { <# .SYNOPSIS Get information about registered Server Agents or Agentless clients .DESCRIPTION Get information about registered Server Agent or Agentless clients. .PARAMETER ClientType The client type. Allowed values include VenafiAgent, AgentJuniorMachine, AgentJuniorUser, Portal, Agentless, PreEnrollment, iOS, Android .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS None .OUTPUTS PSCustomObject .EXAMPLE Find-VdcClient Find all clients .EXAMPLE Find-VdcClient -ClientType Portal Find clients with the specific type .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Find-VdcClient/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Find-VdcClient.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-ClientDetails.php #> [CmdletBinding()] [Alias('Find-TppClient')] param ( [Parameter()] [ValidateSet('VenafiAgent', 'AgentJuniorMachine', 'AgentJuniorUser', 'Portal', 'Agentless', 'PreEnrollment', 'iOS', 'Android')] [String] $ClientType, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Get' UriLeaf = 'Client/Details/' Body = @{ } } if ( $ClientType ) { $params.Body.ClientType = $ClientType } # if no filters provided, get all if ( $params.Body.Count -eq 0 ) { $params.Body.LastSeenOnLess = (Get-Date) | ConvertTo-UtcIso8601 } } process { Invoke-VenafiRestMethod @params } } #EndRegion './Public/Find-VdcClient.ps1' 80 #Region './Public/Find-VdcEngine.ps1' -1 function Find-VdcEngine { <# .SYNOPSIS Find TLSPDC engines using an optional pattern .DESCRIPTION Find TLSPDC engines using an optional pattern. This function is an engine wrapper for Find-VdcObject. .PARAMETER Pattern Filter against engine names using asterisk (*) and/or question mark (?) wildcard characters. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided, but this requires an environment variable VDC_SERVER to be set. .INPUTS Pattern .OUTPUTS TppObject .EXAMPLE Find-VdcEngine -Pattern '*partialname*' Get engines whose name matches the supplied pattern .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Find-VdcEngine/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Find-VdcEngine.ps1 #> [CmdletBinding()] [Alias('Find-TppEngine')] param ( [Parameter(Mandatory, ValueFromPipeline)] [String] $Pattern, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { $params = @{ Class = 'Venafi Platform' Path = '\VED\Engines' Pattern = $Pattern } Find-VdcObject @params } } #EndRegion './Public/Find-VdcEngine.ps1' 61 #Region './Public/Find-VdcIdentity.ps1' -1 function Find-VdcIdentity { <# .SYNOPSIS Search for identity details .DESCRIPTION Returns information about individual identity, group identity, or distribution groups from a local or non-local provider such as Active Directory. You can specify individual identity types to search for or all .PARAMETER Name The individual identity, group identity, or distribution group name to search for .PARAMETER First First how many items are returned, the default is 500, but is limited by the provider. .PARAMETER IncludeUsers Include user identity type in search .PARAMETER IncludeSecurityGroups Include security group identity type in search .PARAMETER IncludeDistributionGroups Include distribution group identity type in search .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Name .OUTPUTS PSCustomObject with the following properties: Name ID Path .EXAMPLE Find-VdcIdentity -Name 'greg' -IncludeUsers Find only user identities with the name greg .EXAMPLE 'greg', 'brownstein' | Find-VdcIdentity Find all identity types with the name greg and brownstein .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Identity-Browse.php #> [CmdletBinding()] [Alias('Find-TppIdentity')] param ( [Parameter(Mandatory, ValueFromPipeline)] [ValidateNotNullOrEmpty()] [String[]] $Name, [Parameter()] [Alias('Limit')] [int] $First = 500, [Parameter(ParameterSetName = 'Find')] [Switch] $IncludeUsers, [Parameter(ParameterSetName = 'Find')] [Switch] $IncludeSecurityGroups, [Parameter(ParameterSetName = 'Find')] [Switch] $IncludeDistributionGroups, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $identityType = 0 # determine settings to use if ( $PSBoundParameters.ContainsKey('IncludeUsers') ) { $identityType += [TppIdentityType]::User } if ( $PSBoundParameters.ContainsKey('IncludeSecurityGroups') ) { $identityType += [TppIdentityType]::SecurityGroups } if ( $PSBoundParameters.ContainsKey('IncludeDistributionGroups') ) { $identityType += [TppIdentityType]::DistributionGroups } # if no types to include were provided, include all if ( $identityType -eq 0 ) { $identityType = [TppIdentityType]::User + [TppIdentityType]::SecurityGroups + [TppIdentityType]::DistributionGroups } $params = @{ Method = 'Post' UriLeaf = 'Identity/Browse' Body = @{ Filter = 'placeholder' Limit = $First IdentityType = $identityType } } } process { $response = $Name.ForEach{ $params.Body.Filter = $_ Invoke-VenafiRestMethod @params } $ids = $response.Identities if ( $ids ) { $ids | ConvertTo-VdcIdentity } } } #EndRegion './Public/Find-VdcIdentity.ps1' 122 #Region './Public/Find-VdcObject.ps1' -1 function Find-VdcObject { <# .SYNOPSIS Find objects by path, class, or pattern .DESCRIPTION Find objects by path, class, or pattern. .PARAMETER Path The path to start our search. The default is \ved\policy. .PARAMETER Class 1 or more classes/types to search for .PARAMETER Pattern Filter against object paths. If the Attribute parameter is provided, this will filter against an object's attribute/custom field values instead of the path. Follow the below rules: - To list DNs that include an asterisk or question mark, prepend the character with two backslashes. - To list DNs with a wildcard character, append a question mark (?). For example, "test_?.mycompany.net" counts test_1.MyCompany.net and test_2.MyCompany.net but not test12.MyCompany.net. - To list DNs with similar names, prepend an asterisk. For example, *est.MyCompany.net, counts Test.MyCompany.net and West.MyCompany.net. You can also use both literals and wildcards in a pattern. .PARAMETER Attribute A list of attribute names to limit the search against. Only valid when searching by pattern. A custom field name can also be provided. .PARAMETER Recursive Searches the subordinates of the object specified in Path. .PARAMETER NoLookup Default functionality when finding by Attribute is to perform a lookup to see if they are custom fields or not. If they are, pass along the guid instead of name required by the api for custom fields. To override this behavior and use the attribute name as is, add -NoLookup. Useful if on the off chance you have a custom field with the same name as a built-in attribute. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS TppObject .EXAMPLE Find-VdcObject Get all objects recursively starting from \ved\policy .EXAMPLE Find-VdcObject -Path '\VED\Policy\certificates' Get all objects in the root of a specific folder .EXAMPLE Find-VdcObject -Path '\VED\Policy\My Folder' -Recursive Get all objects in a folder and subfolders .EXAMPLE Find-VdcObject -Path '\VED\Policy' -Pattern '*test*' Get items in a specific folder filtering the path .EXAMPLE Find-VdcObject -Class 'capi' -Path '\ved\policy\installations' -Recursive Get objects of a specific type .EXAMPLE Find-VdcObject -Class 'capi' -Pattern '*test*' -Path '\ved\policy\installations' -Recursive Get all objects of a specific type where the path is of a specific pattern .EXAMPLE Find-VdcObject -Class 'capi', 'iis6' -Pattern '*test*' -Path '\ved\policy\installations' -Recursive Get objects for multiple types .EXAMPLE Find-VdcObject -Pattern '*f5*' Find objects with the specific name. All objects under \ved\policy (the default) will be searched. .EXAMPLE Find-VdcObject -Attribute 'Description' -Pattern 'awesome' Find objects where the specific attribute matches the pattern .EXAMPLE Find-VdcObject -Attribute 'Environment' -Pattern 'Development' Find objects where a custom field value matches the pattern. By default, the attribute will be checked against the current list of custom fields. .EXAMPLE Find-VdcObject -Attribute 'Description' -Pattern 'duplicate' -NoLookup Bypass custom field lookup and force Attribute to be treated as a built-in attribute. Useful if there are conflicting custom field and built-in attribute names and you want to force the lookup against built-in. .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Find-VdcObject/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Find-VdcObject.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-find.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-findobjectsofclass.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-enumerate.php #> [CmdletBinding(DefaultParameterSetName = 'FindByPath')] [Alias('fto', 'Find-TppObject')] param ( [Parameter(ParameterSetName = 'FindByPath', ValueFromPipeline, ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'FindByClass', ValueFromPipeline, ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'FindByPattern', ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Alias('DN')] [String] $Path = '\ved\policy', [Parameter(Mandatory, ParameterSetName = 'FindByPattern')] [Parameter(ParameterSetName = 'FindByClass')] [Parameter(Mandatory, ParameterSetName = 'FindByAttribute')] [ValidateNotNull()] [AllowEmptyString()] [String] $Pattern, [Parameter(Mandatory, ParameterSetName = 'FindByClass')] [ValidateNotNullOrEmpty()] [Alias('TypeName')] [String[]] $Class, [Parameter(Mandatory, ParameterSetName = 'FindByAttribute')] [ValidateNotNullOrEmpty()] [Alias('AttributeName')] [String[]] $Attribute, [Parameter(ParameterSetName = 'FindByPath')] [Parameter(ParameterSetName = 'FindByClass')] [Parameter(ParameterSetName = 'FindByPattern')] [Alias('r')] [switch] $Recursive, [Parameter(ParameterSetName = 'FindByAttribute')] [switch] $NoLookup, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { $params = @{ Method = 'Post' Body = @{ 'ObjectDN' = $Path | ConvertTo-VdcFullPath } } Switch ($PsCmdlet.ParameterSetName) { 'FindByAttribute' { $customField = $VenafiSessionNested.CustomField | Where-Object { $_.Label -eq $Attribute[0] -or $_.Guid -eq $Attribute[0] } # if attribute isn't a custom field or user doesn't want to perform a cf lookup for a conflicting attrib/cf name, perform standard find object if ( $NoLookup -or (-not $customField) ) { $params.UriLeaf = 'config/find' $params.Body = @{ AttributeNames = $Attribute } } else { # cf found $params.UriLeaf = 'Metadata/Find' $params.Body = @{ ItemGuid = $customField.Guid Value = $Pattern } } } { $_ -in 'FindByPath', 'FindByPattern', 'FindByClass' } { # if a path wasn't provided, default to recursive enumeration of \ved\policy if ( -not $PSBoundParameters.ContainsKey('Path') ) { $params.Body.Recursive = 'true' } } { $_ -in 'FindByPath', 'FindByPattern' } { $params.UriLeaf = 'config/enumerate' } 'FindByClass' { $params.UriLeaf = 'config/FindObjectsOfClass' } } # pattern is not used by custom field lookup if ( $PSBoundParameters.ContainsKey('Pattern') -and ($params.UriLeaf -ne 'Metadata/Find') ) { $params.Body.Pattern = $Pattern } if ( $PSBoundParameters.ContainsKey('Recursive') ) { $params.Body.Recursive = 'true' } if ( $PSBoundParameters.ContainsKey('Class') ) { # the rest api doesn't have the ability to search for multiple classes and path at the same time # loop through classes to get around this $params.Body.Class = '' $objects = $Class.ForEach{ $thisClass = $_ $params.Body.Class = $thisClass $response = Invoke-VenafiRestMethod @params if ( $response.Result -eq 1 ) { $response.Objects } else { Write-Error ('Retrieval of class {0} failed with error {1}' -f $thisClass, $response.Error) Continue } } } else { $response = Invoke-VenafiRestMethod @params # success for cf lookup is 0, all others are config calls and success is 1 if ( $response.Result -in 0, 1 ) { $objects = $response.Objects } else { Write-Error $response.Error } } foreach ($object in $objects) { ConvertTo-VdcObject -Path $object.DN -Guid $object.Guid -TypeName $object.TypeName } } } #EndRegion './Public/Find-VdcObject.ps1' 255 #Region './Public/Find-VdcVaultId.ps1' -1 function Find-VdcVaultId { <# .SYNOPSIS Find vault IDs in the secret store .DESCRIPTION Find vault IDs in the secret store by their attributes and associated values .PARAMETER Attribute Name and value to search. See https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Secretstore-lookupbyassociation.php for more details. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Attribute .OUTPUTS String .EXAMPLE Find-VdcVaultId -Attribute @{'Serial'='0812E11D213DE8E07890BCC1234567'} Find a vault id .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Find-VdcVaultId/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Find-VdcVaultId.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Secretstore-lookupbyassociation.php #> [CmdletBinding()] [Alias('Find-TppVaultId')] param ( [Parameter(Mandatory, ValueFromPipeline)] [hashtable] $Attribute, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' UriLeaf = 'SecretStore/LookupByAssociation' Body = @{} } } process { $thisKey = "$($Attribute.Keys[0])" $thisValue = "$($Attribute.Values[0])" switch ($thisKey) { { $_ -in 'Certificate Type', 'Key Size', 'Parent ID', 'Template Major Version' } { $type = 'IntValue' } { $_ -in 'Create Date', 'Revocation Check Date', 'Revocation Date', 'ValidFrom', 'ValidTo' } { $type = 'ValueDate' } Default { $type = 'StringValue' } } $params.Body = @{ 'Name' = $thisKey $type = $thisValue } $response = Invoke-VenafiRestMethod @params if ( $response.Result -eq 0 ) { $response.VaultIDs } else { throw ('Secret store search failed with error code {0}' -f $response.Result) } } end { } } #EndRegion './Public/Find-VdcVaultId.ps1' 102 #Region './Public/Get-VcApplication.ps1' -1 function Get-VcApplication { <# .SYNOPSIS Get application info .DESCRIPTION Get 1 or more applications. .PARAMETER Application Application ID or name .PARAMETER All Get all applications .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Get-VcApplication -Application 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' applicationId : 96fc9310-67ec-11eb-a8a7-794fe75a8e6f certificateIssuingTemplate : @{Name=MyTemplate; id=7fb6af20-b22e-11ea-9a24-930fb5d2b247} companyId : 09b24f81-b22b-11ea-91f3-ebd6dea5452e name : myapp description : ownerIdsAndTypes : {@{ownerId=0a2adae0-b22b-11ea-91f3-ebd6dea5452f; ownerType=TEAM}} fullyQualifiedDomainNames : {} ipRanges : {} ports : {} modificationDate : 6/8/2023 11:06:43 AM creationDate : 2/5/2021 2:59:00 PM ownership : @{owningUsers=System.Object[]} Get a single object by ID .EXAMPLE Get-VcApplication -Application 'My Awesome App' Get a single object by name. The name is case sensitive. .EXAMPLE Get-VcApplication -All Get all applications #> [CmdletBinding(DefaultParameterSetName = 'ID')] [Alias('Get-VaasApplication')] param ( [Parameter(Mandatory, ParameterSetName = 'ID', ValueFromPipeline, ValueFromPipelineByPropertyName, Position = 0)] [Alias('applicationId', 'ID')] [string] $Application, [Parameter(Mandatory, ParameterSetName = 'All')] [switch] $All, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { $params = @{ UriRoot = 'outagedetection/v1' UriLeaf = 'applications' } if ( $PSBoundParameters.ContainsKey('Application') ) { if ( Test-IsGuid($Application) ) { $params.UriLeaf += "/{0}" -f $Application } else { # search by name $params.UriLeaf += "/name/$Application" } } try { $response = Invoke-VenafiRestMethod @params } catch { if ( $_.Exception.Response.StatusCode.value__ -eq 404 ) { # not found, return nothing return } else { throw $_ } } if ( $response.PSObject.Properties.Name -contains 'applications' ) { $applications = $response | Select-Object -ExpandProperty applications } else { $applications = $response } if ( $applications ) { $applications | Select-Object @{'n' = 'applicationId'; 'e' = { $_.Id } }, @{ 'n' = 'issuingTemplate' 'e' = { $_.certificateIssuingTemplateAliasIdMap.psobject.Properties | Select-Object @{'n' = 'name'; 'e' = { $_.Name } }, @{'n' = 'issuingTemplateId'; 'e' = { $_.Value } } } }, * -ExcludeProperty Id, certificateIssuingTemplateAliasIdMap } } } #EndRegion './Public/Get-VcApplication.ps1' 121 #Region './Public/Get-VcCertificate.ps1' -1 function Get-VcCertificate { <# .SYNOPSIS Get certificate information .DESCRIPTION Get certificate information, either all available to the api key provided or by id or zone. .PARAMETER ID Certificate identifier, the ID or certificate name. .PARAMETER All Retrieve all certificates .PARAMETER IncludeVaasOwner Retrieve extended application owner info .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also be provided. .INPUTS ID .OUTPUTS PSCustomObject .EXAMPLE Get-VdcCertificate -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' Get certificate info for a specific cert .EXAMPLE Get-VdcCertificate -All Get certificate info for all certs #> [CmdletBinding(DefaultParameterSetName = 'Id')] param ( [Parameter(ParameterSetName = 'Id', Mandatory, ValueFromPipelineByPropertyName, Position = 0)] [Alias('certificateId')] [string] $ID, [Parameter(Mandatory, ParameterSetName = 'All')] [Switch] $All, [Parameter()] [switch] $IncludeVaasOwner, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $appOwners = [System.Collections.Generic.List[object]]::new() } process { if ( $All ) { return (Find-VcCertificate -IncludeVaasOwner:$IncludeVaasOwner) } $params = @{ UriRoot = 'outagedetection/v1' UriLeaf = "certificates/" } if ( Test-IsGuid($ID) ) { $params.UriLeaf += $ID } else { $findParams = @{ Filter = @('certificateName', 'eq', $ID) IncludeVaasOwner = $IncludeVaasOwner } return (Find-VcCertificate @findParams | Get-VcCertificate) } $params.UriLeaf += "?ownershipTree=true" $response = Invoke-VenafiRestMethod @params if ( $response.PSObject.Properties.Name -contains 'certificates' ) { $certs = $response | Select-Object -ExpandProperty certificates } else { $certs = $response } $certs | Select-Object @{ 'n' = 'certificateId' 'e' = { $_.Id } }, @{ 'n' = 'application' 'e' = { if ( $_.applicationIds ) { $_.applicationIds | Get-VcApplication | Select-Object -Property * -ExcludeProperty ownerIdsAndTypes, ownership } } }, @{ 'n' = 'owner' 'e' = { if ( $IncludeVaasOwner ) { # this scriptblock requires ?ownershipTree=true be part of the url foreach ( $thisOwner in $_.ownership.owningContainers.owningUsers ) { $thisOwnerDetail = $appOwners | Where-Object { $_.id -eq $thisOwner } if ( -not $thisOwnerDetail ) { $thisOwnerDetail = Get-VcIdentity -ID $thisOwner | Select-Object firstName, lastName, emailAddress, @{ 'n' = 'status' 'e' = { $_.userStatus } }, @{ 'n' = 'role' 'e' = { $_.systemRoles } }, @{ 'n' = 'type' 'e' = { 'USER' } }, @{ 'n' = 'userId' 'e' = { $_.id } } $appOwners.Add($thisOwnerDetail) } $thisOwnerDetail } foreach ($thisOwner in $_.ownership.owningContainers.owningTeams) { $thisOwnerDetail = $appOwners | Where-Object { $_.id -eq $thisOwner } if ( -not $thisOwnerDetail ) { $thisOwnerDetail = Get-VcTeam -ID $thisOwner | Select-Object name, role, members, @{ 'n' = 'type' 'e' = { 'TEAM' } }, @{ 'n' = 'teamId' 'e' = { $_.id } } $appOwners.Add($thisOwnerDetail) } $thisOwnerDetail } } else { $_.ownership.owningContainers | Select-Object owningUsers, owningTeams } } }, @{ 'n' = 'instance' 'e' = { $_.instances } }, * -ExcludeProperty Id, applicationIds, instances, totalInstanceCount, ownership } } #EndRegion './Public/Get-VcCertificate.ps1' 176 #Region './Public/Get-VcConnector.ps1' -1 function Get-VcConnector { <# .SYNOPSIS Get connector info .DESCRIPTION Get details on 1 or all connectors .PARAMETER Connector Connector ID or name .PARAMETER All Get all connectors .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Get-VcConnector -Connector 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' | ConvertTo-Json { "connectorId": "a7ddd210-0a39-11ee-8763-134b935c90aa", "name": "ServiceNow-expiry, "properties": { "connectorKind": "WEBHOOK", "filter": { "filterType": "EXPIRATION", "applicationIds": [] }, "target": { "type": "generic", "connection": { "secret": "MySecret", "url": "https://instance.service-now.com/api/company/endpoint" } } } } Get a single object by ID .EXAMPLE Get-VcConnector -Connector 'My Connector' Get a single object by name. The name is case sensitive. .EXAMPLE Get-VcConnector -All Get all connectors #> [CmdletBinding(DefaultParameterSetName = 'ID')] [Alias('Get-VaasConnector')] param ( [Parameter(Mandatory, ParameterSetName = 'ID', ValueFromPipelineByPropertyName, Position = 0)] [Alias('connectorId', 'ID')] [string] $Connector, [Parameter(Mandatory, ParameterSetName = 'All')] [switch] $All, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { $params = @{ UriLeaf = 'plugins' } if ( $PSBoundParameters.ContainsKey('Connector') ) { if ( Test-IsGuid($Connector) ) { $params.UriLeaf += "/{0}" -f $Connector } else { # search by name return Get-VcConnector -All | Where-Object { $_.name -eq $Connector } } } else { $params.Body = @{'includeDisabled' = $true } } $response = Invoke-VenafiRestMethod @params if ( $response.PSObject.Properties.Name -contains 'plugins' ) { $connectors = $response | Select-Object -ExpandProperty 'plugins' } else { $connectors = $response } if ( $connectors ) { $connectors | Select-Object @{ 'n' = 'connectorId'; 'e' = { $_.Id } }, @{ 'n' = 'connectorType'; 'e' = { $_.pluginType } }, * -ExcludeProperty Id, pluginType } } } #EndRegion './Public/Get-VcConnector.ps1' 112 #Region './Public/Get-VcIssuingTemplate.ps1' -1 function Get-VcIssuingTemplate { <# .SYNOPSIS Get issuing template info .DESCRIPTION Get 1 or more issuing template details .PARAMETER IssuingTemplate Issuing template ID or name .PARAMETER All Get all issuing templates .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Get-VcIssuingTemplate -IssuingTemplate 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' issuingTemplateId : 0a19eaf2-b22b-11ea-a1eb-a37c69eabd4e companyId : 09b24f81-b22b-11ea-91f3-ebd6dea5452f certificateAuthority : BUILTIN name : Default certificateAuthorityAccountId : 0a19eaf0-b22b-11ea-a1eb-a37c69eabd4e certificateAuthorityProductOptionId : 0a19eaf1-b22b-11ea-a1eb-a37c69eabd4e product : @{certificateAuthority=BUILTIN; productName=Default Product; productTypes=System.Object[]; validityPeriod=P90D} priority : 0 systemGenerated : True creationDate : 6/19/2020 8:47:30 AM modificationDate : 6/19/2020 8:47:30 AM status : AVAILABLE reason : referencingApplicationIds : {995d1fb0-67e9-11eb-a8a7-794fe75a8e6f} subjectCNRegexes : {.*} subjectORegexes : {.*} subjectOURegexes : {.*} subjectSTRegexes : {.*} subjectLRegexes : {.*} subjectCValues : {.*} sanRegexes : {.*} sanDnsNameRegexes : {.*} keyTypes : {@{keyType=RSA; keyLengths=System.Object[]}} keyReuse : False extendedKeyUsageValues : {} csrUploadAllowed : True keyGeneratedByVenafiAllowed : False resourceConsumerUserIds : {} resourceConsumerTeamIds : {} everyoneIsConsumer : True Get a single object by ID .EXAMPLE Get-VcIssuingTemplate -IssuingTemplate 'MyTemplate' Get a single object by name. The name is case sensitive. .EXAMPLE Get-VcIssuingTemplate -All Get all issuing templates #> [CmdletBinding(DefaultParameterSetName='ID')] [Alias('Get-VaasIssuingTemplate')] param ( [Parameter(Mandatory, ParameterSetName = 'ID', ValueFromPipelineByPropertyName, Position = 0)] [Alias('issuingTemplateId', 'ID')] [string] $IssuingTemplate, [Parameter(Mandatory, ParameterSetName = 'All')] [switch] $All, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { $params = @{ UriLeaf = 'certificateissuingtemplates' } if ( $PSBoundParameters.ContainsKey('IssuingTemplate') ) { if ( Test-IsGuid($IssuingTemplate) ) { $params.UriLeaf += "/{0}" -f $IssuingTemplate } else { # search by name return Get-VcIssuingTemplate -All | Where-Object { $_.name -eq $IssuingTemplate } } } try { $response = Invoke-VenafiRestMethod @params } catch { if ( $_.Exception.Response.StatusCode.value__ -eq 404 ) { # not found, return nothing return } else { throw $_ } } if ( $response.PSObject.Properties.Name -contains 'certificateissuingtemplates' ) { $templates = $response | Select-Object -ExpandProperty certificateissuingtemplates } else { $templates = $response } if ( $templates ) { $templates | Select-Object -Property @{'n' = 'issuingTemplateId'; 'e' = { $_.id } }, * -ExcludeProperty id } } } #EndRegion './Public/Get-VcIssuingTemplate.ps1' 132 #Region './Public/Get-VcMachine.ps1' -1 function Get-VcMachine { <# .SYNOPSIS Get machine details .DESCRIPTION Get machine details for 1 or all. .PARAMETER Machine Machine ID or name .PARAMETER All Get all machines .PARAMETER IncludeConnectionDetail Getting all machines does not include connection details. Use -IncludeConnectionDetail to add this to the output, but note it will require an additional API call for each machine and can take some time. Execute with PowerShell v7+ to run in parallel and speed things up. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS Machine .EXAMPLE Get-VcMachine -Machine 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' machineId : cf7cfdc0-2b2a-11ee-9546-5136c4b21504 companyId : cf7cfdc0-2b2a-11ee-9546-5136c4b21504 machineTypeId : fc569b60-cf24-11ed-bdc6-77a4bac4cb50 pluginId : ff645e14-bd1a-11ed-a009-ce063932f86d integrationId : cf7c8014-2b2a-11ee-9a03-fa8930555887 machineName : MyCitrix status : VERIFIED machineType : Citrix ADC creationDate : 7/25/2023 4:35:36 PM modificationDate : 7/25/2023 4:35:36 PM machineIdentitiesCount : 0 owningTeam : 59920180-a3e2-11ec-8dcd-3fcbf84c7db1 ownership : @{owningTeams=System.Object[]} connectionDetails : @{hostnameOrAddress=1.2.3.4; password=uYroVBk/KtuuujEbfFC/06wtkIrOga7N96JdFSEQFhhn7KPUEWA=; username=ZLQlnciWsVp+qIUJQ8nYcAuHh55FxKdFsWhHVp7LLU+0y8aDp1pw==} Get a single machine by ID .EXAMPLE Get-VcMachine -Machine 'MyCitrix' Get a single machine by name. The name is case sensitive. .EXAMPLE Get-VcMachine -All machineId : cf7cfdc0-2b2a-11ee-9546-5136c4b21504 companyId : cf7cfdc0-2b2a-11ee-9546-5136c4b21504 machineTypeId : fc569b60-cf24-11ed-bdc6-77a4bac4cb50 pluginId : ff645e14-bd1a-11ed-a009-ce063932f86d integrationId : cf7c8014-2b2a-11ee-9a03-fa8930555887 machineName : MyCitrix status : VERIFIED machineType : Citrix ADC creationDate : 7/25/2023 4:35:36 PM modificationDate : 7/25/2023 4:35:36 PM machineIdentitiesCount : 0 owningTeam : 59920180-a3e2-11ec-8dcd-3fcbf84c7db1 ownership : @{owningTeams=System.Object[]} Get all machines. Note the connection details are not included by default with -All. See -IncludeConnectionDetails if this is needed. .EXAMPLE Get-VcMachine -All -IncludeConnectionDetails machineId : cf7cfdc0-2b2a-11ee-9546-5136c4b21504 companyId : cf7cfdc0-2b2a-11ee-9546-5136c4b21504 machineTypeId : fc569b60-cf24-11ed-bdc6-77a4bac4cb50 pluginId : ff645e14-bd1a-11ed-a009-ce063932f86d integrationId : cf7c8014-2b2a-11ee-9a03-fa8930555887 machineName : MyCitrix status : VERIFIED machineType : Citrix ADC creationDate : 7/25/2023 4:35:36 PM modificationDate : 7/25/2023 4:35:36 PM machineIdentitiesCount : 0 owningTeam : 59920180-a3e2-11ec-8dcd-3fcbf84c7db1 ownership : @{owningTeams=System.Object[]} connectionDetails : @{hostnameOrAddress=1.2.3.4; password=uYroVBk/KtuuujEbfFC/06wtkIrOga7N96JdFSEQFhhn7KPUEWA=; username=ZLQlnciWsVp+qIUJQ8nYcAuHh55FxKdFsWhHVp7LLU+0y8aDp1pw==} Get all machines and include the connection details. Getting connection details will require an additional API call for each machine and can take some time. Use PowerShell v7+ to perform this in parallel and speed things up. #> [CmdletBinding(DefaultParameterSetName = 'ID')] [Alias('Get-VaasMachine')] param ( [Parameter(Mandatory, ParameterSetName = 'ID', ValueFromPipelineByPropertyName, Position = 0)] [Alias('machineId', 'ID')] [string] $Machine, [Parameter(Mandatory, ParameterSetName = 'All')] [switch] $All, [Parameter(ParameterSetName = 'All')] [switch] $IncludeConnectionDetail, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { if ( $PSCmdlet.ParameterSetName -eq 'All' ) { $allMachines = Find-VcObject -Type Machine if ( $IncludeConnectionDetail ) { $params = @{ InputObject = $allMachines ScriptBlock = { $PSItem | Get-VcMachine } } return Invoke-VenafiParallel @params } else { return $allMachines } } else { if ( Test-IsGuid($Machine) ) { try { $response = Invoke-VenafiRestMethod -UriLeaf ('machines/{0}' -f $Machine) } catch { if ( $_.Exception.Response.StatusCode.value__ -eq 404 ) { # not found, return nothing return } else { throw $_ } } } else { # no lookup by name directly. search for it and then get details Find-VcObject -Type 'Machine' -Name $Machine | Get-VcMachine } if ( $response ) { $response | Select-Object @{ 'n' = 'machineId'; 'e' = { $_.Id } }, * -ExcludeProperty Id } } } } #EndRegion './Public/Get-VcMachine.ps1' 166 #Region './Public/Get-VcMachineIdentity.ps1' -1 function Get-VcMachineIdentity { <# .SYNOPSIS Get machine identities .DESCRIPTION Get 1 or all machine identities .PARAMETER ID Machine identity ID .PARAMETER All Get all machine identities .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Get-VcMachineIdentity -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' machineIdentityId : cc57e830-1a90-11ee-abe7-bda0c823b1ad companyId : cc57e830-1a90-11ee-abe7-bda0c823b1ad machineId : 5995ecf0-19ca-11ee-9386-3ba941243b67 certificateId : cc535450-1a90-11ee-8774-3d248c9b48c5 status : DISCOVERED creationDate : 7/4/2023 1:32:50 PM lastSeenOn : 7/4/2023 1:32:50 PM modificationDate : 7/4/2023 1:32:50 PM keystore : @{friendlyName=1.test.net; keystoreCapiStore=my; privateKeyIsExportable=False} binding : @{createBinding=False; port=40112; siteName=domain.io} Get a single machine identity by ID .EXAMPLE Get-VcMachineIdentity -All Get all machine identities #> [CmdletBinding(DefaultParameterSetName = 'ID')] param ( [Parameter(Mandatory, ParameterSetName = 'ID', ValueFromPipelineByPropertyName, Position = 0)] [Alias('machineIdentityId')] [ValidateScript( { if ( Test-IsGuid($_) ) { $true } else { throw '-ID must be a uuid/guid' } } )] [string] $ID, [Parameter(Mandatory, ParameterSetName = 'All')] [switch] $All, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { if ( $PSCmdlet.ParameterSetName -eq 'All' ) { $params = @{ InputObject = Find-VcObject -Type MachineIdentity ScriptBlock = { $PSItem | Get-VcMachineIdentity } } Invoke-VenafiParallel @params } else { try { $response = Invoke-VenafiRestMethod -UriLeaf ('machineidentities/{0}' -f $ID) } catch { if ( $_.Exception.Response.StatusCode.value__ -eq 404 ) { # not found, return nothing return } else { throw $_ } } if ( $response ) { $response | Select-Object @{ 'n' = 'machineIdentityId'; 'e' = { $_.Id } }, @{ 'n'='certificateValidityEnd' 'e'={ Get-VcCertificate -CertificateID $_.certificateId | Select-Object -ExpandProperty validityEnd } }, * -ExcludeProperty Id } } } } #EndRegion './Public/Get-VcMachineIdentity.ps1' 106 #Region './Public/Get-VcSatellite.ps1' -1 function Get-VcSatellite { <# .SYNOPSIS Get VSatellite info .DESCRIPTION Get 1 or more VSatellites. Encyption key and algorithm will be included. .PARAMETER VSatellite VSatellite ID or name .PARAMETER All Get all VSatellites .PARAMETER IncludeWorkers Include VSatellite workers in the output .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Get-VcSatellite -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' vsatelliteId : e2d60b61-9a8c-4a3a-985c-92498bd1fc77 encryptionKey : o4aFaJUTtCydprvb1jN15hIa5vJqFpQ1ZiY= encryptionKeyAlgorithm : ED25519 companyId : e2d60b61-9a8c-4a3a-985c-92498bd1fc77 productEntitlements : {ANY} environmentId : ea2c3f80-658b-11eb-9bbd-338917ba2e36 pairingCodeId : e2d60b61-9a8c-4a3a-985c-92498bd1fc77 name : VSatellite Hub 0001 edgeType : HUB edgeStatus : ACTIVE clientId : e2d60b61-9a8c-4a3a-985c-92498bd1fc77 modificationDate : 6/15/2023 11:48:40 AM address : 1.2.3.4 deploymentDate : 6/15/2023 11:44:14 AM lastSeenOnDate : 8/13/2023 8:00:06 AM reconciliationFailed : False encryptionKeyId : mwU4oTesrjyGBln0pZ8FkRfhek0UtvighIw= encryptionKeyDeploymentDate : 6/15/2023 11:48:40 AM kubernetesVersion : v1.23.6+k3s1 integrationServicesCount : 0 Get a single object by ID .EXAMPLE Get-VcSatellite -ID 'My Awesome App' Get a single object by name. The name is case sensitive. .EXAMPLE Get-VcSatellite -All Get all VSatellites .EXAMPLE Get-VcSatellite -All -IncludeWorkers Get all VSatellites and include workers #> [CmdletBinding()] [Alias('Get-VaasSatellite')] param ( [Parameter(Mandatory, ParameterSetName = 'ID', ValueFromPipelineByPropertyName)] [Alias('vsatelliteId', 'ID')] [string] $VSatellite, [Parameter(Mandatory, ParameterSetName = 'All')] [switch] $All, [Parameter()] [switch] $IncludeWorkers, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allKeys = Invoke-VenafiRestMethod -UriLeaf 'edgeencryptionkeys' | Select-Object -ExpandProperty encryptionKeys } process { if ( $PSCmdlet.ParameterSetName -eq 'All' ) { $response = Invoke-VenafiRestMethod -UriLeaf 'edgeinstances' | Select-Object -ExpandProperty edgeinstances } else { # if the value is a guid, we can look up the vsat directly otherwise get all and search by name if ( Test-IsGuid($VSatellite) ) { $guid = [guid] $VSatellite $response = Invoke-VenafiRestMethod -UriLeaf ('edgeinstances/{0}' -f $guid.ToString()) } else { $response = Invoke-VenafiRestMethod -UriLeaf 'edgeinstances' | Select-Object -ExpandProperty edgeinstances | Where-Object { $_.name -eq $VSatellite } } } if ( -not $response ) { return } $out = $response | Select-Object @{'n' = 'vsatelliteId'; 'e' = { $_.Id } }, @{ 'n' = 'encryptionKey' 'e' = { $thisId = $_.encryptionKeyId ($allKeys | Where-Object { $_.id -eq $thisId }).key } }, @{ 'n' = 'encryptionKeyAlgorithm' 'e' = { $thisId = $_.encryptionKeyId ($allKeys | Where-Object { $_.id -eq $thisId }).KeyAlgorithm } }, * -ExcludeProperty Id if ( $IncludeWorkers ) { $out | Select-Object *, @{ 'n' = 'workers' 'e' = { Get-VcSatelliteWorker -VSatellite $_.vsatelliteId } } } else { $out } } } #EndRegion './Public/Get-VcSatellite.ps1' 138 #Region './Public/Get-VcSatelliteWorker.ps1' -1 function Get-VcSatelliteWorker { <# .SYNOPSIS Get VSatellite worker info .DESCRIPTION Get 1 or more VSatellite workers, the bridge between a vsatellite and ADCS .PARAMETER ID VSatellite worker ID .PARAMETER All Get all VSatellite workers .PARAMETER VSatellite Get workers associated with a specific VSatellite, specify either VSatellite ID or name .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID, VSatelliteID .EXAMPLE Get-VcSatelliteWorker -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' vsatelliteWorkerId : 5df78790-a155-11ef-a5a8-8f3513444123 companyId : 09b24f81-b22b-11ea-91f3-123456789098 host : 1.2.3.4 port : 555 pairingCode : a138fe58-ecb6-45a4-a9af-01dd4d5c74d1 pairingPublicKey : FDww6Nml8IUFQZ56j9LRweEWoCQ1732wi/ZfZaQj+s0= status : DRAFT Get a single worker by ID .EXAMPLE Get-VcSatelliteWorker -All Get all VSatellite workers .EXAMPLE Get-VcSatelliteWorker -VSatellite 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f3' Get all workers associated with a specific VSatellite #> [CmdletBinding()] param ( [Parameter(Mandatory, ParameterSetName = 'ID', ValueFromPipelineByPropertyName)] [Alias('vsatelliteWorkerId')] [guid] $ID, [Parameter(Mandatory, ParameterSetName = 'All')] [switch] $All, [Parameter(Mandatory, ParameterSetName = 'VSatellite', ValueFromPipelineByPropertyName)] [Alias('vsatelliteId')] [string] $VSatellite, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { switch ($PSCmdlet.ParameterSetName) { 'All' { $response = Invoke-VenafiRestMethod -UriLeaf 'edgeworkers' | Select-Object -ExpandProperty edgeWorkers } 'ID' { $guid = [guid] $ID $response = Invoke-VenafiRestMethod -UriLeaf ('edgeworkers/{0}' -f $guid.ToString()) } 'VSatellite' { # limit workers retrieved by the vsat they are associated with # if the value is a guid, we can look up the vsat directly otherwise get all and search by name $vsatelliteId = if ( Test-IsGuid($VSatellite) ) { $guid = [guid] $VSatellite $guid.ToString() } else { Invoke-VenafiRestMethod -UriLeaf 'edgeinstances' | Select-Object -ExpandProperty edgeInstances | Where-Object { $_.name -eq $VSatellite } | Select-Object -ExpandProperty id } $response = Invoke-VenafiRestMethod -UriLeaf 'edgeworkers' -Body @{'edgeInstanceId' = $vsatelliteID } | Select-Object -ExpandProperty edgeWorkers } } if ( -not $response ) { return } $response | Select-Object ` @{'n' = 'vsatelliteWorkerId'; 'e' = { $_.Id } }, @{'n' = 'vsatelliteId'; 'e' = { $_.edgeInstanceId } }, * -ExcludeProperty Id, edgeInstanceId } } #EndRegion './Public/Get-VcSatelliteWorker.ps1' 109 #Region './Public/Get-VcTag.ps1' -1 function Get-VcTag { <# .SYNOPSIS Get tags from TLSPC .DESCRIPTION Get 1 or all tags. Tag values will be provided. .PARAMETER Name Tag name .PARAMETER All Get all tags .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided.key can also provided. .INPUTS Name .EXAMPLE Get-VcTag -Name 'MyTag' Get a single tag .EXAMPLE Get-VcTag -All Get all tags #> [CmdletBinding()] param ( [Parameter(Mandatory, ParameterSetName = 'ID', ValueFromPipelineByPropertyName, Position = 0)] [string] $Name, [Parameter(Mandatory, ParameterSetName = 'All')] [switch] $All, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { if ( $PSCmdlet.ParameterSetName -eq 'All' ) { $values = Invoke-VenafiRestMethod -UriLeaf 'tags/values' | Select-Object -ExpandProperty values $response = Invoke-VenafiRestMethod -UriLeaf 'tags' | Select-Object -ExpandProperty tags } else { $response = Invoke-VenafiRestMethod -UriLeaf "tags/$Name" $values = Invoke-VenafiRestMethod -UriLeaf "tags/$Name/values" | Select-Object -ExpandProperty values } if ( $response ) { $response | Select-Object @{'n' = 'tagId'; 'e' = { $_.key } }, @{ 'n' = 'value' 'e' = { $thisId = $_.id , @(($values | Where-Object { $_.tagId -eq $thisId }).value) } }, * -ExcludeProperty id, name } } } #EndRegion './Public/Get-VcTag.ps1' 77 #Region './Public/Get-VcTeam.ps1' -1 function Get-VcTeam { <# .SYNOPSIS Get team info .DESCRIPTION Get info on teams including members and owners. Retrieve info on 1 or all. .PARAMETER Team Team name or guid. .PARAMETER All Get all teams .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .OUTPUTS PSCustomObject .EXAMPLE Get-VcTeam -Team 'MyTeam' Get info for a team by name .EXAMPLE Get-VcTeam -Team 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' Get info for a team by id .EXAMPLE Get-VcTeam -All Get info for all teams .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html?urls.primaryName=account-service#/Teams/get_2 .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html?urls.primaryName=account-service#/Teams/get_1 #> [CmdletBinding()] param ( [Parameter(Mandatory, ParameterSetName = 'ID', ValueFromPipelineByPropertyName, Position = 0)] [Alias('teamID', 'owningTeam', 'owningTeams', 'owningTeamId', 'ownedTeams', 'ID')] [string[]] $Team, [Parameter(Mandatory, ParameterSetName = 'All')] [switch] $All, [Parameter()] [Alias('Key', 'AccessToken')] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { if ( $PSCmdlet.ParameterSetName -eq 'All' ) { $response = Invoke-VenafiRestMethod -UriLeaf 'teams' } else { if ( Test-IsGuid -InputObject $Team ) { $guid = [guid] $Team $response = Invoke-VenafiRestMethod -UriLeaf ('teams/{0}' -f $guid.ToString()) } else { # assume team name $response = Invoke-VenafiRestMethod -UriLeaf 'teams' | Where-Object { $_.name -eq $Team } } } if ( $response.PSObject.Properties.Name -contains 'teams' ) { $response | Select-Object -ExpandProperty teams | ConvertTo-VcTeam } else { $response | ConvertTo-VcTeam } } } #EndRegion './Public/Get-VcTeam.ps1' 94 #Region './Public/Get-VcUser.ps1' -1 function Get-VcUser { <# .SYNOPSIS Get user details .DESCRIPTION Returns user information for TLSPC. .PARAMETER User Either be the user id (guid) or username which is the email address. .PARAMETER Me Returns details of the authenticated/current user .PARAMETER All Return a complete list of local users. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .OUTPUTS PSCustomObject username userId companyId firstname lastname emailAddress userType userAccountType userStatus systemRoles productRoles localLoginDisabled hasPassword firstLoginDate creationDate ownedTeams memberedTeams .EXAMPLE Get-VcUser -ID 9e9db8d6-234a-409c-8299-e3b81ce2f916 Get user details from an id .EXAMPLE Get-VcUser -ID 'greg.brownstein@venafi.com' Get user details from a username .EXAMPLE Get-VcUser -Me Get user details for authenticated/current user .EXAMPLE Get-VcUser -All Get all users .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html?urls.primaryName=account-service#/Users/users_getByUsername #> [CmdletBinding(DefaultParameterSetName = 'Id')] [Alias('Get-VcIdentity')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = "Parameter is used")] param ( [Parameter(Mandatory, ParameterSetName = 'Id', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Alias('userId', 'owningUser', 'owningUsers', 'owningUserId', 'ID')] [String] $User, [Parameter(Mandatory, ParameterSetName = 'Me')] [Switch] $Me, [Parameter(Mandatory, ParameterSetName = 'All')] [Switch] $All, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { Switch ($PsCmdlet.ParameterSetName) { 'Id' { # can search by user id (guid) or username if ( Test-IsGuid($User) ) { $guid = [guid] $User $response = Invoke-VenafiRestMethod -UriLeaf ('users/{0}' -f $guid.ToString()) } else { $response = Invoke-VenafiRestMethod -UriLeaf "users/username/$User" | Select-Object -ExpandProperty users } } 'Me' { $response = Invoke-VenafiRestMethod -UriLeaf 'useraccounts' | Select-Object -ExpandProperty user } 'All' { $response = Invoke-VenafiRestMethod -UriLeaf 'users' | Select-Object -ExpandProperty users } } $response | Select-Object @{'n' = 'userId'; 'e' = { $_.id } }, * -ExcludeProperty id } } #EndRegion './Public/Get-VcUser.ps1' 120 #Region './Public/Get-VcWebhook.ps1' -1 function Get-VcWebhook { <# .SYNOPSIS Get webhook info .DESCRIPTION Get 1 or all webhooks .PARAMETER ID Webhook ID or name .PARAMETER All Get all webhooks .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Get-VcWebhook -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' | ConvertTo-Json { "webhookId": "a7ddd210-0a39-11ee-8763-134b935c90aa", "name": "ServiceNow-expiry, "properties": { "connectorKind": "WEBHOOK", "filter": { "filterType": "EXPIRATION", "applicationIds": [] }, "target": { "type": "generic", "connection": { "secret": "MySecret", "url": "https://instance.service-now.com/api/company/endpoint" } } } } Get a single object by ID .EXAMPLE Get-VcWebhook -ID 'My Webhook' Get a single object by name. The name is case sensitive. .EXAMPLE Get-VcWebhook -All Get all webhooks #> [CmdletBinding(DefaultParameterSetName = 'ID')] param ( [Parameter(Mandatory, ParameterSetName = 'ID', ValueFromPipelineByPropertyName, Position = 0)] [Alias('webhookId')] [string] $ID, [Parameter(Mandatory, ParameterSetName = 'All')] [switch] $All, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { $params = @{ UriLeaf = 'connectors' } if ( $PSBoundParameters.ContainsKey('ID') ) { if ( Test-IsGuid($ID) ) { $params.UriLeaf += "/{0}" -f $ID } else { # search by name return Get-VcWebhook -All | Where-Object { $_.name -eq $ID } } } $response = Invoke-VenafiRestMethod @params if ( $response.PSObject.Properties.Name -contains 'connectors' ) { $connectors = $response | Select-Object -ExpandProperty 'connectors' } else { $connectors = $response } if ( $connectors ) { $connectors | Select-Object @{ 'n' = 'webhookId'; 'e' = { $_.Id } }, * -ExcludeProperty Id } } } #EndRegion './Public/Get-VcWebhook.ps1' 108 #Region './Public/Get-VdcAttribute.ps1' -1 function Get-VdcAttribute { <# .SYNOPSIS Get object attributes as well as policy attributes .DESCRIPTION Retrieves object attributes as well as policy attributes. You can either retrieve all attributes or individual ones. Policy folders can have attributes as well as policies which apply to the resultant objects. For more info on policies and how they are different than attributes, see https://docs.venafi.com/Docs/current/TopNav/Content/Policies/c_policies_tpp.php. Attribute properties are directly added to the return object for ease of access. To retrieve attribute configuration, see the Attribute property of the return object which has properties Name, PolicyPath, Locked, Value, Overridden (when applicable), and CustomFieldGuid (when applicable). .PARAMETER Path Path to the object. If the root is excluded, \ved\policy will be prepended. .PARAMETER Attribute Only retrieve the value/values for this attribute. For custom fields, you can provide either the Guid or Label. .PARAMETER Class Get policy attributes instead of object attributes. Provide the class name to retrieve the value(s) for. If unsure of the class name, add the value through the TLSPDC UI and go to Support->Policy Attributes to find it. The Attribute property of the return object will contain the path where the policy was applied. .PARAMETER All Get all object attributes or policy attributes. This will perform 3 steps, get the object type, enumerate the attributes for the object type, and get all the values. Note, expect this to take longer than usual given the number of api calls. .PARAMETER NoLookup Default functionality is to perform lookup of attributes names to see if they are custom fields or not. If they are, pass along the guid instead of name required by the api for custom fields. To override this behavior and use the attribute name as is, add -NoLookup. Useful if, on the off chance, you have a custom field with the same name as a built-in attribute. Can also be used with -All and the output will contain guids instead of looked up names. .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can be provided directly. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS PSCustomObject .EXAMPLE Get-VdcAttribute -Path '\VED\Policy\certificates\test.gdb.com' -Attribute 'State' Name : test.gdb.com Path : \VED\Policy\Certificates\test.gdb.com TypeName : X509 Server Certificate Guid : b7a7221b-e038-41d9-9d49-d7f45c1ca128 Attribute : {@{Name=State; PolicyPath=\VED\Policy\Certificates; Locked=False; Value=UT; Overridden=False}} State : UT Retrieve a single attribute .EXAMPLE Get-VdcAttribute -Path '\VED\Policy\certificates\test.gdb.com' -Attribute 'State', 'Driver Name' Name : test.gdb.com Path : \VED\Policy\Certificates\test.gdb.com TypeName : X509 Server Certificate Guid : b7a7221b-e038-41d9-9d49-d7f45c1ca128 Attribute : {@{Name=State; PolicyPath=\VED\Policy\Certificates; Locked=False; Value=UT; Overridden=False}, @{Name=Driver Name; PolicyPath=; Locked=False; Value=appx509certificate; Overridden=False}} State : UT Driver Name : appx509certificate Retrieve multiple attributes .EXAMPLE Get-VdcAttribute -Path '\VED\Policy\certificates\test.gdb.com' -Attribute 'ServiceNow Assignment Group' Name : test.gdb.com Path : \VED\Policy\Certificates\test.gdb.com TypeName : X509 Server Certificate Guid : b7a7221b-e038-41d9-9d49-d7f45c1ca128 Attribute : {@{CustomFieldGuid={7f214dec-9878-495f-a96c-57291f0d42da}; Name=ServiceNow Assignment Group; PolicyPath=; Locked=False; Value=Venafi Management; Overridden=False}} ServiceNow Assignment Group : Venafi Management Retrieve a custom field attribute. You can specify either the guid or custom field label name. .EXAMPLE Get-VdcAttribute -Path '\VED\Policy\mydevice\myapp' -Attribute 'Certificate' -NoLookup Name : myapp Path : \VED\Policy\mydevice\myapp TypeName : Adaptable App Guid : b7a7221b-e038-41d9-9d49-d7f45c1ca128 Attribute : {@{Name=Certificate; PolicyPath=; Value=\VED\Policy\mycert; Locked=False; Overridden=False}} Certificate : \VED\Policy\mycert Retrieve an attribute value without custom value lookup .EXAMPLE Get-VdcAttribute -Path '\VED\Policy\certificates\test.gdb.com' -All Name : test.gdb.com Path : \VED\Policy\Certificates\test.gdb.com TypeName : X509 Server Certificate Guid : b7a7221b-e038-41d9-9d49-d7f45c1ca128 Attribute : {@{CustomFieldGuid={7f214dec-9878-495f-a96c-57291f0d42da}; Name=ServiceNow Assignment Group; PolicyPath=; Locked=False; Value=Venafi Management; Overridden=False}…} ServiceNow Assignment Group : Venafi Management City : Salt Lake City Consumers : {\VED\Policy\Installations\Agentless\US Zone\mydevice\myapp} Contact : local:{b1c77034-c099-4a5c-9911-9e26007817da} Country : US Created By : WebAdmin Driver Name : appx509certificate ... Retrieve all attributes applicable to this object .EXAMPLE Get-VdcAttribute -Path 'Certificates' -Class 'X509 Certificate' -Attribute 'State' Name : Certificates Path : \VED\Policy\Certificates TypeName : Policy Guid : a91fc152-a9fb-4b49-a7ca-7014b14d73eb Attribute : {@{Name=State; PolicyPath=\VED\Policy\Certificates; Locked=False; Value=UT}} ClassName : X509 Certificate State : UT Retrieve a policy attribute value for the specified policy folder and class. \ved\policy will be prepended to the path. .EXAMPLE Get-VdcAttribute -Path '\VED\Policy\certificates' -Class 'X509 Certificate' -All Name : Certificates Path : \VED\Policy\Certificates TypeName : Policy Guid : a91fc152-a9fb-4b49-a7ca-7014b14d73eb Attribute : {@{CustomFieldGuid={7f214dec-9878-495f-a96c-57291f0d42da}; Name=ServiceNow Assignment Group; PolicyPath=; Locked=False; Value=}…} ClassName : X509 Certificate Approver : local:{b1c77034-c099-4a5c-9911-9e26007817da} Key Algorithm : RSA Key Bit Strength : 2048 Managed By : Aperture Management Type : Enrollment Network Validation Disabled : 1 Notification Disabled : 0 ... Retrieve all policy attributes for the specified policy folder and class .EXAMPLE Find-VdcCertificate | Get-VdcAttribute -Attribute Contact,'Managed By','Want Renewal' -ThrottleLimit 50 Name : mycert Path : \VED\Policy\mycert TypeName : X509 Server Certificate Guid : 1dc31664-a9f3-407c-8bf3-1e388e90a114 Attribute : {@{Name=Contact; PolicyPath=\VED\Policy; Value=local:{ab2a2e32-b412-4466-b5b5-484478a99bf4}; Locked=False; Overridden=False}, @{Name=Managed By; PolicyPath=\VED\Policy; Value=Aperture; Locked=True; Overridden=False}, @{Name=Want Renewal; PolicyPath=\VED\Policy; Value=0; Locked=True; Overridden=False}} Contact : local:{ab2a2e32-b412-4466-b5b5-484478a99bf4} Managed By : Aperture Want Renewal : 0 ... Retrieve specific attributes for all certificates. Throttle the number of threads to 50, the default is 100 .LINK https://docs.venafi.com/Docs/currentSDK/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-findpolicy.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-readeffectivepolicy.php #> [CmdletBinding(DefaultParameterSetName = 'Attribute')] [Alias('Get-TppAttribute')] param ( [Parameter(Mandatory, ParameterSetName = 'Attribute', ValueFromPipeline, ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'All', ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('DN')] [String] $Path, [Parameter(Mandatory, ParameterSetName = 'Attribute')] [ValidateNotNullOrEmpty()] [String[]] $Attribute, [ValidateNotNullOrEmpty()] [Alias('ClassName', 'PolicyClass')] [string] $Class, [Parameter(Mandatory, ParameterSetName = 'All')] [switch] $All, [Parameter()] [switch] $NoLookup, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Write-Verbose $PSCmdlet.ParameterSetName Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $newAttribute = $Attribute if ( $All -and $Class ) { Write-Verbose "Getting attributes for class $Class" $newAttribute = Get-VdcClassAttribute -ClassName $Class | Select-Object -ExpandProperty Name -Unique } $allItems = [System.Collections.Generic.List[hashtable]]::new() } process { if ( $PSCmdlet.ParameterSetName -eq 'Attribute') { # small number of attributes so focus parallelism on the objects # this is done in the end block $allItems.Add( @{ Path = $Path | ConvertTo-VdcFullPath Attribute = $newAttribute } ) return } # All parameter set below # with -All there is a large list of attributes so focus parallelism on them $newPath = $Path | ConvertTo-VdcFullPath $thisObject = Get-VdcObject -Path $newPath if ( $Class -and ($thisObject.TypeName -ne 'Policy') ) { Write-Error ('You are attempting to retrieve policy attributes, but {0} is not a policy path' -f $newPath) return } $return = [pscustomobject] @{ Name = $thisObject.Name Path = $newPath TypeName = $thisObject.TypeName Guid = $thisObject.Guid Attribute = [pscustomobject] @{} } if ( $Class ) { $return | Add-Member @{ 'ClassName' = $Class } } else { # get list of attributes for this specific class $newAttribute = Get-VdcClassAttribute -ClassName $thisObject.TypeName | Select-Object -ExpandProperty Name -Unique } $allAttributes = Invoke-VenafiParallel -InputObject $newAttribute -ScriptBlock { $thisAttribute = $PSItem if ( $using:Class ) { $params = @{ Method = 'Post' Body = @{ Class = $using:Class ObjectDN = $using:newPath AttributeName = $thisAttribute } UriLeaf = 'config/FindPolicy' } } else { $params = @{ Method = 'Post' Body = @{ ObjectDN = $using:newPath AttributeName = $thisAttribute } UriLeaf = 'config/ReadEffectivePolicy' } } Write-Verbose "Processing attribute $thisAttribute" $customField = $null if ( -not $using:NoLookup ) { # parallel lookup $customField = $VenafiSession.CustomField | Where-Object { $_.Label -eq $thisAttribute -or $_.Guid -eq $thisAttribute } if ( -not $customField ) { # sequential lookup $customField = $VenafiSessionNested.CustomField | Where-Object { $_.Label -eq $thisAttribute -or $_.Guid -eq $thisAttribute } } if ( $customField ) { $params.Body.AttributeName = $customField.Guid } } # disabled is a special kind of attribute which cannot be read with readeffectivepolicy if ( $params.Body.AttributeName -eq 'Disabled' ) { $oldUri = $params.UriLeaf $params.UriLeaf = 'Config/Read' $response = Invoke-VenafiRestMethod @params $params.UriLeaf = $oldUri } else { $response = Invoke-VenafiRestMethod @params } if ( $response.Error ) { if ( $response.Result -in 601, 112) { Write-Error "'$thisAttribute' is not a valid attribute for $newPath. Are you looking for a policy attribute? If so, add -Class." continue } elseif ( $response.Result -eq 102) { # attribute is valid, but value not set # we're ok with this one } else { Write-Error $response.Error continue } } $valueOut = $null if ( $response.Values ) { switch ($response.Values.GetType().Name) { 'Object[]' { switch ($response.Values.Count) { 1 { $valueOut = $response.Values[0] } Default { $valueOut = $response.Values } } } Default { $valueOut = $response.Values } } } $newProp = [pscustomobject] @{} # only add attributes to the root of the response object if they have a value # always add them to .Attribute ($newProp) if ( $CustomField ) { $newProp | Add-Member @{ Name = $customField.Label 'CustomFieldGuid' = $customField.Guid } if ( $valueOut ) { $using:return | Add-Member @{ $customField.Label = $valueOut } } } else { if ( $valueOut ) { $using:return | Add-Member @{ $thisAttribute = $valueOut } -ErrorAction SilentlyContinue } $newProp | Add-Member @{ Name = $thisAttribute } } $newProp | Add-Member @{ Value = $valueOut PolicyPath = $response.PolicyDN Locked = $response.Locked } # overridden not available at policy level if ( -not $PSBoundParameters.ContainsKey('Class') ) { $newProp | Add-Member @{ 'Overridden' = $response.Overridden } } $newProp } -ThrottleLimit $ThrottleLimit -ProgressTitle 'Getting attributes' $return.Attribute = @($allAttributes) $return } end { # parallelism is focused on the objects, not attributes # used when -Attribute is provided, not -All Invoke-VenafiParallel -InputObject $allItems -ScriptBlock { $newPath = $PSItem.Path $thisObject = Get-VdcObject -Path $newPath if ( $using:Class -and ($thisObject.TypeName -ne 'Policy') ) { Write-Error ('You are attempting to retrieve policy attributes, but {0} is not a policy path' -f $newPath) return } $newAttribute = $PSItem.Attribute $return = [pscustomobject] @{ Name = $thisObject.Name Path = $newPath TypeName = $thisObject.TypeName Guid = $thisObject.Guid Attribute = [pscustomobject] @{} } if ( $using:Class ) { $return | Add-Member @{ 'ClassName' = $using:Class } $params = @{ Method = 'Post' Body = @{ Class = $using:Class ObjectDN = $newPath } UriLeaf = 'config/FindPolicy' } } else { $params = @{ Method = 'Post' Body = @{ ObjectDN = $newPath } UriLeaf = 'config/ReadEffectivePolicy' } } $allAttributes = foreach ($thisAttribute in $newAttribute) { Write-Verbose "Processing attribute $thisAttribute" $params.Body.AttributeName = $thisAttribute $customField = $null if ( -not $using:NoLookup ) { # parallel lookup $customField = $VenafiSession.CustomField | Where-Object { $_.Label -eq $thisAttribute -or $_.Guid -eq $thisAttribute } if ( -not $customField ) { # sequential lookup $customField = $VenafiSessionNested.CustomField | Where-Object { $_.Label -eq $thisAttribute -or $_.Guid -eq $thisAttribute } } if ( $customField ) { $params.Body.AttributeName = $customField.Guid } } # disabled is a special kind of attribute which cannot be read with readeffectivepolicy if ( $params.Body.AttributeName -eq 'Disabled' ) { $oldUri = $params.UriLeaf $params.UriLeaf = 'Config/Read' $response = Invoke-VenafiRestMethod @params $params.UriLeaf = $oldUri } else { $response = Invoke-VenafiRestMethod @params } if ( $response.Error ) { if ( $response.Result -in 601, 112) { Write-Error "'$thisAttribute' is not a valid attribute for $newPath. Are you looking for a policy attribute? If so, add -Class." continue } elseif ( $response.Result -eq 102) { # attribute is valid, but value not set # we're ok with this one } else { Write-Error $response.Error continue } } $valueOut = $null if ( $response.Values ) { switch ($response.Values.GetType().Name) { 'Object[]' { switch ($response.Values.Count) { 1 { $valueOut = $response.Values[0] } Default { $valueOut = $response.Values } } } Default { $valueOut = $response.Values } } } $newProp = [pscustomobject] @{} # only add attributes to the root of the response object if they have a value # always add them to .Attribute ($newProp) if ( $CustomField ) { $newProp | Add-Member @{ Name = $customField.Label 'CustomFieldGuid' = $customField.Guid } if ( $valueOut ) { $return | Add-Member @{ $customField.Label = $valueOut } } } else { if ( $valueOut ) { $return | Add-Member @{ $thisAttribute = $valueOut } -ErrorAction SilentlyContinue } $newProp | Add-Member @{ Name = $thisAttribute } } $newProp | Add-Member @{ Value = $valueOut PolicyPath = $response.PolicyDN Locked = $response.Locked } # overridden not available at policy level if ( -not $using:Class ) { $newProp | Add-Member @{ 'Overridden' = $response.Overridden } } $newProp } $return.Attribute = @($allAttributes) $return } -ThrottleLimit $ThrottleLimit -ProgressTitle 'Getting attributes' } } #EndRegion './Public/Get-VdcAttribute.ps1' 572 #Region './Public/Get-VdcCertificate.ps1' -1 function Get-VdcCertificate { <# .SYNOPSIS Get certificate information .DESCRIPTION Get certificate information, either all available to the api key provided or by id or zone. .PARAMETER ID Certificate identifier by either path or guid. \ved\policy will be automatically applied if a full path isn't provided. .PARAMETER IncludePreviousVersions Returns details about previous (historical) versions of a certificate. This option will add a property named PreviousVersions to the returned object. .PARAMETER ExcludeExpired Omits expired versions of the previous (historical) versions of a certificate. Can only be used with the IncludePreviousVersions parameter. .PARAMETER ExcludeRevoked Omits revoked versions of the previous (historical) versions of a certificate. Can only be used with the IncludePreviousVersions parameter. .PARAMETER All Retrieve all certificates .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS ID .OUTPUTS PSCustomObject .EXAMPLE Get-VdcCertificate -ID '\ved\policy\mycert.com' Get certificate info for a specific cert .EXAMPLE Get-VdcCertificate -All Get certificate info for all certs .EXAMPLE Get-VdcCertificate -ID '\ved\policy\mycert.com' -IncludePreviousVersions Get certificate info for a specific cert, including historical versions of the certificate. .EXAMPLE Get-VdcCertificate -ID '\ved\policy\mycert.com' -IncludeTppPreviousVersions -ExcludeRevoked -ExcludeExpired Get certificate info for a specific cert, including historical versions of the certificate that are not revoked or expired. .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-Certificates-guid.php #> [CmdletBinding(DefaultParameterSetName = 'Id')] param ( [Parameter(ParameterSetName = 'Id', Mandatory, ValueFromPipelineByPropertyName, Position = 0)] [Parameter(ParameterSetName = 'IdWithPrevious', Mandatory, ValueFromPipelineByPropertyName, Position = 0)] [Alias('Guid', 'Path')] [string] $ID, [Parameter(Mandatory, ParameterSetName = 'All')] [Parameter(Mandatory, ParameterSetName = 'AllWithPrevious')] [Switch] $All, [Parameter(Mandatory, ParameterSetName = 'IdWithPrevious')] [Parameter(Mandatory, ParameterSetName = 'AllWithPrevious')] [switch] $IncludePreviousVersions, [Parameter(ParameterSetName = 'IdWithPrevious')] [Parameter(ParameterSetName = 'AllWithPrevious')] [switch] $ExcludeExpired, [Parameter(ParameterSetName = 'IdWithPrevious')] [Parameter(ParameterSetName = 'AllWithPrevious')] [switch] $ExcludeRevoked, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $certs = [System.Collections.Generic.List[string]]::new() } process { if ( $All ) { return (Find-VdcCertificate -Path '\ved' -Recursive | Get-VdcCertificate -IncludePreviousVersions:$IncludePreviousVersions -ExcludeExpired:$ExcludeExpired -ExcludeRevoked:$ExcludeRevoked) } if ( Test-IsGuid($ID) ) { $certs.Add($ID) } else { $certs.Add((ConvertTo-VdcFullPath -Path $ID)) } } end { Invoke-VenafiParallel -InputObject $certs -ScriptBlock { if ( $PSItem -like '\ved*' ) { # a path was provided, get the guid $thisGuid = ConvertTo-VdcGuid -Path $PSItem } else { $thisGuid = ([guid] $PSItem).ToString() } $params = @{ UriLeaf = [System.Web.HttpUtility]::UrlEncode("certificates/{$thisGuid}") } $response = Invoke-VenafiRestMethod @params if ( $IncludePreviousVersions ) { $params.UriLeaf = [System.Web.HttpUtility]::UrlEncode("certificates/{$thisGuid}/PreviousVersions") $params.Body = @{} if ( $ExcludeExpired.IsPresent ) { $params.Body.ExcludeExpired = $ExcludeExpired } if ( $ExcludeRevoked.IsPresent ) { $params.Body.ExcludeRevoked = $ExcludeRevoked } $previous = Invoke-VenafiRestMethod @params if ( $previous.PreviousVersions ) { $previous.PreviousVersions.CertificateDetails | ForEach-Object { $_.StoreAdded = [datetime]$_.StoreAdded $_.ValidFrom = [datetime]$_.ValidFrom $_.ValidTo = [datetime]$_.ValidTo } } $response | Add-Member @{'PreviousVersions' = $previous.PreviousVersions } } # object transformations # put in try/catch in case datetime conversion fails try { $response.CertificateDetails.StoreAdded = [datetime]$response.CertificateDetails.StoreAdded $response.CertificateDetails.ValidFrom = [datetime]$response.CertificateDetails.ValidFrom $response.CertificateDetails.ValidTo = [datetime]$response.CertificateDetails.ValidTo } catch { } $selectProps = @{ Property = @{ n = 'Name' e = { $_.Name } }, @{ n = 'TypeName' e = { $_.SchemaClass } }, @{ n = 'Path' e = { $_.DN } }, @{ n = 'Guid' e = { [guid]$_.guid } }, @{ n = 'ParentPath' e = { $_.ParentDN } }, @{ n = 'CreatedOn' e = { [datetime]$_.CreatedOn } }, '*' ExcludeProperty = 'DN', 'GUID', 'ParentDn', 'SchemaClass', 'Name', 'CreatedOn' } $response | Select-Object @selectProps } -ThrottleLimit $ThrottleLimit -ProgressTitle 'Getting certificates' } } #EndRegion './Public/Get-VdcCertificate.ps1' 208 #Region './Public/Get-VdcClassAttribute.ps1' -1 function Get-VdcClassAttribute { <# .SYNOPSIS List all attributes for a specified class .DESCRIPTION List all attributes for a specified class, helpful for validation or to pass to Get-VdcAttribute .EXAMPLE Get-VdcClassAttribute -ClassName 'X509 Server Certificate' Get all attributes for the specified class .INPUTS ClassName .OUTPUTS PSCustomObject #> [CmdletBinding()] [Alias('Get-TppClassAttribute')] param ( [Parameter(Mandatory, ValueFromPipeline)] [string] $ClassName, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $allAttributes = [System.Collections.Generic.List[object]]::new() } process { Write-Verbose "Processing $ClassName" $params = @{ VenafiSession = $VenafiSession Method = 'Post' UriLeaf = 'configschema/class' Body = @{ 'Class' = $ClassName } } $classDetails = Invoke-VenafiRestMethod @params | Select-Object -ExpandProperty 'ClassDefinition' if ($ClassName -ne 'Top') { $recurseAttribs = $classDetails.SuperClassNames | Get-VdcClassAttribute foreach ($item in $recurseAttribs) { $allAttributes.Add($item) } } foreach ($item in ($classDetails.OptionalNames)) { $allAttributes.Add( [pscustomobject] @{ 'Name' = $item 'Class' = $classDetails.Name } ) } } end { $allAttributes | Sort-Object -Property 'Name', 'Class' -Unique } } #EndRegion './Public/Get-VdcClassAttribute.ps1' 68 #Region './Public/Get-VdcCredential.ps1' -1 function Get-VdcCredential { <# .SYNOPSIS Get credential details .DESCRIPTION Get credential details. Object returned will depend on the credential type. .PARAMETER Path The full path to the credential object .PARAMETER IncludeDetail Include metadata associated with the credential in addition to the credential itself .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS Password/UsernamePassword Credential - PSCredential Certificate Credential - X509Certificate2 with IncludeDetail - PSCustomObject .EXAMPLE Get-VdcCredential -Path '\VED\Policy\MySecureCred' Get a credential .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Get-VdcCredential/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Get-VdcCredential.ps1 #> [CmdletBinding()] [Alias('Get-TppCredential')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'Generating cred from api call response data')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [String] $Path, [Parameter()] [switch] $IncludeDetail, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ VenafiSession = $VenafiSession Method = 'Post' UriLeaf = 'Credentials/Retrieve' Body = @{} } } process { $params.Body.CredentialPath = $Path $response = Invoke-VenafiRestMethod @params if ( -not $response ) { continue } switch ($response.Classname) { 'Password Credential' { $pw = $response.Values | Where-Object { $_.Name -eq 'Password' } | Select-Object -ExpandProperty Value $cred = New-Object System.Management.Automation.PSCredential((Split-Path -Path $Path -Leaf), ($pw | ConvertTo-SecureString -AsPlainText -Force)) } 'Username Password Credential' { $un = $response.Values | Where-Object { $_.Name -eq 'Username' } | Select-Object -ExpandProperty Value $pw = $response.Values | Where-Object { $_.Name -eq 'Password' } | Select-Object -ExpandProperty Value $cred = New-Object System.Management.Automation.PSCredential($un, ($pw | ConvertTo-SecureString -AsPlainText -Force)) } 'Certificate Credential' { $cert = $response.Values | Where-Object { $_.Name -eq 'Certificate' } | Select-Object -ExpandProperty Value $pw = $response.Values | Where-Object { $_.Name -eq 'Password' } | Select-Object -ExpandProperty Value $cred = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new([system.convert]::FromBase64String($cert), $pw) } Default { throw "Credential type '$_' is not supported yet. Submit an enhancement request." } } if ( $IncludeDetail ) { $return = $response | Select-Object -Property @{ 'n' = 'Type' 'e' = { $_.Classname } }, *, @{ 'n' = 'Credential' 'e' = { $cred } }, @{ 'n' = 'Contact' 'e' = { Get-VdcIdentity -Id $_.Contact.PrefixedUniversal } } -ExcludeProperty Classname, FriendlyName, Values, Result, Contact if ( $response.Classname -eq 'Certificate Credential' ) { $return | Add-Member @{ 'CertificateLinkPath' = ($response.Values | Where-Object { $_.Name -eq 'Certificate DN' }).Value 'Password' = if ($pw) { ConvertTo-SecureString -String $pw -AsPlainText -Force } } } $return } else { $cred } } } #EndRegion './Public/Get-VdcCredential.ps1' 140 #Region './Public/Get-VdcCustomField.ps1' -1 function Get-VdcCustomField { <# .SYNOPSIS Get custom field details .DESCRIPTION Get details about custom fields .PARAMETER Class Class to get details on .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS None .OUTPUTS Query returns a PSCustomObject with the following properties: Items AllowedValues Classes ConfigAttribute DN DefaultValues Guid Label Mandatory Name Policyable RenderHidden RenderReadOnly Single Type Locked Result .EXAMPLE Get-VdcCustomField -Class 'X509 Certificate' Get custom fields for certificates .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Get-VdcCustomField/ .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Metadata-GetItemsForClass.php .NOTES All custom fields are retrieved upon inital connect to the server and a property of VenafiSession #> [CmdletBinding()] [Alias('Get-TppCustomField')] param ( [Parameter(Mandatory, ValueFromPipeline)] [string] $Class, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { $params = @{ Method = 'Post' UriLeaf = 'Metadata/GetItemsForClass' Body = @{ 'ConfigClass' = $Class } } $response = Invoke-VenafiRestMethod @params if ( $response.Result -eq [TppMetadataResult]::Success ) { [PSCustomObject] @{ Items = $response.Items Locked = $response.Locked } } else { throw $response.Error } } } #EndRegion './Public/Get-VdcCustomField.ps1' 91 #Region './Public/Get-VdcEngineFolder.ps1' -1 function Get-VdcEngineFolder { <# .SYNOPSIS Get TLSPDC folder/engine assignments .DESCRIPTION When the input is a policy folder, retrieves an array of assigned TLSPDC processing engines. When the input is a TLSPDC engine, retrieves an array of assigned policy folders. If there are no matching assignments, nothing will be returned. .PARAMETER ID The full DN path or Guid to a TLSPDC processing engine or policy folder. .PARAMETER All Get all engine/folder assignments .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided, but this requires an environment variable VDC_SERVER to be set. .INPUTS ID .OUTPUTS PSCustomObject .EXAMPLE Get-VdcEngineFolder -Path '\VED\Engines\MYVENSERVER' Get an array of policy folders assigned to the TLSPDC processing engine 'MYVENSERVER'. .EXAMPLE Get-VdcEngineFolder -Path '\VED\Policy\Certificates\Web Team' Get an array of TLSPDC processing engines assigned to the policy folder '\VED\Policy\Certificates\Web Team'. .EXAMPLE [guid]'866e1d59-d5d2-482a-b9e6-7bb657e0f416' | Get-VdcEngineFolder When the GUID is assigned to a TLSPDC processing engine, returns an array of assigned policy folders. When the GUID is assigned to a policy folder, returns an array of assigned TLSPDC processing engines. Otherwise nothing will be returned. .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Get-VdcEngineFolder/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Get-VdcEngineFolder.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-ProcessingEngines-Engine-eguid.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-ProcessingEngines-Folder-fguid.php #> [CmdletBinding(DefaultParameterSetName = 'ID')] param ( [Parameter(Mandatory, ParameterSetName = 'ID', ValueFromPipelineByPropertyName, Position = 0)] [ValidateNotNullOrEmpty()] [Alias('EngineGuid', 'Guid', 'EnginePath', 'Path')] [String] $ID, [Parameter(ParameterSetName = 'All', Mandatory)] [switch] $All, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { if ( $PSCmdlet.ParameterSetName -eq 'All' ) { Invoke-VenafiRestMethod -UriLeaf 'ProcessingEngines/' | Select-Object -ExpandProperty Engines | Get-VdcEngineFolder } else { if ( [guid]::TryParse($ID, $([ref][guid]::Empty)) ) { $thisObject = Get-VdcObject -Guid $ID } else { $thisObject = Get-VdcObject -Path $ID } $thisObjectGuid = '{{{0}}}' -f $thisObject.Guid if ( $thisObject.TypeName -eq 'Venafi Platform' ) { # engine $response = Invoke-VenafiRestMethod -UriLeaf "ProcessingEngines/Engine/$thisObjectGuid" | Select-Object -ExpandProperty Folders $response | Where-Object { $_.FolderGuid -ne $thisObjectGuid } | Select-Object FolderName, @{ 'n' = 'FolderPath'; 'e' = { $_.FolderDN } }, @{ 'n' = 'FolderGuid'; 'e' = { $_.FolderGuid.Trim('{}') } }, @{ 'n' = 'EngineName'; 'e' = { $thisObject.Name } }, @{ 'n' = 'EnginePath'; 'e' = { $thisObject.Path } }, @{ 'n' = 'EngineGuid'; 'e' = { $thisObject.Guid } } } elseif ( $thisObject.TypeName -eq 'Policy' ) { # policy folder $response = Invoke-VenafiRestMethod -UriLeaf "ProcessingEngines/Folder/$thisObjectGuid" | Select-Object -ExpandProperty Engines $response | Select-Object EngineName, @{ 'n' = 'EnginePath'; 'e' = { $_.EngineDN } }, @{ 'n' = 'EngineGuid'; 'e' = { $_.EngineGuid.Trim('{}') } }, @{ 'n' = 'FolderName'; 'e' = { $thisObject.Name } }, @{ 'n' = 'FolderPath'; 'e' = { $thisObject.Path } }, @{ 'n' = 'FolderGuid'; 'e' = { $thisObject.Guid } } } else { throw ('Unsupported object type, {0}' -f $thisObject.TypeName) } } } } #EndRegion './Public/Get-VdcEngineFolder.ps1' 122 #Region './Public/Get-VdcIdentity.ps1' -1 function Get-VdcIdentity { <# .SYNOPSIS Get user and group details .DESCRIPTION Returns user/group information for TLSPDC This returns individual identity, group identity, or distribution groups from a local or non-local provider such as Active Directory. .PARAMETER ID Provide the guid or prefixed universal id. To search, use Find-VdcIdentity. .PARAMETER IncludeAssociated Include all associated identity groups and folders. .PARAMETER IncludeMembers Include all individual members if the ID is a group. .PARAMETER Me Returns the identity of the authenticated/current user .PARAMETER All Return a complete list of local users. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS ID .OUTPUTS PSCustomObject Name ID Path FullName Associated (if -IncludeAssociated provided) Members (if -IncludeMembers provided) .EXAMPLE Get-VdcIdentity -ID 'AD+myprov:asdfgadsf9g87df98g7d9f8g7' Get identity details from an id .EXAMPLE Get-VdcIdentity -ID 'AD+myprov:asdfgadsf9g87df98g7d9f8g7' -IncludeMembers Get identity details including members if the identity is a group .EXAMPLE Get-VdcIdentity -ID 'AD+myprov:asdfgadsf9g87df98g7d9f8g7' -IncludeAssociated Get identity details including associated groups/folders .EXAMPLE Get-VdcIdentity -Me Get identity details for authenticated/current user .EXAMPLE Get-VdcIdentity -All Get all user and group info .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Identity-Validate.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-Identity-Self.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Identity-GetAssociatedEntries.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Identity-GetMembers.php #> [CmdletBinding(DefaultParameterSetName = 'Id')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = "Parameter is used")] [Alias('Get-TppIdentity')] param ( [Parameter(Mandatory, ParameterSetName = 'Id', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Alias('Guid', 'FullName')] [String] $ID, [Parameter(Mandatory, ParameterSetName = 'Me')] [Switch] $Me, [Parameter(Mandatory, ParameterSetName = 'All')] [Switch] $All, [Parameter(ParameterSetName = 'Id')] [Parameter(ParameterSetName = 'All')] [Switch] $IncludeAssociated, [Parameter(ParameterSetName = 'Id')] [Parameter(ParameterSetName = 'All')] [Switch] $IncludeMembers, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { Switch ($PsCmdlet.ParameterSetName) { 'Id' { $params = @{ Method = 'Post' UriLeaf = 'Identity/Validate' Body = @{'ID' = @{ } } } if ( Test-VdcIdentityFormat -ID $ID -Format 'Universal' ) { $params.Body.ID.PrefixedUniversal = $ID } elseif ( Test-VdcIdentityFormat -ID $ID -Format 'Name' ) { $params.Body.ID.PrefixedName = $ID } elseif ( [guid]::TryParse($ID, $([ref][guid]::Empty)) ) { $guid = [guid] $ID $params.Body.ID.PrefixedUniversal = 'local:{{{0}}}' -f $guid.ToString() } else { Write-Error "'$ID' is not a valid identity" return } $response = Invoke-VenafiRestMethod @params | Select-Object -ExpandProperty ID if ( $IncludeAssociated ) { $assocParams = $params.Clone() $assocParams.UriLeaf = 'Identity/GetAssociatedEntries' $associated = Invoke-VenafiRestMethod @assocParams $response | Add-Member @{ 'Associated' = $null } $response.Associated = $associated.Identities | ConvertTo-VdcIdentity } if ( $IncludeMembers ) { $response | Add-Member @{ 'Members' = $null } if ( $response.IsGroup ) { $assocParams = $params.Clone() $assocParams.UriLeaf = 'Identity/GetMembers' $assocParams.Body.ResolveNested = "1" $members = Invoke-VenafiRestMethod @assocParams $response.Members = $members.Identities | ConvertTo-VdcIdentity } } $idOut = $response } 'Me' { $response = Invoke-VenafiRestMethod -UriLeaf 'Identity/Self' $idOut = $response.Identities | Select-Object -First 1 } 'All' { # no built-in api for this, get group objects and then get details Find-VdcObject -Path '\VED\Identity' -Class 'User', 'Group' | Get-VdcIdentity -IncludeAssociated:$IncludeAssociated.IsPresent -IncludeMembers:$IncludeMembers.IsPresent } } if ( $idOut ) { $idOut | ConvertTo-VdcIdentity } } } #EndRegion './Public/Get-VdcIdentity.ps1' 180 #Region './Public/Get-VdcIdentityAttribute.ps1' -1 function Get-VdcIdentityAttribute { <# .SYNOPSIS Get attribute values for TLSPDC identity objects .DESCRIPTION Get attribute values for TLSPDC identity objects. .PARAMETER ID The id that represents the user or group. Use Find-VdcIdentity to get the id. .PARAMETER Attribute Retrieve identity attribute values for the users and groups. Common user attributes include Group Membership, Name, Internet Email Address, Given Name, and Surname. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS ID .OUTPUTS PSCustomObject with the properties Identity and Attribute .EXAMPLE Get-VdcIdentityAttribute -IdentityId 'AD+blah:{1234567890olikujyhtgrfedwsqa}' Get basic attributes .EXAMPLE Get-VdcIdentityAttribute -IdentityId 'AD+blah:{1234567890olikujyhtgrfedwsqa}' -Attribute 'Surname' Get specific attribute for user .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Identity-Validate.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Identity-Readattribute.php #> [CmdletBinding()] [Alias('Get-TppIdentityAttribute')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('PrefixedUniversalId', 'Contact', 'IdentityId')] [string[]] $ID, [Parameter()] [string[]] $Attribute, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' UriLeaf = 'Identity/Validate' Body = @{ 'ID' = @{ PrefixedUniversal = 'placeholder' } } } if ( $PSBoundParameters.ContainsKey('Attribute') ) { $params.UriLeaf = 'Identity/ReadAttribute' $params.Body.Add('AttributeName', 'placeholder') } } process { foreach ( $thisId in $ID ) { $params.Body.ID.PrefixedUniversal = $thisId if ( $PSBoundParameters.ContainsKey('Attribute') ) { $attribHash = @{ } foreach ( $thisAttribute in $Attribute ) { $params.Body.AttributeName = $thisAttribute $response = Invoke-VenafiRestMethod @params if ( $response.Attributes ) { $attribHash.$thisAttribute = $response.Attributes[0] } } $attribsOut = [PSCustomObject] $attribHash } else { $response = Invoke-VenafiRestMethod @params $attribsOut = $response.Id } [PSCustomObject] @{ ID = $thisId Attributes = $attribsOut } } } } #EndRegion './Public/Get-VdcIdentityAttribute.ps1' 115 #Region './Public/Get-VdcObject.ps1' -1 function Get-VdcObject { <# .SYNOPSIS Get object information .DESCRIPTION Return object information by either path or guid. This will return a TppObject which can be used with many other functions. .PARAMETER Path The full path to the object. \ved\policy will be automatically applied if a full path isn't provided. .PARAMETER Guid Guid of the object .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path, Guid .OUTPUTS PSCustomObject .EXAMPLE Get-VdcObject -Path '\VED\Policy\My object' Get an object by path .EXAMPLE [guid]'dab22152-0a81-4fb8-a8da-8c5e3d07c3f1' | Get-VdcObject Get an object by guid .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Get-VdcObject/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Get-VdcObject.ps1 #> [CmdletBinding()] [Alias('Get-TppObject', 'gvdo')] param ( [Parameter(Mandatory, ParameterSetName = 'ByPath', ValueFromPipeline, ValueFromPipelineByPropertyName, Position = 0)] [ValidateNotNullOrEmpty()] [Alias('DN')] [String[]] $Path, [Parameter(Mandatory, ParameterSetName = 'ByGuid', ValueFromPipeline)] [ValidateNotNullOrEmpty()] [Alias('ObjectGuid')] [guid[]] $Guid, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { if ( $PSCmdLet.ParameterSetName -eq 'ByPath' ) { $Path | ConvertTo-VdcFullPath | ForEach-Object { ConvertTo-VdcObject -Path $_ } } else { $Guid | ForEach-Object { ConvertTo-VdcObject -Guid $_ } } } } #EndRegion './Public/Get-VdcObject.ps1' 82 #Region './Public/Get-VdcPermission.ps1' -1 function Get-VdcPermission { <# .SYNOPSIS Get permissions for TLSPDC objects .DESCRIPTION Get permissions for users and groups on any object. The effective permissions will be retrieved by default, but inherited/explicit permissions can optionally be retrieved. You can retrieve all permissions for an object or for a specific user/group. .PARAMETER InputObject TppObject representing an object in TLSPDC, eg. from Find-VdcObject or Get-VdcObject .PARAMETER Path Full path to an object .PARAMETER Guid Guid representing a unique object .PARAMETER IdentityId Specifying this optional parameter will only return objects that have permissions assigned to this id. You can use Find-VdcIdentity to search for identities. .PARAMETER Explicit Get explicit (direct) and implicit (inherited) permissions instead of effective. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS InputObject, Path, Guid, IdentityId .OUTPUTS PSCustomObject with the following properties: Path Guid Name TypeName IdentityId IdentityPath, may be null if the identity has been deleted IdentityName, may be null if the identity has been deleted EffectivePermissions (if Explicit switch is not used) ExplicitPermissions (if Explicit switch is used) ImplicitPermissions (if Explicit switch is used) .EXAMPLE Get-VdcPermission -Path '\VED\Policy\barron' Path : \ved\policy\barron Guid : 3ba630d8-acf0-4b52-9824-df549cb33b82 Name : barron TypeName : Policy IdentityId : AD+domain:410aaf10ea816c4d823e9e05b1ad055d IdentityPath : CN=Greg Brownstein,OU=Users,OU=Enterprise Administration,DC=domain,DC=net IdentityName : greg EffectivePermissions : TppPermission Get all assigned effective permissions for users/groups on a specific policy folder .EXAMPLE Get-VdcObject -Path '\VED\Policy\My folder' | Get-VdcPermission Get all assigned effective permissions for users/groups on a specific policy folder by piping the object .EXAMPLE Get-VdcObject -Path '\VED\Policy\barron' | Get-VdcPermission -Explicit Path : \ved\policy\barron Guid : 3ba630d8-acf0-4b52-9824-df549cb33b82 Name : barron TypeName : Policy IdentityId : AD+domain:410aaf10ea816c4d823e9e05b1ad055d IdentityPath : CN=Greg Brownstein,OU=Users,OU=Enterprise Administration,DC=domain,DC=net IdentityName : greg ExplicitPermissions : TppPermission ImplicitPermissions : TppPermission Get explicit and implicit permissions for users/groups on a specific policy folder .EXAMPLE Find-VdcObject -Path '\VED' -Recursive | Get-VdcPermission -IdentityId 'AD+myprov:jasdf87s9dfsdfhkashfg78f7' Find assigned permissions for a specific user across all objects .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Get-VdcPermission/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Get-VdcPermission.ps1 .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Get-VdcIdentityAttribute.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-Permissions-object-guid.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-Permissions-object-guid-external.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-Permissions-object-guid-local.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-Permissions-object-guid-principal.php #> [CmdletBinding(DefaultParameterSetName = 'ByObject')] [Alias('Get-TppPermission')] param ( [Parameter(Mandatory, ParameterSetName = 'ByObject', ValueFromPipeline)] [pscustomobject] $InputObject, [Parameter(Mandatory, ParameterSetName = 'ByPath', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('DN')] [String[]] $Path, [Parameter(Mandatory, ParameterSetName = 'ByGuid', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Alias('ObjectGuid')] [guid[]] $Guid, [Parameter(ValueFromPipelineByPropertyName)] [ValidateScript( { if ( $_ | Test-VdcIdentityFormat ) { $true } else { throw "'$_' is not a valid Identity format. See https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-IdentityInformation.php." } })] [Alias('PrefixedUniversalId', 'ID')] [string[]] $IdentityId, [Parameter()] [Alias('ExplicitImplicit')] [switch] $Explicit, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Get' UriLeaf = 'placeholder' } } process { switch ( $PsCmdLet.ParameterSetName) { 'ByObject' { $newInputObject = $InputObject } 'ByPath' { $newInputObject = $Path } 'ByGuid' { $newInputObject = $Guid } Default { throw ('Unknown parameterset {0}' -f $PsCmdLet.ParameterSetName) } } foreach ( $thisInputObject in $newInputObject ) { switch ( $PsCmdLet.ParameterSetName) { 'ByObject' { $thisTppObject = $thisInputObject } Default { $thisTppObject = $thisInputObject | ConvertTo-VdcObject } } $uriBase = ('Permissions/Object/{{{0}}}' -f $thisTppObject.Guid ) $params.UriLeaf = $uriBase try { # get list of identities permissioned to this object $identities = Invoke-VenafiRestMethod @params } catch { Write-Error ('Couldn''t obtain list of permissions for {0}. {1}' -f $thisTppObject.Path, $_ | Out-String) continue } # limit to specific identities provided if ( $PSBoundParameters.ContainsKey('IdentityId') ) { $identities = $identities | Where-Object { $_ -in $IdentityId } } foreach ( $thisId in $identities ) { Write-Verbose ('Path: {0}, Id: {1}' -f $thisTppObject.Path, $thisId) $params.UriLeaf = $uriBase if ( $thisId.StartsWith('local:') ) { # format of local is local:universalId $type, $id = $thisId.Split(':') $params.UriLeaf += "/local/$id" } else { # external source, eg. AD, LDAP # format is type+name:universalId $type, $name, $id = $thisId -Split { $_ -in '+', ':' } $params.UriLeaf += "/$type/$name/$id" } if ( -not $Explicit.IsPresent ) { $params.UriLeaf += '/Effective' } $thisReturnObject = [PSCustomObject] @{ Path = $thisTppObject.Path Guid = $thisTppObject.Guid Name = $thisTppObject.Name TypeName = $thisTppObject.TypeName IdentityId = $thisId IdentityPath = $null IdentityName = $null } if ( $Explicit ) { $thisReturnObject | Add-Member @{ ExplicitPermissions = $null ImplicitPermissions = $null } } else { $thisReturnObject | Add-Member @{ EffectivePermissions = $null } } try { $response = Invoke-VenafiRestMethod @params if ( $Explicit ) { $thisReturnObject.ExplicitPermissions = [TppPermission] $response.ExplicitPermissions $thisReturnObject.ImplicitPermissions = [TppPermission] $response.ImplicitPermissions } else { $thisReturnObject.EffectivePermissions = [TppPermission] $response.EffectivePermissions } $attribParams = @{ IdentityId = $thisReturnObject.IdentityId } $attribResponse = Get-VdcIdentityAttribute @attribParams -ErrorAction SilentlyContinue if ( $attribResponse ) { $thisReturnObject.IdentityPath = $attribResponse.Attributes.FullName $thisReturnObject.IdentityName = $attribResponse.Attributes.Name } } catch { # handle edge case where permissions had been set, but the user account has been deleted # this way we can return the permissions that are set, just not the identity attributes, eg. name if ( $_ -like '*Unable to verify principal*' ) { if ( $Explicit ) { # this will only return explicit permissions, not effective $notFoundParams = @{ Method = 'Post' UriLeaf = 'permissions/getpermissions' Body = @{ ObjectDN = $thisTppObject.Path Principal = $thisID } } $notFoundResponse = invoke-venafirestmethod @notFoundParams if ( $notFoundResponse.Permissions ) { $thisReturnObject.ExplicitPermissions = [TppPermission]$notFoundResponse.Permissions } } } else { Write-Error ('Unable to retrieve permissions. Path: {0}, Id: {1}, Error: {2}' -f $thisTppObject.Path, $thisId, $_) } } $thisReturnObject } } } } #EndRegion './Public/Get-VdcPermission.ps1' 317 #Region './Public/Get-VdcSystemStatus.ps1' -1 function Get-VdcSystemStatus { <# .SYNOPSIS Get the TLSPDC system status .DESCRIPTION Returns service module statuses for Trust Protection Platform, Log Server, and Trust Protection Platform services that run on Microsoft Internet Information Services (IIS) .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS none .OUTPUTS PSCustomObject .EXAMPLE Get-VdcSystemStatus Get the status .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Get-VdcSystemStatus/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Get-VdcSystemStatus.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-SystemStatus.php #> [CmdletBinding()] [Alias('Get-TppSystemStatus')] param ( [Parameter()] [psobject] $VenafiSession ) Write-Warning "Possible bug with Venafi TLSPDC API causing this to fail" Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Get' UriLeaf = 'SystemStatus/' } try { Invoke-VenafiRestMethod @params } catch { Throw ("Getting the system status failed with the following error: {0}. Ensure you have read rights to the engine root." -f $_) } } #EndRegion './Public/Get-VdcSystemStatus.ps1' 60 #Region './Public/Get-VdcTeam.ps1' -1 function Get-VdcTeam { <# .SYNOPSIS Get team info .DESCRIPTION Get info for a team including members and owners. .PARAMETER ID Team ID in local prefixed universal format. You can find the team/group ID with Find-VdcIdentity. .PARAMETER All Provide this switch to get all teams .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS ID .OUTPUTS PSCustomObject .EXAMPLE Get-VdcTeam -ID 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e6}' Get info for a TLSPDC team .EXAMPLE Find-VdcIdentity -Name MyTeamName | Get-VdcTeam Search for a team and then get details .EXAMPLE Get-VdcTeam -All Get info for all teams .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-Teams-prefix-universal.php #> [CmdletBinding(DefaultParameterSetName = 'ID')] [Alias('Get-TppTeam')] param ( [Parameter(Mandatory, ParameterSetName = 'ID', ValueFromPipelineByPropertyName, Position = 0)] [Alias('PrefixedUniversal', 'Guid', 'PrefixedName')] [string] $ID, [Parameter(Mandatory, ParameterSetName = 'All')] [switch] $All, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { if ( $PSCmdlet.ParameterSetName -eq 'All' ) { # no built-in api for this, get group objects and then get details Find-VdcObject -Path '\VED\Identity' -Class 'Group' | Where-Object { $_.Name -ne 'Everyone' } | Get-VdcTeam } else { # not only does -match set $matches, but -notmatch does as well if ( $ID -notmatch '(?im)^(local:)?\{?([0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12})\}?$' ) { Write-Error "'$ID' is not the proper format for a Team. Format should either be a guid or local:{guid}." return } $params = @{ UriLeaf = ('Teams/local/{{{0}}}' -f $matches[2]) } try { $response = Invoke-VenafiRestMethod @params $out = [pscustomobject] ($response.ID | ConvertTo-VdcIdentity) $out | Add-Member @{ Members = $response.Members | ConvertTo-VdcIdentity Owners = $response.Owners | ConvertTo-VdcIdentity } $out } catch { # handle known errors where the local group is not actually a team if ( $_.ErrorDetails.Message -like '*Failed to read the team identity;*' ) { Write-Verbose "$ID looks to be a local group and not a Team. The server responded with $_" } else { Write-Error "$ID : $_" } } } } } #EndRegion './Public/Get-VdcTeam.ps1' 109 #Region './Public/Get-VdcVersion.ps1' -1 function Get-VdcVersion { <# .SYNOPSIS Get the TLSPDC version .DESCRIPTION Returns the TLSPDC version .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS none .OUTPUTS Version .EXAMPLE Get-VdcVersion Get the version .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Get-VdcVersion/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Get-VdcVersion.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-SystemStatusVersion.php #> [CmdletBinding()] [Alias('Get-TppVersion')] [OutputType([System.Version])] param ( [Parameter()] [psobject] $VenafiSession ) Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Get' UriLeaf = 'SystemStatus/Version' } try { [Version]((Invoke-VenafiRestMethod @params).Version) } catch { Throw ("Getting the version failed with the following error: {0}. This feature was introduced in v18.3." -f $_) } } #EndRegion './Public/Get-VdcVersion.ps1' 60 #Region './Public/Get-VdcWorkflowTicket.ps1' -1 function Get-VdcWorkflowTicket { <# .SYNOPSIS Get workflow ticket .DESCRIPTION Get details about workflow tickets associated with a certificate. .PARAMETER InputObject TppObject which represents a certificate object .PARAMETER Path Path to the certificate .PARAMETER Guid Certificate guid .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS InputObject, Path, or Guid .OUTPUTS PSCustomObject with the following properties: Guid: Workflow ticket Guid ApprovalExplanation: The explanation supplied by the approver. ApprovalFrom: The identity to be contacted for approving. ApprovalReason: The administrator-defined reason text. Approvers: An array of workflow approvers for the certificate. Blocking: The object that the ticket is associated with. Created: The date/time the ticket was created. IssuedDueTo: The workflow object that caused this ticket to be created (if any). Result: Integer result code indicating success 1 or failure. For more information, see Workflow result codes. Status: The status of the ticket. Updated: The date/time that the ticket was last updated. .EXAMPLE Get-VdcWorkflowTicket -Path '\VED\policy\myapp.company.com' Get ticket details for 1 certificate .EXAMPLE $certs | Get-VdcWorkflowTicket Get ticket details for multiple certificates .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Get-VdcWorkflowTicket/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Get-VdcWorkflowTicket.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Workflow-ticket-enumerate.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Workflow-ticket-details.php #> [CmdletBinding()] [Alias('Get-TppWorkflowTicket')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('DN', 'CertificateDN')] [String[]] $Path, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' Write-Verbose ("Parameter set {0}" -f $PsCmdlet.ParameterSetName) } process { $ticketGuid = foreach ($thisDn in $Path) { $params = @{ Method = 'Post' UriLeaf = 'Workflow/Ticket/Enumerate' Body = @{ 'ObjectDN' = $thisDn } } $response = Invoke-VenafiRestMethod @params if ( $response ) { Write-Verbose ("Found {0} workflow tickets for certificate {1}" -f $response.GUIDs.count, $thisDn) $response.GUIDs } } foreach ($thisGuid in $ticketGuid) { $params = @{ Method = 'Post' UriLeaf = 'Workflow/Ticket/Details' Body = @{ 'GUID' = $thisGuid } } $response = Invoke-VenafiRestMethod @params if ( $response.Result -eq [TppWorkflowResult]::Success ) { $response | Add-Member @{ TicketGuid = [guid] $thisGuid } $response } else { throw ("Error getting ticket details, error is {0}" -f [enum]::GetName([TppWorkflowResult], $response.Result)) } } } } #EndRegion './Public/Get-VdcWorkflowTicket.ps1' 135 #Region './Public/Import-VcCertificate.ps1' -1 function Import-VcCertificate { <# .SYNOPSIS Import one or more certificates .DESCRIPTION Import one or more certificates and their private keys. Currently PKCS #8 and PKCS #12 (.pfx or .p12) are supported. .PARAMETER Path Path to a certificate file. Provide either this or -Data. .PARAMETER Data Contents of a certificate/key to import. Provide either this or -Path. .PARAMETER Pkcs8 Provided -Data is in PKCS #8 format .PARAMETER Pkcs12 Provided -Data is in PKCS #12 format .PARAMETER PrivateKeyPassword Password the private key was encrypted with .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 10. Applicable to PS v7+ only. 100 keystores will be imported at a time so it's less important to have a very high throttle limit. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .EXAMPLE Import-VcCertificate -CertificatePath c:\www.VenafiPS.com.pfx Import a certificate/key .EXAMPLE $p12 = Export-VdcCertificate -Path '\ved\policy\my.cert.com' -Pkcs12 -PrivateKeyPassword 'myPassw0rd!' $p12 | Import-VcCertificate -Pkcs12 -PrivateKeyPassword 'myPassw0rd!' -VenafiSession $vaas_key Export from TLSPDC and import into TLSPC. As $VenafiSession can only point to one platform at a time, in this case TLSPDC, the session needs to be overridden for the import. .EXAMPLE $p12 = Find-VdcCertificate -Path '\ved\policy\certs' -Recursive | Export-VdcCertificate -Pkcs12 -PrivateKeyPassword 'myPassw0rd!' $p12 | Import-VcCertificate -Pkcs12 -PrivateKeyPassword 'myPassw0rd!' -VenafiSession $vaas_key Bulk export from TLSPDC and import into TLSPC. As $VenafiSession can only point to one platform at a time, in this case TLSPDC, the session needs to be overridden for the import. .INPUTS Path, Data .LINK https://developer.venafi.com/tlsprotectcloud/reference/certificates_import .NOTES This function requires the use of sodium encryption. .net standard 2.0 or greater is required via PS Core (recommended) or supporting .net runtime. On Windows, the latest Visual C++ redist must be installed. See https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist. #> [CmdletBinding(DefaultParameterSetName = 'ByFile')] [Alias('Import-VaasCertificate')] param ( [Parameter(Mandatory, ParameterSetName = 'ByFile', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( -not (Test-Path -Path (Resolve-Path -Path $_) -PathType Leaf) ) { throw "'$_' is not a valid file path" } if ([System.IO.Path]::GetExtension((Resolve-Path -Path $_)) -notin '.pfx', '.p12') { throw "$_ is not a .p12 or .pfx file" } $true })] [Alias('FullName', 'CertificatePath')] [String] $Path, [Parameter(Mandatory, ParameterSetName = 'Pkcs12', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'Pkcs8', ValueFromPipelineByPropertyName)] [AllowNull()] [AllowEmptyString()] [Alias('CertificateData')] [String] $Data, [Parameter(Mandatory, ParameterSetName = 'Pkcs12')] [switch] $Pkcs12, [Parameter(Mandatory, ParameterSetName = 'Pkcs8')] [switch] $Pkcs8, [Parameter(Mandatory)] [ValidateScript( { if ( $_ -is [string] -or $_ -is [securestring] -or $_ -is [pscredential] ) { $true } else { throw 'Unsupported type. Provide either a String, SecureString, or PSCredential.' } } )] [psobject] $PrivateKeyPassword, [Parameter()] [int32] $ThrottleLimit = 10, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' Initialize-PSSodium $vSat = Get-VcData -Type 'VSatellite' -First if ( -not $vSat ) { throw 'No active VSatellites were found' } $pkPassString = $PrivateKeyPassword | ConvertTo-PlaintextString $allCerts = [System.Collections.Generic.List[hashtable]]::new() } process { if ( $PSBoundParameters.ContainsKey('Path') ) { $thisCertPath = Resolve-Path -Path $Path switch ([System.IO.Path]::GetExtension($thisCertPath)) { { $_ -in '.pfx', '.p12' } { $format = 'Pkcs12' } } if ($PSVersionTable.PSVersion.Major -lt 6) { $cert = Get-Content $thisCertPath -Encoding Byte } else { $cert = Get-Content $thisCertPath -AsByteStream } $allCerts.Add(@{ 'CertData' = [System.Convert]::ToBase64String($cert) 'Format' = $format } ) } else { # check if Data exists since we allow null/empty in case piping from another function and data is not there if ( $Data ) { $addMe = @{ 'Format' = $PSCmdlet.ParameterSetName } switch ($PSCmdlet.ParameterSetName) { 'Pkcs12' { $addMe.'CertData' = $Data -replace "`r|`n|-----BEGIN CERTIFICATE-----|-----END CERTIFICATE-----" } 'Pkcs8' { $splitData = Split-CertificateData -CertificateData $Data $addMe.CertPem = $splitData.CertPem if ( $splitData.KeyPem ) { $addMe.KeyPem = $splitData.KeyPem } } } $allCerts.Add($addMe) } } } end { $importList = [System.Collections.Generic.List[hashtable]]::new() $dekEncryptedPassword = ConvertTo-SodiumEncryptedString -Text $pkPassString -PublicKey $vSat.encryptionKey # rebuild invoke params as the payload can contain multiple keys at once # max 100 keys at a time for ($i = 0; $i -lt $allCerts.Count; $i += 100) { $params = @{ Method = 'post' UriRoot = 'outagedetection/v1' UriLeaf = 'certificates/imports' Body = @{ 'edgeInstanceId' = $vSat.vsatelliteId 'encryptionKeyId' = $vSat.encryptionKeyId } VenafiSession = $VenafiSession } $keystores = foreach ($thisCert in $allCerts[$i..($i + 99)]) { switch ($allCerts[$i].Format) { 'Pkcs12' { @{ 'pkcs12Keystore' = $thisCert.CertData 'dekEncryptedPassword' = $dekEncryptedPassword } } 'Pkcs8' { $thisKeystore = @{ 'certificate' = $thisCert.CertPem 'dekEncryptedPassword' = $dekEncryptedPassword } if ( $thisCert.KeyPem ) { $thisKeystore.passwordEncryptedPrivateKey = $thisCert.KeyPem } $thisKeystore } } } $params.Body.importInformation = @($keystores) $importList.Add($params) } $sb = { $params = $PSItem $requestResponse = Invoke-VenafiRestMethod @params do { Write-Verbose "checking job status for id $($requestResponse.id)" $jobResponse = invoke-VenafiRestMethod -UriRoot 'outagedetection/v1' -UriLeaf "certificates/imports/$($requestResponse.id)" Start-Sleep 2 } until ( $jobResponse.status -in 'COMPLETED', 'FAILED' ) if ( $jobResponse.status -eq 'COMPLETED' ) { $jobResponse.results } else { # importing only 1 keycert that fails does not give us any results to return to the user :( throw 'Import failed' } } $invokeParams = @{ InputObject = $importList ScriptBlock = $sb ThrottleLimit = $ThrottleLimit ProgressTitle = 'Importing certificates' } $invokeResponse = Invoke-VenafiParallel @invokeParams $invokeResponse | Select-Object -Property fingerprint, status, reason } } #EndRegion './Public/Import-VcCertificate.ps1' 257 #Region './Public/Import-VdcCertificate.ps1' -1 function Import-VdcCertificate { <# .SYNOPSIS Import one or more certificates .DESCRIPTION Import one or more certificates with or without private key. PowerShell v5 will execute sequentially and v7 will run in parallel. .PARAMETER Path Path to a certificate file. Provide either this or -Data. .PARAMETER Data Contents of a certificate to import. Provide either this or -Path. .PARAMETER PolicyPath Policy path to import the certificate to. \ved\policy is prepended if not provided. .PARAMETER EnrollmentAttribute A hashtable providing any CA attributes to store with the Certificate object, and then submit to the CA during enrollment .PARAMETER Name Optional name for the certificate object. If not provided, the certificate Common Name (CN) is used. The derived certificate object name references an existing object (of any class). If another certificate has the same CN, a dash (-) integer appends to the CertificateDN. For example, test.venafi.example - 3. If not provided and the CN is also missing, the name becomes the first Domain Name System (DNS) Subject Alternative Name (SAN). Finally, if none of the above are found, the serial number is used. .PARAMETER PrivateKey Private key data; requires a value for PrivateKeyPassword. For a PEM certificate, the private key is in either the RSA or PKCS#8 format. Do not provide for a PKCS#12 certificate as the private key is already included. .PARAMETER PrivateKeyPassword Password required if providing a private key. You can either provide a String, SecureString, or PSCredential. .PARAMETER Reconcile Controls certificate and corresponding private key replacement. By default, this function will import and replace the certificate regardless of whether a past, future, or same version of the certificate exists in Trust Protection Platform. By using this parameter, this function will import, but use newest. Only import the certificate when no Certificate object exists with a past, present, or current version of the imported certificate. If a match is found between the Certificate object and imported certificate, activate the certificate with the most current 'Valid From' date. Archive the unused certificate, even if it is the imported certificate, to the History tab. See https://docs.venafi.com/Docs/currentSDK/TopNav/Content/CA/c-CA-Import-ReconciliationRules-tpp.php for a flowchart of the reconciliation algorithm. .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER PassThru Return a TppObject representing the newly imported object. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .EXAMPLE Import-VdcCertificate -PolicyPath \ved\policy\mycerts -Path c:\www.VenafiPS.com.cer Import a certificate .EXAMPLE gci c:\certs | Import-VdcCertificate -PolicyPath \ved\policy\mycerts Import multiple certificates. On PS v7+, the certificates will be imported in parallel. .EXAMPLE Import-VdcCertificate -PolicyPath mycerts -Data $certData Import a certificate from data instead of a path .INPUTS Path, Data .OUTPUTS TppObject, if PassThru provided .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Certificates-Import.php #> [CmdletBinding(DefaultParameterSetName = 'ByFile')] [Alias('Import-TppCertificate')] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [String] $PolicyPath, [Parameter(Mandatory, ParameterSetName = 'ByFile', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'ByFileWithPrivateKey', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-Path ) { $true } else { throw "'$_' is not a valid path" } })] [Alias('FullName')] [String] $Path, [Parameter(Mandatory, ParameterSetName = 'ByData', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'ByDataWithPrivateKey', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [String] $Data, [Parameter()] [ValidateNotNullOrEmpty()] [String] $Name, [Parameter()] [ValidateNotNullOrEmpty()] [Hashtable] $EnrollmentAttribute, [Parameter(Mandatory, ParameterSetName = 'ByFileWithPrivateKey')] [Parameter(Mandatory, ParameterSetName = 'ByDataWithPrivateKey')] [ValidateNotNullOrEmpty()] [String] $PrivateKey, [Parameter(ParameterSetName = 'ByFile')] [Parameter(ParameterSetName = 'ByData')] [Parameter(Mandatory, ParameterSetName = 'ByFileWithPrivateKey')] [Parameter(Mandatory, ParameterSetName = 'ByDataWithPrivateKey')] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ -is [string] -or $_ -is [securestring] -or $_ -is [pscredential] ) { $true } else { throw 'Unsupported type. Provide either a String, SecureString, or PSCredential.' } } )] [psobject] $PrivateKeyPassword, [Parameter()] [switch] $Reconcile, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $allCerts = [System.Collections.Generic.List[hashtable]]::new() $params = @{ Method = 'Post' UriLeaf = 'certificates/import' Body = @{ PolicyDN = $PolicyPath | ConvertTo-VdcFullPath } } if ( $PSBoundParameters.ContainsKey('EnrollmentAttribute') ) { $updatedAttribute = @($EnrollmentAttribute.GetEnumerator() | ForEach-Object { @{'Name' = $_.name; 'Value' = $_.value } }) $params.Body.CASpecificAttributes = $updatedAttribute } if ( $Reconcile ) { $params.Body.Reconcile = 'true' } if ( $PSBoundParameters.ContainsKey('Name') ) { $params.Body.ObjectName = $Name } if ( $PSBoundParameters.ContainsKey('PrivateKeyPassword') ) { $params.Body.PrivateKeyPassword = $PrivateKeyPassword | ConvertTo-PlaintextString } if ( $PSBoundParameters.ContainsKey('PrivateKey') ) { $params.Body.PrivateKeyData = $PrivateKey } } process { $allCerts.Add( @{ InvokeParams = $params Data = $Data Path = $Path } ) } end { Invoke-VenafiParallel -InputObject $allCerts -ScriptBlock { $certData = $PSItem.Data if ( $PSItem.Path ) { if ((([System.IO.Path]::GetExtension($PSItem.Path)) -in '.pfx', '.p12') -and $PSItem.InvokeParams.Body.PrivateKeyPassword ) { # tpp won't accept a p12 and password so use this workaround to decrypt first $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($PSItem.Path, $PSItem.InvokeParams.Body.PrivateKeyPassword, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable) $certData = [System.Convert]::ToBase64String( $cert.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12)) } else { if ($PSVersionTable.PSVersion.Major -lt 6) { $cert = Get-Content $PSItem.Path -Encoding Byte } else { $cert = Get-Content $PSItem.Path -AsByteStream } $certData = [System.Convert]::ToBase64String($cert) } } $params = $PSItem.InvokeParams $params.Body.CertificateData = $certData try { $response = Invoke-VenafiRestMethod @params if ( $using:PassThru ) { Get-VdcObject -Guid $response.Guid.trim('{}') } } catch { Write-Error $_ } } -ThrottleLimit $ThrottleLimit -ProgressTitle 'Importing certificates' } } #EndRegion './Public/Import-VdcCertificate.ps1' 246 #Region './Public/Invoke-VcCertificateAction.ps1' -1 function Invoke-VcCertificateAction { <# .SYNOPSIS Perform an action against one or more certificates .DESCRIPTION One stop shop for certificate actions. You can Retire, Recover, Renew, Validate, Provision, or Delete. .PARAMETER ID ID of the certificate .PARAMETER Retire Retire a certificate .PARAMETER Recover Recover a retired certificate .PARAMETER Renew Requests immediate renewal for an existing certificate. If more than 1 application is associated with the certificate, provide -AdditionalParameters @{'Application'='application id'} to specify the id. Use -AdditionalParameters to provide additional parameters to the renewal request, see https://developer.venafi.com/tlsprotectcloud/reference/certificaterequests_create. .PARAMETER Validate Initiates SSL/TLS network validation .PARAMETER Delete Delete a certificate. As only retired certificates can be deleted, this will be performed first. .PARAMETER Provision Provision a certificate to all associated machine identities. .PARAMETER BatchSize How many certificates to retire per retirement API call. Useful to prevent API call timeouts. Defaults to 1000. Not applicable to Renew or Provision. .PARAMETER AdditionalParameters Additional items specific to the action being taken, if needed. See the api documentation for appropriate items, many are in the links in this help. .PARAMETER Force Force the operation under certain circumstances. - During a renewal, force choosing the first CN in the case of multiple CNs as only 1 is supported. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .OUTPUTS When using retire and recover, PSCustomObject with the following properties: CertificateID - Certificate uuid Success - A value of true indicates that the action was successful .EXAMPLE Invoke-VcCertificateAction -ID '3699b03e-ff62-4772-960d-82e53c34bf60' -Retire Perform an action against 1 certificate .EXAMPLE Invoke-VcCertificateAction -ID '3699b03e-ff62-4772-960d-82e53c34bf60' -Renew -AdditionalParameters @{'Application'='10f71a12-daf3-4737-b589-6a9dd1cc5a97'} Perform an action against 1 certificate with additional parameters. In this case we are renewing a certificate, but the certificate has multiple applications associated with it. Only one certificate and application combination can be renewed at a time so provide the specific application to be renewed. .EXAMPLE Find-VcCertificate -Version CURRENT -Issuer i1 | Invoke-VcCertificateAction -Renew -AdditionalParameters @{'certificateIssuingTemplateId'='10f71a12-daf3-4737-b589-6a9dd1cc5a97'} Find all current certificates issued by i1 and renew them with a different issuer. .EXAMPLE Invoke-VcCertificateAction -ID '3699b03e-ff62-4772-960d-82e53c34bf60' -Renew -Force Renewals can only support 1 CN assigned to a certificate. To force this function to renew and automatically select the first CN, use -Force. .EXAMPLE Invoke-VcCertificateAction -ID '3699b03e-ff62-4772-960d-82e53c34bf60' -Delete Delete a certificate. As only retired certificates can be deleted, it will be retired first. .EXAMPLE Invoke-VcCertificateAction -ID '3699b03e-ff62-4772-960d-82e53c34bf60' -Delete -Confirm:$false Perform an action bypassing the confirmation prompt. Only applicable to Delete. .EXAMPLE Find-VcObject -Type Certificate -Filter @('certificateStatus','eq','retired') | Invoke-VcCertificateAction -Delete -BatchSize 100 Search for all retired certificates and delete them using a non default batch size of 100 .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html?configUrl=%2Fv3%2Fapi-docs%2Fswagger-config&urls.primaryName=outagedetection-service .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html?urls.primaryName=outagedetection-service#/Certificates/certificateretirement_deleteCertificates .NOTES If performing a renewal and subjectCN has more than 1 value, only the first will be submitted with the renewal. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Params being used in paramset check, not by variable')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Alias('certificateID')] [guid] $ID, [Parameter(Mandatory, ParameterSetName = 'Retire')] [switch] $Retire, [Parameter(Mandatory, ParameterSetName = 'Recover')] [switch] $Recover, [Parameter(Mandatory, ParameterSetName = 'Renew')] [switch] $Renew, [Parameter(Mandatory, ParameterSetName = 'Validate')] [switch] $Validate, [Parameter(Mandatory, ParameterSetName = 'Delete')] [switch] $Delete, [Parameter(Mandatory, ParameterSetName = 'Provision')] [Parameter(ParameterSetName = 'Renew')] [switch] $Provision, [Parameter(ParameterSetName = 'Retire')] [Parameter(ParameterSetName = 'Recover')] [Parameter(ParameterSetName = 'Validate')] [Parameter(ParameterSetName = 'Delete')] [ValidateRange(1, 10000)] [int] $BatchSize = 1000, [Parameter(ParameterSetName = 'Renew')] [switch] $Force, [Parameter()] [hashtable] $AdditionalParameters, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $params = @{ Method = 'Post' UriRoot = 'outagedetection/v1' } $allCerts = [System.Collections.Generic.List[string]]::new() Write-Verbose $PSCmdlet.ParameterSetName } process { switch ($PSCmdlet.ParameterSetName) { 'Provision' { # get all machine identities associated with certificate # since ID is a guid, ensure its converted to string otherwise Find will think it's another filter $mi = Find-VcMachineIdentity -Filter @('certificateId', 'eq', $ID.ToString()) | Select-Object -ExpandProperty machineIdentityId if ( -not $mi ) { throw "No machine identities found for certificate ID $ID" } Write-Verbose ('Provisioning certificate ID {0} to machine identities {1}' -f $ID, ($mi -join ',')) $mi | Invoke-VcWorkflow -Workflow 'Provision' } 'Renew' { $out = [pscustomobject] @{ oldCertificateId = $ID success = $false error = $null } $thisCert = Get-VcCertificate -ID $ID # only current certs can be renewed if ( $thisCert.versionType -ne 'CURRENT' ) { $out.error = 'Only certificates with a versionType of CURRENT can be renewed' return $out } # multiple CN certs are supported by tlspc, but the request/renew api does not support it if ( $thisCert.subjectCN.count -gt 1 ) { if ( -not $Force ) { $out.error = 'The certificate you are trying to renew has more than 1 common name. You can either use -Force to automatically choose the first common name or utilize a different process to renew.' return $out } } switch (([array]$thisCert.application).count) { 1 { $thisAppId = $thisCert.application.applicationId } 0 { throw 'To renew a certificate at least one application must be assigned' } Default { # more than 1 application assigned if ( $AdditionalParameters.Application ) { $thisAppId = $AdditionalParameters.Application } else { $out.error = 'Multiple applications associated, {0}. Only 1 application can be renewed at a time. Rerun Invoke-VcCertificateAction and add ''-AdditionalParameter @{{''Application''=''application id''}}'' and provide the actual id you would like to renew.' -f (($thisCert.application | ForEach-Object { '{0} ({1})' -f $_.name, $_.applicationId }) -join ',') return $out } } } if ( -not $thisCert.certificateRequestId ) { $out.error = 'An initial certificate request could not be found. This is required to renew a certificate.' return $out } $thisCertRequest = Invoke-VenafiRestMethod -UriRoot 'outagedetection/v1' -UriLeaf "certificaterequests/$($thisCert.certificateRequestId)" $renewParams = @{ existingCertificateId = $ID certificateIssuingTemplateId = $thisCertRequest.certificateIssuingTemplateId applicationId = $thisAppId isVaaSGenerated = $true validityPeriod = $thisCertRequest.validityPeriod certificateOwnerUserId = $thisCertRequest.certificateOwnerUserId csrAttributes = @{} } switch ($thisCert.PSObject.Properties.Name) { 'subjectCN' { $renewParams.csrAttributes.commonName = $thisCert.subjectCN[0] } 'subjectO' { $renewParams.csrAttributes.organization = $thisCert.subjectO } 'subjectOU' { $renewParams.csrAttributes.organizationalUnits = $thisCert.subjectOU } 'subjectL' { $renewParams.csrAttributes.locality = $thisCert.subjectL } 'subjectST' { $renewParams.csrAttributes.state = $thisCert.subjectST } 'subjectC' { $renewParams.csrAttributes.country = $thisCert.subjectC } 'subjectAlternativeNamesByType' { $renewParams.csrAttributes.subjectAlternativeNamesByType = @{ 'dnsNames' = $thisCert.subjectAlternativeNamesByType.dNSName 'ipAddresses' = $thisCert.subjectAlternativeNamesByType.iPAddress 'rfc822Names' = $thisCert.subjectAlternativeNamesByType.rfc822Name 'uniformResourceIdentifiers' = $thisCert.subjectAlternativeNamesByType.uniformResourceIdentifier } } } if ( $AdditionalParameters ) { foreach ($key in $AdditionalParameters.Keys) { $renewParams[$key] = $AdditionalParameters[$key] } } try { $renewResponse = Invoke-VenafiRestMethod -Method 'Post' -UriRoot 'outagedetection/v1' -UriLeaf 'certificaterequests' -Body $renewParams -ErrorAction Stop $newCertId = $renewResponse.certificateRequests.certificateIds[0] $out | Add-Member @{ 'renew' = $renewResponse 'certificateID' = $newCertId } if ( $Provision ) { Write-Verbose "Renew was successful, now provisioning certificate ID $newCertId" # wait a few seconds for machine identities to be reassociated with the new certificate Start-Sleep -Seconds 5 $provisionResponse = Invoke-VcCertificateAction -ID $newCertId -Provision $out | Add-Member @{'provision' = $provisionResponse } } $out.success = $true } catch { $out.error = $_ } return $out } Default { $allCerts.Add($ID) } } } end { if ( $allCerts.Count -eq 0 ) { return } switch ($PSCmdLet.ParameterSetName) { 'Renew' { # handled in Process } 'Retire' { $params.UriLeaf = "certificates/retirement" if ( $AdditionalParameters ) { $params.Body += $AdditionalParameters } if ( $PSCmdlet.ShouldProcess('TLSPC', ('Retire {0} certificate(s) in batches of {1}' -f $allCerts.Count, $BatchSize) ) ) { $allCerts | Select-VenBatch -Activity 'Retiring certificates' -BatchSize $BatchSize -BatchType 'string' -TotalCount $allCerts.Count | ForEach-Object { $params.Body = @{"certificateIds" = $_ } $response = Invoke-VenafiRestMethod @params $processedIds = $response.certificates.id foreach ($certId in $_) { [pscustomobject] @{ CertificateID = $certId Success = ($certId -in $processedIds) } } } } } 'Recover' { $params.UriLeaf = "certificates/recovery" if ( $AdditionalParameters ) { $params.Body += $AdditionalParameters } if ( $PSCmdlet.ShouldProcess('TLSPC', ('Recover {0} certificate(s) in batches of {1}' -f $allCerts.Count, $BatchSize) ) ) { $allCerts | Select-VenBatch -Activity 'Recovering certificates' -BatchSize $BatchSize -BatchType 'string' -TotalCount $allCerts.Count | ForEach-Object { $params.Body = @{"certificateIds" = $_ } $response = Invoke-VenafiRestMethod @params $processedIds = $response.certificates.id foreach ($certId in $_) { [pscustomobject] @{ CertificateID = $certId Success = ($certId -in $processedIds) } } } } } 'Validate' { $params.UriLeaf = "certificates/validation" if ( $PSCmdlet.ShouldProcess('TLSPC', ('Validate {0} certificate(s) in batches of {1}' -f $allCerts.Count, $BatchSize) ) ) { $allCerts | Select-VenBatch -Activity 'Validating certificates' -BatchSize $BatchSize -BatchType 'string' -TotalCount $allCerts.Count | ForEach-Object { $params.Body = @{"certificateIds" = $_ } $null = Invoke-VenafiRestMethod @params } } } 'Delete' { $params.UriLeaf = "certificates/deletion" if ( $PSCmdlet.ShouldProcess('TLSPC', ('Delete {0} certificate(s) in batches of {1}' -f $allCerts.Count, $BatchSize) ) ) { $null = $allCerts | Invoke-VcCertificateAction -Retire -BatchSize $BatchSize -Confirm:$false $allCerts | Select-VenBatch -Activity 'Deleting certificates' -BatchSize $BatchSize -BatchType 'string' -TotalCount $allCerts.Count | ForEach-Object { $params.Body = @{"certificateIds" = $_ } $null = Invoke-VenafiRestMethod @params } } } } } } #EndRegion './Public/Invoke-VcCertificateAction.ps1' 387 #Region './Public/Invoke-VcWorkflow.ps1' -1 function Invoke-VcWorkflow { <# .SYNOPSIS Start a machine or machine identity workflow .DESCRIPTION Start a workflow to either test machine credentials or provision or discover machine identities .PARAMETER ID Machine or machine identity id for the workflow to trigger. Workflows 'Test' and 'GetConfig' require the machine ID. Workflows 'Provision' and 'Discover' require the machine identity ID. .PARAMETER Workflow The name of the workflow to trigger. Valid values are 'Test', 'GetConfig', 'Provision', or 'Discover'. .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .EXAMPLE Invoke-VcWorkflow -ID '1345baf1-fc56-49b7-aa03-78e35bfe0a1a' -Workflow 'Provision' ID Success WorkflowName WorkflowID -- ------- ------------ ---------- 1345baf1-fc56-49b7-aa03-78e35bfe0a1a True Provision 345b9d33-8c8a-4d4b-9fea-124f3a72f957 Trigger provisioning .EXAMPLE Invoke-VcWorkflow -ID '1345baf1-fc56-49b7-aa03-78e35bfe0a1a' -Workflow 'Test' ID : 1345baf1-fc56-49b7-aa03-78e35bfe0a1a Success : False WorkflowName : Test WorkflowID : 345b9d33-8c8a-4d4b-9fea-124f3a72f957 Error : failed to connect to Citrix ADC: [ERROR] nitro-go: Failed to create resource of type login, name=login, err=failed: 401 Unauthorized ({ "errorcode": 354, "message": "Invalid username or password", "severity": "ERROR" }) Trigger test connection, but it failed .EXAMPLE Find-VcObject -Type MachineIdentity -Filter @('and', @('certificateValidityEnd', 'lt', (get-date).AddDays(30)), @('certificateValidityEnd', 'gt', (get-date))) | ForEach-Object { $renewResult = $_ | Invoke-VenafiCertificateAction -Renew # optionally add renew validation $_ | Invoke-VcWorkflow -Workflow 'Provision' } ID Success WorkflowName WorkflowID -- ------- ------------ ---------- 1345baf1-fc56-49b7-aa03-78e35bfe0a1a True Provision 345b9d33-8c8a-4d4b-9fea-124f3a72f957 89fa4370-2026-11ee-8a18-ff9579bb988e True Provision 7598917c-7027-4927-be73-e592bcc4c567 Renew and provision all machine identities with certificates expiring within 30 days .INPUTS ID .OUTPUTS pscustomobject #> [CmdletBinding()] [Alias('Invoke-VaasWorkflow')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('machineID', 'machineIdentityID')] [string] $ID, [Parameter()] [ValidateSet('Test', 'GetConfig', 'Provision', 'Discover')] [string] $Workflow = 'Test', [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allIDs = [System.Collections.Generic.List[string]]::new() } process { $allIDs.Add($ID) } end { Invoke-VenafiParallel -InputObject $allIDs -ScriptBlock { $thisID = $PSItem $workflow = $using:Workflow $thisWebSocketID = (New-Guid).Guid try { $WS = New-Object System.Net.WebSockets.ClientWebSocket $CT = New-Object System.Threading.CancellationToken if ( $VenafiSession -is [PSCustomObject] ) { $server = $VenafiSession.Server.Replace('https://', '') $WS.Options.SetRequestHeader("tppl-api-key", $VenafiSession.Key.GetNetworkCredential().password) } else { $VcRegions | ConvertTo-Json | Write-Verbose if ( $env:VC_SERVER ) { $server = $env:VC_SERVER } else { # default to US region $server = ($script:VcRegions).'us' } $server = $server.Replace('https://', '') $WS.Options.SetRequestHeader("tppl-api-key", $VenafiSession) } $URL = 'wss://{0}/ws/notificationclients/{1}' -f $server, $thisWebSocketID #Get connected $Conn = $WS.ConnectAsync($URL, $CT) While ( !$Conn.IsCompleted ) { Start-Sleep -Milliseconds 100 } Write-Verbose "Connecting to $($URL)..." $Size = 2048 $Array = [byte[]] @(, 0) * $Size #Send Starting Request $Command = [System.Text.Encoding]::UTF8.GetBytes("ACTION=Command") $Send = New-Object System.ArraySegment[byte] -ArgumentList @(, $Command) $Conn = $WS.SendAsync($Send, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, $CT) While (!$Conn.IsCompleted) { Start-Sleep -Milliseconds 100 } #Start reading the received items $Recv = New-Object System.ArraySegment[byte] -ArgumentList @(, $Array) $Conn = $WS.ReceiveAsync($Recv, $CT) Write-Verbose 'Triggering workflow' $triggerParams = @{ UriLeaf = "machines/$thisID/workflows" Method = 'Post' Body = @{ 'workflowInput' = @{ 'wsClientId' = $thisWebSocketID } 'workflowName' = 'testConnection' } } switch ($Workflow) { 'GetConfig' { $triggerParams.Body.workflowName = 'getTargetConfiguration' } 'Provision' { $triggerParams.Body.workflowName = 'provisionCertificate' $triggerParams.UriLeaf = "machineidentities/$thisID/workflows" } 'Discover' { $triggerParams.Body.workflowName = 'discoverCertificates' $triggerParams.UriLeaf = "machines/$thisID/workflows" } } $null = Invoke-VenafiRestMethod @triggerParams While (!$Conn.IsCompleted) { Start-Sleep -Milliseconds 100 } $response = '' $Recv.Array[0..($Conn.Result.Count - 1)] | ForEach-Object { $response += [char]$_ } Write-Verbose $response $responseObj = $response | ConvertFrom-Json $out = [pscustomobject]@{ ID = $thisID Success = $true WorkflowName = $Workflow WorkflowID = $thisWebSocketID } if ( $responseObj.data.result -ne $true ) { $out.Success = $false $out | Add-Member @{'Error' = $responseObj.data.result.message } } $out } finally { if ( $WS ) { $WS.Dispose() } } } -ThrottleLimit $ThrottleLimit -ProgressTitle 'Invoking workflow' } } #EndRegion './Public/Invoke-VcWorkflow.ps1' 221 #Region './Public/Invoke-VdcCertificateAction.ps1' -1 function Invoke-VdcCertificateAction { <# .SYNOPSIS Perform an action against a certificate .DESCRIPTION One stop shop for basic certificate actions. You can Retire, Reset, Renew, Push, Validate, Revoke, or Delete. If using PowerShell v7+, this will be run in parallel. .PARAMETER Path Full path to the certificate .PARAMETER Disable Disable a certificate .PARAMETER Reset Reset the state of a certificate and its associated applications .PARAMETER Renew Requests immediate renewal for an existing certificate .PARAMETER Push Provisions the same certificate and private key to one or more devices or servers. The certificate must be associated with one or more Application objects. By default, this will provision the certificate to all associated applications. To specify a subset of applications, use the AdditionalParameter parameter as shown in the examples. .PARAMETER Validate Initiates SSL/TLS network validation .PARAMETER Revoke Sends a revocation request to the certificate CA .PARAMETER Delete Delete a certificate. .PARAMETER AdditionalParameter Additional items specific to the action being taken, if needed. See the examples for suggestions. .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS PSCustomObject with the following properties: CertificateID - Certificate path Success - A value of true indicates that the action was successful Error - Indicates any errors that occurred. Not returned when Success is true .EXAMPLE Invoke-VdcCertificateAction -Path '\VED\Policy\My folder\app.mycompany.com' -Revoke Perform an action .EXAMPLE Invoke-VdcCertificateAction -Path '\VED\Policy\My folder\app.mycompany.com' -Delete -Confirm:$false Perform an action bypassing the confirmation prompt. Only applicable to revoke, disable, and delete. .EXAMPLE Invoke-VdcCertificateAction -Path '\VED\Policy\My folder\app.mycompany.com' -Revoke -Confirm:$false | Invoke-VdcCertificateAction -Delete -Confirm:$false Chain multiple actions together .EXAMPLE Invoke-VdcCertificateAction -Path '\VED\Policy\My folder\app.mycompany.com' -Push -AdditionalParameter @{'PushToAll'=$false; 'ApplicationDN'=@('\VED\Policy\My folder\app.mycompany.com\app1','\VED\Policy\My folder\app.mycompany.com\app2')} Perform a push to a subset of associated applications overwriting the default of pushing to all. .EXAMPLE Invoke-VdcCertificateAction -Path '\VED\Policy\My folder\app.mycompany.com' -Revoke -AdditionalParameter @{'Comments'='Key compromised'; 'Reason'='3'} Perform a revoke sending additional parameters. Comments: The details about why the certificate is being revoked. Be sure the comment length does not exceed the limitation from the CA. When accepting a revocation request, they may handle data outside their limits differently. For Entrust CA or EntrustPKI CA, the maximum character limit is 250. Values for Reason can be: 0: None 1: User key compromised 2: CA key compromised 3: User changed affiliation 4: Certificate superseded 5: Original use no longer valid .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Certificates-Reset.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Certificates-renew.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Certificates-Push.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Certificates-Validate.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Certificates-revoke.php #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Params being used in paramset check, not by variable')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Alias('CertificateID', 'id')] [string] $Path, [Parameter(Mandatory, ParameterSetName = 'Disable')] [Alias('Retire')] [switch] $Disable, [Parameter(Mandatory, ParameterSetName = 'Reset')] [switch] $Reset, [Parameter(Mandatory, ParameterSetName = 'Renew')] [switch] $Renew, [Parameter(Mandatory, ParameterSetName = 'Push')] [switch] $Push, [Parameter(Mandatory, ParameterSetName = 'Validate')] [switch] $Validate, [Parameter(Mandatory, ParameterSetName = 'Revoke')] [switch] $Revoke, [Parameter(Mandatory, ParameterSetName = 'Delete')] [switch] $Delete, [Parameter()] [hashtable] $AdditionalParameter, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $allCerts = [System.Collections.Generic.List[string]]::new() } process { $addThis = $true if ( $PsCmdlet.ParameterSetName -in 'Delete', 'Revoke', 'Disable' ) { $addThis = $PSCmdlet.ShouldProcess($Path, ('{0} certificate' -f $PsCmdlet.ParameterSetName)) } if ( $addThis ) { $allCerts.Add($Path) } } end { if ( $allCerts.Count -eq 0 ) { return } $action = $PsCmdlet.ParameterSetName Invoke-VenafiParallel -InputObject $allCerts -ScriptBlock { $action = $using:action $thisCert = $PSItem $params = @{ Method = 'Post' } $returnObject = [PSCustomObject]@{ Path = $PSItem Success = $true Error = $null } # at times, we don't want to call an api in the process block $performInvoke = $true switch ($action) { 'Disable' { $performInvoke = $false try { Set-VdcAttribute -Path $thisCert -Attribute @{ 'Disabled' = '1' } } catch { $returnObject.Success = $false $returnObject.Error = $_ } } 'Reset' { $params.UriLeaf = 'Certificates/Reset' $params.Body = @{CertificateDN = $thisCert } } 'Renew' { $params.UriLeaf = 'Certificates/Renew' $params.Body = @{CertificateDN = $thisCert } } 'Push' { $params.UriLeaf = 'Certificates/Push' $params.Body = @{ CertificateDN = $thisCert 'PushToAll' = $true } } 'Validate' { $params.UriLeaf = 'Certificates/Validate' $params.Body = @{CertificateDNs = @($thisCert) } } 'Revoke' { $params.UriLeaf = 'Certificates/Revoke' $params.Body = @{CertificateDN = $thisCert } } 'Delete' { $performInvoke = $false Remove-VdcCertificate -Path $thisCert -Confirm:$false } } if ( $AdditionalParameter ) { $params.Body += $AdditionalParameter } if ( $performInvoke ) { try { $null = Invoke-VenafiRestMethod @params -FullResponse } catch { $returnObject.Success = $false $returnObject.Error = $_ } } # return path so another function can be called $returnObject } -ThrottleLimit $ThrottleLimit -ProgressTitle ('{0} certificates' -f $PsCmdlet.ParameterSetName) } } #EndRegion './Public/Invoke-VdcCertificateAction.ps1' 269 #Region './Public/Invoke-VenafiRestMethod.ps1' -1 function Invoke-VenafiRestMethod { <# .SYNOPSIS Ability to execute REST API calls which don't exist in a dedicated function yet .DESCRIPTION Ability to execute REST API calls which don't exist in a dedicated function yet .PARAMETER VenafiSession VenafiSession object from New-VenafiSession. For typical calls to New-VenafiSession, the object will be stored as a session object named $VenafiSession. Otherwise, if -PassThru was used, provide the resulting object. .PARAMETER Method API method, either get, post, patch, put or delete. .PARAMETER UriLeaf Path to the api endpoint excluding the base url and site, eg. certificates/import .PARAMETER Header Optional additional headers. The authorization header will be included automatically. .PARAMETER Body Optional body to pass to the endpoint .INPUTS None .OUTPUTS PSCustomObject .EXAMPLE Invoke-VenafiRestMethod -Method Delete -UriLeaf 'Discovery/{1345311e-83c5-4945-9b4b-1da0a17c45c6}' Api call .EXAMPLE Invoke-VenafiRestMethod -Method Post -UriLeaf 'Certificates/Revoke' -Body @{'CertificateDN'='\ved\policy\mycert.com'} Api call with optional payload #> [CmdletBinding(DefaultParameterSetName = 'Session')] [Alias('Invoke-TppRestMethod')] param ( [Parameter(ParameterSetName = 'Session')] [AllowNull()] [Alias('Key', 'AccessToken')] [psobject] $VenafiSession, [Parameter(Mandatory, ParameterSetName = 'URL')] [ValidateNotNullOrEmpty()] [Alias('ServerUrl')] [String] $Server, [Parameter(ParameterSetName = 'URL')] [Alias('UseDefaultCredentials')] [switch] $UseDefaultCredential, [Parameter(ParameterSetName = 'URL')] [X509Certificate] $Certificate, [Parameter()] [ValidateSet("Get", "Post", "Patch", "Put", "Delete", 'Head')] [String] $Method = 'Get', [Parameter()] [String] $UriRoot = 'vedsdk', [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [String] $UriLeaf, [Parameter()] [hashtable] $Header, [Parameter()] [Hashtable] $Body, [Parameter()] [switch] $FullResponse, [Parameter()] [Int32] $TimeoutSec = 0, [Parameter()] [switch] $SkipCertificateCheck ) $params = @{ Method = $Method ContentType = 'application/json' UseBasicParsing = $true TimeoutSec = $TimeoutSec } if ( $PSCmdLet.ParameterSetName -eq 'Session' ) { # if ( -not $VenafiSession ) { if ( $env:VDC_TOKEN ) { $VenafiSession = $env:VDC_TOKEN Write-Verbose 'Using TLSPDC token environment variable' } elseif ( $env:VC_KEY ) { $VenafiSession = $env:VC_KEY Write-Verbose 'Using TLSPC key environment variable' } elseif ( $PSBoundParameters.VenafiSession ) { Write-Verbose 'Using session provided' } elseif ($script:VenafiSessionNested) { $VenafiSession = $script:VenafiSessionNested Write-Verbose 'Using nested session' } elseif ( $script:VenafiSession ) { $VenafiSession = $script:VenafiSession Write-Verbose 'Using script session' } else { throw 'Please run New-VenafiSession or provide a TLSPC key or TLSPDC token.' } # } switch ($VenafiSession.GetType().Name) { 'PSCustomObject' { $Server = $VenafiSession.Server $platform = $VenafiSession.Platform if ( $VenafiSession.Platform -eq 'VC' ) { $auth = $VenafiSession.Key.GetNetworkCredential().password } else { # TLSPDC $auth = $VenafiSession.Token.AccessToken.GetNetworkCredential().password } $SkipCertificateCheck = $VenafiSession.SkipCertificateCheck $params.TimeoutSec = $VenafiSession.TimeoutSec break } 'String' { $auth = $VenafiSession if ( Test-IsGuid($VenafiSession) ) { if ( $env:VC_SERVER ) { $Server = $env:VC_SERVER } else { # default to US region $Server = ($script:VcRegions).'us' } if ( $Server -notlike 'https://*') { $Server = 'https://{0}' -f $Server } $platform = 'VC' } else { # TLSPDC access token # get server from environment variable if ( -not $env:VDC_SERVER ) { throw 'VDC_SERVER environment variable was not found' } $Server = $env:VDC_SERVER if ( $Server -notlike 'https://*') { $Server = 'https://{0}' -f $Server } $platform = 'VDC' } } Default { throw "Unknown session '$VenafiSession'. Please run New-VenafiSession or provide a TLSPC key or TLSPDC token." } } # set auth switch ($platform) { 'VC' { $allHeaders = @{ "tppl-api-key" = $auth } if ( -not $PSBoundParameters.ContainsKey('UriRoot') ) { $UriRoot = 'v1' } } 'VDC' { $allHeaders = @{ 'Authorization' = 'Bearer {0}' -f $auth } } Default {} } } $params.Uri = '{0}/{1}/{2}' -f $Server, $UriRoot, $UriLeaf # append any headers passed in if ( $Header ) { $allHeaders += $Header } # if there are any headers, add to the rest payload # in the case of inital authentication, eg, there won't be any if ( $allHeaders ) { $params.Headers = $allHeaders } if ( $UseDefaultCredential.IsPresent -and $Certificate ) { throw 'You cannot use UseDefaultCredential and Certificate parameters together' } if ( $UseDefaultCredential.IsPresent ) { $params.Add('UseDefaultCredentials', $true) } if ( $Body ) { switch ($Method.ToLower()) { 'head' { # a head method requires the params be provided as a query string, not body # invoke-webrequest does not do this so we have to build the string manually $newUri = New-HttpQueryString -Uri $uri -QueryParameter $Body $params.Uri = $newUri $params.Body = $null } 'get' { $params.Body = $Body } Default { $preJsonBody = $Body $params.Body = (ConvertTo-Json $Body -Depth 20 -Compress) # for special characters, we need to set the content type to utf-8 $params.ContentType = "application/json; charset=utf-8" } } } if ( $preJsonBody ) { $paramsToWrite = $params.Clone() $paramsToWrite.Body = $preJsonBody $paramsToWrite | Write-VerboseWithSecret } else { $params | Write-VerboseWithSecret } # ConvertTo-Json, used in Write-VerboseWithSecret, has an issue with certificates # add this param after if ( $Certificate ) { $params.Add('Certificate', $Certificate) } if ( $SkipCertificateCheck -or $env:VENAFIPS_SKIP_CERT_CHECK -eq '1' ) { if ( $PSVersionTable.PSVersion.Major -lt 6 ) { if ( [System.Net.ServicePointManager]::CertificatePolicy.GetType().FullName -ne 'TrustAllCertsPolicy' ) { add-type @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy } } else { $params.Add('SkipCertificateCheck', $true) } } $oldProgressPreference = $ProgressPreference $ProgressPreference = 'SilentlyContinue' try { $verboseOutput = $($response = Invoke-WebRequest @params -ErrorAction Stop) 4>&1 $verboseOutput.Message | Write-VerboseWithSecret } catch { # if trying with a slash below doesn't work, we want to provide the original error $originalError = $_ $statusCode = [int]$originalError.Exception.Response.StatusCode Write-Verbose ('Response status code {0}' -f $statusCode) switch ($statusCode) { 403 { $permMsg = '' # get scope details for tpp if ( $platform -ne 'VC' ) { $callingFunction = @(Get-PSCallStack)[1].InvocationInfo.MyCommand.Name $callingFunctionScope = ($script:functionConfig).$callingFunction.TppTokenScope if ( $callingFunctionScope ) { $permMsg += "$callingFunction requires a token scope of '$callingFunctionScope'." } $rejectedScope = Select-String -InputObject $originalError.ErrorDetails.Message -Pattern 'Grant rejected scope ([^.]+)' if ( $rejectedScope.Matches.Groups.Count -gt 1 ) { $permMsg += (" The current scope of {0} is insufficient." -f $rejectedScope.Matches.Groups[1].Value.Replace('\u0027', "'")) } $permMsg += ' Call New-VenafiSession with the correct scope.' } else { $permMsg = $originalError.ErrorDetails.Message } throw $permMsg } 409 { # 409 = item already exists. some functions use this for a 'force' option, eg. Set-VdcPermission # treat this as non error/exception if FullResponse provided if ( $FullResponse ) { $response = [pscustomobject] @{ StatusCode = $statusCode Error = try { $originalError.ErrorDetails.Message | ConvertFrom-Json } catch { $originalError.ErrorDetails.Message } } } else { throw $originalError } } Default { throw $originalError } } } finally { $ProgressPreference = $oldProgressPreference } if ( $FullResponse ) { $response } else { if ( $response.Content ) { try { $response.Content | ConvertFrom-Json } catch { throw ('Invalid JSON response {0}' -f $response.Content) } } } } #EndRegion './Public/Invoke-VenafiRestMethod.ps1' 356 #Region './Public/Move-VdcObject.ps1' -1 function Move-VdcObject { <# .SYNOPSIS Move an object of any type .DESCRIPTION Move an object of any type from one policy to another. A rename can be done at the same time as the move by providing a full target path including the new object name. .PARAMETER SourcePath Full path to an existing object in TLSPDC .PARAMETER TargetPath New path. This can either be an existing policy and the existing object name will be kept or a full path including a new object name. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS SourcePath (Path) .OUTPUTS n/a .EXAMPLE Move-VdcObject -SourceDN '\VED\Policy\My Folder\mycert.company.com' -TargetDN '\VED\Policy\New Folder\mycert.company.com' Move object to a new Policy folder .EXAMPLE Find-VdcCertificate -Path '\ved\policy\certs' | Move-VdcObject -TargetDN '\VED\Policy\New Folder' Move all objects found in 1 folder to another .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Move-VdcObject/ .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Test-VdcObject/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Move-VdcObject.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-renameobject.php #> [CmdletBinding(SupportsShouldProcess)] [Alias('Move-TppObject')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('SourceDN', 'Path')] [String] $SourcePath, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('TargetDN')] [String] $TargetPath, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' # determine if target is a policy or other object # if policy, we'll need to append the object name in the process block when moving try { $targetObject = Get-VdcObject -Path $TargetPath -ErrorAction SilentlyContinue } catch { # expected if target is a new object name and not policy } $targetIsPolicy = ($targetObject.TypeName -eq 'Policy') } process { $params = @{ Method = 'Post' UriLeaf = 'config/RenameObject' Body = @{ ObjectDN = $SourcePath NewObjectDN = $TargetPath } } # if target is a policy, append the object name from source if ( $targetIsPolicy ) { # get object name, issue 129 $childPath = $SourcePath.Split('\')[-1] $params.Body.NewObjectDN = '{0}\{1}' -f $targetObject.Path, $childPath } if ( $PSCmdlet.ShouldProcess($SourcePath, ('Move to {0}' -f $params.Body.NewObjectDN)) ) { $response = Invoke-VenafiRestMethod @params if ( $response.Result -ne 1 ) { Write-Error $response.Error } } } } #EndRegion './Public/Move-VdcObject.ps1' 125 #Region './Public/New-VcApplication.ps1' -1 function New-VcApplication { <# .SYNOPSIS Create a new application .DESCRIPTION Create a new application with optional details .PARAMETER Name Application name .PARAMETER Owner List of user and/or team IDs or names to be owners .PARAMETER Description Application description .PARAMETER IssuingTemplate 1 or more issuing template IDs or names to associate with the new application .PARAMETER Fqdn Fully qualified domain names to assign to the application .PARAMETER IPRange IP ranges to assign to the application .PARAMETER Port Ports to assign to the application. Required if either Fqdn or IPRange are specified. .PARAMETER PassThru Return newly created application object .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .OUTPUTS PSCustomObject, if PassThru provided .EXAMPLE New-VcApplication -Name 'MyNewApp' -Owner '4ba1e64f-12ad-4a34-a0e2-bc4481a56f7d','greg@venafi.com' Create a new application .EXAMPLE New-VcApplication -Name 'MyNewApp' -Owner '4ba1e64f-12ad-4a34-a0e2-bc4481a56f7d' -CertificateIssuingTemplate @{'9c9618e8-6b4c-4a1c-8c11-902c9b2676d3'=$null} -Description 'this app is awesome' -Fqdn 'me.com' -IPRange '1.2.3.4/24' -Port '443','9443' Create a new application with optional details .EXAMPLE New-VcApplication -Name 'MyNewApp' -Owner '4ba1e64f-12ad-4a34-a0e2-bc4481a56f7d' -PassThru Create a new application and return the newly created application object #> [CmdletBinding(DefaultParameterSetName = 'NoTarget', SupportsShouldProcess)] [Alias('New-VaasApplication')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string[]] $Owner, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [String] $Description, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string[]] $IssuingTemplate, [Parameter(ParameterSetName = 'Fqdn', Mandatory, ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'FqdnIPRange', Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string[]] $Fqdn, [Parameter(ParameterSetName = 'IPRange', Mandatory, ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'FqdnIPRange', Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string[]] $IPRange, [Parameter(ParameterSetName = 'Fqdn', Mandatory, ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'IPRange', Mandatory, ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'FqdnIPRange', Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string[]] $Port, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' # determine if user or team and build the payload $ownerHash = foreach ($thisOwner in $Owner) { $team = Get-VcTeam -ID $thisOwner -ErrorAction SilentlyContinue if ( $team ) { @{ 'ownerId' = $team.teamId; 'ownerType' = 'TEAM' } } else { $user = Get-VcIdentity -ID $thisOwner -ErrorAction SilentlyContinue if ( $user ) { @{ 'ownerId' = $user.userId; 'ownerType' = 'USER' } } else { Write-Error "Owner $thisOwner not found" Continue } } } $templateHash = @{} foreach ($thisTemplateID in $IssuingTemplate) { $thisTemplate = Get-VcIssuingTemplate -ID $thisTemplateID if ( $thisTemplate ) { $templateHash.Add($thisTemplate.name, $thisTemplate.issuingTemplateId) } else { throw ('Template ID {0} not found' -f $thisTemplateID) } } # if ( $PSBoundParameters.ContainsKey('IssuingTemplate') ) { # $IssuingTemplate.GetEnumerator() | ForEach-Object { # if ( $_.Value ) { # $templateHash.Add($_.Value, $_.Key) # } # else { # $thisTemplate = Get-VcIssuingTemplate -ID $_.Key -ErrorAction SilentlyContinue # if ( $thisTemplate ) { # $templateHash.Add($thisTemplate.Name, $_.Key) # } # else { # Write-Error ('Template ID {0} not found' -f $_.Key) # Continue # } # } # } # } } process { Write-Verbose $PSCmdlet.ParameterSetName if ( -not $ownerHash ) { return } $params = @{ VenafiSession = $VenafiSession Method = 'Post' UriRoot = 'outagedetection/v1' UriLeaf = 'applications' Body = @{ name = $Name ownerIdsAndTypes = [array] $ownerHash } FullResponse = $true } if ( $PSBoundParameters.ContainsKey('Description') ) { $params.Body.description = $Description } if ( $templateHash.Count -gt 0 ) { $params.Body.certificateIssuingTemplateAliasIdMap = $templateHash } if ( $PSBoundParameters.ContainsKey('Fqdn') ) { $params.Body.fullyQualifiedDomainNames = $Fqdn } if ( $PSBoundParameters.ContainsKey('IPRange') ) { $params.Body.ipRanges = $IPRange } if ( $PSBoundParameters.ContainsKey('Port') ) { $params.Body.ports = $Port } if ( $PSCmdlet.ShouldProcess($Name, 'Create application') ) { try { $response = Invoke-VenafiRestMethod @params switch ( $response.StatusCode ) { 201 { if ( $PassThru ) { $response.Content | ConvertFrom-Json | Select-Object -ExpandProperty applications | Select-Object -Property @{'n' = 'applicationId'; 'e' = { $_.id } }, * -ExcludeProperty id } } 409 { throw "$Name already exists" } default { throw $response } } } catch { $PSCmdlet.ThrowTerminatingError($PSItem) } } } } #EndRegion './Public/New-VcApplication.ps1' 222 #Region './Public/New-VcCertificate.ps1' -1 function New-VcCertificate { <# .SYNOPSIS Create certificate request .DESCRIPTION Create certificate request from automated secure keypair details or CSR .PARAMETER Application Application name (wildcards supported) or id to associate this certificate. .PARAMETER IssuingTemplate Issuing template name (wildcards supported) or id to use. The template must be available with the selected Application. .PARAMETER Csr CSR in PKCS#10 format which conforms to the rules of the issuing template .PARAMETER CommonName Common name (CN) .PARAMETER Organization The Organization field for the certificate Subject DN .PARAMETER OrganizationalUnit One or more departments or divisions within the organization that is responsible for maintaining the certificate .PARAMETER City The City/Locality field for the certificate Subject DN .PARAMETER State The State field for the certificate Subject DN .PARAMETER Country The Country field for the certificate Subject DN .PARAMETER SanDns One or more subject alternative name dns entries .PARAMETER SanIP One or more subject alternative name ip address entries .PARAMETER SanUri One or more subject alternative name uri entries .PARAMETER SanEmail One or more subject alternative name email entries .PARAMETER ValidUntil Date at which the certificate becomes invalid. Days and hours are supported, not minutes. .PARAMETER PassThru Return the certificate request. If the certificate was successfully issued, it will be returned as the property 'certificate'. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided directly. .INPUTS CommonName .OUTPUTS pscustomobject, if PassThru is provided .EXAMPLE New-VcCertificate -Application 'MyApp' -IssuingTemplate 'MSCA - 1 year' -CommonName 'app.mycert.com' Create certificate .EXAMPLE New-VcCertificate -Application 'MyApp' -IssuingTemplate 'MSCA - 1 year' -CommonName 'app.mycert.com' -SanIP '1.2.3.4' Create certificate with optional SAN data .EXAMPLE New-VcCertificate -Application 'MyApp' -IssuingTemplate 'MSCA - 1 year' -CommonName 'app.mycert.com' -ValidUntil (Get-Date).AddMonths(6) Create certificate with specific validity .EXAMPLE New-VcCertificate -Application 'MyApp' -IssuingTemplate 'MSCA - 1 year' -CommonName 'app.mycert.com' -PassThru Create certificate and return the created object .EXAMPLE New-VcCertificate -Application 'MyApp' -IssuingTemplate 'MSCA - 1 year' -Csr "-----BEGIN CERTIFICATE REQUEST-----\nMIICYzCCAUsCAQAwHj....BoiNIqtVQxFsfT+\n-----END CERTIFICATE REQUEST-----\n" Create certificate with a CSR .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html?urls.primaryName=outagedetection-service#/Certificate%20Request/certificaterequests_create #> [CmdletBinding(DefaultParameterSetName = 'Ask', SupportsShouldProcess)] [Alias('New-VaasCertificate')] param ( [Parameter(Mandatory)] [String] $Application, [Parameter(Mandatory)] [String] $IssuingTemplate, [Parameter(ParameterSetName = 'Csr', Mandatory)] [string] $Csr, [Parameter(ParameterSetName = 'Ask', Mandatory)] [ValidateNotNullOrEmpty()] [String] $CommonName, [Parameter(ParameterSetName = 'Ask')] [ValidateNotNullOrEmpty()] [String] $Organization, [Parameter(ParameterSetName = 'Ask')] [ValidateNotNullOrEmpty()] [String[]] $OrganizationalUnit, [Parameter(ParameterSetName = 'Ask')] [ValidateNotNullOrEmpty()] [String] $City, [Parameter(ParameterSetName = 'Ask')] [ValidateNotNullOrEmpty()] [String] $State, [Parameter(ParameterSetName = 'Ask')] [ValidateNotNullOrEmpty()] [String] $Country, [Parameter()] [ValidateNotNullOrEmpty()] [String[]] $SanDns, [Parameter()] [ValidateNotNullOrEmpty()] [String[]] $SanIP, [Parameter()] [ValidateNotNullOrEmpty()] [String[]] $SanUri, [Parameter()] [ValidateNotNullOrEmpty()] [String[]] $SanEmail, [Parameter()] [ValidateScript( { $span = $_ - (Get-Date) if ( $span.Days -ge 0 -or $span.Hours -ge 0 ) { $true } else { throw 'ValidUntil must be a date in the future' } } )] [DateTime] $ValidUntil = (Get-Date).AddDays(90), [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' # validation $allApps = Get-VcApplication -All $thisApp = $allApps | Where-Object { $_.Name -like $Application -or $_.applicationId -eq $Application } switch (@($thisApp).Count) { 0 { throw ('Application not found. Valid applications are {0}.' -f ($allApps.name -join ', ')) } 1 { Write-Verbose ('Found application {0}, ID: {1}' -f $thisApp.name, $thisApp.applicationId) $thisAppID = $thisApp.applicationId } Default { throw ('More than 1 application found that matches {0}: {1}' -f $Application, ($thisApp.name -join ', ')) } } $thisTemplate = $thisApp.issuingTemplate | Where-Object { $_.Name -like $IssuingTemplate -or $_.issuingTemplateId -eq $IssuingTemplate } switch (@($thisTemplate).Count) { 0 { throw ('Issuing template not found or not valid for this application. Valid templates are {0}.' -f ($thisApp.certificateIssuingTemplate.name -join ', ')) } 1 { Write-Verbose ('Found template {0}, ID: {1}' -f $thisTemplate.name, $thisTemplate.id) $thisTemplateID = $thisTemplate.issuingTemplateId } Default { throw ('More than 1 issuing template found that matches {0}: {1}' -f $IssuingTemplate, ($thisTemplate.name -join ', ')) } } $span = New-TimeSpan -Start (Get-Date) -End $ValidUntil $validity = 'P{0}DT{1}H' -f $span.Days, $span.Hours $params = @{ Method = 'Post' UriRoot = 'outagedetection/v1' UriLeaf = 'certificaterequests' Body = @{ isVaaSGenerated = $true applicationId = $thisAppID certificateIssuingTemplateId = $thisTemplateID validityPeriod = $validity } } if ( $PSCmdlet.ParameterSetName -eq 'Ask' ) { $params.Body.csrAttributes = @{} } else { $params.Body.certificateSigningRequest = $Csr } if ( $PSBoundParameters.ContainsKey('Organization') ) { $params.Body.csrAttributes.organization = $Organization } if ( $PSBoundParameters.ContainsKey('OrganizationalUnit') ) { $params.Body.csrAttributes.organizationalUnits = @($OrganizationalUnit) } if ( $PSBoundParameters.ContainsKey('City') ) { $params.Body.csrAttributes.locality = $City } if ( $PSBoundParameters.ContainsKey('State') ) { $params.Body.csrAttributes.state = $State } if ( $PSBoundParameters.ContainsKey('Country') ) { $params.Body.csrAttributes.country = $Country } if ( $SanDns -or $SanEmail -or $SanIP -or $SanUri ) { $params.Body.csrAttributes.subjectAlternativeNamesByType = @{} } if ( $PSBoundParameters.ContainsKey('SanDns') ) { $params.Body.csrAttributes.subjectAlternativeNamesByType.dnsNames = @($SanDns) } if ( $PSBoundParameters.ContainsKey('SanEmail') ) { $params.Body.csrAttributes.subjectAlternativeNamesByType.rfc822Names = @($SanEmail) } if ( $PSBoundParameters.ContainsKey('SanIP') ) { $params.Body.csrAttributes.subjectAlternativeNamesByType.ipAddresses = @($SanIP) } if ( $PSBoundParameters.ContainsKey('SanUri') ) { $params.Body.csrAttributes.subjectAlternativeNamesByType.uniformResourceIdentifiers = @($SanUri) } } process { if ( $PSCmdlet.ParameterSetName -eq 'Ask' ) { $params.Body.csrAttributes.commonName = $CommonName $target = $CommonName } else { $target = 'CSR' } if ( $PSCmdlet.ShouldProcess("$target", 'New certificate request') ) { try { $response = Invoke-VenafiRestMethod @params if ( $PassThru ) { $certRequest = $response | Select-Object -ExpandProperty certificateRequests if ( $certRequest.certificateIds ) { $actualCert = Get-VcCertificate -CertificateId $certRequest.certificateIds[0] $certRequest | Add-Member @{ 'certificate' = $actualCert } } $certRequest | Select-Object @{'n' = 'certificateRequestId'; 'e' = { $_.id } }, *, @{'n' = 'certificateId'; 'e' = { $_.certificateIds } } -ExcludeProperty id, certificateIds } } catch { Write-Error $_ continue } } } } #EndRegion './Public/New-VcCertificate.ps1' 308 #Region './Public/New-VcConnector.ps1' -1 function New-VcConnector { <# .SYNOPSIS Create a new connector .DESCRIPTION Create a new machine, CA, TPP, or credential connector .PARAMETER ManifestPath Path to an existing manifest. Manifest can either be directly from the simulator or a full manifest with deployment element. If the manifest is from the simulator, the DeploymentImage parameter is required. .PARAMETER DeploymentImage Path to the already uploaded docker image. This parameter is only to be used for a manifest directly from the simulator. .PARAMETER Maintainer Optional value to specify the organization, individual, email, location, or website responsible for maintaining the connector This parameter is only to be used for a manifest directly from the simulator. .PARAMETER PassThru Return newly created connector object .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .OUTPUTS PSCustomObject, if PassThru provided .EXAMPLE New-VcConnector -ManifestPath '/tmp/manifest.json' Create a new connector from a full manifest .EXAMPLE New-VcConnector -ManifestPath '/tmp/manifest.json' -PassThru Create a new connector and return the newly created connector object .EXAMPLE New-VcConnector -ManifestPath '/tmp/manifest.json' -DeploymentImage 'docker.io/venafi/connector:latest@sha256:1234567890abcdef' Create a new connector from a manifest from the simulator .LINK https://developer.venafi.com/tlsprotectcloud/reference/post-v1-plugins #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'FullManifest')] param ( [Parameter(Mandatory, ParameterSetName = 'FromSimulator')] [Parameter(Mandatory, ParameterSetName = 'FullManifest')] [ValidateScript( { if ( -not ( Test-Path $_ ) ) { throw "The manifest path $_ cannot be found" } $true } )] [string] $ManifestPath, [Parameter(Mandatory, ParameterSetName = 'FromSimulator')] [string] $DeploymentImage, [Parameter(ParameterSetName = 'FromSimulator')] [string] $Maintainer, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { $manifestObject = Get-Content -Path $ManifestPath -Raw | ConvertFrom-Json if ( $PSCmdlet.ParameterSetName -eq 'FromSimulator' ) { if ( $manifestObject.manifest -or !$manifestObject.name ) { throw 'This manifest is not from the simulator' } $manifestBody = @{ pluginType = $manifestObject.pluginType manifest = $manifestObject } $manifestBody.manifest | Add-Member @{'deployment' = @{ image = $DeploymentImage 'executionTarget' = 'vsat' } } if ( $Maintainer ) { $manifestBody.maintainer = $Maintainer } } else { # full manifest with deployment details, validate we have the structure and data needed if ( !$manifestObject.manifest -or !$manifestObject.manifest.deployment ) { throw 'This is not the correct manifest structure. See https://developer.venafi.com/tlsprotectcloud/reference/post-v1-plugins.' } $manifestBody = $manifestObject } $params = @{ Method = 'Post' UriLeaf = 'plugins' Body = $manifestBody } if ( $PSCmdlet.ShouldProcess($manifestBody.manifest.name, 'Create connector') ) { try { $response = Invoke-VenafiRestMethod @params if ( $PassThru ) { $response.plugins | Select-Object @{ 'n' = 'connectorId'; 'e' = { $_.Id } }, @{ 'n' = 'connectorType'; 'e' = { $_.pluginType } }, * -ExcludeProperty Id, pluginType } } catch { $PSCmdlet.ThrowTerminatingError($PSItem) } } } } #EndRegion './Public/New-VcConnector.ps1' 137 #Region './Public/New-VcMachine.ps1' -1 function New-VcMachine { <# .SYNOPSIS Create 1 or more machines .DESCRIPTION This creation function is to be used for 'simple' machine types, eg. F5 and Citrix, where hostname, credential and optionally port are used. Machine creation for types with additional functionality will have dedicated functions, eg. New-VcMachineIis. By default, the machine details will be verified by performing a test connection; this can be turned off with -NoVerify. Creation will occur in parallel and PowerShell v7+ is required. .PARAMETER Name Machine name .PARAMETER MachineType Machine type by either ID or name, eg. 'Citrix ADC'. A list can be found by create a new session and executing $VenafiSession.MachineType. .PARAMETER VSatellite ID or name of a vsatellite. If not provided, the first vsatellite found will be used. .PARAMETER Owner ID or name of a team to be the owner of the machine .PARAMETER Tag Optional list of tags to assign .PARAMETER Hostname IP or fqdn of the machine. If this is to be the same value as -Name, this parameter can be ommitted. .PARAMETER Credential Username/password to access the machine .PARAMETER Port Optional port. The default value will depend on the machine type. Eg. for Citrix ADC this is 443. .PARAMETER ConnectionDetail Full connection detail object to create a machine. This is typically for use with other machine creation functions, but here for flexibility. .PARAMETER DekID ID of the data encryption key .PARAMETER NoVerify By default a connection to the host will be attempted. Use this switch to turn off this behavior. Not recommended. .PARAMETER Status Set the machine status to either 'DRAFT', 'VERIFIED', or 'UNVERIFIED'. This optional field has been added for flexibility, but should not be needed under typical usage. The platform will handle changing the status to the appropriate value. Setting this to a value other than VERIFIED will affect the ability to initiate workflows. .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER PassThru Return newly created object .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .EXAMPLE $params = @{ Name = 'c1' MachineType = 'Citrix ADC' Owner = 'MyTeam' Hostname = 'c1.company.com' Credential = $cred } New-VcMachine @params machineId : cf7cfdc0-2b2a-11ee-9546-5136c4b21504 testConnection : @{Success=True; Error=; WorkflowID=c39310ee-51fc-49f3-8b5b-e504e1bc43d2} companyId : 20b24f81-b22b-11ea-91f3-ebd6dea5453f name : c1 machineType : Citrix ADC pluginId : ff645e14-bd1a-11ed-a009-ce063932f86d integrationId : cf7c8014-2b2a-11ee-9a03-fa8930555887 edgeInstanceId : 0bc771e1-7abe-4339-9fcd-93fffe9cba7f creationDate : 7/25/2023 4:35:36 PM modificationDate : 7/25/2023 4:35:36 PM status : UNVERIFIED owningTeamId : 59920180-a3e2-11ec-8dcd-3fcbf84c7da7 Create a new Citrix machine .EXAMPLE [pscustomobject] @{ Name = 'c1.company.com' MachineType = 'Citrix ADC' Owner = 'MyTeam' Credential = $cred } | New-VcMachine Use pipeline data to create a machine. More than 1 machine can be sent thru the pipeline and they will be created in parallel. You could also import a csv and pipe it to this function as well. .NOTES To see a full list of tab-completion options, be sure to set the Tab option, Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete. This function requires the use of sodium encryption. .net standard 2.0 or greater is required via PS Core (recommended) or supporting .net runtime. On Windows, the latest Visual C++ redist must be installed. See https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist. #> [CmdletBinding()] [Alias('New-VaasMachine')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $MachineType, [Parameter(ParameterSetName = 'BasicMachine', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'AdvancedMachine', ValueFromPipelineByPropertyName)] [string] $VSatellite, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Owner, [Parameter(ValueFromPipelineByPropertyName)] [string[]] $Tag, [Parameter(ValueFromPipelineByPropertyName)] [ValidateSet('DRAFT', 'VERIFIED', 'UNVERIFIED')] [string] $Status, [Parameter(ParameterSetName = 'BasicMachine', ValueFromPipelineByPropertyName)] [string] $Hostname, [Parameter(Mandatory, ParameterSetName = 'BasicMachine', ValueFromPipelineByPropertyName)] [pscredential] $Credential, [Parameter(ParameterSetName = 'BasicMachine', ValueFromPipelineByPropertyName)] [string] $Port, [Parameter(Mandatory, ParameterSetName = 'AdvancedMachine', ValueFromPipelineByPropertyName)] [hashtable] $ConnectionDetail, [Parameter(Mandatory, ParameterSetName = 'AdvancedMachine', ValueFromPipelineByPropertyName)] [string] $DekID, [Parameter()] [switch] $NoVerify, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' Initialize-PSSodium $allMachines = [System.Collections.Generic.List[hashtable]]::new() if ( $Credential ) { if ( $MachineType -in 'c1521d80-db7a-11ec-b79a-f3ded6c9808c', 'Microsoft IIS' ) { throw 'To create IIS machines, please use New-VcMachineIis' } if ( $MachineType -in '575389b0-e6be-11ec-9172-d3c56ea8bcf6', 'Common Keystore (PEM, JKS, PKCS#12)' ) { throw 'To create Common Keystore machines, please use New-VcMachineCommonKeystore' } } } process { Write-Verbose $PSCmdlet.ParameterSetName $thisMachineType = Get-VcData -InputObject $MachineType -Type 'MachineType' -Object if ( -not $thisMachineType ) { Write-Error "'$MachineType' is not a valid machine type id or name" return } $ownerId = Get-VcData -InputObject $Owner -Type 'Team' if ( -not $ownerId ) { Write-Error "'$Owner' is not a valid team id or name" return } if ( $PSCmdlet.ParameterSetName -eq 'AdvancedMachine' ) { $thisEdgeInstanceId = $VSatellite $thisDekId = $DekID $thisConnectionDetail = $ConnectionDetail } else { if ( $VSatellite ) { $vSat = Get-VcData -InputObject $VSatellite -Type 'VSatellite' -Object if ( -not $vSat ) { Write-Error "'$VSatellite' is either not a valid VSatellite id or name or it is not active." return } } else { $vSat = Get-VcData -Type 'VSatellite' -First if ( -not $vSat ) { Write-Error "An active VSatellite could not be found" return } } $thisEdgeInstanceId = $vSat.vsatelliteId $thisDekId = $vSat.encryptionKeyId $userEnc = ConvertTo-SodiumEncryptedString -text $Credential.UserName -PublicKey $vSat.encryptionKey $pwEnc = ConvertTo-SodiumEncryptedString -text $Credential.GetNetworkCredential().Password -PublicKey $vSat.encryptionKey $thisConnectionDetail = @{ hostnameOrAddress = if ($Hostname) { $Hostname } else { $Name } username = $userEnc password = $pwEnc } if ( $Port ) { $thisConnectionDetail.port = $Port } } $bodyParams = @{ name = $Name edgeInstanceId = $thisEdgeInstanceId dekId = $thisDekId machineTypeId = $thisMachineType.machineTypeId pluginId = $thisMachineType.pluginId owningTeamId = $ownerId connectionDetails = $thisConnectionDetail } if ( $Tag ) { $bodyParams.tags = $Tag } if ( $Status ) { $bodyParams.status = $Status } $allMachines.Add( $bodyParams ) } end { $response = Invoke-VenafiParallel -InputObject $allMachines -ScriptBlock { $response = Invoke-VenafiRestMethod -Method 'Post' -UriLeaf 'machines' -Body $PSItem if ( $using:NoVerify ) { $response | Select-Object @{ 'n' = 'machineId' 'e' = { $_.id } }, * -ExcludeProperty id } else { $workflowResponse = Invoke-VcWorkflow -ID $response.id -Workflow 'Test' $response | Select-Object @{ 'n' = 'machineId' 'e' = { $_.id } }, @{ 'n' = 'testConnection' 'e' = { $workflowResponse | Select-Object Success, Error, WorkflowID } }, * -ExcludeProperty id } } -ThrottleLimit $ThrottleLimit -VenafiSession $VenafiSession if ( $PassThru ) { $response } } } #EndRegion './Public/New-VcMachine.ps1' 291 #Region './Public/New-VcMachineCommonKeystore.ps1' -1 function New-VcMachineCommonKeystore { <# .SYNOPSIS Create a new common keystore machine .DESCRIPTION Create a new common keystore, PEM/JKS/PKCS#12, machine. SSH and WinRM are both supported in addition to different authentication types. By default, the machine details will be verified by performing a test connection; this can be turned off with -NoVerify. Creation will occur in parallel and PowerShell v7+ is required. .PARAMETER Name Machine name .PARAMETER VSatellite ID or name of a VSatellite. If not provided, the first active VSatellite found will be used. .PARAMETER Owner ID or name of a team to be the owner of the machine .PARAMETER Tag Optional list of tags to assign .PARAMETER Status Set the machine status to either 'DRAFT', 'VERIFIED', or 'UNVERIFIED'. This optional field has been added for flexibility, but should not be needed under typical usage. The platform will handle changing the status to the appropriate value. Setting this to a value other than VERIFIED will affect the ability to initiate workflows. .PARAMETER SshPassword Connect to the target machine over SSH with username and password .PARAMETER SshKey Connect to the target machine over SSH with username and private key .PARAMETER WinrmBasic Connect to the target machine over WinRM with Basic authentication .PARAMETER WinrmKerberos Connect to the target machine over WinRM with Kerberos authentication .PARAMETER Hostname IP or fqdn of the machine. If this is to be the same value as -Name, this parameter can be ommitted. .PARAMETER Credential Username/password to access the machine. If using key-based authentication over SSH, set the password to the private key. .PARAMETER Port Optional SSH/WinRM port. The default for SSH is 22 and WinRM is 5985. .PARAMETER UseTls Connect with WinRM over HTTPS as opposed to the default of HTTP .PARAMETER SkipCertificateCheck If connecting with WinRM over HTTPS and you wish to bypass certificate validation .PARAMETER DomainName Machine domain name for WinRM .PARAMETER KeyDistributionCenter Address or hostname of the key distribution center for WinRM .PARAMETER SPN Service Principal Name, eg. WSMAN/server.company.com, for WinRM .PARAMETER NoVerify By default a connection to the host will be attempted. Use this switch to turn off this behavior. Not recommended. .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER PassThru Return newly created object .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .OUTPUTS PSCustomObject, if PassThru provided .EXAMPLE New-VcMachineCommonKeystore -Name 'ck1' -Owner 'MyTeam' -Hostname 'ck1.company.com' -Credential $cred -SshPassword machineId : a9b60a70-2b28-11ee-b5b5-4b044579acad testConnection : @{Success=True; Error=; WorkflowID=c14e181b-82ea-423a-b0fd-c3fe9b218a64} companyId : 20b24f81-b22b-11ea-91f3-ebd6dea5453f name : ck1 machineType : Common KeyStore (PEM, JKS, PKCS#12) pluginId : 0e565e41-dd31-11ec-841d-a7d91c5a907c integrationId : a9b5b842-2b28-11ee-9263-9e16d4b8a8c9 edgeInstanceId : 0bc771e1-7abe-4339-9fcd-93fffe9cba7f creationDate : 7/25/2023 4:20:14 PM modificationDate : 7/25/2023 4:20:14 PM status : UNVERIFIED owningTeamId : 59920180-a3e2-11ec-8dcd-3fcbf84c7da7 Create a new machine with SSH password authentication .NOTES This function requires the use of sodium encryption. .net standard 2.0 or greater is required via PS Core (recommended) or supporting .net runtime. On Windows, the latest Visual C++ redist must be installed. See https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist. #> [CmdletBinding(DefaultParameterSetName = 'SshPassword')] [Alias('New-VaasMachineCommonKeystore')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(ValueFromPipelineByPropertyName)] [string] $VSatellite, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Owner, [Parameter(ValueFromPipelineByPropertyName)] [string] $Hostname, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [pscredential] $Credential, [Parameter(ValueFromPipelineByPropertyName)] [string[]] $Tag, [Parameter(ValueFromPipelineByPropertyName)] [ValidateSet('DRAFT', 'VERIFIED', 'UNVERIFIED')] [string] $Status, [Parameter(ParameterSetName = 'SshPassword', Mandatory, ValueFromPipelineByPropertyName)] [switch] $SshPassword, [Parameter(ParameterSetName = 'SshKey', Mandatory, ValueFromPipelineByPropertyName)] [switch] $SshKey, [Parameter(ParameterSetName = 'WinrmBasic', Mandatory, ValueFromPipelineByPropertyName)] [switch] $WinrmBasic, [Parameter(ParameterSetName = 'WinrmKerberos', Mandatory, ValueFromPipelineByPropertyName)] [switch] $WinrmKerberos, [Parameter(ValueFromPipelineByPropertyName)] [int] $Port, [Parameter(ParameterSetName = 'WinrmBasic', ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'WinrmKerberos', ValueFromPipelineByPropertyName)] [switch] $UseTls, [Parameter(ParameterSetName = 'WinrmBasic', ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'WinrmKerberos', ValueFromPipelineByPropertyName)] [switch] $SkipCertificateCheck, [Parameter(ParameterSetName = 'WinrmKerberos', Mandatory, ValueFromPipelineByPropertyName)] [string] $DomainName, [Parameter(ParameterSetName = 'WinrmKerberos', Mandatory, ValueFromPipelineByPropertyName)] [string] $KeyDistributionCenter, [Parameter(ParameterSetName = 'WinrmKerberos', Mandatory, ValueFromPipelineByPropertyName)] [string] $SPN, [Parameter()] [switch] $NoVerify, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allMachines = [System.Collections.Generic.List[pscustomobject]]::new() $machineTypeId = '575389b0-e6be-11ec-9172-d3c56ea8bcf6' Initialize-PSSodium } process { # need vsat to get dek for encrypting username/password if ( $VSatellite ) { $vSat = Get-VcData -InputObject $VSatellite -Type 'VSatellite' -Object if ( -not $vSat ) { throw "'$VSatellite' is either not a valid VSatellite id or name or it is not active" } } else { $vSat = Get-VcData -Type 'VSatellite' -First if ( -not $vSat ) { throw "An active VSatellite could not be found" } } $userEnc = ConvertTo-SodiumEncryptedString -text $Credential.UserName -PublicKey $vSat.encryptionKey $pwEnc = ConvertTo-SodiumEncryptedString -text $Credential.GetNetworkCredential().Password -PublicKey $vSat.encryptionKey switch ($PSCmdlet.ParameterSetName) { 'SshPassword' { $connectionDetails = @{ protocol = 'ssh2' protocolSsh = @{ hostnameOrAddress = if ($Hostname) { $Hostname } else { $Name } sshAuthentication = 'password' sshPassword = @{ credentialType = 'local' username = $userEnc password = $pwEnc } } } } 'SshKey' { $connectionDetails = @{ protocol = 'ssh2' protocolSsh = @{ hostnameOrAddress = if ($Hostname) { $Hostname } else { $Name } sshAuthentication = "key" sshPrivateKey = @{ credentialType = 'local' username = $userEnc privateKey = $pwEnc } } } } 'WinrmBasic' { $connectionDetails = @{ protocol = 'winrm2' protocolWinRm = @{ hostnameOrAddress = if ($Hostname) { $Hostname } else { $Name } authenticationType = "basic" credentialType = 'local' username = $userEnc password = $pwEnc } } } 'WinrmKerberos' { $connectionDetails = @{ protocol = 'winrm2' protocolWinRm = @{ hostnameOrAddress = if ($Hostname) { $Hostname } else { $Name } authenticationType = 'kerberos' credentialType = 'local' username = $userEnc password = $pwEnc kerberos = @{ domain = "$DomainName" keyDistributionCenter = "$KeyDistributionCenter" servicePrincipalName = "$SPN" } } } } } if ( $Port ) { $connectionDetails.protocolWinRm.port = $Port } if ( $UseTls ) { $connectionDetails.protocolWinRm.https = $true if ( $SkipCertificateCheck ) { $connectionDetails.protocolWinRm.skipTlsVerify = $true } } $params = @{ Name = $Name MachineType = $machineTypeId VSatellite = $vSat.vsatelliteId DekID = $vSat.encryptionKeyId Owner = $Owner ConnectionDetail = $connectionDetails } if ( $Tag ) { $params.Tag = $Tag } if ( $Status ) { $params.Status = $Status } $allMachines.Add( [pscustomobject]$params ) } end { $newParams = @{ NoVerify = $NoVerify ThrottleLimit = $ThrottleLimit PassThru = $true } $response = $allMachines | New-VcMachine @newParams if ( $PassThru ) { $response } } } #EndRegion './Public/New-VcMachineCommonKeystore.ps1' 327 #Region './Public/New-VcMachineIis.ps1' -1 function New-VcMachineIis { <# .SYNOPSIS Create a new IIS machine .DESCRIPTION Create a new IIS machine with either basic or kerberos authentication. By default, the machine details will be verified by performing a test connection; this can be turned off with -NoVerify. Creation will occur in parallel and PowerShell v7+ is required. .PARAMETER Name Machine name .PARAMETER VSatellite ID or name of a vsatellite. If not provided, the first vsatellite found will be used. .PARAMETER Owner ID or name of a team to be the owner of the machine .PARAMETER Tag Optional list of tags to assign .PARAMETER Hostname IP or fqdn of the machine. If this is to be the same value as -Name, this parameter can be ommitted. .PARAMETER Credential Username/password to access the machine .PARAMETER Port Optional WinRM port. The default is 5985. .PARAMETER UseTls Connect over HTTPS as opposed to the default of HTTP .PARAMETER SkipCertificateCheck If connecting over HTTPS and you wish to bypass certificate validation .PARAMETER DomainName Machine domain name .PARAMETER KeyDistributionCenter Address or hostname of the key distribution center .PARAMETER SPN Service Principal Name, eg. WSMAN/server.company.com .PARAMETER Status Set the machine status to either 'DRAFT', 'VERIFIED', or 'UNVERIFIED'. This optional field has been added for flexibility, but should not be needed under typical usage. The platform will handle changing the status to the appropriate value. Setting this to a value other than VERIFIED will affect the ability to initiate workflows. .PARAMETER NoVerify By default a connection to the host will be attempted. Use this switch to turn off this behavior. Not recommended. .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER PassThru Return newly created object .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .EXAMPLE $params = @{ Name = 'iis1' Owner = 'MyTeam' Hostname = 'iis1.company.com' Credential = $cred DomainName = 'company.com' KeyDistributionCenter = '1.2.3.4' SPN = 'WSMAN/iis1.company.com' } New-VcMachineIis @params machineId : 55e054d0-2b2a-11ee-9546-5136c4b21504 testConnection : @{Success=True; Error=; WorkflowID=c39310ee-51fc-49f3-8b5b-e504e1bc43d2} companyId : 20b24f81-b22b-11ea-91f3-ebd6dea5453f name : iis1 machineType : Microsoft IIS pluginId : be453281-d080-11ec-a07a-6d5bc1b54078 integrationId : 55df8877-2b2a-11ee-9264-9e16d4b8a8c9 edgeInstanceId : 0bc771e1-7abe-4339-9fcd-93fffe9cba7f creationDate : 7/25/2023 4:32:12 PM modificationDate : 7/25/2023 4:32:12 PM status : UNVERIFIED owningTeamId : 59920180-a3e2-11ec-8dcd-3fcbf84c7da7 Create a new machine with Kerberos authentication .NOTES This function requires the use of sodium encryption. .net standard 2.0 or greater is required via PS Core (recommended) or supporting .net runtime. On Windows, the latest Visual C++ redist must be installed. See https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist. #> [CmdletBinding(DefaultParameterSetName = 'WinrmBasic')] [Alias('New-VaasMachineIis')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'IIS is not plural')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(ValueFromPipelineByPropertyName)] [string] $VSatellite, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Owner, [Parameter(ValueFromPipelineByPropertyName)] [string] $Hostname, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [pscredential] $Credential, [Parameter(ValueFromPipelineByPropertyName)] [string[]] $Tag, [Parameter(ValueFromPipelineByPropertyName)] [ValidateSet('DRAFT', 'VERIFIED', 'UNVERIFIED')] [string] $Status, [Parameter(ValueFromPipelineByPropertyName)] [int] $Port, [Parameter(ValueFromPipelineByPropertyName)] [switch] $UseTls, [Parameter(ValueFromPipelineByPropertyName)] [switch] $SkipCertificateCheck, [Parameter(ParameterSetName = 'WinrmKerberos', Mandatory, ValueFromPipelineByPropertyName)] [string] $DomainName, [Parameter(ParameterSetName = 'WinrmKerberos', Mandatory, ValueFromPipelineByPropertyName)] [string] $KeyDistributionCenter, [Parameter(ParameterSetName = 'WinrmKerberos', Mandatory, ValueFromPipelineByPropertyName)] [string] $SPN, [Parameter()] [switch] $NoVerify, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allMachines = [System.Collections.Generic.List[pscustomobject]]::new() $machineTypeId = 'c1521d80-db7a-11ec-b79a-f3ded6c9808c' Initialize-PSSodium } process { # need vsat to get dek for encrypting username/password if ( $VSatellite ) { $vSat = Get-VcData -InputObject $VSatellite -Type 'VSatellite' -Object if ( -not $vSat ) { throw "'$VSatellite' is either not a valid VSatellite id or name or it is not active" } } else { $vSat = Get-VcData -Type 'VSatellite' -First if ( -not $vSat ) { throw "An active VSatellite could not be found" } } $userEnc = ConvertTo-SodiumEncryptedString -text $Credential.UserName -PublicKey $vSat.encryptionKey $pwEnc = ConvertTo-SodiumEncryptedString -text $Credential.GetNetworkCredential().Password -PublicKey $vSat.encryptionKey switch ($PSCmdlet.ParameterSetName) { 'WinrmBasic' { $connectionDetails = @{ hostnameOrAddress = if ($Hostname) { $Hostname } else { $Name } authenticationType = "basic" credentialType = 'local' username = $userEnc password = $pwEnc } } 'WinrmKerberos' { $connectionDetails = @{ hostnameOrAddress = if ($Hostname) { $Hostname } else { $Name } authenticationType = 'kerberos' credentialType = 'local' username = $userEnc password = $pwEnc kerberos = @{ domain = "$DomainName" keyDistributionCenter = "$KeyDistributionCenter" servicePrincipalName = "$SPN" } } } } if ( $Port ) { $connectionDetails.protocolWinRm.port = $Port } if ( $UseTls ) { $connectionDetails.protocolWinRm.https = $true if ( $SkipCertificateCheck ) { $connectionDetails.protocolWinRm.skipTlsVerify = $true } } $params = @{ Name = $Name MachineType = $machineTypeId VSatellite = $vSat.vsatelliteId DekID = $vSat.encryptionKeyId Owner = $Owner ConnectionDetail = $connectionDetails } if ( $Tag ) { $params.Tag = $Tag } if ( $Status ) { $params.Status = $Status } $allMachines.Add( [pscustomobject]$params ) } end { $newParams = @{ NoVerify = $NoVerify ThrottleLimit = $ThrottleLimit PassThru = $true } $response = $allMachines | New-VcMachine @newParams if ( $PassThru ) { $response } } } #EndRegion './Public/New-VcMachineIis.ps1' 269 #Region './Public/New-VcTeam.ps1' -1 function New-VcTeam { <# .SYNOPSIS Create a new team .DESCRIPTION Create a new TLSPC team .PARAMETER Name Team name .PARAMETER Owner 1 or more owners for the team. Provide the unique guid obtained from Get-VcIdentity. .PARAMETER Member 1 or more members for the team. Provide the unique guid obtained from Get-VcIdentity. .PARAMETER Role Team role, either 'System Admin', 'PKI Admin', 'Resource Owner' or 'Guest' .PARAMETER UserMatchingRule If SSO is enabled, build your team membership rules to organize your users into teams automatically. If more than 1 rule is configured, they must all be met for a user to meet the criteria. Each rule should be of the format @('claim name', 'operator', 'value') where operator can be equals, not_equals, contains, not_contains, starts_with, or ends_with. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .EXAMPLE New-VenafiTeam -Name 'My New Team' -Member 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Owner @('ca7ff555-88d2-4bfc-9efa-2630ac44c1f3', 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f4') -Role 'System Admin' Create a new team .EXAMPLE New-VenafiTeam -Name 'My New Team' -Member 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Owner @('ca7ff555-88d2-4bfc-9efa-2630ac44c1f3', 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f4') -Role 'System Admin' -UserMatchingRule @('MyClaim', 'CONTAINS', 'Group') Create a new team with user matching rule .EXAMPLE New-VenafiTeam -Name 'My New Team' -Member 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Owner @('ca7ff555-88d2-4bfc-9efa-2630ac44c1f3', 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f4') -Role 'System Admin' -PassThru id : a7d60730-a967-11ec-8832-4d051bf6d0b4 name : My New Team systemRoles : {SYSTEM_ADMIN} productRoles : role : SYSTEM_ADMIN members : {443de910-a6cc-11ec-ad22-018e33741844} owners : {0a2adae0-b22b-11ea-91f3-ebd6dea5452e} companyId : 0bc771e1-7abe-4339-9fcd-93fffe9cba7f userMatchingRules : {} modificationDate : 3/21/2022 6:38:40 PM Create a new team returning the new team .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html#/Teams/create_1 .LINK https://docs.venafi.cloud/vcs-platform/creating-new-teams/ #> [CmdletBinding()] param ( [Parameter(Mandatory)] [string] $Name, [Parameter(Mandatory)] [string[]] $Owner, [Parameter(Mandatory)] [string[]] $Member, [Parameter(Mandatory)] [ValidateSet('System Admin', 'PKI Admin', 'Resource Owner', 'Guest')] [string] $Role, [Parameter()] [System.Collections.Generic.List[array]] $UserMatchingRule, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { $params = @{ Method = 'Post' UriLeaf = 'teams' } $rules = foreach ($rule in $UserMatchingRule) { if ( $rule.Count -ne 3 ) { throw 'Each rule must contain a claim name, operator, and value' } if ( $rule[1].ToUpper() -notin 'EQUALS', 'NOT_EQUALS', 'CONTAINS', 'NOT_CONTAINS', 'STARTS_WITH', 'ENDS_WITH') { throw 'Valid values for operator are EQUALS, NOT_EQUALS, CONTAINS, NOT_CONTAINS, STARTS_WITH, ENDS_WITH' } @{ 'claimName' = $rule[0] 'operator' = $rule[1].ToUpper() 'value' = $rule[2] } } $params.Body = @{ 'name' = $Name 'role' = $Role.Replace(' ', '_').ToUpper() 'members' = @($Member) 'owners' = @($Owner) 'userMatchingRules' = @($rules) } $response = Invoke-VenafiRestMethod @params if ( $PassThru ) { $response | Get-VcTeam } } } #EndRegion './Public/New-VcTeam.ps1' 137 #Region './Public/New-VcWebhook.ps1' -1 function New-VcWebhook { <# .SYNOPSIS Create a new webhook .DESCRIPTION Create a new webhook .PARAMETER Name Webhook name .PARAMETER Url Endpoint to be called when the event type/name is triggered. This should be the full url and will be validated during webhook creation. .PARAMETER EventType One or more event types to trigger on. You can retrieve a list of possible values from the Event Log and filtering on Event Type. .PARAMETER EventName One or more event names to trigger on. .PARAMETER Secret Secret value used to calculate signature which will be sent to the endpoint in the header .PARAMETER CriticalOnly Only subscribe to log messages deemed as critical .PARAMETER PassThru Return newly created webhook object .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .OUTPUTS PSCustomObject, if PassThru provided .EXAMPLE New-VcWebhook -Name 'MyWebhook' -Url 'https://my.com/endpoint' -EventType 'Authentication' Create a new webhook for one event type .EXAMPLE New-VcWebhook -Name 'MyWebhook' -Url 'https://my.com/endpoint' -EventType 'Authentication', 'Certificates', 'Applications' Create a new webhook with multiple event types .EXAMPLE New-VcWebhook -Name 'MyWebhook' -Url 'https://my.com/endpoint' -EventName 'Certificate Validation Started' Create a new webhook with event names as opposed to event types. This will result in fewer messages received as opposed to subscribing at the event type level. .EXAMPLE New-VcWebhook -Name 'MyWebhook' -Url 'https://my.com/endpoint' -EventType 'Certificates' -CriticalOnly Subscribe to critical messages only for a specific event type .EXAMPLE New-VcWebhook -Name 'MyWebhook' -Url 'https://my.com/endpoint' -EventType 'Authentication' -Secret 'MySecret' Create a new webhook with optional secret .EXAMPLE New-VcWebhook -Name 'MyWebhook' -Url 'https://my.com/endpoint' -EventType 'Authentication' -PassThru Create a new webhook returning the newly created object .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html?urls.primaryName=connectors-service#/Connectors/connectors_create #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'EventName')] param ( [Parameter(Mandatory)] [string] $Name, [Parameter(Mandatory)] [string] $Url, [Parameter(Mandatory, ParameterSetName = 'EventType')] [String[]] $EventType, [Parameter(Mandatory, ParameterSetName = 'EventName')] [String[]] $EventName, [Parameter()] [ValidateNotNullOrEmpty()] [Alias('token')] [string] $Secret, [Parameter()] [switch] $CriticalOnly, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' # validate inputs $at = Invoke-VenafiRestMethod -UriLeaf 'activitytypes' if ( $PSBoundParameters.ContainsKey('EventType') ) { $compare = compare-object -ReferenceObject $EventType -DifferenceObject $at.readablename | Where-Object { $_.SideIndicator -eq '<=' } if ( $compare ) { throw ('{0} are not valid event types. Valid values include {1}.' -f ($compare.InputObject -join ', '), ($at.readablename -join ', ')) } } else { $compare = compare-object -ReferenceObject $EventName -DifferenceObject $at.values.readablename | Where-Object { $_.SideIndicator -eq '<=' } if ( $compare ) { throw ('{0} are not valid event names. Valid values include {1}.' -f ($compare.InputObject -join ', '), ($at.values.readablename -join ', ')) } } } process { $params = @{ VenafiSession = $VenafiSession Method = 'Post' UriRoot = 'v1' UriLeaf = 'connectors' Body = @{ name = $Name properties = @{ 'connectorKind' = 'WEBHOOK' 'target' = @{ 'type' = 'generic' 'connection' = @{ 'url' = $Url } } 'filter' = @{ criticality = [int]$CriticalOnly.IsPresent } } } FullResponse = $true } # either event type or name will be provided if ( $PSBoundParameters.ContainsKey('EventType') ) { $params.Body.properties.filter.activityTypes = @($EventType) } else { $params.Body.properties.filter.activities = @($EventName) } if ( $PSBoundParameters.ContainsKey('Secret') ) { $params.Body.properties.target.connection.secret = $Secret } if ( $PSCmdlet.ShouldProcess($Name, 'Create webhook') ) { try { $response = Invoke-VenafiRestMethod @params switch ( $response.StatusCode ) { 201 { if ( $PassThru ) { $response.Content | ConvertFrom-Json | Select-Object -Property @{'n' = 'webhookId'; 'e' = { $_.id } }, * -ExcludeProperty id } } 409 { throw "Webhook '$Name' already exists" } default { throw $response } } } catch { $PSCmdlet.ThrowTerminatingError($PSItem) } } } } #EndRegion './Public/New-VcWebhook.ps1' 190 #Region './Public/New-VdcCapiApplication.ps1' -1 function New-VdcCapiApplication { <# .SYNOPSIS Create a new CAPI application .DESCRIPTION Create a new CAPI application .PARAMETER Path Full path, including name, to the application to be created. The application must be created under a device. Alternatively, provide the path to the device and provide ApplicationName. .PARAMETER ApplicationName 1 or more application names to create. Path property must be a path to a device. .PARAMETER CertificatePath Path to the certificate to associate to the new application .PARAMETER CredentialPath Path to the associated credential which has rights to access the connected device .PARAMETER FriendlyName The Friendly Name that helps to uniquely identify the certificate after it has been installed in the Windows CAPI store .PARAMETER Descripion Application description .PARAMETER WinRmPort WinRM port to connect to application on .PARAMETER Disable Set processing to disabled. It is enabled by default. .PARAMETER WebSiteName The unique name of the IIS web site .PARAMETER BindingIp The IP address to bind the certificate to the IIS web site. If not specified, the Internet Information Services (IIS) Manager console shows 'All Unassigned'. .PARAMETER BindingPort The TCP port 1 to 65535 to bind the certificate to the IIS web site .PARAMETER BindingHostName The hostname to bind the certificate to the IIS web site. Specifying this value will make it so the certificate is only accessible to clients using Server Name Indication (SNI) .PARAMETER CreateBinding Specify that Trust Protection Platform should create an IIS web site binding if the one specified doesn’t already exist. .PARAMETER PushCertificate Push the certificate to the application. CertificatePath must be provided. .PARAMETER SkipExistenceCheck By default, the paths for the new application, certifcate, and credential will be validated for existence. Specify this switch to bypass this check. .PARAMETER PassThru Return a TppObject representing the newly created capi app. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS TppObject, if PassThru provided .EXAMPLE New-VdcCapiApplication -Path '\ved\policy\mydevice\capi' -CertificatePath $cert.Path -CredentialPath $cred.Path Create a new application .EXAMPLE New-VdcCapiApplication -Path '\ved\policy\mydevice\capi' -CertificatePath $cert.Path -CredentialPath $cred.Path -WebSiteName 'mysite' -BindingIp '1.2.3.4' Create a new application and update IIS .EXAMPLE New-VdcCapiApplication -Path '\ved\policy\mydevice\capi' -CertificatePath $cert.Path -CredentialPath $cred.Path -WebSiteName 'mysite' -BindingIp '1.2.3.4' -PushCertificate Create a new application, update IIS, and push the certificate to the new app .EXAMPLE New-VdcCapiApplication -Path '\ved\policy\mydevice\capi' -CertificatePath $cert.Path -CredentialPath $cred.Path -PassThru Create a new application and return a TppObject for the newly created app .LINK http://VenafiPS.readthedocs.io/en/latest/functions/New-VdcCapiApplication/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/New-VdcCapiApplication.ps1 .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/New-VdcObject.ps1 .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Find-VdcCertificate/ .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Get-VdcObject/ .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-create.php #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'NonIis')] [Alias('New-TppCapiApplication')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', '')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [string] $Path, [Parameter()] [ValidateNotNullOrEmpty()] [string[]] $ApplicationName, [Parameter()] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('CertificateDN')] [String] $CertificatePath, [Parameter()] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('CredentialDN')] [String] $CredentialPath, [Parameter()] [ValidateNotNullOrEmpty()] [String] $FriendlyName, [Parameter()] [ValidateNotNullOrEmpty()] [String] $Description, [Parameter()] [ValidateNotNullOrEmpty()] [Int] $WinRmPort, [Parameter()] [Switch] $Disable, [Parameter(Mandatory, ParameterSetName = 'Iis')] [ValidateNotNullOrEmpty()] [String] $WebSiteName, [Parameter(ParameterSetName = 'Iis')] [ValidateNotNullOrEmpty()] [Alias('BindingIpAddress')] [ipaddress] $BindingIp, [Parameter(ParameterSetName = 'Iis')] [ValidateNotNullOrEmpty()] [Int] $BindingPort, [Parameter(ParameterSetName = 'Iis')] [ValidateNotNullOrEmpty()] [String] $BindingHostName, [Parameter(ParameterSetName = 'Iis')] [ValidateNotNullOrEmpty()] [bool] $CreateBinding, [Parameter()] [switch] $PushCertificate, [Parameter()] [switch] $SkipExistenceCheck, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' if ( $PushCertificate.IsPresent -and (-not $PSBoundParameters.ContainsKey('CertificatePath')) ) { throw 'A CertificatePath must be provided when using PushCertificate' } if ( -not $PSBoundParameters.ContainsKey('SkipExistenceCheck') ) { if ( $PSBoundParameters.ContainsKey('CertificatePath') ) { # issue 129 $certName = $CertificatePath.Split('\')[-1] $certPath = $CertificatePath.Substring(0, $CertificatePath.LastIndexOf("\$certName")) $certObject = Find-VdcCertificate -Path $certPath if ( -not $certObject -or ($certName -notin $certObject.Name) ) { throw ('A certificate object could not be found at ''{0}''' -f $CertificatePath) } } # ensure the credential exists and is actually of type credential if ( $PSBoundParameters.ContainsKey('CredentialPath') ) { $credObject = Get-VdcObject -Path $CredentialPath if ( -not $credObject -or $credObject.TypeName -notlike '*credential*' ) { throw ('A credential object could not be found at ''{0}''' -f $CredentialPath) } } } $params = @{ Path = '' Class = 'CAPI' Attribute = @{ 'Driver Name' = 'appcapi' } PassThru = $true } if ( $PSBoundParameters.ContainsKey('FriendlyName') ) { $params.Attribute.Add('Friendly Name', $FriendlyName) } if ( $PSBoundParameters.ContainsKey('CertificatePath') ) { $params.Attribute.Add('Certificate', $CertificatePath) } if ( $PSBoundParameters.ContainsKey('CredentialPath') ) { $params.Attribute.Add('Credential', $CredentialPath) } if ( $Disable.IsPresent ) { $params.Attribute.Add('Disabled', '1') } if ( $PSBoundParameters.ContainsKey('WebSiteName') ) { $params.Attribute.Add('Update IIS', '1') $params.Attribute.Add('Web Site Name', $WebSiteName) } if ( $PSBoundParameters.ContainsKey('BindingIp') ) { $params.Attribute.Add('Binding IP Address', $BindingIp.ToString()) } if ( $PSBoundParameters.ContainsKey('BindingPort') ) { $params.Attribute.Add('Binding Port', $BindingPort.ToString()) } if ( $PSBoundParameters.ContainsKey('BindingHostName') ) { $params.Attribute.Add('Hostname', $BindingHostName) } if ( $PSBoundParameters.ContainsKey('CreateBinding') ) { $params.Attribute.Add('Create Binding', ([int]$CreateBinding).ToString()) } if ( $PSBoundParameters.ContainsKey('WinRmPort') ) { $params.Attribute.Add('Port', $WinRmPort.ToString()) } } process { if ( -not $PSBoundParameters.ContainsKey('SkipExistenceCheck') ) { # ensure the parent path exists and is of type device if ( $PSBoundParameters.ContainsKey('ApplicationName') ) { $devicePath = $Path } else { $deviceName = $Path.Split('\')[-1] $devicePath = $Path -replace ('\\+{0}' -f $deviceName), '' } $device = Get-VdcObject -Path $devicePath if ( $device ) { if ( $device.TypeName -ne 'Device' ) { throw ('A device object could not be found at ''{0}''' -f $devicePath) } } else { throw ('No object was found at the parent path ''{0}''' -f $devicePath) } } if ( $PSBoundParameters.ContainsKey('ApplicationName') ) { $appPaths = $ApplicationName | ForEach-Object { $Path + "\$_" } } else { $appPaths = @($Path) } if ( $PSCmdlet.ShouldProcess($Path, 'Create CAPI application(s)') ) { foreach ($thisPath in $appPaths) { $params.Path = $thisPath $response = New-VdcObject @params if ( $PassThru ) { $response } } if ( $PushCertificate.IsPresent ) { $params = @{ Path = $CertificatePath AdditionalParameter = @{ ApplicationDN = @($appPaths) } Push = $true } Invoke-VdcCertificateAction @params } } } end {} } #EndRegion './Public/New-VdcCapiApplication.ps1' 352 #Region './Public/New-VdcCertificate.ps1' -1 function New-VdcCertificate { <# .SYNOPSIS Enrolls or provisions a new certificate .DESCRIPTION Enrolls or provisions a new certificate. Prior to TLSPDC 22.1, this function is asynchronous and will always return success. Beginning with 22.1, you can control this behavior. See https://docs.venafi.com/Docs/currentSDK/TopNav/Content/SDK/WebSDK/r-SDK-Certificates-API-settings.php. .PARAMETER Path The folder DN path for the new certificate. .PARAMETER Name Name of the certifcate object. If CommonName isn't provided, this value will be used. .PARAMETER CommonName Subject Common Name. If CommonName isn't provided, Name 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. The default is X.509 Server Certificate. .PARAMETER CertificateAuthorityPath The path of the Certificate Authority Template object for enrolling the certificate. If the value is missing, it is expected a policy has been applied to Path. .PARAMETER CertificateAuthorityAttribute Name/value pairs providing any CA attributes to store with the Certificate object. During enrollment, these values will be submitted to the CA. .PARAMETER ManagementType The level of management that Trust Protection Platform applies to the certificate: - Enrollment: Default. Issue a new certificate, renewed certificate, or key generation request to a CA for enrollment. Do not automatically provision the certificate. - Provisioning: Issue a new certificate, renewed certificate, or key generation request to a CA for enrollment. Automatically install or provision the certificate. - Monitoring: Allow Trust Protection Platform to monitor the certificate for expiration and renewal. - Unassigned: Certificates are neither enrolled or monitored by Trust Protection Platform. .PARAMETER SubjectAltName A list of Subject Alternate Names. The value must be 1 or more hashtables with the SAN type and value. Acceptable SAN types are OtherName, Email, DNS, URI, and IPAddress. You can provide more than 1 of the same SAN type with multiple hashtables. .PARAMETER CustomField 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 TimeoutSec Introduced in 22.1, this controls the wait time, in seconds, for a CA to issue/renew a certificate. The default is 60 seconds. .PARAMETER PassThru Return an object representing the newly created certificate. If devices and/or applications were created, a 'Device' property will be available as well. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS None .OUTPUTS TppObject, if PassThru is provided If devices and/or applications were created, a 'Device' property will be available as well. .EXAMPLE New-VdcCertificate -Path '\ved\policy\folder' -Name 'mycert.com' Create certificate by name. A CA template policy must be defined. .EXAMPLE New-VdcCertificate -Path '\ved\policy\folder' -Name 'mycert.com' -CertificateAuthorityPath '\ved\policy\CA Templates\my template' Create certificate by name with specific CA template .EXAMPLE New-VdcCertificate -Path '\ved\policy\folder' -CertificateAuthorityPath '\ved\policy\CA Templates\my template' -Csr '-----BEGIN CERTIFICATE REQUEST-----\nMIIDJDCCAgwCAQAw...-----END CERTIFICATE REQUEST-----' Create certificate using a CSR .EXAMPLE New-VdcCertificate -Path '\ved\policy\folder' -Name 'mycert.com' -CertificateAuthorityPath '\ved\policy\CA Templates\my template' -CustomField @{''=''} Create certificate and update custom fields .EXAMPLE New-VdcCertificate -Path '\ved\policy\folder' -CommonName 'mycert.com' -CertificateAuthorityPath '\ved\policy\CA Templates\my template' -PassThru Create certificate using common name. Return the created object. .EXAMPLE New-VdcCertificate -Path '\ved\policy\folder' -Name 'mycert.com' -CertificateAuthorityPath '\ved\policy\CA Templates\my template' -SubjectAltName @{'Email'='me@x.com'},@{'IPAddress'='1.2.3.4'} Create certificate including subject alternate names .EXAMPLE New-VdcCertificate -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-VdcCertificate/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/New-VdcCertificate.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Certificates-request.php #> [CmdletBinding(DefaultParameterSetName = 'ByName', SupportsShouldProcess)] [Alias('New-TppCertificate')] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('PolicyDN')] [String] $Path, [Parameter(Mandatory, ParameterSetName = 'ByName', ValueFromPipeline)] [Parameter(Mandatory, ParameterSetName = 'ByNameWithDevice', ValueFromPipeline)] [ValidateNotNullOrEmpty()] [String] $Name, [Parameter()] [ValidateNotNullOrEmpty()] [Alias('Subject')] [String] $CommonName, [Parameter()] [string] $Csr, [Parameter()] [String] $CertificateType, [Parameter()] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('CertificateAuthorityDN')] [Alias('CADN')] [String] $CertificateAuthorityPath, [Parameter()] [Hashtable] $CertificateAuthorityAttribute, [Parameter()] [TppManagementType] $ManagementType, [Parameter()] [Hashtable[]] $SubjectAltName, [Parameter()] [Hashtable] $CustomField, [Parameter()] [switch] $NoWorkToDo, [Parameter(ParameterSetName = 'ByName')] [Parameter(Mandatory, ParameterSetName = 'ByNameWithDevice')] [hashtable[]] $Device, [Parameter(ParameterSetName = 'ByNameWithDevice')] [hashtable[]] $Application, [Parameter()] [Alias('WorkToDoTimeout')] [int32] $TimeoutSec = 60, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' if ( $PSBoundParameters.ContainsKey('SubjectAltName') ) { $errors = $SubjectAltName | ForEach-Object { $_.GetEnumerator() | ForEach-Object { $thisKey = $_.Key $thisValue = $_.Value switch ($thisKey) { 'OtherName' { # no validaton } 'Email' { try { $null = [mailaddress]$thisValue } catch { ('''{0}'' is not a valid email' -f $thisValue) } } 'DNS' { # no validaton } 'URI' { # no validaton } 'IPAddress' { try { $null = [ipaddress]$thisValue } catch { ('''{0}'' is not a valid IP Address' -f $thisValue) } } Default { # invalid type name provided ('''{0}'' is not a valid SAN type. Valid values include OtherName, Email, DNS, URI, and IPAddress.' -f $thisKey) } } } } if ( $errors ) { throw $errors } } $params = @{ Method = 'Post' UriLeaf = 'certificates/request' Body = @{ PolicyDN = $Path Origin = 'VenafiPS' CASpecificAttributes = @( @{ 'Name' = 'Origin' 'Value' = 'VenafiPS' } ) SetWorkToDo = -not $NoWorkToDo } } if ( $CertificateType ) { $params.Body.Add('CertificateType', $CertificateType) } if ( $PSBoundParameters.ContainsKey('CertificateAuthorityAttribute') ) { $CertificateAuthorityAttribute.GetEnumerator() | ForEach-Object { $params.Body.CASpecificAttributes += @{ 'Name' = $_.Key 'Value' = $_.Value } } } if ( $Csr ) { $params.Body.Add('PKCS10', ($Csr -replace "`n|`r")) } if ( $PSBoundParameters.ContainsKey('CertificateAuthorityPath') ) { $params.Body.Add('CADN', $CertificateAuthorityPath) } if ( $PSBoundParameters.ContainsKey('CommonName') ) { $params.Body.Add('Subject', $CommonName) } if ( $PSBoundParameters.ContainsKey('ManagementType') ) { $params.Body.Add('ManagementType', [enum]::GetName([TppManagementType], $ManagementType)) } $params.Body.Add('WorkToDoTimeout', $TimeoutSec) if ( $PSBoundParameters.ContainsKey('SubjectAltName') ) { $newSan = @($SubjectAltName | ForEach-Object { $_.GetEnumerator() | ForEach-Object { @{ 'TypeName' = $_.Key 'Name' = $_.Value } } } ) $params.Body.Add('SubjectAltNames', $newSan) } if ( $PSBoundParameters.ContainsKey('CustomField') ) { $newCf = $CustomField.GetEnumerator() | ForEach-Object { @{ 'Name' = $_.Key 'Values' = @($_.Value) } } $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 { $params.Body.ObjectName = $Name if ( -not $PSBoundParameters.ContainsKey('CommonName')) { $params.Body.Subject = $Name } if ( $PSCmdlet.ShouldProcess("$Path\$Name", 'Create new certificate') ) { try { $response = Invoke-VenafiRestMethod @params Write-Verbose ($response | Out-String) if ( $PassThru ) { $newCert = Get-VdcObject -Path $response.CertificateDN if ( $Device ) { $newCert | Add-Member @{ 'Device' = @{'Path' = $response.Devices.DN } } if ( $Application ) { $newCert.Device.Application = $response.Devices.Applications.DN } } $newCert } } catch { Write-Error $_ continue } } } } #EndRegion './Public/New-VdcCertificate.ps1' 398 #Region './Public/New-VdcCustomField.ps1' -1 function New-VdcCustomField { <# .SYNOPSIS Create new custom field in Venafi of the specified class and type. .DESCRIPTION Creates a new custom field in Venafi. Required parameters are name, label, class and type. See Venafi docs for information about other metadata items. .PARAMETER Name Name of new custom field .PARAMETER Label Label of new custom field .PARAMETER Class Class of new custom field, either 'Device' or 'X509 Certificate' .PARAMETER Type Type of new custom field, one of 'String', 'List', 'DateTime', 'Identity' .PARAMETER AllowedValue An array of allowable values for the Custom Field. .PARAMETER Single Controls the number of input selections. If not used the user can select multiple values for the Custom Field. Otherwise the user can select only one value .PARAMETER Help The tool tip to show to the user how to populate the Custom Field. .PARAMETER ErrorMessage The error message that you define for this Custom Field. .PARAMETER Mandatory Determines if a value is required in the custom field. If not used a value is optional, otherwise the user must enter a value. .PARAMETER Policyable Determines if the custom field can be used in a policy setting to apply to all objects in the policy. If not used the custom field cannot apply to a policy. .PARAMETER RegEx The regular expression to control user input. .PARAMETER RenderHidden Controls the visibility of the custom field in the UI. By default custom fields are visible in the class they are created for. This switch hides them. .PARAMETER RenderReadOnly Controls if the custom field is read only. By default a user can change the custom field value. This switch makes it the custom field value cannot be changed. .PARAMETER DateOnly Controls if the custom field requires a calendar date. By default a date is not required. .PARAMETER TimeOnly Controls if the custom field requires a time of day. By default a time is not required. .PARAMETER PassThru Return a PSCustomObject with the following properties: AllowedValues Class DateOnly DN ErrorMessage Guid Help Label Mandatory Name Policyable RegularExpression RenderHidden RenderReadOnly Single TimeOnly Type .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS None .OUTPUTS PSCustomObject, if PassThru provided .EXAMPLE New-VdcCustomField -Name "Last Date" -Label "Last Date" -Class "X509 Certificate" -Type "String" -RenderReadOnly -Help "Last Date of certificate import" Create new custom field for certificates .LINK http://VenafiPS.readthedocs.io/en/latest/functions/New-VdcCustomField/ .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Metadata-DefineItem.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Metadata-Item.php #> [CmdletBinding(SupportsShouldProcess)] [Alias('New-TppCustomField')] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Label, [Parameter(Mandatory)] [ValidateSet('Device', 'X509 Certificate')] [ValidateNotNullOrEmpty()] [string[]]$Class, [Parameter(Mandatory)] [ValidateSet('String', 'List', 'DateTime', 'Identity')] [ValidateNotNullOrEmpty()] [string]$Type, [Parameter()] [string[]]$AllowedValue, [Parameter()] [switch]$Single, [Parameter()] [string]$Help, [Parameter()] [string]$ErrorMessage, [Parameter()] [switch]$Mandatory, [Parameter()] [switch]$Policyable, [Parameter()] [string]$RegEx, [Parameter()] [switch]$RenderHidden, [Parameter()] [switch]$RenderReadOnly, [Parameter()] [switch]$DateOnly, [Parameter()] [switch]$TimeOnly, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $resultObj = @() if ( $Type -eq 'String' ) { $ItemType = '1' } elseif ( $Type -eq 'List' ) { $ItemType = '2' } elseif ( $Type -eq 'DateTime' ) { $ItemType = '4' } elseif ( $Type -eq 'Identity' ) { $ItemType = '5' } $params = @{ Method = 'Post' UriLeaf = 'Metadata/DefineItem' Body = @{ "Item" = @{ "Name" = $Name "Classes" = @($Class) "Label" = $Label "Type" = $ItemType "Single" = $Single.ToString().ToLower() "Mandatory" = $Mandatory.ToString().ToLower() "Policyable" = $Policyable.ToString().ToLower() "RenderHidden" = $RenderHidden.ToString().ToLower() "RenderReadOnly" = $RenderReadOnly.ToString().ToLower() "DateOnly" = $DateOnly.ToString().ToLower() "TimeOnly" = $TimeOnly.ToString().ToLower() } } } if ( $PSBoundParameters.ContainsKey('Help') ) { $params.Body.Item['Help'] = $Help } if ( $PSBoundParameters.ContainsKey('AllowedValue') ) { $params.Body.Item['AllowedValues'] = @($AllowedValue) } if ( $PSBoundParameters.ContainsKey('ErrorMessage') ) { $params.Body.Item['ErrorMessage'] = $ErrorMessage } if ( $PSBoundParameters.ContainsKey('RegEx') ) { $params.Body.Item['RegularExpression'] = $RegEx } } end { if ( $PSCmdlet.ShouldProcess($Label) ) { $response = Invoke-VenafiRestMethod @params if ( $response.Result -eq [TppMetadataResult]::Success ) { if (( $PassThru )) { $resultObj = [PSCustomObject] @{ "Path" = $response.Item.DN "Label" = $response.Item.Label "Name" = $response.Item.Name "Guid" = [guid]$response.Item.Guid "Type" = $response.Item.Type "Class" = $response.Item.Classes } if ($response.Item.Mandatory) { $resultObj | Add-Member -MemberType NoteProperty -Name "Mandatory" -Value $response.Item.Mandatory } if ($response.Item.Policyable) { $resultObj | Add-Member -MemberType NoteProperty -Name "Policyable" -Value $response.Item.Policyable } if ($response.Item.RenderHidden) { $resultObj | Add-Member -MemberType NoteProperty -Name "RenderHidden" -Value $response.Item.RenderHidden } if ($response.Item.RenderReadOnly) { $resultObj | Add-Member -MemberType NoteProperty -Name "RenderReadOnly" -Value $response.Item.RenderReadOnly } if ($response.Item.DateOnly) { $resultObj | Add-Member -MemberType NoteProperty -Name "DateOnly" -Value $response.Item.DateOnly } if ($response.Item.TimeOnly) { $resultObj | Add-Member -MemberType NoteProperty -Name "TimeOnly" -Value $response.Item.TimeOnly } if ($response.Item.Help) { $resultObj | Add-Member -MemberType NoteProperty -Name "Help" -Value $response.Item.Help } if ($response.Item.AllowedValues) { $resultObj | Add-Member -MemberType NoteProperty -Name "AllowedValues" -Value $response.Item.AllowedValues } if ($response.Item.Single) { $resultObj | Add-Member -MemberType NoteProperty -Name "Single" -Value $response.Item.Single } if ($response.Item.ErrorMessage) { $resultObj | Add-Member -MemberType NoteProperty -Name "ErrorMessage" -Value $response.Item.ErrorMessage } if ($response.Item.RegularExpression) { $resultObj | Add-Member -MemberType NoteProperty -Name "RegularExpression" -Value $response.Item.RegularExpression } return $resultObj } } else { throw $response.Error } } } } #EndRegion './Public/New-VdcCustomField.ps1' 280 #Region './Public/New-VdcDevice.ps1' -1 function New-VdcDevice { <# .SYNOPSIS Add a new device .DESCRIPTION Add a new device with optional attributes .PARAMETER Path Full path to the new device. Alternatively, you can provide just the policy path, but then DeviceName must be provided. .PARAMETER DeviceName Name of 1 or more devices to create. Path must be of type Policy to use this. .PARAMETER Description Device description .PARAMETER CredentialPath Path to the credential which has permissions to update the device .PARAMETER Hostname Hostname or IP Address of the device .PARAMETER PassThru Return a TppObject representing the newly created policy. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS TppObject, if PassThru provided .EXAMPLE $newPolicy = New-VdcDevice -Path '\VED\Policy\MyFolder\device' -PassThru Create device with full path to device and returning the object created .EXAMPLE $policyPath | New-VdcDevice -DeviceName 'myDevice' -Hostname 1.2.3.4 Pipe policy path and provide device details .LINK http://VenafiPS.readthedocs.io/en/latest/functions/New-VdcDevice/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/New-VdcDevice.ps1 .LINK http://VenafiPS.readthedocs.io/en/latest/functions/New-VdcObject/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/New-VdcObject.ps1 #> [CmdletBinding(SupportsShouldProcess)] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', '')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [string] $Path, [Parameter()] [ValidateNotNullOrEmpty()] [String[]] $DeviceName, [Parameter()] [ValidateNotNullOrEmpty()] [String] $Description, [Parameter()] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [string] $CredentialPath, [Parameter()] [Alias('IpAddress')] [string] $Hostname, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { # leave .Validate() out as New-VdcObject will do it for us later $params = @{ Path = '' Class = 'Device' PassThru = $true Attribute = @{ } } if ( $PSBoundParameters.ContainsKey('Description') ) { $params.Attribute['Description'] = $Description } if ( $PSBoundParameters.ContainsKey('CredentialPath') ) { $params.Attribute['Credential'] = $CredentialPath } if ( $PSBoundParameters.ContainsKey('Hostname') ) { $params.Attribute['Host'] = $Hostname } # if no attributes were provided, we need to pull out the attribute key # otherwise the request will fail if ( $params.Attribute.Count -eq 0 ) { $params.Remove('Attribute') } } process { if ( $PSBoundParameters.ContainsKey('DeviceName') ) { $devicePaths = $DeviceName | ForEach-Object { $Path + "\$_" } } else { $devicePaths = @($Path) } foreach ($thisPath in $devicePaths) { $params.Path = $thisPath if ( $PSCmdlet.ShouldProcess($thisPath, 'Create Device Object') ) { $response = New-VdcObject @params if ( $PassThru ) { $response } } } } } #EndRegion './Public/New-VdcDevice.ps1' 166 #Region './Public/New-VdcObject.ps1' -1 function New-VdcObject { <# .SYNOPSIS Create a new object .DESCRIPTION Generic use function to create a new object if a specific function hasn't been created yet for the class. .PARAMETER Path Full path, including name, for the object to be created. If the root path is excluded, \ved\policy will be prepended. .PARAMETER Class Class name of the new object. See https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/SchemaReference/r-SDK-CNattributesWhere.php for more info. .PARAMETER Attribute Hashtable with initial values for the new object. These will be specific to the object class being created. .PARAMETER PushCertificate If creating an application object, you can optionally push the certificate once the creation is complete. Only available if a 'Certificate' key containing the certificate path is provided for Attribute. .PARAMETER Force Force the creation of missing parent policy folders when the class is either Policy or Device. .PARAMETER PassThru Return a TppObject representing the newly created object. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .EXAMPLE New-VdcObject -Path '\VED\Policy\Test Device' -Class 'Device' -Attribute @{'Description'='new device testing'} Create a new object .EXAMPLE New-VdcObject -Path 'missing\folder\again' -Class 'Policy' -Force Create a new object as well as any missing policy folders in the path .EXAMPLE New-VdcObject -Path '\VED\Policy\Test Device' -Class 'Device' -Attribute @{'Description'='new device testing'} -PassThru Create a new object and return the resultant object .EXAMPLE New-VdcObject -Path '\VED\Policy\Test Device\App' -Class 'Basic' -Attribute @{'Driver Name'='appbasic';'Certificate'='\Ved\Policy\mycert.com'} Create a new Basic application and associate it to a device and certificate .INPUTS none .OUTPUTS TppObject, if PassThru provided .LINK http://VenafiPS.readthedocs.io/en/latest/functions/New-VdcObject/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/New-VdcObject.ps1 .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Add-VdcCertificateAssociation.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-create.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/SchemaReference/r-SDK-CNattributesWhere.php #> [CmdletBinding(DefaultParameterSetName = 'NonApplicationObject', SupportsShouldProcess)] [Alias('New-TppObject')] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Path, [Parameter(Mandatory)] [String] $Class, [Parameter()] [ValidateNotNullOrEmpty()] [Hashtable] $Attribute, [Parameter()] [Alias('ProvisionCertificate')] [switch] $PushCertificate, [Parameter()] [switch] $Force, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' if ( $PushCertificate -and (-not $Attribute.Certificate) ) { Write-Warning 'A ''Certificate'' key containing the certificate path must be provided for Attribute when using PushCertificate, eg. -Attribute @{''Certificate''=''\Ved\Policy\mycert.com''}. Certificate provisioning will not take place.' } $newPath = $Path | ConvertTo-VdcFullPath $params = @{ Method = 'Post' UriLeaf = 'config/create' Body = @{ ObjectDN = $newPath Class = $Class } } if ( $PSBoundParameters.ContainsKey('Attribute') ) { # api requires a list of hashtables for nameattributelist # with 2 items per hashtable, with key names 'name' and 'value' # this is cumbersome for the user so allow them to pass a standard hashtable and convert it for them $updatedAttribute = @($Attribute.GetEnumerator() | ForEach-Object { @{'Name' = $_.name; 'Value' = $_.value } }) $params.Body.Add('NameAttributeList', $updatedAttribute) } if ( $PSCmdlet.ShouldProcess($newPath, ('Create {0} Object' -f $Class)) ) { $retryCount = 0 do { $retryCreate = $false $response = Invoke-VenafiRestMethod @params switch ($response.Result) { 1 { Write-Verbose "Successfully created $Class at $newPath" $returnObject = ConvertTo-VdcObject -Path $response.Object.DN -Guid $response.Object.Guid -TypeName $response.Object.TypeName } 400 { # occurs when a parent object, anywhere in the path, is missing # with these classes we know the parent is a policy so we can create them if ( $Class -in 'Policy', 'Device' ) { if ( -not $Force ) { throw "Part of the path $newPath does not exist. Use -Force to create the missing policy folders." } else { $pathSplit = $newPath.Split('\') # create the parent policy folders # don't try and create \ved or \ved\policy levels for ($i = 3; $i -lt ($pathSplit.Count - 1); $i++) { if ( -not (Find-VdcObject -Path ($pathSplit[0..($i - 1)] -join '\') -Pattern $pathSplit[$i])) { Write-Verbose ('Creating missing policy folder {0}' -f ($pathSplit[0..$i] -join '\')) New-VdcPolicy -Path ($pathSplit[0..$i] -join '\') } } $retryCreate = $true } } else { throw "Part of path $newPath does not exist." } } 401 { throw "$newPath already exists" } Default { throw ('Error creating object: {0}, {1}' -f $response.Result, $_) } } $retryCount++ } until ( -not $retryCreate -or $retryCount -gt 2 ) if ( $Attribute.Certificate ) { $associateParams = @{ CertificatePath = $Attribute.Certificate ApplicationPath = $response.Object.DN } if ( $PushCertificate.IsPresent ) { $associateParams.Add('PushCertificate', $true) } Add-VdcCertificateAssociation @associateParams } if ( $PassThru ) { $returnObject } } } #EndRegion './Public/New-VdcObject.ps1' 209 #Region './Public/New-VdcPolicy.ps1' -1 function New-VdcPolicy { <# .SYNOPSIS Add a new policy folder .DESCRIPTION Add a new policy folder(s). Add object attributes or policy attributes at the same time. .PARAMETER Path Full path to the new policy folder. If the root path is excluded, \ved\policy will be prepended. If used with -Name, this will be the root path and subfolders will be created. .PARAMETER Name One of more policy folders to create under -Path. .PARAMETER Attribute Hashtable with names and values to be set on the policy itself. If used with -Class, this will set policy attributes. If setting a custom field, you can use either the name or guid as the key. To clear a value overwriting policy, set the value to $null. .PARAMETER Class Use with -Attribute to set policy attributes at policy creation time. If unsure of the class name, add the value through the TLSPDC UI and go to Support->Policy Attributes to find it. .PARAMETER Lock Use with -PolicyAttribute and -Class to lock the policy attribute .PARAMETER Description Deprecated. Use -Attribute @{''Description''=''my description''} instead. .PARAMETER Force Force the creation of missing parent policy folders .PARAMETER PassThru Return a TppObject representing the newly created policy. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS TppObject, if PassThru provided .EXAMPLE $newPolicy = New-VdcPolicy -Path 'new' Create a new policy folder .EXAMPLE $newPolicy = New-VdcPolicy -Path 'existing' -Name 'new1', 'new2', 'new3' Create multiple policy folders .EXAMPLE $newPolicy = New-VdcPolicy -Path 'new1\new2\new3' -Force Create a new policy folder named new3 and create new1 and new2 if they do not exist .EXAMPLE $newPolicy = New-VdcPolicy -Path 'new' -Attribute {'Description'='my new policy folder'} Create a new policy folder setting attributes on the object at creation time .EXAMPLE $newPolicy = New-VdcPolicy -Path 'new' -Class 'X509 Certificate' -Attribute {'State'='UT'} Create a new policy folder setting policy attributes (not object attributes) .EXAMPLE $newPolicy = New-VdcPolicy -Path 'new' -Class 'X509 Certificate' -Attribute {'State'='UT'} -Lock Create a new policy folder setting policy attributes (not object attributes) and locking them .EXAMPLE $newPolicy = New-VdcPolicy -Path 'new' -PassThru Create a new policy folder returning the policy object created .LINK http://VenafiPS.readthedocs.io/en/latest/functions/New-VdcPolicy/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/New-VdcPolicy.ps1 .LINK http://VenafiPS.readthedocs.io/en/latest/functions/New-VdcObject/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/New-VdcObject.ps1 #> [CmdletBinding(SupportsShouldProcess)] [Alias('New-TppPolicy')] param ( [Parameter(Mandatory, ParameterSetName = 'Path', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'Name', ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'PathWithPolicyAttribute', Mandatory, ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'NameWithPolicyAttribute', Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Path, [Parameter(ParameterSetName = 'Name', Mandatory)] [Parameter(ParameterSetName = 'NameWithPolicyAttribute', Mandatory)] [string[]] $Name, [Parameter(ParameterSetName = 'Path')] [Parameter(ParameterSetName = 'Name')] [String] $Description, [Parameter(ParameterSetName = 'Path')] [Parameter(ParameterSetName = 'Name')] [Parameter(ParameterSetName = 'PathWithPolicyAttribute', Mandatory)] [Parameter(ParameterSetName = 'NameWithPolicyAttribute', Mandatory)] [hashtable] $Attribute, [Parameter(ParameterSetName = 'PathWithPolicyAttribute', Mandatory)] [Parameter(ParameterSetName = 'NameWithPolicyAttribute', Mandatory)] [string] $Class, [Parameter(ParameterSetName = 'PathWithPolicyAttribute')] [Parameter(ParameterSetName = 'NameWithPolicyAttribute')] [switch] $Lock, [Parameter()] [switch] $Force, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { $params = @{ Class = 'Policy' PassThru = $true Force = $Force } if ( ($PSBoundParameters.ContainsKey('Description') -or $PSBoundParameters.ContainsKey('Attribute')) -and $PSCmdlet.ParameterSetName -in 'Path', 'Name' ) { $params.Attribute = @{} if ( $PSBoundParameters.ContainsKey('Description') ) { $params.Attribute += @{'Description' = $Description } } if ( $PSBoundParameters.ContainsKey('Attribute') ) { $params.Attribute += $Attribute } } } process { $newPath = $Path | ConvertTo-VdcFullPath if ( $PSCmdlet.ParameterSetName -in 'Path', 'PathWithPolicyAttribute' ) { $params.Path = $newPath if ( $PSCmdlet.ShouldProcess($newPath, 'Create Policy') ) { $response = New-VdcObject @params if ( $PSBoundParameters.ContainsKey('Class') ) { $response | Set-VdcAttribute -Attribute $Attribute -Class $Class -Lock:$Lock } if ( $PassThru ) { $response } } } else { foreach ($thisName in $Name) { $PSBoundParameters['Path'] = "$newPath\$thisName" $null = $PSBoundParameters.Remove('Name') New-VdcPolicy @PSBoundParameters } } } } #EndRegion './Public/New-VdcPolicy.ps1' 195 #Region './Public/New-VdcTeam.ps1' -1 function New-VdcTeam { <# .SYNOPSIS Create a new team .DESCRIPTION Create a new TLSPDC team .PARAMETER Name Team name .PARAMETER Owner 1 or more owners for the team Provide the identity ID property from Find-VdcIdentity or Get-VdcIdentity. .PARAMETER Member 1 or more members for the team Provide the identity ID property from Find-VdcIdentity or Get-VdcIdentity. .PARAMETER Policy 1 or more policy folder paths this team manages. .PARAMETER Product 1 or more product names, 'TLS', 'SSH', and/or 'Code Signing'. .PARAMETER Description Team description or purpose. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token key can also provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .EXAMPLE New-VenafiTeam -Name 'My New Team' -Member 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e6}' -Owner 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e7}' -Product 'TLS' Create a new team .EXAMPLE New-VenafiTeam -Name 'My New Team' -Member 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e6}' -Owner 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e7}' -Product 'TLS' -Policy '\ved\policy\myfolder' Create a new team and assign it to a policy .EXAMPLE New-VenafiTeam -Name 'My New Team' -Member 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e6}' -Owner 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e7}' -Product 'TLS' -Description 'One amazing team' Create a new team with optional description .EXAMPLE New-VenafiTeam -Name 'My New Team' -Member 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e6}' -Owner 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e7}' -Product 'TLS' -PassThru Name : My New Team ID : local:{a6053090-e309-49d9-98a7-28cbe7896c27} Path : \VED\Identity\My New Team FullName : local:My New Team IsGroup : True Members : @{Name=sample-user; ID=local:{6baad36c-7cac-48c8-8e54-000cc22ad88f}; Path=\VED\Identity\sample-user; FullName=local:sample-user; IsGroup=False} Owners : @{Name=sample-owner; ID=local:{d1a76bc7-d3a6-431b-9bea-d2d8780ecd86}; Path=\VED\Identity\sample-owner; FullName=local:sample-owner; IsGroup=False} Create a new team returning the new team .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Teams.php #> [CmdletBinding()] param ( [Parameter(Mandatory)] [string] $Name, [Parameter(Mandatory)] [string[]] $Owner, [Parameter(Mandatory)] [string[]] $Member, [Parameter()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid policy path" } })] [string[]] $Policy, [Parameter(Mandatory)] [ValidateSet('TLS', 'SSH', 'Code Signing')] [string[]] $Product, [Parameter()] [string] $Description, [Parameter()] [switch] $PassThru, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { $params = @{ Method = 'Post' UriLeaf = 'Teams/' } $members = foreach ($thisMember in $Member) { if ( $thisMember.StartsWith('local') ) { $memberIdentity = Get-VdcIdentity -ID $thisMember @{ 'PrefixedName' = $memberIdentity.FullName 'PrefixedUniversal' = $memberIdentity.ID } } else { @{'PrefixedUniversal' = $thisMember } } } $owners = foreach ($thisOwner in $Owner) { if ( $thisOwner.StartsWith('local') ) { $ownerIdentity = Get-VdcIdentity -ID $thisOwner @{ 'PrefixedName' = $ownerIdentity.FullName 'PrefixedUniversal' = $ownerIdentity.ID } } else { @{'PrefixedUniversal' = $thisOwner } } } $params.Body = @{ 'Name' = @{'PrefixedName' = "local:$Name" } 'Members' = @($members) 'Owners' = @($owners) 'Products' = @($Product) } if ( $Policy ) { $params.Body.Add('Assets', @($Policy)) } if ( $Description ) { $params.Body.Add('Description', $Description) } $response = Invoke-VenafiRestMethod @params | Select-Object -ExpandProperty ID if ( $PassThru ) { $response | Get-VdcTeam } } } #EndRegion './Public/New-VdcTeam.ps1' 165 #Region './Public/New-VdcToken.ps1' -1 function New-VdcToken { <# .SYNOPSIS Get a new access token or refresh an existing one .DESCRIPTION Get an access token and refresh token (if enabled) to be used with New-VenafiSession or other scripts/utilities that take such a token. You can also refresh an existing access token if you have the associated refresh token. Authentication can be provided as integrated, credential, or certificate. .PARAMETER AuthServer Auth server or url, eg. venafi.company.com .PARAMETER ClientId Application/integration ID configured in Venafi for token-based authentication. Case sensitive. .PARAMETER Scope Hashtable with Scopes and privilege restrictions. The key is the scope and the value is one or more privilege restrictions separated by commas. A privilege restriction of none or read, use a value of $null. Scopes include Agent, Certificate, Code Signing, Configuration, Restricted, Security, SSH, and statistics. See https://docs.venafi.com/Docs/current/TopNav/Content/SDK/AuthSDK/r-SDKa-OAuthScopePrivilegeMapping.php Using a scope of {'all'='core'} will set all scopes except for admin. Using a scope of {'all'='admin'} will set all scopes including admin. Usage of the 'all' scope is not suggested for production. .PARAMETER Credential Username / password credential used to request API Token .PARAMETER State A session state, redirect URL, or random string to prevent Cross-Site Request Forgery (CSRF) attacks .PARAMETER Jwt JSON web token. Available in TLSPDC v22.4 and later. Ensure jwt mapping has been configured in VCC, Access Management->JWT Mappings. .PARAMETER Certificate Certificate used to request API token. Certificate authentication must be configured for remote web sdk clients, https://docs.venafi.com/Docs/current/TopNav/Content/CA/t-CA-ConfiguringInTPPandIIS-tpp.php. .PARAMETER RefreshToken Provide -RefreshToken along with -ClientId to obtain a new access and refresh token. You can either provide a String, SecureString, or PSCredential. If providing a credential, the username is not used. .PARAMETER SkipCertificateCheck Bypass certificate validation when connecting to the server. This can be helpful for pre-prod environments where ssl isn't setup on the website or you are connecting via IP. .PARAMETER VenafiSession VenafiSession object created from New-VenafiSession method. .EXAMPLE New-VdcToken -AuthServer 'https://mytppserver.example.com' -Scope @{ Certificate = "manage,discover"; Configuration = "manage" } -ClientId 'MyAppId' -Credential $credential Get a new token with OAuth .EXAMPLE New-VdcToken -AuthServer 'mytppserver.example.com' -Scope @{ Certificate = "manage,discover"; Configuration = "manage" } -ClientId 'MyAppId' Get a new token with Integrated authentication .EXAMPLE New-VdcToken -AuthServer 'mytppserver.example.com' -Scope @{ Certificate = "manage,discover"; Configuration = "manage" } -ClientId 'MyAppId' -Certificate $cert Get a new token with certificate authentication .EXAMPLE New-VdcToken -AuthServer 'mytppserver.example.com' -ClientId 'MyApp' -RefreshToken $refreshCred Refresh an existing access token by providing the refresh token directly .EXAMPLE New-VdcToken -VenafiSession $mySession Refresh an existing access token by providing a VenafiSession object .INPUTS None .OUTPUTS PSCustomObject with the following properties: Server AccessToken RefreshToken Scope Identity TokenType ClientId Expires RefreshExpires (This property is null when TLSPDC version is less than 21.1) #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Integrated')] [Alias('New-TppToken')] [OutputType([PSCustomObject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'Generating cred from api call response data')] [OutputType([System.Boolean])] param ( [Parameter(ParameterSetName = 'OAuth', Mandatory)] [Parameter(ParameterSetName = 'Integrated', Mandatory)] [Parameter(ParameterSetName = 'Certificate', Mandatory)] [Parameter(ParameterSetName = 'Jwt', Mandatory)] [Parameter(ParameterSetName = 'RefreshToken', Mandatory)] [ValidateScript( { $validateMe = if ( $_ -notlike 'https://*') { 'https://{0}' -f $_ } else { $_ } try { $null = [System.Uri]::new($validateMe) $true } catch { throw 'Please enter a valid server, https://venafi.company.com or venafi.company.com' } } )] [Alias('Server')] [string] $AuthServer, [Parameter(ParameterSetName = 'OAuth', Mandatory)] [Parameter(ParameterSetName = 'Integrated', Mandatory)] [Parameter(ParameterSetName = 'Certificate', Mandatory)] [Parameter(ParameterSetName = 'RefreshToken', Mandatory)] [Parameter(ParameterSetName = 'Jwt', Mandatory)] [string] $ClientId, [Parameter(ParameterSetName = 'OAuth', Mandatory)] [Parameter(ParameterSetName = 'Integrated', Mandatory)] [Parameter(ParameterSetName = 'Certificate', Mandatory)] [Parameter(ParameterSetName = 'Jwt', Mandatory)] [hashtable] $Scope, [Parameter(ParameterSetName = 'OAuth', Mandatory)] [System.Management.Automation.PSCredential] $Credential, [Parameter(ParameterSetName = 'Integrated')] [Parameter(ParameterSetName = 'OAuth')] [string] $State, [Parameter(ParameterSetName = 'Jwt', Mandatory)] [string] $Jwt, [Parameter(ParameterSetName = 'Certificate', Mandatory)] [X509Certificate] $Certificate, [Parameter(ParameterSetName = 'RefreshToken', Mandatory)] [ValidateScript( { if ( $_ -is [string] -or $_ -is [securestring] -or $_ -is [pscredential] ) { $true } else { throw 'Unsupported type. Provide either a String, SecureString, or PSCredential.' } } )] [psobject] $RefreshToken, [Parameter()] [switch] $SkipCertificateCheck, [Parameter(ParameterSetName = 'RefreshSession', Mandatory)] [ValidateScript( { if ( -not $_.Token.RefreshToken ) { throw 'VenafiSession does not have a refresh token. To get a new access token, create a new session with New-VenafiSession.' } if ( $_.Token.RefreshExpires -and $_.Token.RefreshExpires -lt (Get-Date) ) { throw "The refresh token has expired. Retrieve a new access token with New-VenafiSession." } $true })] [pscustomobject] $VenafiSession ) $params = @{ Method = 'Post' UriRoot = 'vedauth' Body = @{} SkipCertificateCheck = $SkipCertificateCheck } if ( $PsCmdlet.ParameterSetName -eq 'RefreshSession' ) { $params.Server = $VenafiSession.Token.Server $params.UriLeaf = 'authorize/token' $params.Body = @{ client_id = $VenafiSession.Token.ClientId refresh_token = $VenafiSession.Token.RefreshToken.GetNetworkCredential().password } # workaround for bug pre 21.3 where client id needs to be lowercase if ( $VenafiSession.Version -lt [Version]::new('21', '3', '0') ) { $params.Body.client_id = $params.Body.client_id.ToLower() } } else { $AuthUrl = $AuthServer # add prefix if just server url was provided if ( $AuthServer -notlike 'https://*') { $AuthUrl = 'https://{0}' -f $AuthUrl } $params.Server = $AuthUrl if ( $PsCmdlet.ParameterSetName -eq 'RefreshToken' ) { $params.UriLeaf = 'authorize/token' $params.Body = @{ client_id = $ClientId } $params.Body.refresh_token = $RefreshToken | ConvertTo-PlaintextString } else { # obtain new token $scopeString = switch ($Scope.all) { 'core' { 'agent:delete;certificate:approve,delete,discover,manage,revoke;configuration:delete,manage;restricted:delete,manage;security:delete,manage;ssh:approve,delete,discover,manage;statistics' } 'admin' { 'admin:delete,viewlogs,recyclebin;agent:delete;certificate:delete,discover,manage,revoke;configuration:delete,manage;restricted:delete,manage;security:delete,manage;ssh:approve,delete,discover,manage;statistics' } Default { @( $scope.GetEnumerator() | ForEach-Object { if ($_.Value) { '{0}:{1}' -f $_.Key, $_.Value } else { $_.Key } } ) -join ';' } } $params.Body = @{ client_id = $ClientId scope = $scopeString } $params.UriLeaf = 'authorize/{0}' -f $PSCmdlet.ParameterSetName.ToLower() switch ($PsCmdlet.ParameterSetName) { 'Integrated' { $params.UseDefaultCredentials = $true } 'OAuth' { $params.Body.username = $Credential.UserName $params.Body.password = $Credential.GetNetworkCredential().Password } 'Certificate' { $params.Certificate = $Certificate } 'Jwt' { $params.Body.jwt = $Jwt } Default { throw ('Unknown parameter set {0}' -f $PSCmdlet.ParameterSetName) } } if ( $State ) { $params.Body.state = $State } } } if ( $PSCmdlet.ShouldProcess($params.Server, 'New access token') ) { if ( $PsCmdlet.ParameterSetName -eq 'RefreshToken' ) { try { $response = Invoke-VenafiRestMethod @params } catch { # workaround bug pre 21.3 where client_id must be lowercase if ( $_ -like '*The client_id value being requested with the refresh token does not match the client_id of the access token making the call*') { $params.Body.client_id = $params.Body.client_id.ToLower() $response = Invoke-VenafiRestMethod @params } else { throw $_ } } } else { $response = Invoke-VenafiRestMethod @params } $response | Write-VerboseWithSecret $newToken = [PSCustomObject] @{ Server = $params.Server AccessToken = New-Object System.Management.Automation.PSCredential('AccessToken', ($response.access_token | ConvertTo-SecureString -AsPlainText -Force)) RefreshToken = $null Scope = $Scope Identity = $response.identity TokenType = $response.token_type ClientId = $params.Body.client_id Expires = ([datetime] '1970-01-01 00:00:00').AddSeconds($response.Expires) RefreshExpires = $null } if ( $response.refresh_token ) { $newToken.RefreshToken = New-Object System.Management.Automation.PSCredential('RefreshToken', ($response.refresh_token | ConvertTo-SecureString -AsPlainText -Force)) # refresh_until added in 21.1 if ($response.refresh_until) { $newToken.RefreshExpires = ([datetime] '1970-01-01 00:00:00').AddSeconds($response.refresh_until) } } $newToken } } #EndRegion './Public/New-VdcToken.ps1' 326 #Region './Public/New-VenafiSession.ps1' -1 function New-VenafiSession { <# .SYNOPSIS Create a new Venafi TLSPDC or TLSPC session .DESCRIPTION Authenticate a user and create a new session with which future calls can be made. Key based username/password and windows integrated are supported as well as token-based integrated, oauth, and certificate. By default, a session variable will be created and automatically used with other functions unless -PassThru is used. Tokens and TLSPC keys can be saved in a vault for future calls. .PARAMETER Server Server or url to access vedsdk, venafi.company.com or https://venafi.company.com. If AuthServer is not provided, this will be used to access vedauth as well for token-based authentication. If just the server name is provided, https:// will be appended. .PARAMETER Credential Username and password used for token-based authentication. Not required for integrated authentication. .PARAMETER ClientId Application/integration ID configured in Venafi for token-based authentication. Case sensitive. .PARAMETER Scope Hashtable with Scopes and privilege restrictions. The key is the scope and the value is one or more privilege restrictions separated by commas, @{'certificate'='delete,manage'}. Scopes include Agent, Certificate, Code Signing, Configuration, Restricted, Security, SSH, and statistics. For no privilege restriction or read access, use a value of $null. For a scope to privilege mapping, see https://docs.venafi.com/Docs/current/TopNav/Content/SDK/AuthSDK/r-SDKa-OAuthScopePrivilegeMapping.php Using a scope of {'all'='core'} will set all scopes except for admin. Using a scope of {'all'='admin'} will set all scopes including admin. Usage of the 'all' scope is not suggested for production. .PARAMETER State A session state, redirect URL, or random string to prevent Cross-Site Request Forgery (CSRF) attacks .PARAMETER AccessToken Provide an existing access token to create a session. You can either provide a String, SecureString, or PSCredential. If providing a credential, the username is not used. .PARAMETER VaultAccessTokenName Name of the SecretManagement vault entry for the access token; the name of the vault must be VenafiPS. This value can be provided standalone or with credentials. First time use requires it to be provided with credentials to retrieve the access token to populate the vault. With subsequent uses, it can be provided standalone and the access token will be retrieved without the need for credentials. .PARAMETER RefreshToken Provide an existing refresh token to create a session. You can either provide a String, SecureString, or PSCredential. If providing a credential, the username is not used. .PARAMETER VaultRefreshTokenName Name of the SecretManagement vault entry for the refresh token; the name of the vault must be VenafiPS. This value can be provided standalone or with credentials. Each time this is used, a new access and refresh token will be obtained. First time use requires it to be provided with credentials to retrieve the refresh token and populate the vault. With subsequent uses, it can be provided standalone and the refresh token will be retrieved without the need for credentials. .PARAMETER Jwt JSON web token. Available in TLSPDC v22.4 and later. Ensure JWT mapping has been configured in VCC, Access Management->JWT Mappings. .PARAMETER Certificate Certificate for TLSPDC token-based authentication .PARAMETER AuthServer If you host your authentication service, vedauth, is on a separate server than vedsdk, use this parameter to specify the url eg., venafi.company.com or https://venafi.company.com. If AuthServer is not provided, the value provided for Server will be used. If just the server name is provided, https:// will be appended. .PARAMETER VcKey Api key from your TLSPC instance. The api key can be found under your user profile->preferences. You can either provide a String, SecureString, or PSCredential. If providing a credential, the username is not used. .PARAMETER VcRegion TLSPC region to connect to. Valid values are 'us' and 'eu'. Defaults to 'us'. .PARAMETER VaultVcKeyName Name of the SecretManagement vault entry for the TLSPC key. First time use requires it to be provided with -VcKey to populate the vault. With subsequent uses, it can be provided standalone and the key will be retrieved without the need for -VcKey. The server associated with the region will be saved and restored when this parameter is used on subsequent use. .PARAMETER SkipCertificateCheck Bypass certificate validation when connecting to the server. This can be helpful for pre-prod environments where ssl isn't setup on the website or you are connecting via IP. You can also create an environment variable named VENAFIPS_SKIP_CERT_CHECK and set it to 1 for the same effect. .PARAMETER TimeoutSec Specifies how long the request can be pending before it times out. Enter a value in seconds. The default value, 0, specifies an indefinite time-out. .PARAMETER PassThru Optionally, send the session object to the pipeline instead of script scope. .OUTPUTS VenafiSession, if -PassThru is provided .EXAMPLE New-VenafiSession -Server venafitpp.mycompany.com -ClientId MyApp -Scope @{'certificate'='manage'} Create token-based session using Windows Integrated authentication with a certain scope and privilege restriction .EXAMPLE New-VenafiSession -Server venafitpp.mycompany.com -Credential $cred -ClientId MyApp -Scope @{'certificate'='manage'} Create token-based session .EXAMPLE New-VenafiSession -Server venafitpp.mycompany.com -Certificate $myCert -ClientId MyApp -Scope @{'certificate'='manage'} Create token-based session using a client certificate .EXAMPLE New-VenafiSession -Server venafitpp.mycompany.com -AuthServer tppauth.mycompany.com -ClientId MyApp -Credential $cred Create token-based session using oauth authentication where the vedauth and vedsdk are hosted on different servers .EXAMPLE $sess = New-VenafiSession -Server venafitpp.mycompany.com -Credential $cred -PassThru Create session and return the session object instead of setting to script scope variable .EXAMPLE New-VenafiSession -Server venafitpp.mycompany.com -AccessToken $accessCred Create session using an access token obtained outside this module .EXAMPLE New-VenafiSession -Server venafitpp.mycompany.com -RefreshToken $refreshCred -ClientId MyApp Create session using a refresh token .EXAMPLE New-VenafiSession -Server venafitpp.mycompany.com -RefreshToken $refreshCred -ClientId MyApp -VaultRefreshTokenName TppRefresh Create session using a refresh token and store the newly created refresh token in the vault .EXAMPLE New-VenafiSession -VcKey $cred Create session against TLSPC .EXAMPLE New-VenafiSession -VcKey $cred -VcRegion 'eu' Create session against TLSPC in EU region .EXAMPLE New-VenafiSession -VaultVcKeyName vaas-key Create session against TLSPC with a key stored in a vault .LINK http://VenafiPS.readthedocs.io/en/latest/functions/New-VenafiSession/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/New-VenafiSession.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/API_Reference/r-SDK-POST-Authorize.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/API_Reference/r-SDK-GET-Authorize-Integrated.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/AuthSDK/r-SDKa-POST-Authorize-Integrated.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/AuthSDK/r-SDKa-POST-AuthorizeOAuth.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/AuthSDK/r-SDKa-POST-AuthorizeCertificate.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/AuthSDK/r-SDKa-POST-AuthorizeJwt.php .LINK https://github.com/PowerShell/SecretManagement .LINK https://github.com/PowerShell/SecretStore #> [CmdletBinding(DefaultParameterSetName = 'KeyIntegrated')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Not needed')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'Converting secret to credential')] param( [Parameter(Mandatory, ParameterSetName = 'KeyCredential')] [Parameter(Mandatory, ParameterSetName = 'KeyIntegrated')] [Parameter(Mandatory, ParameterSetName = 'TokenOAuth')] [Parameter(Mandatory, ParameterSetName = 'TokenIntegrated')] [Parameter(Mandatory, ParameterSetName = 'TokenCertificate')] [Parameter(Mandatory, ParameterSetName = 'TokenJwt')] [Parameter(Mandatory, ParameterSetName = 'AccessToken')] [Parameter(Mandatory, ParameterSetName = 'RefreshToken')] [Parameter(ParameterSetName = 'VaultAccessToken')] [Parameter(ParameterSetName = 'VaultRefreshToken')] [Alias('ServerUrl', 'Url')] [ValidateScript( { $validateMe = if ( $_ -notlike 'https://*') { 'https://{0}' -f $_ } else { $_ } try { $null = [System.Uri]::new($validateMe) $true } catch { throw 'Please enter a valid server, https://venafi.company.com or venafi.company.com' } } )] [string] $Server, [Parameter(Mandatory, ParameterSetName = 'KeyCredential')] [Parameter(Mandatory, ParameterSetName = 'TokenOAuth')] [System.Management.Automation.PSCredential] $Credential, [Parameter(Mandatory, ParameterSetName = 'TokenIntegrated')] [Parameter(Mandatory, ParameterSetName = 'TokenOAuth')] [Parameter(Mandatory, ParameterSetName = 'TokenCertificate')] [Parameter(Mandatory, ParameterSetName = 'TokenJwt')] [Parameter(ParameterSetName = 'RefreshToken', Mandatory)] [Parameter(ParameterSetName = 'VaultRefreshToken')] [string] $ClientId, [Parameter(Mandatory, ParameterSetName = 'TokenIntegrated')] [Parameter(Mandatory, ParameterSetName = 'TokenOAuth')] [Parameter(Mandatory, ParameterSetName = 'TokenCertificate')] [Parameter(Mandatory, ParameterSetName = 'TokenJwt')] [Parameter(ParameterSetName = 'VaultAccessToken')] [Parameter(ParameterSetName = 'VaultRefreshToken')] [hashtable] $Scope, [Parameter(ParameterSetName = 'TokenIntegrated')] [Parameter(ParameterSetName = 'TokenOAuth')] [string] $State, [Parameter(Mandatory, ParameterSetName = 'AccessToken')] [psobject] $AccessToken, [Parameter(Mandatory, ParameterSetName = 'RefreshToken')] [psobject] $RefreshToken, [Parameter(Mandatory, ParameterSetName = 'TokenJwt')] [string] $Jwt, [Parameter(Mandatory, ParameterSetName = 'TokenCertificate')] [X509Certificate] $Certificate, [Parameter(Mandatory, ParameterSetName = 'VaultAccessToken')] [Parameter(ParameterSetName = 'AccessToken')] [Parameter(ParameterSetName = 'TokenIntegrated')] [Parameter(ParameterSetName = 'TokenOAuth')] [Parameter(ParameterSetName = 'TokenCertificate')] [string] $VaultAccessTokenName, [Parameter(Mandatory, ParameterSetName = 'VaultRefreshToken')] [Parameter(ParameterSetName = 'RefreshToken')] [Parameter(ParameterSetName = 'TokenIntegrated')] [Parameter(ParameterSetName = 'TokenOAuth')] [Parameter(ParameterSetName = 'TokenCertificate')] [string] $VaultRefreshTokenName, [Parameter(ParameterSetName = 'TokenOAuth')] [Parameter(ParameterSetName = 'TokenIntegrated')] [Parameter(ParameterSetName = 'TokenCertificate')] [Parameter(ParameterSetName = 'RefreshToken')] [ValidateScript( { $validateMe = if ( $_ -notlike 'https://*') { 'https://{0}' -f $_ } else { $_ } try { $null = [System.Uri]::new($validateMe) $true } catch { throw 'Please enter a valid server, https://venafi.company.com or venafi.company.com' } } )] [string] $AuthServer, [Parameter(Mandatory, ParameterSetName = 'Vc')] [Alias('VaasKey')] [psobject] $VcKey, [Parameter(ParameterSetName = 'Vc')] [ValidateScript( { if ( $_ -notin ($script:VcRegions).Keys ) { throw ('{0} is not a valid region. Valid regions include {1}.' -f $_, (($script:VcRegions).Keys -join ',')) } $true } )] [string] $VcRegion = 'us', [Parameter(ParameterSetName = 'Vc')] [Parameter(Mandatory, ParameterSetName = 'VaultVcKey')] [Alias('VaultVaasKeyName')] [string] $VaultVcKeyName, [Parameter()] [Int32] $TimeoutSec = 0, [Parameter()] [switch] $PassThru, [Parameter(ParameterSetName = 'TokenOAuth')] [Parameter(ParameterSetName = 'TokenIntegrated')] [Parameter(ParameterSetName = 'TokenCertificate')] [Parameter(ParameterSetName = 'TokenJwt')] [Parameter(ParameterSetName = 'AccessToken')] [Parameter(ParameterSetName = 'RefreshToken')] [Parameter(ParameterSetName = 'VaultAccessToken')] [Parameter(ParameterSetName = 'VaultRefreshToken')] [switch] $SkipCertificateCheck ) $isVerbose = if ($PSBoundParameters.Verbose -eq $true) { $true } else { $false } $serverUrl = $Server # add prefix if just server url was provided if ( $Server -notlike 'https://*') { $serverUrl = 'https://{0}' -f $serverUrl } $authServerUrl = $serverUrl if ( $AuthServer ) { $authServerUrl = $AuthServer if ( $authServerUrl -notlike 'https://*') { $authServerUrl = 'https://{0}' -f $authServerUrl } } $newSession = [pscustomobject] @{ Platform = 'VDC' Server = $serverUrl TimeoutSec = $TimeoutSec SkipCertificateCheck = $SkipCertificateCheck.IsPresent } Write-Verbose ('Parameter set: {0}' -f $PSCmdlet.ParameterSetName) if ( $ClientId -and $ClientId -inotmatch 'venafips' ) { Write-Warning 'When creating your API Integration in Venafi, please ensure the id begins with “VenafiPS-” like the example below. Be sure to adjust the scope for your specific use case. { "id": "VenafiPS-<USE CASE>", "name": "VenafiPS for <USE CASE>", "description": "This application uses the VenafiPS module to automate <USE CASE>", "scope": "certificate:manage;configuration:manage" }' } if ( $PSBoundParameters.Keys -like 'Vault*') { # ensure the appropriate setup has been performed if ( -not (Get-Module -Name Microsoft.PowerShell.SecretManagement -ListAvailable)) { throw 'Vault functionality requires the module Microsoft.PowerShell.SecretManagement as well as a vault named ''VenafiPS''. See the github readme for guidance, https://github.com/Venafi/VenafiPS#tokenkey-secret-storage.' } $vault = Get-SecretVault -Name 'VenafiPS' -ErrorAction SilentlyContinue if ( -not $vault ) { throw 'A SecretManagement vault named ''VenafiPS'' could not be found' } } # if ( $PSCmdlet.ShouldProcess($Server, 'New session') ) { Switch ($PsCmdlet.ParameterSetName) { { $_ -in 'KeyCredential', 'KeyIntegrated' } { Write-Warning 'Key-based authentication has been deprecated. Get started with token authentication today, https://docs.venafi.com/Docs/current/TopNav/Content/SDK/AuthSDK/t-SDKa-Setup-OAuth.php.' } { $_ -in 'TokenOAuth', 'TokenIntegrated', 'TokenCertificate', 'TokenJwt' } { $params = @{ AuthServer = $authServerUrl ClientId = $ClientId Scope = $Scope SkipCertificateCheck = $SkipCertificateCheck } if ($Credential) { $params.Credential = $Credential } if ($Certificate) { $params.Certificate = $Certificate } if ( $PSBoundParameters.ContainsKey('Jwt') ) { $params.Jwt = $Jwt } if ($State) { $params.State = $State } $token = New-VdcToken @params -Verbose:$isVerbose $newSession | Add-Member @{Token = $token } } 'AccessToken' { $newSession | Add-Member @{'Token' = [PSCustomObject]@{ Server = $authServerUrl # we don't have the expiry so create one # rely on the api call itself to fail if access token is invalid Expires = (Get-Date).AddMonths(12) AccessToken = $null } } $newSession.Token.AccessToken = if ( $AccessToken -is [string] ) { New-Object System.Management.Automation.PSCredential('AccessToken', ($AccessToken | ConvertTo-SecureString -AsPlainText -Force)) } elseif ($AccessToken -is [pscredential]) { $AccessToken } elseif ($AccessToken -is [securestring]) { New-Object System.Management.Automation.PSCredential('AccessToken', $AccessToken) } else { throw 'Unsupported type for -AccessToken. Provide either a String, SecureString, or PSCredential.' } # validate token $null = Invoke-VenafiRestMethod -UriRoot 'vedauth' -UriLeaf 'Authorize/Verify' -VenafiSession $newSession } 'VaultAccessToken' { $tokenSecret = Get-Secret -Name $VaultAccessTokenName -Vault 'VenafiPS' -ErrorAction SilentlyContinue if ( -not $tokenSecret ) { throw "'$VaultAccessTokenName' secret not found in vault VenafiPS." } # check if metadata was stored or we should get from params $secretInfo = Get-SecretInfo -Name $VaultAccessTokenName -Vault 'VenafiPS' -ErrorAction SilentlyContinue if ( $secretInfo.Metadata.Count -gt 0 ) { $newSession.Server = $secretInfo.Metadata.Server $newSession.Token = [PSCustomObject]@{ Server = $secretInfo.Metadata.AuthServer AccessToken = $tokenSecret ClientId = $secretInfo.Metadata.ClientId Scope = $secretInfo.Metadata.Scope } $newSession.SkipCertificateCheck = [bool] $secretInfo.Metadata.SkipCertificateCheck $newSession.TimeoutSec = $secretInfo.Metadata.TimeoutSec } else { throw 'Server and ClientId metadata not found. Execute New-VenafiSession -Server $server -Credential $cred -ClientId $clientId -Scope $scope -VaultAccessToken $secretName and attempt the operation again.' } } 'RefreshToken' { $params = @{ AuthServer = $authServerUrl ClientId = $ClientId } $params.RefreshToken = if ( $RefreshToken -is [string] ) { New-Object System.Management.Automation.PSCredential('RefreshToken', ($RefreshToken | ConvertTo-SecureString -AsPlainText -Force)) } elseif ($RefreshToken -is [pscredential]) { $RefreshToken } elseif ($RefreshToken -is [securestring]) { New-Object System.Management.Automation.PSCredential('RefreshToken', $RefreshToken) } else { throw 'Unsupported type for -RefreshToken. Provide either a String, SecureString, or PSCredential.' } $newToken = New-VdcToken @params $newSession | Add-Member @{ 'Token' = $newToken } } 'VaultRefreshToken' { $tokenSecret = Get-Secret -Name $VaultRefreshTokenName -Vault 'VenafiPS' -ErrorAction SilentlyContinue if ( -not $tokenSecret ) { throw "'$VaultRefreshTokenName' secret not found in vault VenafiPS." } # check if metadata was stored or we should get from params $secretInfo = Get-SecretInfo -Name $VaultRefreshTokenName -Vault 'VenafiPS' -ErrorAction SilentlyContinue if ( $secretInfo.Metadata.Count -gt 0 ) { $params = @{ AuthServer = $secretInfo.Metadata.AuthServer ClientId = $secretInfo.Metadata.ClientId SkipCertificateCheck = [bool] $secretInfo.Metadata.SkipCertificateCheck } } else { throw 'Server and ClientId metadata not found. Execute New-VenafiSession -Server $server -Credential $cred -ClientId $clientId -Scope $scope -VaultRefreshToken $secretName and attempt the operation again.' } $params.RefreshToken = $tokenSecret $newToken = New-VdcToken @params $newSession | Add-Member @{ 'Token' = $newToken } $newSession.Server = $newToken.Server $newSession.Token.Scope = $secretInfo.Metadata.Scope | ConvertFrom-Json $newSession.SkipCertificateCheck = [bool] $secretInfo.Metadata.SkipCertificateCheck $newSession.TimeoutSec = $secretInfo.Metadata.TimeoutSec } 'Vc' { $newSession.Platform = 'VC' $newSession.Server = ($script:VcRegions).$VcRegion $key = if ( $VcKey -is [string] ) { New-Object System.Management.Automation.PSCredential('VcKey', ($VcKey | ConvertTo-SecureString -AsPlainText -Force)) } elseif ($VcKey -is [pscredential]) { $VcKey } elseif ($VcKey -is [securestring]) { New-Object System.Management.Automation.PSCredential('VcKey', $VcKey) } else { throw 'Unsupported type for -VcKey. Provide either a String, SecureString, or PSCredential.' } $newSession | Add-Member @{ 'Key' = $key } if ( $VaultVcKeyName ) { $metadata = @{ Server = $newSession.Server TimeoutSec = [int]$newSession.TimeoutSec } Set-Secret -Name $VaultVcKeyName -Secret $newSession.Key -Vault 'VenafiPS' -Metadata $metadata } } 'VaultVcKey' { $keySecret = Get-Secret -Name $VaultVcKeyName -Vault 'VenafiPS' -ErrorAction SilentlyContinue if ( -not $keySecret ) { throw "'$VaultVcKeyName' secret not found in vault VenafiPS." } $secretInfo = Get-SecretInfo -Name $VaultVcKeyName -Vault 'VenafiPS' -ErrorAction SilentlyContinue if ( $secretInfo.Metadata.Count -gt 0 ) { $newSession.Server = $secretInfo.Metadata.Server } else { throw 'Server metadata not found. Execute New-VenafiSession -VcKey $key -VaultVcKeyName $secretName and attempt the operation again.' } $newSession.Platform = 'VC' $newSession | Add-Member @{ 'Key' = $keySecret } } Default { throw ('Unknown parameter set {0}' -f $PSCmdlet.ParameterSetName) } } # will fail if user is on an older version. this isn't required so bypass on failure # only applicable to tpp if ( $newSession.Platform -eq 'VDC' ) { $newSession | Add-Member @{ Version = (Get-VdcVersion -VenafiSession $newSession -ErrorAction SilentlyContinue) } $certFields = 'X509 Certificate', 'Device', 'Application Base' | Get-VdcCustomField -VenafiSession $newSession -ErrorAction SilentlyContinue # make sure we remove duplicates $newSession | Add-Member @{ CustomField = $certFields.Items | Sort-Object -Property Guid -Unique } } else { $newSession | Add-Member @{ User = (Invoke-VenafiRestMethod -UriLeaf 'useraccounts' -VenafiSession $newSession -ErrorAction SilentlyContinue | Select-Object -ExpandProperty user | Select-Object @{ 'n' = 'userId' 'e' = { $_.Id } }, * -ExcludeProperty id) } } if ( $VaultAccessTokenName -or $VaultRefreshTokenName ) { # save secret and all associated metadata to be retrieved later $metadata = @{ Server = $newSession.Server AuthServer = $newSession.Token.Server ClientId = $newSession.Token.ClientId Scope = $newSession.Token.Scope | ConvertTo-Json -Compress SkipCertificateCheck = [int]$newSession.SkipCertificateCheck TimeoutSec = [int]$newSession.TimeoutSec } $metadata | ConvertTo-Json | Write-Verbose if ( $VaultAccessTokenName ) { Set-Secret -Name $VaultAccessTokenName -Secret $newSession.Token.AccessToken -Vault 'VenafiPS' -Metadata $metadata } else { if ( $newSession.Token.RefreshToken ) { Set-Secret -Name $VaultRefreshTokenName -Secret $newSession.Token.RefreshToken -Vault 'VenafiPS' -Metadata $metadata } else { Write-Warning 'Refresh token not provided by server and will not be saved in the vault' } } } if ( $PassThru ) { $newSession } else { $Script:VenafiSession = $newSession } } #EndRegion './Public/New-VenafiSession.ps1' 589 #Region './Public/Read-VdcLog.ps1' -1 function Read-VdcLog { <# .SYNOPSIS Read entries from the TLSPDC log .DESCRIPTION Read entries from the TLSPDC log. .PARAMETER Path Path to search for related records .PARAMETER EventId Event ID as found in Logging->Event Definitions .PARAMETER Severity Filter records by severity .PARAMETER StartTime Start time of events .PARAMETER EndTime End time of events .PARAMETER Text1 Filter matching results of Text1 .PARAMETER Text2 Filter matching results of Text2 .PARAMETER Value1 Filter matching results of Value1 .PARAMETER Value2 Filter matching results of Value2 .PARAMETER First Return only these number of records .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS PSCustomObject EventId ClientTimestamp Component ComponentId ComponentSubsystem Data Grouping Id Name ServerTimestamp Severity SourceIP Text1 Text2 Value1 Value2 .EXAMPLE Read-VdcLog -First 10 Get the most recent 10 log items .EXAMPLE $capiObject | Read-VdcLog Find all events for a specific object .EXAMPLE Read-VdcLog -EventId '00130003' Find all events with event ID '00130003', Certificate Monitor - Certificate Expiration Notice .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-GET-Log.php #> [CmdletBinding()] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('DN')] [string] $Path, [Parameter()] [string] $EventId, [Parameter()] [TppEventSeverity] $Severity, [Parameter()] [DateTime] $StartTime, [Parameter()] [DateTime] $EndTime, [Parameter()] [ValidateNotNullOrEmpty()] [string] $Text1, [Parameter()] [ValidateNotNullOrEmpty()] [string] $Text2, [Parameter()] [int] $Value1, [Parameter()] [int] $Value2, [Parameter()] [int] $First, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ VenafiSession = $VenafiSession Method = 'Get' UriLeaf = 'Log/' Body = @{ } } switch ($PSBoundParameters.Keys) { 'EventId' { $params.Body.Add('Id', [uint32]('0x{0}' -f $EventId)) } 'Severity' { $params.Body.Add('Severity', $Severity) } 'StartTime' { $params.Body.Add('FromTime', ($StartTime | ConvertTo-UtcIso8601) ) } 'EndTime' { $params.Body.Add('ToTime', ($EndTime | ConvertTo-UtcIso8601) ) } 'Text1' { $params.Body.Add('Text1', $Text1) } 'Text2' { $params.Body.Add('Text2', $Text2) } 'Value1' { $params.Body.Add('Value1', $Value1) } 'Value2' { $params.Body.Add('Value2', $Value2) } 'First' { $params.Body.Add('Limit', $First) } } } process { if ( $PSBoundParameters.ContainsKey('Path') ) { $params.Body.Component = $Path } Invoke-VenafiRestMethod @params | Select-Object -ExpandProperty LogEvents | Select-Object -Property @{'n' = 'EventId'; 'e' = { '{0:x8}' -f $_.Id } }, * } } #EndRegion './Public/Read-VdcLog.ps1' 198 #Region './Public/Remove-VcApplication.ps1' -1 function Remove-VcApplication { <# .SYNOPSIS Remove a application .DESCRIPTION Remove a application from TLSPC .PARAMETER ID Application ID, this is the guid/uuid .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Remove-VcApplication -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' Remove a application .EXAMPLE Remove-VcApplication -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Confirm:$false Remove a application bypassing the confirmation prompt #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('applicationId')] [string] $ID, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allObjects = [System.Collections.Generic.List[object]]::new() } process { if ( $PSCmdlet.ShouldProcess($ID, "Delete application") ) { $allObjects.Add($ID) } } end { Invoke-VenafiParallel -InputObject $allObjects -ScriptBlock { $null = Invoke-VenafiRestMethod -Method 'Delete' -UriRoot 'outagedetection/v1' -UriLeaf "applications/$PSItem" } -ThrottleLimit $ThrottleLimit -VenafiSession $VenafiSession } } #EndRegion './Public/Remove-VcApplication.ps1' 61 #Region './Public/Remove-VcCertificate.ps1' -1 function Remove-VcCertificate { <# .SYNOPSIS Remove a certificate .DESCRIPTION Remove a certificate .PARAMETER ID Certificate ID of a certificate that has been retired .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Remove-VcCertificate -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' Remove a certificate .EXAMPLE Find-VcCertificate | Remove-VcCertificate Remove multiple certificates based on a search .EXAMPLE Remove-VcCertificate -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Confirm:$false Remove a certificate bypassing the confirmation prompt #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('certificateId')] [string] $ID, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allObjects = [System.Collections.Generic.List[object]]::new() } process { if ( $PSCmdlet.ShouldProcess($ID, "Delete certificate") ) { $allObjects.Add($ID) } } end { # handle certs differently since you send them all in 1 call # and parallel functionality not needed $params = @{ Method = 'Post' UriRoot = 'outagedetection/v1' UriLeaf = 'certificates/deletion' Body = @{ certificateIds = $allObjects } } $null = Invoke-VenafiRestMethod @params } } #EndRegion './Public/Remove-VcCertificate.ps1' 75 #Region './Public/Remove-VcConnector.ps1' -1 function Remove-VcConnector { <# .SYNOPSIS Remove a connector .DESCRIPTION Remove a connector from TLSPC .PARAMETER ID Connector ID, this is the guid/uuid .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Remove-VcConnector -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' Remove a connector .EXAMPLE Remove-VcConnector -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Confirm:$false Remove a connector bypassing the confirmation prompt #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('connectorId')] [ValidateScript( { if ( -not (Test-IsGuid -InputObject $_ ) ) { throw "$_ is not a valid connector id format" } $true } )] [string] $ID, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { if ( $PSCmdlet.ShouldProcess($ID, "Delete connector") ) { $null = Invoke-VenafiRestMethod -Method 'Delete' -UriLeaf "plugins/$ID" } } } #EndRegion './Public/Remove-VcConnector.ps1' 59 #Region './Public/Remove-VcIssuingTemplate.ps1' -1 function Remove-VcIssuingTemplate { <# .SYNOPSIS Remove a issuing template .DESCRIPTION Remove a issuing template from TLSPC .PARAMETER ID Issuing template ID, this is the guid/uuid .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Remove-VcIssuingTemplate -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' Remove a issuing template .EXAMPLE Remove-VcIssuingTemplate -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Confirm:$false Remove a issuing template bypassing the confirmation prompt #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('issuingTemplateId')] [string] $ID, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allObjects = [System.Collections.Generic.List[object]]::new() } process { if ( $PSCmdlet.ShouldProcess($ID, "Delete issuing template") ) { $allObjects.Add($ID) } } end { Invoke-VenafiParallel -InputObject $allObjects -ScriptBlock { $null = Invoke-VenafiRestMethod -Method 'Delete' -UriLeaf "certificateissuingtemplates/$PSItem" } -ThrottleLimit $ThrottleLimit -VenafiSession $VenafiSession } } #EndRegion './Public/Remove-VcIssuingTemplate.ps1' 61 #Region './Public/Remove-VcMachine.ps1' -1 function Remove-VcMachine { <# .SYNOPSIS Remove a machine .DESCRIPTION Remove a machine from TLSPC .PARAMETER ID Machine ID, this is the guid/uuid .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Remove-VcMachine -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' Remove a machine .EXAMPLE Remove-VcMachine -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Confirm:$false Remove a machine bypassing the confirmation prompt #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('machineId')] [string] $ID, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allObjects = [System.Collections.Generic.List[object]]::new() } process { if ( $PSCmdlet.ShouldProcess($ID, "Delete machine") ) { $allObjects.Add($ID) } } end { Invoke-VenafiParallel -InputObject $allObjects -ScriptBlock { $null = Invoke-VenafiRestMethod -Method 'Delete' -UriLeaf "machines/$PSItem" } -ThrottleLimit $ThrottleLimit -VenafiSession $VenafiSession } } #EndRegion './Public/Remove-VcMachine.ps1' 61 #Region './Public/Remove-VcMachineIdentity.ps1' -1 function Remove-VcMachineIdentity { <# .SYNOPSIS Remove a machine identity .DESCRIPTION Remove a machine identity from TLSPC .PARAMETER ID Machine Identity ID, this is the guid/uuid .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Remove-VcMachineIdentity -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' Remove a machine identity .EXAMPLE Remove-VcMachineIdentity -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Confirm:$false Remove a machine identity bypassing the confirmation prompt #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('machineIdentityId')] [string] $ID, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allObjects = [System.Collections.Generic.List[object]]::new() } process { if ( $PSCmdlet.ShouldProcess($ID, "Delete machine identity") ) { $allObjects.Add($ID) } } end { Invoke-VenafiParallel -InputObject $allObjects -ScriptBlock { $null = Invoke-VenafiRestMethod -Method 'Delete' -UriLeaf "machineidentities/$PSItem" } -ThrottleLimit $ThrottleLimit -VenafiSession $VenafiSession } } #EndRegion './Public/Remove-VcMachineIdentity.ps1' 61 #Region './Public/Remove-VcSatelliteWorker.ps1' -1 function Remove-VcSatelliteWorker { <# .SYNOPSIS Remove a vsatellite worker .DESCRIPTION Remove a vsatellite worker from TLSPC .PARAMETER ID Worker ID .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Remove-VcSatelliteWorker -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' Remove a worker .EXAMPLE Remove-VcSatelliteWorker -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Confirm:$false Remove a worker bypassing the confirmation prompt .EXAMPLE Get-VcSatelliteWorker -VSatellite 'My vsat1' | Remove-VcSatelliteWorker Remove all workers associated with a specific vsatellite #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('vsatelliteWorkerId')] [guid] $ID, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { if ( $PSCmdlet.ShouldProcess($ID, "Delete VSatellite Worker") ) { $null = Invoke-VenafiRestMethod -Method 'Delete' -UriLeaf "edgeworkers/$ID" } } end { } } #EndRegion './Public/Remove-VcSatelliteWorker.ps1' 61 #Region './Public/Remove-VcTag.ps1' -1 function Remove-VcTag { <# .SYNOPSIS Remove a tag .DESCRIPTION Remove a tag from TLSPC .PARAMETER ID Tag ID/name .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS Name .EXAMPLE Remove-VcTag -ID 'MyTag' Remove a tag .EXAMPLE Remove-VcTag -ID 'MyTag' -Confirm:$false Remove a tag bypassing the confirmation prompt #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('tagId')] [string] $ID, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allObjects = [System.Collections.Generic.List[object]]::new() } process { if ( $PSCmdlet.ShouldProcess($ID, "Delete Tag") ) { $allObjects.Add($ID) } } end { Invoke-VenafiParallel -InputObject $allObjects -ScriptBlock { $null = Invoke-VenafiRestMethod -Method 'Delete' -UriLeaf "tags/$PSItem" } -ThrottleLimit $ThrottleLimit -VenafiSession $VenafiSession } } #EndRegion './Public/Remove-VcTag.ps1' 61 #Region './Public/Remove-VcTeam.ps1' -1 function Remove-VcTeam { <# .SYNOPSIS Remove a team .DESCRIPTION Remove a team from TLSPC .PARAMETER ID Team ID, this is the guid/uuid .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Remove-VcTeam -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' Remove a team .EXAMPLE Remove-VcTeam -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Confirm:$false Remove a team bypassing the confirmation prompt #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('teamId')] [string] $ID, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allObjects = [System.Collections.Generic.List[object]]::new() } process { if ( $PSCmdlet.ShouldProcess($ID, "Delete Team") ) { $allObjects.Add($ID) } } end { Invoke-VenafiParallel -InputObject $allObjects -ScriptBlock { $null = Invoke-VenafiRestMethod -Method 'Delete' -UriLeaf "teams/$PSItem" } -ThrottleLimit $ThrottleLimit -VenafiSession $VenafiSession } } #EndRegion './Public/Remove-VcTeam.ps1' 61 #Region './Public/Remove-VcTeamMember.ps1' -1 function Remove-VcTeamMember { <# .SYNOPSIS Remove team member .DESCRIPTION Remove a team member from TLSPC .PARAMETER ID Team ID, this is the unique guid obtained from Get-VcTeam. .PARAMETER Member 1 or more members to remove from the team This is the unique guid obtained from Get-VcIdentity. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Remove-VcTeamMember -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Member @('ca7ff555-88d2-4bfc-9efa-2630ac44c1f3', 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f4') Remove members from a team .EXAMPLE Remove-VcTeamMember -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Member 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f3' -Confirm:$false Remove members from a team with no confirmation prompting .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html#/Teams/removeMember #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('teamId')] [string] $ID, [Parameter(Mandatory)] [string[]] $Member, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { $params = @{ Method = 'Delete' UriLeaf = "teams/$ID/members" Body = @{ 'members' = @($Member) } } if ( $PSCmdlet.ShouldProcess($ID, "Delete team members") ) { $null = Invoke-VenafiRestMethod @params } } } #EndRegion './Public/Remove-VcTeamMember.ps1' 72 #Region './Public/Remove-VcTeamOwner.ps1' -1 function Remove-VcTeamOwner { <# .SYNOPSIS Remove team owner .DESCRIPTION Remove a team owner from TLSPC .PARAMETER ID Team ID, the unique guid obtained from Get-VcTeam. .PARAMETER Owner 1 or more owners to remove from the team This is the unique guid obtained from Get-VcIdentity. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Remove-VcTeamOwner -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Owner @('ca7ff555-88d2-4bfc-9efa-2630ac44c1f3', 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f4') Remove owners from a team .EXAMPLE Remove-VcTeamOwner -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Owner 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f3' -Confirm:$false Remove an owner from a team with no confirmation prompting .LINK https://api.venafi.cloud/webjars/swagger-ui/index.html#/Teams/removeOwner #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('teamId')] [string] $ID, [Parameter(Mandatory)] [string[]] $Owner, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { # get team details and ensure at least 1 owner will remain $thisTeam = Get-VcTeam -ID $ID $ownerCompare = Compare-Object -ReferenceObject $thisTeam.owners -DifferenceObject $Owner if ( -not ($ownerCompare | Where-Object { $_.SideIndicator -eq '<=' }) ) { throw 'A team must have at least one owner and you are attempting to remove them all' } $params = @{ Method = 'Delete' UriLeaf = "teams/$ID/owners" Body = @{ 'owners' = @($Owner) } } if ( $PSCmdlet.ShouldProcess($ID, "Delete team owners") ) { $null = Invoke-VenafiRestMethod @params } } } #EndRegion './Public/Remove-VcTeamOwner.ps1' 79 #Region './Public/Remove-VcWebhook.ps1' -1 function Remove-VcWebhook { <# .SYNOPSIS Remove a webhook .DESCRIPTION Remove a webhook from TLSPC .PARAMETER ID Webhook ID, this is the guid/uuid .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .EXAMPLE Remove-VcWebhook -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' Remove a webhook .EXAMPLE Remove-VcWebhook -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Confirm:$false Remove a webhook bypassing the confirmation prompt #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('webhookId')] [string] $ID, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $allObjects = [System.Collections.Generic.List[object]]::new() } process { if ( $PSCmdlet.ShouldProcess($ID, "Delete Webhook") ) { $allObjects.Add($ID) } } end { Invoke-VenafiParallel -InputObject $allObjects -ScriptBlock { $null = Invoke-VenafiRestMethod -Method 'Delete' -UriLeaf "connectors/$PSItem" } -ThrottleLimit $ThrottleLimit -VenafiSession $VenafiSession } } #EndRegion './Public/Remove-VcWebhook.ps1' 61 #Region './Public/Remove-VdcCertificate.ps1' -1 function Remove-VdcCertificate { <# .SYNOPSIS Remove a certificate .DESCRIPTION Removes a Certificate object, all associated objects including pending workflow tickets, and the corresponding Secret Store vault information. You must either be a Master Admin or have Delete permission to the objects and have certificate:delete token scope. Run this in parallel with PowerShell v7+ when you have a large number to process. .PARAMETER Path Path to the certificate to remove .PARAMETER KeepAssociatedApps Provide this switch to remove associations prior to certificate removal .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS None .EXAMPLE $cert | Remove-VdcCertificate Remove a certificate via pipeline .EXAMPLE Remove-VdcCertificate -Path '\ved\policy\my cert' Remove a certificate and any associated app .EXAMPLE Remove-VdcCertificate -Path '\ved\policy\my cert' -KeepAssociatedApps Remove a certificate and first remove all associations, keeping the apps .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Remove-VdcCertificate/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Remove-VdcCertificate.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-DELETE-Certificates-Guid.php #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] [Alias('Remove-TppCertificate')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('DN', 'CertificateDN')] [String] $Path, [Parameter()] [switch] $KeepAssociatedApps, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $allCerts = [System.Collections.Generic.List[string]]::new() # use in shouldprocess messaging below $appsMessage = if ($KeepAssociatedApps) { 'but keep associated apps' } else { 'and associated apps' } } process { if ( $PSCmdlet.ShouldProcess($Path, "Remove certificate $appsMessage") ) { $allCerts.Add($Path) } } end { Invoke-VenafiParallel -InputObject $allCerts -ScriptBlock { $guid = $PSItem | ConvertTo-VdcGuid -ErrorAction SilentlyContinue if ( -not $guid ) { Write-Error "'$PSItem' is not a valid path" return } if ($using:KeepAssociatedApps) { $associatedApps = ($PSItem | Get-VdcAttribute -Attribute "Consumers").Consumers if ( $associatedApps ) { Remove-VdcCertificateAssociation -Path $PSItem -ApplicationPath $associatedApps -Confirm:$false } } $null = Invoke-VenafiRestMethod -Method Delete -UriLeaf "Certificates/$guid" } -ThrottleLimit $ThrottleLimit -ProgressTitle 'Deleting certificates' } } #EndRegion './Public/Remove-VdcCertificate.ps1' 120 #Region './Public/Remove-VdcCertificateAssociation.ps1' -1 function Remove-VdcCertificateAssociation { <# .SYNOPSIS Remove certificate associations .DESCRIPTION Dissociates one or more Application objects from an existing certificate. Optionally, you can remove the application objects and corresponding orphaned device objects that no longer have any applications .PARAMETER Path Path to the certificate .PARAMETER ApplicationPath List of application object paths to dissociate .PARAMETER OrphanCleanup Delete the Application object after dissociating it. Only delete the corresponding Device DN when it has no child objects. Otherwise retain the Device path and its children. .PARAMETER All Remove all associated application objects .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS None .EXAMPLE Remove-VdcCertificateAssociation -Path '\ved\policy\my cert' -ApplicationPath '\ved\policy\my capi' Remove a single application object association .EXAMPLE Remove-VdcCertificateAssociation -Path '\ved\policy\my cert' -ApplicationPath '\ved\policy\my capi' -OrphanCleanup Disassociate and delete the application object .EXAMPLE Remove-VdcCertificateAssociation -Path '\ved\policy\my cert' -RemoveAll Remove all certificate associations .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Certificates-Dissociate.php .NOTES You must have: - Write permission to the Certificate object. - Write or Associate permission to Application objects that are associated with the certificate - Delete permission to Application and device objects when specifying -OrphanCleanup #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High', DefaultParameterSetName = 'RemoveOne')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid path" } })] [Alias('DN', 'CertificateDN')] [String] $Path, [Parameter(Mandatory, ParameterSetName = 'RemoveOne')] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid application path" } })] [String[]] $ApplicationPath, [Parameter()] [switch] $OrphanCleanup, [Parameter(Mandatory, ParameterSetName = 'RemoveAll')] [switch] $All, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' UriLeaf = 'Certificates/Dissociate' Body = @{ } } } process { $shouldProcessAction = "Remove associations" if ( -not ($Path | Test-TppObject -ExistOnly) ) { Write-Error ("Certificate path {0} does not exist" -f $Path) Continue } $params.Body = @{ 'CertificateDN' = $Path } if ( $OrphanCleanup ) { $params.Body.DeleteOrphans = $true $shouldProcessAction += ' AND ORPHANS' } if ( $PSBoundParameters.ContainsKey('ApplicationPath') ) { $params.Body.ApplicationDN = @($ApplicationPath) } else { $associatedApps = $Path | Get-VdcAttribute -Attribute "Consumers" | Select-Object -ExpandProperty Consumers if ( $associatedApps ) { $params.Body.ApplicationDN = @($associatedApps) } else { # no associations to process, no need to continue Write-Warning "No associations for path '$Path'" Return } } try { if ( $PSCmdlet.ShouldProcess($Path, $shouldProcessAction) ) { $null = Invoke-VenafiRestMethod @params } } catch { $myError = $_.ToString() | ConvertFrom-Json Write-Error ('Error removing associations from certificate {0}: {1}' -f $Path, $myError.Error) } } } #EndRegion './Public/Remove-VdcCertificateAssociation.ps1' 151 #Region './Public/Remove-VdcClient.ps1' -1 function Remove-VdcClient { <# .SYNOPSIS Remove registered client agents .DESCRIPTION Remove registered client agents. Provide an array of client IDs to remove a large list at once. .PARAMETER ClientId Unique id for one or more clients .PARAMETER RemoveAssociatedDevice For a registered Agent, delete the associated Device objects, and only certificates that belong to the associated device. Delete any related Discovery information. Preserve unrelated device, certificate, and Discovery information in other locations of the Policy tree and Secret Store. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS ClientId .OUTPUTS None .EXAMPLE Remove-VdcClient -ClientId 1234, 5678 Remove clients .EXAMPLE Remove-VdcClient -ClientId 1234, 5678 -RemoveAssociatedDevice Remove clients and associated devices .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Remove-VdcClient/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Remove-VdcClient.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-ClientDelete.php #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] [Alias('Remove-TppClient')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [String[]] $ClientID, [Parameter()] [Alias('RemoveAssociatedDevices')] [switch] $RemoveAssociatedDevice, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' UriLeaf = 'Client/Delete' Body = @{} } } process { if ( $PSCmdlet.ShouldProcess('Remove {0} clients' -f $ClientID.Count) ) { # 5000 clients at a time is an api limitation for ($i = 0; $i -lt $ClientID.Count; $i += 5000) { $clientIds = $ClientID[$i..($i + 4999)] | ForEach-Object { @{ 'ClientId' = $_ } } $params.Body.Clients = [array] $clientIds $params.Body.DeleteAssociatedDevices = $RemoveAssociatedDevice.IsPresent.ToString().ToLower() $response = Invoke-VenafiRestMethod @params if ( $response.Errors ) { Write-Error ($response.Errors | ConvertTo-Json) } } } } } #EndRegion './Public/Remove-VdcClient.ps1' 97 #Region './Public/Remove-VdcEngineFolder.ps1' -1 function Remove-VdcEngineFolder { <# .SYNOPSIS Remove TLSPDC processing engine assignment(s) from policy folder(s) .DESCRIPTION Remove TLSPDC processing engine assignment(s) from policy folder(s). If you do not supply a list of TLSPDC processing engines, then all processing engines will be removed from the supplied list of policy folders. If you do not supply a list of policy folders, then all policy folder assignments will be removed from the supplied list of processing engines. Supplying both a list of policy folders and processing engines will result in the removal of the specified engines from the list of policy folders. Errors due to a policy engine not being assigned to the listed policy folder are ignored. .PARAMETER FolderPath The full DN path to one or more policy folders (string array). .PARAMETER EnginePath The full DN path to one or more TLSPDC processing engines (string array). .PARAMETER Force Suppress the confirmation prompt before removing engine/folder assignments. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided, but this requires an environment variable VDC_SERVER to be set. .INPUTS FolderPath[], EnginePath[] .OUTPUTS None .EXAMPLE Remove-VdcEngineFolder -FolderPath '\VED\Policy\Certificates\Web Team' -EnginePath @('\VED\Engines\MYVENAFI01','\VED\Engines\MYVENAFI02') Remove policy folder '\VED\Policy\Certificates\Web Team' from the processing engines MYVENAFI01 and MYVENAFI02. .EXAMPLE Remove-VdcEngineFolder -FolderPath @('\VED\Policy\Certificates\Web Team','\VED\Policy\Certificates\Database Team') Remove all processing engine assignments for the policy folders '\VED\Policy\Certificates\Web Team' and '\VED\Policy\Certificates\Database Team'. .EXAMPLE Remove-VdcEngineFolder -EnginePath @('\VED\Engines\MYVENAFI01','\VED\Engines\MYVENAFI02') -Confirm:$false Removed all policy folder assignments from the processing engines MYVENAFI01 and MYVENAFI02. Suppress the confirmation prompt. .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Remove-VdcEngineFolder/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Remove-VdcEngineFolder.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-DELETE-ProcessingEngines-Folder-fguid.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-DELETE-ProcessingEngines-Folder-fguid-eguid.php #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] [Alias('Remove-TppEngineFolder')] param ( [Parameter(Mandatory, ParameterSetName = 'AllEngines', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'Matrix', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('FolderDN', 'Folder')] [String[]] $FolderPath, [Parameter(Mandatory, ParameterSetName = 'AllFolders', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'Matrix', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('EngineDN', 'Engine')] [String[]] $EnginePath, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' -Verbose:$false $params = @{ Method = 'Delete' } $apiCall = "ProcessingEngines/Folder" } process { if ($FolderPath) { [TppObject[]] $FolderList = @() foreach ($path in $FolderPath) { try { $folder = Get-VdcObject -Path $path if ($folder.TypeName -eq 'Policy') { $FolderList += $folder } else { Write-Warning ("TLSPDC object '$($path)' is not a policy ($($folder.TypeName))") Continue } } catch { Write-Warning ("TLSPDC object '$($path)' does not exist") Continue } } if ($FolderList.Count -eq 0) { Write-Warning "All supplied policy folders are invalid" Return } } if ($EnginePath) { [TppObject[]] $EngineList = @() foreach ($path in $EnginePath) { try { $engine = Get-VdcObject -Path $path if ($engine.TypeName -eq 'Venafi Platform') { $EngineList += $engine } else { Write-Warning ("TLSPDC object '$($path)' is not an engine ($($engine.TypeName))") Continue } } catch { Write-Warning ("TLSPDC object '$($path)' does not exist") Continue } } if ($EngineList.Count -eq 0) { Write-Warning "All supplied processing engines are invalid" Return } } if ($PSCmdlet.ParameterSetName -eq 'AllEngines') { $shouldProcessAction = "Remove ALL processing engine assignments" if ($FolderList.Count -gt 1) { $shouldProcessTarget = "$($FolderList.Count) folders" } else { $shouldProcessTarget = "$($FolderList.Path)" } if ($PSCmdlet.ShouldProcess($shouldProcessTarget, $shouldProcessAction)) { foreach ($folder in $FolderList) { $uriLeaf = "$($apiCall)/{$($folder.Guid)}" try { $null = Invoke-VenafiRestMethod @params -UriLeaf $uriLeaf } catch { $myError = $_.ToString() | ConvertFrom-Json Write-Warning ("Error removing processing engines from folder policy '$($folder.Path)': $($myError.Error)") } } } } else { if ($PSCmdlet.ParameterSetName -eq 'AllFolders') { $shouldProcessAction = "Remove ALL policy folder assignments" if ($EngineList.Count -gt 1) { $shouldProcessTarget = "$($EngineList.Count) processing engines" } else { $shouldProcessTarget = "$($EngineList.Name)" } } else { # ParameterSetName='Matrix' if ($FolderList.Count -gt 1) { $shouldProcessAction += "Remove $($FolderList.Count) folders" } else { $shouldProcessAction = "Remove $($FolderList.Path)" } if ($EngineList.Count -gt 1) { $shouldProcessTarget = "$($EngineList.Count) processing engines" } else { $shouldProcessTarget = "$($EngineList.Name)" } } if ($PSCmdlet.ShouldProcess($shouldProcessTarget, $shouldProcessAction)) { foreach ($engine in $EngineList) { Write-Verbose ("Processing Engine: '$($engine.Path)'") if ($PSCmdlet.ParameterSetName -eq 'AllFolders') { [TppObject[]] $FolderList = @() $FolderList += ($engine | Get-VdcEngineFolder) Switch ($FolderList.Count) { 0 { $countMessage = 'NO folders' } 1 { $countMessage = '1 folder' } Default { $countMessage = "$($_) folders" } } Write-Verbose "Found $($countMessage) to remove from engine '$($engine.Name)'" } foreach ($folder in $FolderList) { $uriLeaf = "$($apiCall)/{$($folder.Guid)}/{$($engine.Guid)}" try { $null = Invoke-VenafiRestMethod @params -UriLeaf $uriLeaf } catch { $myError = $_.ToString() | ConvertFrom-Json Write-Warning ("Error removing engine '$($engine.Path)' from folder policy '$($folder.Path)': $($myError.Error)") } } } } } } } #EndRegion './Public/Remove-VdcEngineFolder.ps1' 196 #Region './Public/Remove-VdcObject.ps1' -1 function Remove-VdcObject { <# .SYNOPSIS Remove TLSPDC objects .DESCRIPTION Remove a TLSPDC object and optionally perform a recursive removal. This process can be very destructive as it will remove anything you send it!!! Run this in parallel with PowerShell v7+ when you have a large number to process. .PARAMETER Path Full path to an existing object .PARAMETER Recursive Remove recursively, eg. everything within a policy folder .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 100. Setting the value to 1 will disable multithreading. On PS v5 the ThreadJob module is required. If not found, multithreading will be disabled. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS None .EXAMPLE Remove-VdcObject -Path '\VED\Policy\My empty folder' Remove an object .EXAMPLE Remove-VdcObject -Path '\VED\Policy\folder' -Recursive Remove an object and all objects contained .EXAMPLE Find-VdcObject -Class 'capi' | Remove-VdcObject Find 1 or more objects and remove them .EXAMPLE Remove-VdcObject -Path '\VED\Policy\folder' -Confirm:$false Remove an object without prompting for confirmation. Be careful! .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Remove-VdcObject/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Remove-VdcObject.ps1 .LINK https://docs.venafi.com/Docs/currentSDK/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-delete.php #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] [Alias('Remove-TppObject')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [String] $Path, [Parameter()] [switch] $Recursive, [Parameter()] [int32] $ThrottleLimit = 100, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $allItems = [System.Collections.Generic.List[string]]::new() } process { if ( $PSCmdlet.ShouldProcess($Path, "Remove object") ) { $allItems.Add($Path) } } end { Invoke-VenafiParallel -InputObject $allItems -ScriptBlock { $params = @{ Method = 'Post' UriLeaf = 'config/Delete' Body = @{ ObjectDN = $PSItem Recursive = [int] (($using:Recursive).IsPresent) } } $response = Invoke-VenafiRestMethod @params if ( $response.Result -ne 1 ) { Write-Error $response.Error return } } -ThrottleLimit $ThrottleLimit -ProgressTitle 'Removing objects' } } #EndRegion './Public/Remove-VdcObject.ps1' 114 #Region './Public/Remove-VdcPermission.ps1' -1 function Remove-VdcPermission { <# .SYNOPSIS Remove permissions from TLSPDC objects .DESCRIPTION Remove permissions from TLSPDC objects You can opt to remove permissions for a specific user or all assigned .PARAMETER Path Full path to an object. You can also pipe in a TppObject .PARAMETER IdentityId Prefixed Universal Id of the user or group to have their permissions removed .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path, Guid, IdentityId .OUTPUTS None .EXAMPLE Find-VdcObject -Path '\VED\Policy\My folder' | Remove-VdcPermission Remove all permissions from a specific object .EXAMPLE Find-VdcObject -Path '\VED' -Recursive | Remove-VdcPermission -IdentityId 'AD+blah:879s8d7f9a8ds7f9s8d7f9' Remove all permissions for a specific user .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Remove-VdcPermission/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Remove-VdcPermission.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-DELETE-Permissions-object-guid-principal.php #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High', DefaultParameterSetName = 'ByGuid')] [Alias('Remove-TppPermission')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'ByPath')] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [String[]] $Path, [Parameter(Mandatory, ParameterSetName = 'ByGuid', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Alias('ObjectGuid')] [guid[]] $Guid, [Parameter(ValueFromPipelineByPropertyName)] [ValidateScript( { if ( $_ | Test-VdcIdentityFormat -Format 'Universal' ) { $true } else { throw "'$_' is not a valid Prefixed Universal Id format. See https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-IdentityInformation.php." } })] [Alias('PrefixedUniversalId')] [string[]] $IdentityId, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Delete' UriLeaf = 'placeholder' } } process { Write-Verbose ('Parameter set: {0}' -f $PSCmdLet.ParameterSetName) if ( $PSCmdLet.ParameterSetName -eq 'ByPath' ) { $inputObject = $Path } else { $inputObject = $Guid } foreach ($thisInputObject in $inputObject) { if ( $PSCmdLet.ParameterSetName -eq 'ByPath' ) { $thisGuid = $thisInputObject | ConvertTo-VdcGuid } else { $thisGuid = $thisInputObject } $uriBase = "Permissions/object/{$thisGuid}" $params.UriLeaf = $uriBase if ( $PSBoundParameters.ContainsKey('IdentityId') ) { $identities = $IdentityId } else { # get list of identities permissioned to this object $getParams = $params.Clone() $getParams.Method = 'Get' $identities = Invoke-VenafiRestMethod @getParams } foreach ( $thisIdentity in $identities ) { $params.UriLeaf = $uriBase if ( $thisIdentity.StartsWith('local:') ) { # format of local is local:universalId $type, $id = $thisIdentity.Split(':') $params.UriLeaf += "/local/$id" } else { # external source, eg. AD, LDAP # format is type+name:universalId $type, $name, $id = $thisIdentity -Split { $_ -in '+', ':' } $params.UriLeaf += "/$type/$name/$id" } if ( $PSCmdlet.ShouldProcess($thisGuid, "Remove permissions for $thisIdentity") ) { try { Invoke-VenafiRestMethod @params } catch { Write-Error ("Failed to remove permissions on path $thisGuid, user/group $thisIdentity. $_") } } } } } } #EndRegion './Public/Remove-VdcPermission.ps1' 147 #Region './Public/Remove-VdcTeam.ps1' -1 function Remove-VdcTeam { <# .SYNOPSIS Remove a team .DESCRIPTION Remove a team from TLSPDC .PARAMETER ID Team ID, the "local" ID. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS ID .EXAMPLE Remove-VdcTeam -ID 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e6}' Remove a team .EXAMPLE Remove-VdcTeam -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Confirm:$false Remove a team bypassing the confirmation prompt #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('PrefixedUniversal', 'Guid')] [string] $ID, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { # check if just a guid or prefixed universal id if ( Test-VdcIdentityFormat -ID $ID -Format 'Local' ) { $guid = [guid]($ID.Replace('local:', '')) } else { try { $guid = [guid] $ID } catch { Write-Error "$ID is not a valid team id" Continue } } $params = @{ Method = 'Delete' UriLeaf = ('Teams/local/{{{0}}}' -f $guid.ToString()) } if ( $PSCmdlet.ShouldProcess($ID, "Delete team") ) { $null = Invoke-VenafiRestMethod @params } } } #EndRegion './Public/Remove-VdcTeam.ps1' 74 #Region './Public/Remove-VdcTeamMember.ps1' -1 function Remove-VdcTeamMember { <# .SYNOPSIS Remove team member .DESCRIPTION Remove a team member from TLSPDC .PARAMETER ID Team ID, the ID property from Find-VdcIdentity or Get-VdcTeam. .PARAMETER Member 1 or more members to remove from the team This is the identity ID property from Find-VdcIdentity or Get-VdcIdentity. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS ID .EXAMPLE Remove-VdcTeamMember -ID 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e6}' -Member 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e7}' Remove members from a team .EXAMPLE Remove-VdcTeamMember -ID 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e6}' -Member 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e7}' -Confirm:$false Remove members from a team bypassing the confirmation prompt .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-PUT-Teams-RemoveTeamMembers.php #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('PrefixedUniversal', 'Guid')] [string] $ID, [Parameter(Mandatory)] [string[]] $Member, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { $teamName = Get-VdcIdentity -ID $ID | Select-Object -ExpandProperty FullName $members = foreach ($thisMember in $Member) { if ( $thisMember.StartsWith('local') ) { $teamIdentity = Get-VdcIdentity -ID $thisMember @{ 'PrefixedName' = $teamIdentity.FullName 'PrefixedUniversal' = $teamIdentity.ID } } else { @{'PrefixedUniversal' = $thisMember } } } $params = @{ Method = 'Put' UriLeaf = 'Teams/RemoveTeamMembers' Body = @{ 'Team' = @{'PrefixedName' = $teamName } 'Members' = @($members) } } if ( $PSCmdlet.ShouldProcess($ID, "Delete team members") ) { $null = Invoke-VenafiRestMethod @params } } } #EndRegion './Public/Remove-VdcTeamMember.ps1' 87 #Region './Public/Remove-VdcTeamOwner.ps1' -1 function Remove-VdcTeamOwner { <# .SYNOPSIS Remove team owner .DESCRIPTION Remove a team owner from TLSPDC .PARAMETER ID Team ID, the ID property from Find-VdcIdentity or Get-VdcTeam. .PARAMETER Owner 1 or more owners to remove from the team This is the identity ID property from Find-VdcIdentity or Get-VdcIdentity. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS ID .EXAMPLE Remove-VdcTeamOwner -ID 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e6}' -Owner 'local:{803f332e-7576-4696-a5a2-8ac6be6b14e7}' Remove owners from a team .LINK https://docs.venafi.com/Docs/21.4SDK/TopNav/Content/SDK/WebSDK/r-SDK-PUT-Teams-DemoteTeamOwners.php #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('PrefixedUniversal', 'Guid')] [string] $ID, [Parameter(Mandatory)] [string[]] $Owner, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { # get team details and ensure at least 1 owner will remain $thisTeam = Get-VdcTeam -ID $ID $ownerCompare = Compare-Object -ReferenceObject $thisTeam.owners.ID -DifferenceObject $Owner if ( -not ($ownerCompare | Where-Object { $_.SideIndicator -eq '<=' }) ) { throw 'A team must have at least one owner and you are attempting to remove them all' } # $teamName = Get-VdcIdentity -ID $ID | Select-Object -ExpandProperty FullName $owners = foreach ($thisOwner in $Owner) { if ( $thisOwner.StartsWith('local') ) { $ownerIdentity = Get-VdcIdentity -ID $thisOwner @{ 'PrefixedName' = $ownerIdentity.FullName 'PrefixedUniversal' = $ownerIdentity.ID } } else { @{'PrefixedUniversal' = $thisOwner } } } $params = @{ Method = 'Put' UriLeaf = 'Teams/DemoteTeamOwners' Body = @{ 'Team' = @{'PrefixedName' = $thisTeam.FullName } 'Owners' = @($owners) } } if ( $PSCmdlet.ShouldProcess($ID, "Delete team owners") ) { $null = Invoke-VenafiRestMethod @params # we've only demoted the owners to members. now remove them Remove-VdcTeamMember -ID $ID -Member $Owner } } } #EndRegion './Public/Remove-VdcTeamOwner.ps1' 93 #Region './Public/Rename-VdcObject.ps1' -1 function Rename-VdcObject { <# .SYNOPSIS Rename and/or move an object .DESCRIPTION Rename and/or move an object .PARAMETER Path Full path to an existing object .PARAMETER NewPath New path, including name .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS none .OUTPUTS .EXAMPLE Rename-VdcObject -Path '\VED\Policy\My Devices\OldDeviceName' -NewPath '\ved\policy\my devices\NewDeviceName' Rename an object .EXAMPLE Rename-VdcObject -Path '\VED\Policy\My Devices\DeviceName' -NewPath '\ved\policy\new devices folder\DeviceName' Move an object .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Rename-VdcObject/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Rename-VdcObject.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-renameobject.php #> [CmdletBinding()] [Alias('Rename-TppObject')] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('SourceDN')] [String] $Path, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [String] $NewPath, [Parameter()] [psobject] $VenafiSession ) Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' UriLeaf = 'config/RenameObject' Body = @{ ObjectDN = $Path NewObjectDN = $NewPath } } $response = Invoke-VenafiRestMethod @params if ( $response.Result -ne 1 ) { throw $response.Error } } #EndRegion './Public/Rename-VdcObject.ps1' 87 #Region './Public/Revoke-VdcGrant.ps1' -1 function Revoke-VdcGrant { <# .SYNOPSIS Revoke all grants for a specific user .DESCRIPTION Revoke all grants for a specific user. You must either be an administrator or oauth administrator to perform this action. Also, your token must have the admin:delete scope. Available in TLSPDC v22.3 and later. .PARAMETER ID Prefixed universal id for the user. To search, use Find-VdcIdentity. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS ID .OUTPUTS None .EXAMPLE Revoke-VdcGrant -ID local:{9e9db8d6-234a-409c-8299-e3b81ce2f916} Revoke all grants for a user .EXAMPLE Get-VdcIdentity -ID me@x.com | Revoke-VdcGrant Revoke all grants getting universal id from other identity functions .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Revoke-VdcGrant/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Revoke-VdcGrant.ps1 .LINK https://doc.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-oauth-revokegrants.htm #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] [Alias('Revoke-TppGrant')] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateScript( { if ( Test-VdcIdentityFormat -ID $_ -Format 'Universal' ) { $true } else { throw "'$_' is not a valid prefixed universal identity format. See https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-IdentityInformation.php." } })] [Alias('PrefixedUniversalID', 'IdentityID')] [string[]] $ID ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' if ( $VenafiSessionNested.Version -lt [Version]::new('22', '3', '0') ) { throw 'Revoke-VdcGrant is available on TLSPDC v22.3 and greater' } $params = @{ Method = 'Post' UriLeaf = 'oauth/revokegrants' Body = @{} FullResponse = $true } } process { foreach ($thisID in $ID) { $params.Body.GranteePrefixedUniversal = $thisID if ( $PSCmdlet.ShouldProcess($thisID, 'Revoke all grants') ) { $response = Invoke-VenafiRestMethod @params switch ( $response.StatusCode ) { 200 { if ( $response.Result -eq 1 ) { Write-Error 'Grant revocation was unsuccessful' } } 401 { if ( $response.Error.error -eq 'insufficient_rights' ) { throw 'The token user account does not have sufficient permissions for this request. You must be an administrator or OAuth administrator.' } } 403 { throw 'The access token provided does not have the admin:delete scope. Create a new token with this scope and try again.' } Default { throw $response.Error } } } } } } #EndRegion './Public/Revoke-VdcGrant.ps1' 114 #Region './Public/Revoke-VdcToken.ps1' -1 function Revoke-VdcToken { <# .SYNOPSIS Revoke a token .DESCRIPTION Revoke a token and invalidate the refresh token if provided/available. This could be an access token retrieved from this module or from other means. .PARAMETER AuthServer Server name or URL for the vedauth service .PARAMETER AccessToken Provide an existing access token to revoke. You can either provide a String, SecureString, or PSCredential. If providing a credential, the username is not used. .PARAMETER VenafiPsToken Token object obtained from New-VdcToken .PARAMETER Force Bypass the confirmation prompt .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS VenafiPsToken .OUTPUTS none .EXAMPLE Revoke-VdcToken Revoke token stored in session variable $VenafiSession from New-VenafiSession .EXAMPLE Revoke-VdcToken -Force Revoke token bypassing confirmation prompt .EXAMPLE Revoke-VdcToken -AuthServer venafi.company.com -AccessToken $cred Revoke a token obtained from TLSPDC, not necessarily via VenafiPS .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Revoke-VdcToken/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Revoke-VdcToken.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/AuthSDK/r-SDKa-GET-Revoke-Token.php #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High', DefaultParameterSetName = 'Session')] [Alias('Revoke-TppToken')] param ( [Parameter(Mandatory, ParameterSetName = 'AccessToken')] [ValidateScript( { $validateMe = if ( $_ -notlike 'https://*') { 'https://{0}' -f $_ } else { $_ } try { $null = [System.Uri]::new($validateMe) $true } catch { throw 'Please enter a valid server, https://venafi.company.com or venafi.company.com' } } )] [Alias('Server')] [string] $AuthServer, [Parameter(Mandatory, ParameterSetName = 'AccessToken')] [ValidateScript( { if ( $_ -is [string] -or $_ -is [securestring] -or $_ -is [pscredential] ) { $true } else { throw 'Unsupported type. Provide either a String, SecureString, or PSCredential.' } } )] [psobject] $AccessToken, [Parameter(Mandatory, ParameterSetName = 'VenafiPsToken', ValueFromPipeline)] [pscustomobject] $VenafiPsToken, [Parameter()] [switch] $Force, [Parameter(ParameterSetName = 'Session')] [psobject] $VenafiSession = $script:VenafiSession ) begin { $params = @{ Method = 'Get' UriRoot = 'vedauth' UriLeaf = 'Revoke/Token' } } process { Write-Verbose ('Parameter set: {0}' -f $PSCmdlet.ParameterSetName) switch ($PsCmdlet.ParameterSetName) { 'Session' { $params.VenafiSession = $VenafiSession $target = $VenafiSession.Server } 'AccessToken' { $AuthUrl = $AuthServer # add prefix if just server was provided if ( $AuthServer -notlike 'https://*') { $AuthUrl = 'https://{0}' -f $AuthUrl } $params.Server = $target = $AuthUrl $accessTokenString = $AccessToken | ConvertTo-PlaintextString $params.Header = @{'Authorization' = 'Bearer {0}' -f $accessTokenString } } 'VenafiPsToken' { if ( -not $VenafiPsToken.Server -or -not $VenafiPsToken.AccessToken ) { throw 'Not a valid VenafiPsToken' } $params.Server = $target = $VenafiPsToken.Server $params.Header = @{'Authorization' = 'Bearer {0}' -f $VenafiPsToken.AccessToken.GetNetworkCredential().password } } Default { throw ('Unknown parameter set {0}' -f $PSCmdlet.ParameterSetName) } } Write-Verbose ($params | Out-String) if ( $Force ) { $ConfirmPreference = 'None' } if ( $PSCmdlet.ShouldProcess($target) ) { Invoke-VenafiRestMethod @params } } } #EndRegion './Public/Revoke-VdcToken.ps1' 165 #Region './Public/Search-VdcHistory.ps1' -1 function Search-VdcHistory { <# .SYNOPSIS Search TLSPDC history for items with specific attributes .DESCRIPTION Items in the secret store matching the key/value provided will be found and their details returned with their associated 'current' item. As this function may return details on many items, optional parallel processing has been implemented. Be sure to use PowerShell v7+ to take advantage. .PARAMETER Path Starting path to associated current items to limit the search. The default is \VED\Policy. .PARAMETER Attribute Name and value to search. See https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Secretstore-lookupbyassociation.php for more details. Note, ValidFrom will perform a greater than or equal comparison and ValidTo will perform a less than or equal comparison. Currently, one 1 name/value pair can be used. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS None .OUTPUTS PSCustomObject .EXAMPLE Search-VdcHistory -Attribute @{'ValidTo' = (Get-Date)} Name : test.gdb.com TypeName : X509 Server Certificate Path : \VED\Policy\Certificates\test.gdb.com History : {@{AIACAIssuerURL=System.Object[]; AIAKeyIdentifier=F2E970BA11A64D616E78592911D7CC; C=US; CDPURI=0::False; EnhancedKeyUsage=Server Authentication(1.3.6.1.5.5.7.3.1).........}} Find historical items that are still active .EXAMPLE Search-VdcHistory -Attribute @{'ValidTo' = (Get-Date)} -Path '\ved\policy\certs' Find historical items that are still active and the current item starts with a specific path #> [CmdletBinding()] [Alias('Search-TppHistory')] param ( [Parameter()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } } )] [string] $Path = '\VED\Policy', [Parameter(Mandatory)] [hashtable] $Attribute, [Parameter()] [ValidateNotNullOrEmpty()] [psobject] $VenafiSession ) Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $activeVaultId = Find-VdcVaultId -Attribute $Attribute if ( -not $activeVaultId ) { return } Write-Warning ('Found {0} matching vault items' -f $activeVaultId.Count) # we have vault ids, now get path to current item $owners = if ($PSVersionTable.PSVersion.Major -lt 6) { $activeVaultId | ForEach-Object { Invoke-VenafiRestMethod -UriLeaf "secretstore/ownerlookup" -Body @{'Namespace' = 'config'; 'VaultID' = $_ } -Method Post } } else { $activeVaultId | ForEach-Object -ThrottleLimit 100 -Parallel { Import-Module VenafiPS New-VenafiSession -Server ($using:VenafiSession).Server -AccessToken ($using:VenafiSession).Token.AccessToken Invoke-VenafiRestMethod -UriLeaf "secretstore/ownerlookup" -Body @{'Namespace' = 'config'; 'VaultID' = $_ } -Method Post } } # limit current certs to the path provided $certs = $owners.owners.where{ $_ -like "$Path*" } | Select-Object -Unique Write-Warning ('Getting details on {0} current items' -f $certs.Count) # scriptblock which will be used for PS v5 and core $sbGeneric = { $thisDetailedCert = Get-VdcCertificate -Path $_ -IncludePreviousVersions -ErrorAction SilentlyContinue if ( -not $thisDetailedCert ) { return } $history = $thisDetailedCert.PreviousVersions | Where-Object { $_.VaultId -in $activeVaultId } | Select-Object -ExpandProperty CertificateDetails if ( $history ) { $thisDetailedCert | Select-Object Name, TypeName, Path, @{ 'n' = 'History' 'e' = { $history } } } } # needed for parallel in ps7 $sbGenericString = $sbGeneric.ToString() if ($PSVersionTable.PSVersion.Major -lt 6) { $certs | ForEach-Object -Process $sbGeneric } else { $certs | ForEach-Object -ThrottleLimit 100 -Parallel { Import-Module VenafiPS $VenafiSession = New-VenafiSession -Server ($using:VenafiSession).Server -AccessToken ($using:VenafiSession).Token.AccessToken -PassThru $activeVaultId = $using:activeVaultId Invoke-Expression $using:sbGenericString } } } #EndRegion './Public/Search-VdcHistory.ps1' 133 #Region './Public/Set-VcApplication.ps1' -1 function Set-VcApplication { <# .SYNOPSIS Update an existing application .DESCRIPTION Update details of existing applications. Additional properties will be available in the future. .PARAMETER Application The application to update. Specify either ID or name. .PARAMETER Name Provide a new name for the application if you wish to change it. .PARAMETER TeamOwner Associate a team as an owner of this application .PARAMETER IssuingTemplate Associate one or more issuing templates by ID or name .PARAMETER NoOverwrite Append to existing details as opposed to overwriting .PARAMETER PassThru Return the newly updated object .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .OUTPUTS PSCustomObject .EXAMPLE Set-VcApplication -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Name 'ThisAppNameIsBetter' Rename an existing application .EXAMPLE Set-VcApplication -ID 'MyApp' -TeamOwner 'GreatTeam' Change the owner to this team .EXAMPLE Set-VcApplication -ID 'MyApp' -TeamOwner 'GreatTeam' -NoOverwrite Append this team to the list of owners .EXAMPLE Set-VcApplication -ID 'MyApp' -IssuingTemplate 'Template1', 'Template2' Update the templates associated with application. This will overwrite any existing templates configured. #> [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('applicationId', 'ID')] [string] $Application, [Parameter()] [string] $Name, [Parameter()] [string[]] $TeamOwner, [Parameter()] [string[]] $IssuingTemplate, [Parameter()] [switch] $NoOverwrite, [Parameter()] [switch] $PassThru, [Parameter()] [Alias('Key')] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $params = @{ Method = 'Put' UriRoot = 'outagedetection/v1' Body = @{} } switch ($PSBoundParameters.Keys ) { 'TeamOwner' { $allTeams = Get-VcTeam -All } Default {} } } process { $thisApp = Get-VcApplication -Application $Application if ( -not $thisApp ) { # process the next one in the pipeline if we don't have a valid ID this time Write-Error "Application $Application does not exist" Continue } $params.UriLeaf = 'applications/{0}' -f $thisApp.applicationId # set required fields to existing values by default $params.Body.name = if ( $Name ) { $Name } else { $thisApp.name } $params.Body.ownerIdsAndTypes = $thisApp.ownerIdsAndTypes switch ( $PSBoundParameters.Keys ) { 'TeamOwner' { $params.Body.ownerIdsAndTypes = @() foreach ($owner in $TeamOwner ) { if ( Test-IsGuid($owner) ) { $thisOwner = $owner } else { $thisOwner = $allTeams | Where-Object { $_.name -eq $owner } | Select-Object -ExpandProperty teamId } if ( $thisOwner ) { $params.Body.ownerIdsAndTypes += @{ ownerId = $thisOwner ownerType = 'TEAM' } } else { Write-Error "Team $ID does not exist" } } if ( $NoOverwrite -and $thisApp.ownerIdsAndTypes ) { $params.Body.ownerIdsAndTypes += $thisApp.ownerIdsAndTypes } } 'IssuingTemplate' { $newT = @{} # grab existing templates as our starting point if we're not overwriting # issuingTempate is of type PSNoteProperty so we need to iterate and add to hashtable if ( $NoOverwrite -and $thisApp.issuingTemplate ) { $thisApp.issuingTemplate | ForEach-Object { $newT[$_.name] = $_.issuingTemplateId } } foreach ($template in $IssuingTemplate ) { $t = Get-VcIssuingTemplate -IssuingTemplate $template if ( $t ) { $newT[$t.name] = $t.issuingTemplateId } else { Write-Error "Issuing template $template does not exist" } } if ( $newT.Count -gt 0 ) { $params.Body.certificateIssuingTemplateAliasIdMap = $newT } } } if ( $PSCmdlet.ShouldProcess($params.Body.name, "Update application") ) { $response = Invoke-VenafiRestMethod @params } if ( $PassThru ) { $response | ConvertTo-VaasTeam } } } #EndRegion './Public/Set-VcApplication.ps1' 191 #Region './Public/Set-VcCertificate.ps1' -1 function Set-VcCertificate { <# .SYNOPSIS Update a certificate .DESCRIPTION Associate one or more certificates with one or more applications or tags. The associated applications/tags can either replace or be added to existing. By default, applications/tags will be replaced. .PARAMETER Certificate Certificate ID or name to be associated. If a name is provided and multiple certificates are found, they will all be associated. Tab completion can be used for a list of certificate names to choose from. Type 3 or more characters for tab completion to work. .PARAMETER Application One or more application IDs or names. Tab completion can be used for a list of application names. .PARAMETER Tag One of more tag names or name/value pairs. To specify a name/value pair, use the format 'name:value'. .PARAMETER NoOverwrite Append to existing as opposed to overwriting .PARAMETER PassThru Return the newly updated certificate object(s) .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS Certificate .OUTPUTS PSCustomObject .EXAMPLE Add-VcCertificateAssociation -Certificate '7ac56ec0-2017-11ee-9417-a17dd25b82f9' -Application '96fc9310-67ec-11eb-a8a7-794fe75a8e6f' Associate a certificate to an application .EXAMPLE Add-VcCertificateAssociation -Certificate '7ac56ec0-2017-11ee-9417-a17dd25b82f9' -Application '96fc9310-67ec-11eb-a8a7-794fe75a8e6f', 'a05013bd-921d-440c-bc22-c9ead5c8d548' Associate a certificate to multiple applications .EXAMPLE Find-VcCertificate -First 5 | Add-VcCertificateAssociation -Application 'My Awesome App' Associate multiple certificates to 1 application by name .EXAMPLE Add-VcCertificateAssociation -Certificate '7ac56ec0-2017-11ee-9417-a17dd25b82f9' -Tag 'MyTagName' Associate a certificate to a tag .EXAMPLE Add-VcCertificateAssociation -Certificate '7ac56ec0-2017-11ee-9417-a17dd25b82f9' -Tag 'MyTagName:MyTagValue' Associate a certificate to a tag name/value pair .EXAMPLE Add-VcCertificateAssociation -Certificate '7ac56ec0-2017-11ee-9417-a17dd25b82f9' -Tag 'Tag1', 'MyTagName:MyTagValue' Associate a certificate to multiple tags .EXAMPLE Add-VcCertificateAssociation -Certificate 'www.barron.com' -Application '96fc9310-67ec-11eb-a8a7-794fe75a8e6f' -NoOverwrite Associate a certificate, by name, to an additonal application, keeping the existing application in place #> [CmdletBinding(DefaultParameterSetName = 'Application')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('certificateID')] [string] $Certificate, [Parameter(Mandatory, ParameterSetName = 'Application')] [Alias('applicationID')] [string[]] $Application, [Parameter(Mandatory, ParameterSetName = 'Tag')] [string[]] $Tag, [Parameter()] [switch] $NoOverwrite, [Parameter()] [switch] $PassThru, [Parameter()] [Alias('Key')] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' switch ($PSCmdlet.ParameterSetName) { 'Application' { $apps = $Application | Get-VcData -Type 'Application' -FailOnNotFound $params = @{ Method = 'Patch' UriRoot = 'outagedetection/v1' UriLeaf = 'applications/certificates' Body = @{ action = 'REPLACE' targetedApplicationIds = @($apps) } } if ( $NoOverwrite ) { $params.Body.action = 'ADD' } } 'Tag' { # ensure tags exist and have the correct case # tag assignment will fail if the tag name is not exact $tagNames = $Tag | Get-VcData -Type 'Tag' -Name -FailOnNotFound $params = @{ Method = 'Patch' UriLeaf = 'tagsassignment' Body = @{ action = 'REPLACE' targetedTags = @($tagNames) entityType = 'CERTIFICATE' } } if ( $NoOverwrite ) { $params.Body.action = 'ADD' } } } $allCerts = [System.Collections.Generic.List[string]]::new() } process { if ( Test-IsGuid($Certificate) ) { $allCerts.Add($Certificate) } else { # search by name $certIDs = Get-VcData -InputObject $Certificate -Type 'Certificate' foreach ($certID in @($certIDs)) { $allCerts.Add($certID) } } } end { switch ($PSCmdlet.ParameterSetName ) { 'Application' { $params.Body.certificateIds = $allCerts $response = Invoke-VenafiRestMethod @params if ( $PassThru ) { $response.certificates } } 'Tag' { $params.Body.entityIds = $allCerts $response = Invoke-VenafiRestMethod @params if ( $PassThru ) { $response.tagsAssignInformation | Select-Object -Property @{'n' = 'certificateId'; 'e' = { $_.entityId } }, * -ExcludeProperty entityId, entityType } } } } } #EndRegion './Public/Set-VcCertificate.ps1' 188 #Region './Public/Set-VcConnector.ps1' -1 function Set-VcConnector { <# .SYNOPSIS Update an existing connector .DESCRIPTION Update a new machine, CA, TPP, or credential connector. You can either update the manifest or disable/reenable it. .PARAMETER ManifestPath Path to an updated manifest for an existing connector. Ensure the manifest has the deployment element which is not needed when testing in the simulator. See https://github.com/Venafi/vmware-avi-connector?tab=readme-ov-file#manifest for details. .PARAMETER ID Connector ID to update. If not provided, the ID will be looked up by the name in the manifest provided by ManifestPath. Note that if both ManifestPath and ID are provided and the name in the manifest is different than the one associated with ID, the name will be changed. .PARAMETER Disable Disable or reenable a connector .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS Connector .EXAMPLE Set-VcConnector -ManifestPath '/tmp/manifest_v2.json' Update an existing connector with the same name as in the manifest .EXAMPLE Set-VcConnector -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -ManifestPath '/tmp/manifest_v2.json' Update an existing connector utilizing a specific connector ID .EXAMPLE Set-VcConnector -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Disable Disable a connector .EXAMPLE Get-VcConnector -ID 'My connector' | Set-VcConnector -Disable Disable a connector by name .EXAMPLE Set-VcConnector -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Disable:$false Reenable a disabled connector #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Manifest')] param ( [Parameter(ParameterSetName = 'Manifest', Mandatory)] [ValidateScript( { if ( -not ( Test-Path $_ ) ) { throw "The manifest path $_ cannot be found" } $true } )] [string] $ManifestPath, [Parameter(ParameterSetName = 'Manifest', ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'Disable', Mandatory, ValueFromPipelineByPropertyName)] [Alias('connectorId', 'connector')] [ValidateScript( { if ( -not (Test-IsGuid -InputObject $_ ) ) { throw "$_ is not a valid connector id format" } $true } )] [string] $ID, [Parameter(ParameterSetName = 'Disable', Mandatory)] [switch] $Disable, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' } process { switch ($PSCmdLet.ParameterSetName) { 'Manifest' { $manifestObject = Get-Content -Path $ManifestPath -Raw | ConvertFrom-Json $manifest = $manifestObject.manifest # if connector is provided, update that specific one # if not, use the name from the manifest to find the existing connector id if ( $ID ) { $connectorId = $ID } else { $thisConnector = Get-VcConnector -ID $manifest.name if ( -not $thisConnector ) { throw ('An existing connector with the name {0} was not found' -f $manifest.name) } $connectorId = $thisConnector.connectorId } # ensure deployment is provided which is not needed during simulator testing if ( -not $manifest.deployment ) { throw 'A deployment element was not found in the manifest. See https://github.com/Venafi/vmware-avi-connector?tab=readme-ov-file#manifest for details.' } $params = @{ Method = 'Patch' UriLeaf = "plugins/$connectorId" Body = @{ manifest = $manifest } } if ( $PSCmdlet.ShouldProcess($manifest.name, 'Update connector') ) { $null = Invoke-VenafiRestMethod @params } } 'Disable' { if ( $Disable ) { if ( $PSCmdlet.ShouldProcess($ID, "Disable connector") ) { $null = Invoke-VenafiRestMethod -Method 'Post' -UriLeaf "plugins/$ID/disablements" } } else { $null = Invoke-VenafiRestMethod -Method 'Delete' -UriLeaf "plugins/$ID/disablements" } } } } } #EndRegion './Public/Set-VcConnector.ps1' 150 #Region './Public/Set-VcTeam.ps1' -1 function Set-VcTeam { <# .SYNOPSIS Update an existing team .DESCRIPTION Update name, role, and/or user matching rules for existing teams. .PARAMETER ID Team ID or name .PARAMETER Name Provide a new name for the team if you wish to change it. .PARAMETER Role Provide a new role for the team if you wish to change it. Accepted values are 'System Admin', 'PKI Admin', 'Resource Owner', or 'Guest' .PARAMETER UserMatchingRule Rule(s) for user membership which matches SSO claim data. Each rule has 3 parts, ClaimName, Operator, and ClaimValue, in the form of a hashtable. A list/array of hashtables is supported. For a singlepart claim, the operator can be 'equals', 'does not equal', 'starts with', or 'ends with'. For a multivalue claim where ClaimValue will be an array, the operator can be 'contains' or 'does not contain'. ClaimName and ClaimValue are case sensitive. When providing user AD groups or other groups they are most commonly provided as multivalue claims. This parameter will overwrite existing rules by default. To append use -NoOverwrite. .PARAMETER NoOverwrite Append to existing user matching rules as opposed to overwriting .PARAMETER PassThru Return the newly updated team object .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .INPUTS ID .OUTPUTS PSCustomObject .EXAMPLE Set-VcTeam -ID 'MyTeam' -Name 'ThisTeamIsBetter' Rename an existing team .EXAMPLE Set-VcTeam -ID 'ca7ff555-88d2-4bfc-9efa-2630ac44c1f2' -Role 'PKI Admin' Change the role for an existing team .EXAMPLE Set-VcTeam -ID 'MyTeam' -UserMatchingRule @{'ClaimName'='MyClaim';'Operator'='equals';'ClaimValue'='matchme'} Replace a teams user matching rules .EXAMPLE Set-VcTeam -ID 'MyTeam' -UserMatchingRule @{'ClaimName'='MyClaim';'Operator'='equals';'ClaimValue'='matchme'} -NoOverwrite Update a teams user matching rules, appending instead of overwriting .EXAMPLE Set-VcTeam -ID 'MyTeam' -Name 'ThisTeamIsBetter' -PassThru Rename an existing team and return the updated team object .EXAMPLE Get-VcTeam -All | Where-Object {$_.name -like '*shouldnt be sysadmin*'} | Set-VcTeam -NewRole 'PKI Admin' Update many teams #> [CmdletBinding(DefaultParameterSetName = 'NoOverwrite')] [Alias('Set-VaasTeam')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('teamId', 'ID')] [string] $Team, [Parameter()] [string] $Name, [Parameter()] [ValidateSet('System Admin', 'PKI Admin', 'Resource Owner', 'Guest')] [string] $Role, [Parameter()] [Parameter(Mandatory, ParameterSetName = 'Overwrite')] [ValidateScript({ foreach ($rule in $_) { if ( $rule.Keys -contains 'ClaimName' -and $rule.Keys -contains 'Operator' -and $rule.Keys -contains 'ClaimValue' ) { if ( $rule.Operator.Replace(' ', '_').ToUpper() -notin 'EQUALS', 'NOT_EQUALS', 'CONTAINS', 'NOT_CONTAINS', 'STARTS_WITH', 'ENDS_WITH') { throw 'Operator must be one of the following: Equals, Not Equals, Contains, Not Contains, Starts With, or Ends With' } $true } else { throw "NewUserMatchingRule is an array of hashtables where each hashtable must contain keys 'ClaimName', 'Operator', and 'ClaimValue'." } } })] [hashtable[]] $UserMatchingRule, [Parameter(Mandatory, ParameterSetName = 'Overwrite')] [switch] $NoOverwrite, [Parameter()] [switch] $PassThru, [Parameter()] [Alias('Key')] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' $params = @{ VenafiSession = $VenafiSession Method = 'Patch' Body = @{} } if ( $Name ) { $params.Body.name = $Name } if ( $Role ) { $params.Body.role = $Role.Replace(' ', '_').ToUpper() } if ( $UserMatchingRule ) { [array]$params.Body.userMatchingRules = foreach ($rule in $UserMatchingRule) { @{ claimName = $rule.ClaimName operator = $rule.Operator.Replace(' ', '_').ToUpper() value = $rule.ClaimValue } } } } process { $thisID = Get-VcData -InputObject $Team -Type 'Team' -Object if ( -not $thisID ) { Write-Error "Team '$Team' does not exist" return } if ( $NoOverwrite -and $thisID.userMatchingRules ) { $params.Body.userMatchingRules += $thisID.userMatchingRules } $params.UriLeaf = "teams/$($thisID.teamId)" $response = Invoke-VenafiRestMethod @params if ( $PassThru ) { $response | ConvertTo-VcTeam } } } #EndRegion './Public/Set-VcTeam.ps1' 170 #Region './Public/Set-VdcAttribute.ps1' -1 function Set-VdcAttribute { <# .SYNOPSIS Sets a value on an objects attribute or policies (policy attributes) .DESCRIPTION Set the value on an objects attribute. The attribute can either be built-in or custom. You can also set policies (policy attributes). .PARAMETER Path Path to the object to modify .PARAMETER Attribute Hashtable with names and values to be set. If setting a custom field, you can use either the name or guid as the key. To clear a value overwriting policy, set the value to $null. .PARAMETER Class Required when setting policy attributes. Provide the class name to set the value for. If unsure of the class name, add the value through the TLSPDC UI and go to Support->Policy Attributes to find it. .PARAMETER Lock Lock the value on the policy. Only applicable to setting policies. .PARAMETER BypassValidation Bypass data validation. Only applicable to custom fields. .PARAMETER NoOverwrite Add to any existing value, if there is one, as opposed to overwriting. Unlike overwriting, adding can only be a single value, not an array. Not applicable to custom fields. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS None .EXAMPLE Set-VdcAttribute -Path '\VED\Policy\My Folder\app.company.com' -Attribute @{'Consumers'='\VED\Policy\myappobject.company.com'} Set the value on an object .EXAMPLE Set-VdcAttribute -Path '\VED\Policy\My Folder\app.company.com' -Attribute @{'Management Type'=$null} Clear the value on an object, reverting to policy if applicable .EXAMPLE Set-VdcAttribute -Path '\VED\Policy\My Folder\app.company.com' -Attribute @{'My custom field Label'='new custom value'} Set the value on a custom field .EXAMPLE Set-VdcAttribute -Path '\VED\Policy\My Folder\app.company.com' -Attribute @{'My custom field Label'='new custom value'} -BypassValidation Set the value on a custom field bypassing field validation .EXAMPLE Set-VdcAttribute -Path '\VED\Policy\My Folder' -Class 'X509 Certificate' -Attribute @{'Notification Disabled'='0'} Set a policy attribute .EXAMPLE Set-VdcAttribute -Path '\VED\Policy\My Folder' -Class 'X509 Certificate' -Attribute @{'Notification Disabled'='0'} -Lock Set a policy attribute and lock the value .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Set-VdcAttribute/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Set-VdcAttribute.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Metadata-Set.php .LINK https://docs.venafi.com/Docs/currentSDK/TopNav/Content/SDK/WebSDK/r-SDK-POST-Metadata-SetPolicy.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-addvalue.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-addpolicyvalue.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-write.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-writepolicy.php #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'NotPolicy')] [Alias('Set-TppAttribute')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Being flagged incorrectly')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('DN')] [String] $Path, [Parameter(Mandatory)] [hashtable] $Attribute, [Parameter(Mandatory, ParameterSetName = 'Policy')] [Alias('ClassName', 'PolicyClass')] [string] $Class, [Parameter(ParameterSetName = 'Policy')] [switch] $Lock, [Parameter()] [switch] $BypassValidation, [Parameter()] [switch] $NoOverwrite, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' } $baseFields = @() $customFields = @() $Attribute.GetEnumerator() | ForEach-Object { $thisKey = $_.Key if ($null -ne $_.Value) { if ( $_.Value.GetType().BaseType.Name -eq 'Array' ) { $thisValue = @($_.Value) } else { $thisValue = ($_.Value).ToString() } } else { # cannot add 'null', only overwrite to blank out the value $NoOverwrite = $false $thisValue = $_.Value $BypassValidation = $true } $customFieldError = $null $customField = $VenafiSessionNested.CustomField | Where-Object { $_.Label -eq $thisKey -or $_.Guid -eq $thisKey } Write-Verbose ('found custom field {0} - {1}' -f $customField.DN, $customField|ConvertTo-Json) if ( $customField ) { if ( -not $BypassValidation ) { switch ( $customField.Type.ToString() ) { '1' { # string if ( $customField.RegularExpression -and $thisValue -notmatch $customField.RegularExpression ) { $customFieldError = 'regular expression ''{0}'' validation failed' -f $customField.RegularExpression } } '2' { # list if ( $thisValue -notin $customField.AllowedValues ) { $customFieldError = 'value is not in the list of allowed values ''{0}''' -f $customField.AllowedValues } } '5' { # identity if ( -not ($thisValue | Test-VdcIdentity -ExistOnly) ) { $customFieldError = 'value is not a valid identity' } } '4' { # date/time try { [datetime] $thisValue } catch { $customFieldError = 'value is not a valid date' } } Default { $customFieldError = 'unknown custom field type' } } } if ( $customFieldError ) { Write-Error ('The value ''{0}'' for field ''{1}'' encountered an error, {2}' -f $thisValue, $thisKey, $customFieldError) } else { $customFields += @{ ItemGuid = $customField.Guid List = if ($null -eq $thisValue) { , @() } else { , @($thisValue) } } } } else { $baseFields += @{ Name = $thisKey Value = if ($null -eq $thisValue) { '' } else { $thisValue } # Value = if ($null -eq $thisValue) { , @() } else { , @($thisValue) } } } } } process { if ( -not $PSCmdlet.ShouldProcess($Path) ) { continue } # built-in fields and custom fields have different APIs and payloads # as do attributes and policy attributes... if ( $baseFields.Count -gt 0 ) { if ( $PSBoundParameters.ContainsKey('Class') ) { # config/WritePolicy and AddPolicyValue only allows 1 key/value per call foreach ($field in $baseFields) { $params.Body = @{ ObjectDN = $Path Class = $Class AttributeName = $field.Name Locked = [int]$Lock.ToBool() } if ( $NoOverwrite ) { $params.UriLeaf = 'config/AddPolicyValue' $params.Body.Value = $field.Value } else { $params.UriLeaf = 'config/WritePolicy' $params.Body.Values = @($field.Value) } $response = Invoke-VenafiRestMethod @params if ( $response.Result -ne 1 ) { Write-Error $response.Error } } } else { if ( $NoOverwrite ) { $params.UriLeaf = 'config/AddValue' foreach ( $field in $baseFields ) { $params.Body = @{ ObjectDN = $Path AttributeName = $field.Name Value = $field.Value } $response = Invoke-VenafiRestMethod @params if ( $response.Result -ne 1 ) { Write-Error $response.Error } } } else { $params.UriLeaf = 'config/Write' $params.Body = @{ ObjectDN = $Path AttributeData = @($baseFields) } $response = Invoke-VenafiRestMethod @params if ( $response.Result -ne 1 ) { Write-Error $response.Error } } } } if ( $customFields.Count -gt 0 ) { if ( $PSBoundParameters.ContainsKey('Class') ) { $params.UriLeaf = 'Metadata/SetPolicy' $params.Body = @{ DN = $Path ConfigClass = $Class GuidData = $customFields Locked = [int]$Lock.ToBool() } } else { $params.UriLeaf = 'Metadata/Set' $params.Body = @{ DN = $Path GuidData = $customFields KeepExisting = $true } } $response = Invoke-VenafiRestMethod @params if ( $response.Result -ne [TppMetadataResult]::Success ) { Write-Error $response.Error } } } } #EndRegion './Public/Set-VdcAttribute.ps1' 334 #Region './Public/Set-VdcCredential.ps1' -1 function Set-VdcCredential { <# .SYNOPSIS Update credential values .DESCRIPTION Update values for credential objects in TLSPDC. .PARAMETER Path The full path to the credential object .PARAMETER Password New password for a password, username/password, or certificate credential. Provide a string, SecureString, or PSCredential. .PARAMETER Username New username for a username/password credential. A password is also required. .PARAMETER Certificate PKCS #12 certificate object for a certificate credential. You can provide either a certificate object or CertificatePath to a .p12 or .pfx file. A private key password is also required for -Password. .PARAMETER CertificatePath Path to a certificate for a certificate credential. You can provide either a local path to a .p12 or .pfx file or a certificate object with -Certificate. A private key password is also required for -Password. .PARAMETER CertificateLinkPath Provide a path to an existing TLSPDC certificate object to be used as the certificate for a certificate credential. .PARAMETER Expiration Expiration date in UTC for the credential. Provide a DateTime object. This can be set for username or password credentials. .PARAMETER Value Hashtable containing the keys/values to be updated. This parameter will be deprecated in a future release. Use specific parameters for the credential type. The values allowed to be updated are specific to the object type. See https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Credentials-FriendlyName.php for details. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path .OUTPUTS None .EXAMPLE Set-VdcCredential -Path '\VED\Policy\Password Credential' -Password 'my-new-password' Set a new password for a password credential .EXAMPLE Set-VdcCredential -Path '\VED\Policy\UsernamePassword Credential' -Password 'my-new-password' -Username 'greg' Set a new password for a username/password credential .EXAMPLE Set-VdcCredential -Path '\VED\Policy\Certificate Credential' -Password 'my-pk-password' -Certificate $p12 Set a new certificate for a certificate credential .EXAMPLE Set-VdcCredential -Path '\VED\Policy\Password Credential' -Password 'my-new-password' -Expiration (Get-Date).AddDays(30) Set a new password for a password credential and set the expiration date to 30 days from now .EXAMPLE Set-VdcCredential -Path '\VED\Policy\Certificate Credential' -CertificateLinkPath '\VED\Policy\Certificates\newcert.domain.com' Set an existing TLSPDC certificate object as the certificate for a certificate credential .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Set-VdcCredential/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Set-VdcCredential.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Credentials-update.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Credentials-FriendlyName.php #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Password')] [Alias('Set-TppCredential')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingUsernameAndPasswordParams', '', Justification = 'Password is used for more than just username/password credentials so a credential object is not appropriate.')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [String] $Path, [Parameter(ParameterSetName = 'Password', Mandatory)] [Parameter(ParameterSetName = 'UsernamePassword', Mandatory)] [Parameter(ParameterSetName = 'Certificate', Mandatory)] [Parameter(ParameterSetName = 'CertificatePath', Mandatory)] [ValidateScript( { if ( $_ -is [string] -or $_ -is [securestring] -or $_ -is [pscredential] ) { $true } else { throw 'Unsupported type. Provide either a String, SecureString, or PSCredential.' } } )] [psobject] $Password, [Parameter(ParameterSetName = 'UsernamePassword', Mandatory)] [string] $Username, [Parameter(ParameterSetName = 'Certificate', Mandatory)] [ValidateScript( { if ( -not $_.HasPrivateKey ) { throw 'Certificate must contain a private key' } $true } )] [System.Security.Cryptography.X509Certificates.X509Certificate2] $Certificate, [Parameter(Mandatory, ParameterSetName = 'CertificatePath', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( -not (Test-Path -Path (Resolve-Path -Path $_) -PathType Leaf) ) { throw "'$_' is not a valid file path" } if ([System.IO.Path]::GetExtension((Resolve-Path -Path $_)) -notin '.pfx', '.p12') { throw "$_ is not a .p12 or .pfx file" } $true } )] [String] $CertificatePath, [Parameter(ParameterSetName = 'CertificateLinkPath', Mandatory)] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } } )] [string] $CertificateLinkPath, [Parameter(ParameterSetName = 'Password')] [Parameter(ParameterSetName = 'UsernamePassword')] [Parameter(ParameterSetName = 'Certificate')] [Parameter(ParameterSetName = 'CertificatePath')] [Parameter(ParameterSetName = 'CertificateLinkPath')] [datetime] $Expiration, [Parameter(ParameterSetName = 'OldValue', Mandatory)] [hashtable] $Value, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' UriLeaf = 'Credentials/Update' Body = @{ Values = @() } } if ( $PSBoundParameters.ContainsKey('Password') ) { $newPassword = $Password | ConvertTo-PlaintextString $params.Body.Values += @{ 'Name' = 'Password' 'Type' = 'string' 'Value' = $newPassword } } if ( $Username ) { $params.Body.Values += @{ 'Name' = 'Username' 'Type' = 'string' 'Value' = $Username } } if ( $Certificate ) { $params.Body.Values += @{ 'Name' = 'Certificate' 'Type' = 'byte[]' 'Value' = [System.Convert]::ToBase64String($Certificate.Export(1)) } } if ( $CertificatePath ) { if ($PSVersionTable.PSVersion.Major -lt 6) { $cert = Get-Content $CertificatePath -Encoding Byte } else { $cert = Get-Content $CertificatePath -AsByteStream } $params.Body.Values += @{ 'Name' = 'Certificate' 'Type' = 'byte[]' 'Value' = [System.Convert]::ToBase64String($cert) } } if ( $Expiration ) { $params.Body.Expiration = '/Date({0})/' -f [int64]($Expiration.ToUniversalTime() - [datetime]'1970-01-01T00:00:00Z').TotalMilliseconds } # used with -Value parameter, to be deprecated $CredTypes = @{ 'Password Credential' = @{ 'FriendlyName' = 'Password' 'ValueName' = @{ 'Password' = 'string' } } 'Username Password Credential' = @{ 'FriendlyName' = 'UsernamePassword' 'ValueName' = @{ 'Username' = 'string' 'Password' = 'string' } } 'Certificate Credential' = @{ 'FriendlyName' = 'Certificate' 'ValueName' = @{ 'Certificate' = 'byte[]' 'Password' = 'string' } } } } process { # lookup path so we know the type of cred we're dealing with $tppObject = Get-VdcObject -Path $Path $thisType = $tppObject.TypeName # ensure the values looking to be updated are appropriate for this object type if ( $Value ) { Write-Warning "-Value will be deprecated in a future release. Use specific parameters for the credential type instead." if ( -not $CredTypes[$thisType] ) { throw "Credential type '$thisType' is not supported yet. Submit an enhancement request." } $friendlyName = $CredTypes[$thisType].FriendlyName $params.Body.FriendlyName = $friendlyName $newValues = $Value.GetEnumerator() | ForEach-Object { $thisValue = $CredTypes[$thisType].ValueName[$_.Key] if ( $thisValue ) { @{ 'Name' = $_.Key 'Type' = $thisValue 'Value' = $_.Value } } else { throw ('''{0}'' is not a valid item for type ''{1}''' -f $_.Key, $thisType) } } $params.Body.Values = @($newValues) } else { switch ($tppObject.TypeName) { 'Password Credential' { $params.Body.FriendlyName = 'Password' } 'Username Password Credential' { $params.Body.FriendlyName = 'UsernamePassword' } 'Certificate Credential' { $params.Body.FriendlyName = 'Certificate' } Default { Write-Error "$Path : credential type '$thisType' is not supported yet. Submit an enhancement request." continue } } if ( $PSCmdlet.ParameterSetName -notlike ('{0}*' -f $params.Body.FriendlyName) ) { Write-Error "$Path : the credential type for this object, $thisType, does not match the parameters provided" continue } } # certificate link path workaround if ( $CertificateLinkPath ) { $certParams = @{ Path = $Path Attribute = @{ 'Certificate' = $CertificateLinkPath } } Set-VdcAttribute @certParams return } if ( $PSCmdlet.ShouldProcess( $Path )) { $params.Body.CredentialPath = $Path $response = Invoke-VenafiRestMethod @params if ( $response.Result -ne 1 ) { Write-Error $response.Error } } } } #EndRegion './Public/Set-VdcCredential.ps1' 347 #Region './Public/Set-VdcPermission.ps1' -1 function Set-VdcPermission { <# .SYNOPSIS Set explicit permissions for TLSPDC objects .DESCRIPTION Adds, modifies, or removes explicit permissions on TLSPDC objects. You can provide a complete permission object or modify individual permissions. .PARAMETER Path Path to an object .PARAMETER Guid Guid representing a unique object .PARAMETER IdentityId The id that represents the user or group. You can use Find-VdcIdentity or Get-VdcPermission to get the id. .PARAMETER Permission TppPermission object to set. You can create a new object and modify it or get an existing object with Get-VdcPermission. .PARAMETER Force When setting a TppPermission object with -Permission and one already exists, use this to overwrite .PARAMETER IsAssociateAllowed Associate or disassociate an Application and Device object with a certificate. Push the certificate and private key to the Application object. Retry the certificate installation. .PARAMETER IsCreateAllowed The caller can create subordinate objects, such as Devices and Applications. Create permission grants implicit View permission. .PARAMETER IsDeleteAllowed The caller can delete objects. .PARAMETER IsManagePermissionsAllowed The caller can grant other user or group Identities permission to the current object or subordinate objects. .PARAMETER IsPolicyWriteAllowed The caller can modify policy values on folders. Also requires View permission. Manage Policy permission grants implicit Read permission and Write permission. .PARAMETER IsPrivateKeyReadAllowed The caller can download the private key for Policy and Certificate objects. .PARAMETER IsPrivateKeyWriteAllowed The caller can upload the private key for Policy, Certificate, and Private Key Credential objects to Trust Protection Platform. .PARAMETER IsReadAllowed The caller can view and read object data from the Policy tree. However, to view subordinate objects, View permission or higher permissions is also required. .PARAMETER IsRenameAllowed The caller can rename and move Policy tree objects. Move capability also requires Rename permission to the object and Create permission to the target folder. .PARAMETER IsRevokeAllowed The caller can invalidate a certificate. Also requires Write permission to the certificate. .PARAMETER IsViewAllowed The caller can confirm that the object is present in the Policy tree. .PARAMETER IsWriteAllowed The caller can edit object attributes. To move objects in the tree, the caller must have Write permission to the objects and Create permission to the target folder. Write permission grants implicit Read permission. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Guid, IdentityId, Permission .OUTPUTS None .EXAMPLE Set-VdcPermission -Guid '1234abcd-g6g6-h7h7-faaf-f50cd6610cba' -IdentityId 'AD+mydomain.com:azsxdcfvgbhnjmlk09877654321' -Permission $TppPermObject Permission a user/group on an object specified by guid .EXAMPLE Set-VdcPermission -Path '\ved\policy\my folder' -IdentityId 'AD+mydomain.com:azsxdcfvgbhnjmlk09877654321' -Permission $TppPermObject Permission a user/group on an object specified by path .EXAMPLE Get-VdcPermission -Path '\ved\policy\my folder' -IdentityId 'AD+mydomain.com:azsxdcfvgbhnjmlk09877654321' -Explicit | Set-VdcPermission -IdentityId $newId Permission a user/group based on permissions of an existing user/group .EXAMPLE Get-VdcPermission -Path '\ved\policy\my folder' -IdentityId 'AD+mydomain.com:azsxdcfvgbhnjmlk09877654321' -Explicit | Set-VdcPermission -IsWriteAllowed Add specific permission(s) for a specific user/group associated with an object .EXAMPLE Get-VdcPermission -Path '\ved\policy\my folder' -Explicit | Set-VdcPermission -IsAssociateAllowed -IsWriteAllowed Add specific permission(s) for all existing user/group associated with an object .EXAMPLE Get-VdcPermission -Path '\ved\policy\my folder' -Explicit | Set-VdcPermission -IsAssociateAllowed:$false Remove specific permission(s) for all existing user/group associated with an object .EXAMPLE $id = Find-VdcIdentity -Name 'brownstein' | Select-Object -ExpandProperty Id Find-VdcObject -Path '\VED' -Recursive | Get-VdcPermission -IdentityId $id | Set-VdcPermission -Permission $TppPermObject -Force Reset permissions for a specific user/group for all objects. Note the use of -Force to overwrite existing permissions. .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Set-VdcPermission/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Set-VdcPermission.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Permissions-object-guid-principal.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-PUT-Permissions-object-guid-principal.php .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-Permissions-Effective.php .NOTES Confirmation impact is set to Medium, set ConfirmPreference accordingly. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'PermissionObjectGuid')] [Alias('Set-TppPermission')] param ( [Parameter(Mandatory, ParameterSetName = 'PermissionObjectPath')] [Parameter(Mandatory, ParameterSetName = 'PermissionPath')] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('DN')] [String] $Path, [Parameter(Mandatory, ParameterSetName = 'PermissionObjectGuid', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'PermissionGuid', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Alias('ObjectGuid')] [guid] $Guid, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateScript( { if ( $_ | Test-VdcIdentityFormat -Format 'Universal' ) { $true } else { throw "'$_' is not a valid Prefixed Universal Id format. See https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-IdentityInformation.php." } })] [Alias('PrefixedUniversalId', 'ID')] [string] $IdentityId, [Parameter(Mandatory, ParameterSetName = 'PermissionObjectPath', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'PermissionObjectGuid', ValueFromPipelineByPropertyName)] [Alias('ExplicitPermissions')] [TppPermission] $Permission, [Parameter(ParameterSetName = 'PermissionPath')] [Parameter(ParameterSetName = 'PermissionGuid')] [switch] $IsAssociateAllowed, [Parameter(ParameterSetName = 'PermissionPath')] [Parameter(ParameterSetName = 'PermissionGuid')] [switch] $IsCreateAllowed, [Parameter(ParameterSetName = 'PermissionPath')] [Parameter(ParameterSetName = 'PermissionGuid')] [switch] $IsDeleteAllowed, [Parameter(ParameterSetName = 'PermissionPath')] [Parameter(ParameterSetName = 'PermissionGuid')] [switch] $IsManagePermissionsAllowed, [Parameter(ParameterSetName = 'PermissionPath')] [Parameter(ParameterSetName = 'PermissionGuid')] [switch] $IsPolicyWriteAllowed, [Parameter(ParameterSetName = 'PermissionPath')] [Parameter(ParameterSetName = 'PermissionGuid')] [switch] $IsPrivateKeyReadAllowed, [Parameter(ParameterSetName = 'PermissionPath')] [Parameter(ParameterSetName = 'PermissionGuid')] [switch] $IsPrivateKeyWriteAllowed, [Parameter(ParameterSetName = 'PermissionPath')] [Parameter(ParameterSetName = 'PermissionGuid')] [switch] $IsReadAllowed, [Parameter(ParameterSetName = 'PermissionPath')] [Parameter(ParameterSetName = 'PermissionGuid')] [switch] $IsRenameAllowed, [Parameter(ParameterSetName = 'PermissionPath')] [Parameter(ParameterSetName = 'PermissionGuid')] [switch] $IsRevokeAllowed, [Parameter(ParameterSetName = 'PermissionPath')] [Parameter(ParameterSetName = 'PermissionGuid')] [switch] $IsViewAllowed, [Parameter(ParameterSetName = 'PermissionPath')] [Parameter(ParameterSetName = 'PermissionGuid')] [switch] $IsWriteAllowed, [Parameter()] [switch] $Force, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { Write-Verbose "Parameterset = $($PSCmdlet.ParameterSetName)" $params = @{ Method = 'Post' UriLeaf = 'placeholder' Body = $null FullResponse = $true } if ( $Path ) { $thisGuid = $Path | ConvertTo-VdcGuid } else { $thisGuid = $Guid } $params.UriLeaf = "Permissions/Object/{$thisGuid}" if ( $IdentityId.StartsWith('local:') ) { # format of local is local:universalId $type, $id = $IdentityId.Split(':') $params.UriLeaf += "/$type/$id" } else { # external source, eg. AD, LDAP # format is type+name:universalId $type, $name, $id = $IdentityId -Split { $_ -in '+', ':' } $params.UriLeaf += "/$type/$name/$id" } if ( $PSCmdlet.ParameterSetName -like 'PermissionObject*' ) { $params.Body = $Permission.ToHashtable() } else { Write-Verbose "Getting existing permissions for $IdentityId" $thisPerm = $thisGuid | Get-VdcPermission -IdentityId $IdentityId -Explicit | Select-Object -ExpandProperty ExplicitPermissions if ( $thisPerm ) { Write-Verbose 'Existing identity found will be updated' $params.Method = 'Put' } else { Write-Verbose 'Existing identity not found. Only the permissions switches set will be true, all others will be false.' $thisPerm = [TppPermission]::new() } foreach ($k in $PSBoundParameters.Keys) { if ($k -in 'IsAssociateAllowed', 'IsCreateAllowed', 'IsDeleteAllowed', 'IsManagePermissionsAllowed', 'IsPolicyWriteAllowed', 'IsPrivateKeyReadAllowed', 'IsPrivateKeyWriteAllowed', 'IsReadAllowed', 'IsRenameAllowed', 'IsRevokeAllowed', 'IsViewAllowed', 'IsWriteAllowed') { $thisPerm.$k = $PSBoundParameters[$k] } } $params.Body = $thisPerm.ToHashtable() } if ( $PSCmdlet.ShouldProcess($Path, "Set permission for $IdentityId") ) { try { $response = Invoke-VenafiRestMethod @params switch ( $response.StatusCode ) { { $_ -in 200, 201 } { # success } 409 { # user/group already has permissions defined on this object # need to use a put method instead if ( $Force ) { Write-Verbose "Existing user/group found and Force option provided, updating existing permissions" $params.Method = 'Put' $response = Invoke-VenafiRestMethod @params if ( $response.StatusCode -ne 200 ) { Write-Error ('Failed to update permission with error {0}' -f $response.Error) } } else { # force option not provided, let the user know what's up Write-Error ('Permission for {0} already exists. To override, provide the -Force option.' -f $IdentityId) } } default { Write-Error ('Failed to create permission with error {0}, {1}' -f [int]$response.StatusCode, $response.Error) } } } catch { Write-Error ("Failed to set permissions on $Path, user/group $IdentityId. $_") } } } } #EndRegion './Public/Set-VdcPermission.ps1' 334 #Region './Public/Set-VdcWorkflowTicketStatus.ps1' -1 function Set-VdcWorkflowTicketStatus { <# .SYNOPSIS Set workflow ticket status .DESCRIPTION Set workflow ticket status for a certificate .PARAMETER TicketGuid Guid representing a unique ticket .PARAMETER Status The new status to assign to the ticket. Possible values include "Pending", "Approved", "Approved After", "Approved Between", and "Rejected". .PARAMETER Explanation Explanation for the status change .PARAMETER ScheduledStart Specifies the time after which the ticket should be processed. ScheduledStart must be specified when the "Approved After" or "Approved Between" statuses are set .PARAMETER ScheduledStop Specifies the time before which the ticket should be processed. ScheduledStop must be specified when the "Approved Between" status is set .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS TicketGuid .OUTPUTS None .EXAMPLE Get-VdcWorkflowTicket -Path '\VED\policy\myapp.company.com' | Set-VdcWorkflowTicketStatus -Status Approved Approve all tickets for a certificate .EXAMPLE Get-VdcWorkflowTicket -Path '\VED\policy\myapp.company.com' | Set-VdcWorkflowTicketStatus -Status 'Approved After' -ScheduledStart (Get-Date).AaaDays(3) -Explanation 'weekend upgrade' Approve all tickets for a certificate after a certain date with an explanation .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Set-VdcWorkflowTicketStatus/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Set-VdcWorkflowTicketStatus.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Workflow-ticket-updatestatus.php #> [CmdletBinding(SupportsShouldProcess)] [Alias('Set-TppWorkflowTicketStatus')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Guid[]] $TicketGuid, [Parameter(Mandatory)] [ValidateSet('Pending', 'Approved', 'Approved After', 'Approved Between', 'Rejected')] [String] $Status, [Parameter()] [String] $Explanation, [Parameter()] [DateTime] $ScheduledStart, [Parameter()] [DateTime] $ScheduledStop, [Parameter()] [psobject] $VenafiSession ) begin { switch ($Status) { 'Approved After' { if ( -not $ScheduledStart ) { throw "A status of 'Approved After' requires a value for ScheduledStart" } if ( $ScheduledStop ) { throw "Do not provide a scheduled stop with a status of 'Approved After'" } } 'Approved Between' { if ( -not $ScheduledStart -or -not $ScheduledStop ) { throw "A status of 'Approved Between' requires a value for ScheduledStart and ScheduledStop" } } Default { } } Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' } process { foreach ($thisGuid in $TicketGuid) { $params = @{ Method = 'Post' UriLeaf = 'Workflow/Ticket/UpdateStatus' Body = @{ 'GUID' = $thisGuid 'Status' = $Status } } if ( $PSBoundParameters.ContainsKey('Explanation') ) { $params.Body.Explanation = $Explanation } if ( $PSBoundParameters.ContainsKey('ScheduledStart') ) { $params.Body.ScheduledStart = ($ScheduledStart | ConvertTo-UtcIso8601) } if ( $PSBoundParameters.ContainsKey('ScheduledStop') ) { $params.Body.ScheduledStop = ($ScheduledStop | ConvertTo-UtcIso8601) } if ( $PSCmdlet.ShouldProcess($params.Body.GUID, 'Set workflow ticket status') ) { $response = Invoke-VenafiRestMethod @params if ( -not ($response.Result -eq [TppWorkflowResult]::Success) ) { throw ("Error setting workflow ticket status, error is {0}" -f [enum]::GetName([TppWorkflowResult], $response.Result)) } } } } } #EndRegion './Public/Set-VdcWorkflowTicketStatus.ps1' 143 #Region './Public/Test-VdcIdentity.ps1' -1 function Test-VdcIdentity { <# .SYNOPSIS Test if an identity exists .DESCRIPTION Provided with a prefixed universal id, find out if an identity exists. .PARAMETER Identity The id that represents the user or group. .PARAMETER ExistOnly Only return boolean instead of ID and Exists list. Helpful when validating just 1 identity. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Identity .OUTPUTS PSCustomObject will be returned with properties 'ID', a System.String, and 'Exists', a System.Boolean. .EXAMPLE 'local:78uhjny657890okjhhh', 'AD+mydomain.com:azsxdcfvgbhnjmlk09877654321' | Test-VdcIdentity Test multiple identities .EXAMPLE Test-VdcIdentity -Identity 'AD+mydomain.com:azsxdcfvgbhnjmlk09877654321' -ExistOnly Retrieve existence for only one identity, returns boolean .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Test-VdcIdentity/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Test-VdcIdentity.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Identity-Validate.php #> [CmdletBinding()] [Alias('Test-TppIdentity')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateScript( { if ( $_ | Test-VdcIdentityFormat ) { $true } else { throw "'$_' is not a valid Prefixed Universal Id format. See https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-IdentityInformation.php." } })] [Alias('PrefixedUniversal', 'Contact', 'IdentityId', 'FullName')] [string[]] $ID, [Parameter()] [Switch] $ExistOnly, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' UriLeaf = 'Identity/Validate' } } process { foreach ( $thisID in $ID ) { $params.Body = @{ 'ID' = @{} } if ( Test-VdcIdentityFormat -ID $thisID -Format 'Universal' ) { $params.Body.ID.PrefixedUniversal = $thisId } else { $params.Body.ID.PrefixedName = $thisId } $response = Invoke-VenafiRestMethod @params if ( $ExistOnly ) { $null -ne $response.Id } else { [PSCustomObject] @{ Identity = $thisId Exists = ($null -ne $response.Id) } } } } } #EndRegion './Public/Test-VdcIdentity.ps1' 108 #Region './Public/Test-VdcObject.ps1' -1 function Test-VdcObject { <# .SYNOPSIS Test if an object exists .DESCRIPTION Provided with either a DN path or GUID, find out if an object exists. .PARAMETER Path DN path to object. Provide either this or Guid. This is the default if both are provided. .PARAMETER Guid Guid which represents a unqiue object. Provide either this or Path. .PARAMETER ExistOnly Only return boolean instead of Object and Exists list. Helpful when validating just 1 object. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS Path or Guid. .OUTPUTS PSCustomObject will be returned with properties 'Object', a System.String, and 'Exists', a System.Boolean. .EXAMPLE $multDNs | Test-VdcObject Object Exists -------- ----- \VED\Policy\My folder1 True \VED\Policy\My folder2 False Test for existence by Path .EXAMPLE Test-VdcObject -Path '\VED\Policy\My folder' -ExistOnly Retrieve existence for only one object .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Test-VdcObject/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Test-VdcObject.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Config-isvalid.php #> [CmdletBinding(DefaultParameterSetName = 'DN')] [Alias('Test-TppObject')] param ( [Parameter(Mandatory, ParameterSetName = 'DN', ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( $_ | Test-TppDnPath ) { $true } else { throw "'$_' is not a valid DN path" } })] [Alias('DN')] [string[]] $Path, [Parameter(Mandatory, ParameterSetName = 'GUID', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Guid[]] $Guid, [Parameter()] [Switch] $ExistOnly, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' $params = @{ Method = 'Post' UriLeaf = 'config/IsValid' Body = @{} } } process { Switch ($PsCmdlet.ParameterSetName) { 'DN' { $paramSetValue = $Path } 'GUID' { $paramSetValue = $Guid } } foreach ( $thisValue in $paramSetValue ) { Switch ($PsCmdlet.ParameterSetName) { 'DN' { $params.Body = @{ 'ObjectDN' = $thisValue } } 'GUID' { $params.Body = @{ 'ObjectGUID' = "{$thisValue}" } } } $response = Invoke-VenafiRestMethod @params if ( $ExistOnly ) { $response.Result -eq 1 } else { [PSCustomObject] @{ Object = $thisValue Exists = ($response.Result -eq 1) } } } } } #EndRegion './Public/Test-VdcObject.ps1' 134 #Region './Public/Test-VdcToken.ps1' -1 function Test-VdcToken { <# .SYNOPSIS Test if a TLSPDC token is valid .DESCRIPTION Use the TLSPDC API call 'Authorize/Verify' to test if the current token is valid. .PARAMETER AuthServer Auth server or url, venafi.company.com or https://venafi.company.com. This will be used to access vedauth for token-based authentication. If just the server name is provided, https:// will be appended. .PARAMETER AccessToken Access token retrieved outside this module. You can either provide a String, SecureString, or PSCredential. If providing a credential, the username is not used. .PARAMETER VaultAccessTokenName Name of the SecretManagement vault entry for the access token; the name of the vault must be VenafiPS. .PARAMETER VenafiPsToken Token object obtained from New-VdcToken .PARAMETER VenafiSession VenafiSession object to validate. The value defaults to the script session object $VenafiSession created by New-VenafiSession. .PARAMETER GrantDetail Provides detailed info about the token object from the TLSPDC server response as an output. Supported on TLSPDC 20.4 and later. .INPUTS AccessToken .OUTPUTS Boolean (default) PSCustomObject (GrantDetail) ClientId AccessIssued GrantIssued Scope Identity RefreshExpires .EXAMPLE Test-VdcToken Verify that accesstoken stored in $VenafiSession object is valid. .EXAMPLE $VenafiPsToken | Test-VdcToken Verify that token object from pipeline is valid. Can be used to validate directly object from New-VdcToken. .EXAMPLE Test-VdcToken -AuthServer venafi.mycompany.com -AccessToken $cred Verify that PsCredential object containing accesstoken is valid. .EXAMPLE Test-VdcToken -VaultAccessTokenName access-token Verify access token stored in VenafiPS vault, metadata stored with secret .EXAMPLE Test-VdcToken -VaultAccessTokenName access-token -AuthServer venafi.mycompany.com Verify access token stored in VenafiPS vault providing server to authenticate against .EXAMPLE Test-VdcToken -GrantDetail Verify that accesstoken stored in $VenafiSession object is valid and return PsCustomObject as output with details. .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Test-VdcToken/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Test-VdcToken.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/AuthSDK/r-SDKa-GET-Authorize-Verify.php #> [CmdletBinding(DefaultParameterSetName = 'Session')] [Alias('Test-TppToken')] [OutputType([System.Boolean])] param ( [Parameter(Mandatory, ParameterSetName = 'AccessToken')] [Parameter(ParameterSetName = 'VaultAccessToken')] [ValidateScript( { $validateMe = if ( $_ -notlike 'https://*') { 'https://{0}' -f $_ } else { $_ } try { $null = [System.Uri]::new($validateMe) $true } catch { throw 'Please enter a valid server, https://venafi.company.com or venafi.company.com' } } )] [Alias('Server')] [string] $AuthServer, [Parameter(Mandatory, ParameterSetName = 'AccessToken', ValueFromPipeline)] [ValidateScript( { if ( $_ -is [string] -or $_ -is [securestring] -or $_ -is [pscredential] ) { $true } else { throw 'Unsupported type. Provide either a String, SecureString, or PSCredential.' } } )] [psobject] $AccessToken, [Parameter(Mandatory, ParameterSetName = 'VenafiPsToken')] [ValidateScript( { if ( -not $_.Server -or -not $_.AccessToken ) { throw 'Not a valid VenafiPsToken' } $true } )] [pscustomobject] $VenafiPsToken, [Parameter(Mandatory, ParameterSetName = 'VaultAccessToken')] [string] $VaultAccessTokenName, [Parameter()] [switch] $GrantDetail, [Parameter(ParameterSetName = 'Session')] [psobject] $VenafiSession = $script:VenafiSession ) begin { $params = @{ Method = 'Get' UriRoot = 'vedauth' UriLeaf = 'Authorize/Verify' } $serverUrl = $AuthServer # add prefix if just server url was provided if ( $serverUrl -notlike 'https://*') { $serverUrl = 'https://{0}' -f $serverUrl } } process { Write-Verbose ('Parameter set: {0}' -f $PSCmdlet.ParameterSetName) switch ($PsCmdlet.ParameterSetName) { 'Session' { if ( -not $VenafiSession ) { throw [System.ArgumentNullException] 'VenafiSession' } if ( $VenafiSession -isnot [pscustomobject] -or -not $VenafiSession.Token ) { throw [System.ArgumentException]::new('Must provide a VenafiSession object', 'VenafiSession') } $params.VenafiSession = $VenafiSession } 'AccessToken' { $params.Server = $serverUrl $accessTokenString = $AccessToken | ConvertTo-PlaintextString $params.Header = @{'Authorization' = 'Bearer {0}' -f $accessTokenString } } 'VaultAccessToken' { # ensure the appropriate setup has been performed if ( -not (Get-Module -Name Microsoft.PowerShell.SecretManagement -ListAvailable)) { throw 'The module Microsoft.PowerShell.SecretManagement is required as well as a vault named ''VenafiPS''. See the github readme for guidance, https://github.com/Venafi/VenafiPS#tokenkey-secret-storage.' } $vault = Get-SecretVault -Name 'VenafiPS' -ErrorAction SilentlyContinue if ( -not $vault ) { throw 'A SecretManagement vault named ''VenafiPS'' could not be found' } $tokenSecret = Get-Secret -Name $VaultAccessTokenName -Vault 'VenafiPS' -ErrorAction SilentlyContinue if ( -not $tokenSecret ) { throw "'$VaultAccessTokenName' secret not found in vault VenafiPS." } # check if metadata was stored $secretInfo = Get-SecretInfo -Name $VaultAccessTokenName -Vault 'VenafiPS' -ErrorAction SilentlyContinue if ( $secretInfo.Metadata.Count -gt 0 ) { $params.Server = $secretInfo.Metadata.AuthServer } else { if ( -not $AuthServer ) { throw '-AuthServer is a required parameter' } $params.Server = $serverUrl } $params.Header = @{'Authorization' = 'Bearer {0}' -f $tokenSecret.GetNetworkCredential().password } } 'VenafiPsToken' { if ( -not $VenafiPsToken.Server -or -not $VenafiPsToken.AccessToken ) { throw 'Not a valid VenafiPsToken' } $params.Server = $VenafiPsToken.Server $params.Header = @{'Authorization' = 'Bearer {0}' -f $VenafiPsToken.AccessToken.GetNetworkCredential().password } } Default { throw ('Unknown parameter set {0}' -f $PSCmdlet.ParameterSetName) } } Write-Verbose ($params | Out-String) $response = Invoke-VenafiRestMethod @params -FullResponse if ( $GrantDetail ) { switch ( $response.StatusCode ) { 200 { $responseData = $response.Content | ConvertFrom-Json [PSCustomObject] @{ ClientId = $responseData.application AccessIssued = ([datetime] '1970-01-01 00:00:00').AddSeconds($responseData.access_issued_on_unix_time) GrantIssued = ([datetime] '1970-01-01 00:00:00').AddSeconds($responseData.grant_issued_on_unix_time) Scope = $responseData.scope Identity = $responseData.identity RefreshExpires = ([datetime] '1970-01-01 00:00:00').AddSeconds($responseData.expires_unix_time) } } Default { throw ('Grant has been revoked, has expired, or the refresh token is invalid') } } } else { switch ( $response.StatusCode ) { 200 { $true } 401 { $false } Default { throw ('Grant has been revoked, has expired, or the refresh token is invalid') } } } } } #EndRegion './Public/Test-VdcToken.ps1' 270 #Region './Public/Write-VdcLog.ps1' -1 function Write-VdcLog { <# .SYNOPSIS Write entries to the TLSPDC log .DESCRIPTION Write entries to the log for custom event groups. It is not permitted to write to the default log. Ensure the group and event id are correct as the api will not fail if incorrect. .PARAMETER CustomEventGroup ID containing hex values between 0100-0299 referring to the created custom group. .PARAMETER EventId Event ID from within the EventGroup provided, a 4 character hex value. Only provide the 4 character event id, do not precede with group ID. .PARAMETER Component Path to the item this event is associated with .PARAMETER Severity Severity of the event .PARAMETER SourceIp The IP that originated the event .PARAMETER ComponentID Component ID that originated the event .PARAMETER ComponentSubsystem Component subsystem that originated the event .PARAMETER Text1 String data to write to log. See link for event ID messages for more info. .PARAMETER Text2 String data to write to log. See link for event ID messages for more info. .PARAMETER Value1 Integer data to write to log. See link for event ID messages for more info. .PARAMETER Value2 Integer data to write to log. See link for event ID messages for more info. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPDC token can also be provided. If providing a TLSPDC token, an environment variable named VDC_SERVER must also be set. .INPUTS none .OUTPUTS none .EXAMPLE Write-VdcLog -CustomEventGroup '0200' -EventId '0001' -Component '\ved\policy\mycert.com' Log an event to a custom group .LINK http://VenafiPS.readthedocs.io/en/latest/functions/Write-VdcLog/ .LINK https://github.com/Venafi/VenafiPS/blob/main/VenafiPS/Public/Write-VdcLog.ps1 .LINK https://docs.venafi.com/Docs/current/TopNav/Content/SDK/WebSDK/r-SDK-POST-Log.php #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'DefaultGroup')] [Alias('Write-TppLog')] param ( [Parameter(Mandatory, ParameterSetName = 'DefaultGroup')] [string] $EventGroup, [Parameter(Mandatory, ParameterSetName = 'CustomGroup')] [ValidateScript({ if ( $_ -match '^0[1-2]\d\d$' ) { $true } else { throw "$_ is an invalid group. Custom event groups must be betwen 0100-0299." } })] [string] $CustomEventGroup, [Parameter(Mandatory)] [ValidateScript({ if ( $_ -match '^[0-9a-fA-F]{4}$' ) { $true } else { throw "$_ is an invalid event ID. Event IDs must be a 4 character hex value." } })] [string] $EventId, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [String] $Component, [Parameter()] [TppEventSeverity] $Severity, [Parameter()] [ipaddress] $SourceIp, [Parameter()] [int] $ComponentID, [Parameter()] [ValidateNotNullOrEmpty()] [string] $ComponentSubsystem, [Parameter()] [ValidateNotNullOrEmpty()] [string] $Text1, [Parameter()] [ValidateNotNullOrEmpty()] [string] $Text2, [Parameter()] [int] $Value1, [Parameter()] [int] $Value2, [Parameter()] [psobject] $VenafiSession ) if ( $PSCmdlet.ParameterSetName -eq 'DefaultGroup' ) { throw 'Writing to built-in event groups is no longer supported by Venafi. You can write to custom event groups. -EventGroup will be deprecated in a future release.' } Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VDC' # the event id is the group id coupled with the event id $fullEventId = "$CustomEventGroup$EventId" # convert the hex based eventid to decimal equivalent $decEventId = [System.Convert]::ToInt64($fullEventId, 16) $params = @{ Method = 'Post' UriLeaf = 'Log/' Body = @{ ID = $decEventId Component = $Component } } if ( $PSBoundParameters.ContainsKey('Severity') ) { $params.Body.Add('Severity', [TppEventSeverity]::$Severity) } if ( $PSBoundParameters.ContainsKey('SourceIp') ) { $params.Body.Add('SourceIp', $SourceIp.ToString()) } if ( $PSBoundParameters.ContainsKey('ComponentID') ) { $params.Body.Add('ComponentID', $ComponentID) } if ( $PSBoundParameters.ContainsKey('ComponentSubsystem') ) { $params.Body.Add('ComponentSubsystem', $ComponentSubsystem) } if ( $PSBoundParameters.ContainsKey('Text1') ) { $params.Body.Add('Text1', $Text1) } if ( $PSBoundParameters.ContainsKey('Text2') ) { $params.Body.Add('Text2', $Text2) } if ( $PSBoundParameters.ContainsKey('Value1') ) { $params.Body.Add('Value1', $Value1) } if ( $PSBoundParameters.ContainsKey('Value2') ) { $params.Body.Add('Value2', $Value2) } if ( $PSCmdlet.ShouldProcess($Component, 'Write log entry') ) { $response = Invoke-VenafiRestMethod @params if ( $response.LogResult -eq 1 ) { throw "Writing to the TLSPDC log failed. Ensure you have View permission and Read permission to the default SQL channel object." } } } #EndRegion './Public/Write-VdcLog.ps1' 198 #Region './VenafiPS.psm1' -1 # Force TLS 1.2 if currently set lower if ([Net.ServicePointManager]::SecurityProtocol.value__ -lt 3072) { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 } # the new version will be replaced below during deployment $script:ModuleVersion = '6.6.0' $script:VcRegions = @{ 'us' = 'https://api.venafi.cloud' 'eu' = 'https://api.venafi.eu' } $Script:VenafiSession = $null $script:ThreadJobAvailable = ($null -ne (Get-Module -Name Microsoft.PowerShell.ThreadJob -ListAvailable)) $script:DevMode = $script:ModuleVersion -match 'NEW_VERSION' $script:ParallelImportPath = $PSCommandPath Export-ModuleMember -Alias * -Variable VenafiSession -Function * # vaas fields to ensure the values are upper case $script:vaasValuesToUpper = 'certificateStatus', 'signatureAlgorithm', 'signatureHashAlgorithm', 'encryptionType', 'versionType', 'certificateSource', 'deploymentStatus' # vaas fields proper case $script:vaasFields = @( 'certificateId', 'applicationIds', 'companyId', 'managedCertificateId', 'fingerprint', 'certificateName', 'issuerCertificateIds', 'certificateStatus', 'statusModificationUserId', 'modificationDate', 'statusModificationDate', 'validityStart', 'validityEnd', 'selfSigned', 'signatureAlgorithm', 'signatureHashAlgorithm', 'encryptionType', 'keyCurve', 'subjectKeyIdentifierHash', 'authorityKeyIdentifierHash', 'serialNumber', 'subjectDN', 'subjectCN', 'subjectO', 'subjectST', 'subjectC', 'subjectAlternativeNamesByType', 'subjectAlternativeNameDns', 'issuerDN', 'issuerCN', 'issuerST', 'issuerL', 'issuerC', 'keyUsage', 'extendedKeyUsage', 'ocspNoCheck', 'versionType', 'activityDate', 'activityType', 'activityName', 'criticality' ) $vcGenericArgCompleterSb = { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $objectType = $parameterName if ( $parameterName -eq 'ID' ) { # figure out object type based on function name since 'ID' is used in many functions } switch ($objectType) { 'Application' { if ( -not $script:vcApplication ) { $script:vcApplication = Get-VcApplication -All | Sort-Object -Property name } $script:vcApplication | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { "'$($_.name)'" } } 'MachineType' { if ( -not $script:vcMachineType ) { $script:vcMachineType = Invoke-VenafiRestMethod -UriLeaf 'machinetypes' | Select-Object -ExpandProperty machineTypes | Select-Object -Property @{'n' = 'machineTypeId'; 'e' = { $_.Id } }, * -ExcludeProperty id | Sort-Object -Property machineType } $script:vcMachineType | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { "'$($_.machineType)'" } } 'IssuingTemplate' { if ( -not $script:vcIssuingTemplate ) { $script:vcIssuingTemplate = Get-VcIssuingTemplate -All | Sort-Object -Property name } $script:vcIssuingTemplate | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { "'$($_.name)'" } } 'VSatellite' { if ( -not $script:vcVSatellite ) { $script:vcVSatellite = Get-VcSatellite -All | Sort-Object -Property name } $script:vcVSatellite | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { "'$($_.name)'" } } 'Certificate' { # there might be a ton of certs so ensure they provide at least 3 characters if ( $wordToComplete.Length -ge 3 ) { Find-VcCertificate -Name $wordToComplete | ForEach-Object { "'$($_.certificateName)'" } } } } } # 'Application', 'MachineType', 'IssuingTemplate', 'VSatellite', 'CertificateID' | ForEach-Object { 'Application', 'MachineType', 'VSatellite', 'Certificate' | ForEach-Object { Register-ArgumentCompleter -CommandName '*-Vc*' -ParameterName $_ -ScriptBlock $vcGenericArgCompleterSb } $vdcPathArgCompleterSb = { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) if ( -not $wordToComplete ) { # if no word provided, default to \ved\policy $wordToComplete = '\VED\Policy\' } # if the path starts with ' or ", that will come along for the ride so ensure we trim that first $fullWord = $wordToComplete.Trim("`"'") | ConvertTo-VdcFullPath $leaf = $fullWord.Split('\')[-1] $parent = $fullWord.Substring(0, $fullWord.LastIndexOf("\$leaf")) # get items in parent folder $objs = Find-VdcObject -Path $parent $objs | Where-Object { $_.name -like "$leaf*" } | ForEach-Object { if ( $_.TypeName -eq 'Policy' ) { "'$($_.Path)\" } else { "'$($_.Path)" } } } Register-ArgumentCompleter -CommandName '*-Vdc*' -ParameterName 'Path' -ScriptBlock $vdcPathArgCompleterSb $script:functionConfig = @{ 'Add-VdcAdaptableHash' = @{ 'TppVersion' = '' 'TppTokenScope' = 'restricted=manage,delete' } 'Add-VdcCertificateAssociation' = @{ 'TppVersion' = '' 'TppTokenScope' = 'certificate=manage' } 'Add-VdcEngineFolder' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'Add-VdcTeamMember' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'Add-VdcTeamOwner' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'Convert-VdcObject' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'ConvertTo-VdcGuid' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } 'ConvertTo-VdcPath' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } 'Export-VdcCertificate' = @{ 'TppVersion' = '' 'TppTokenScope' = 'certificate=manage' } 'Find-VdcClient' = @{ 'TppVersion' = '' 'TppTokenScope' = 'agent=$null' } 'Find-VdcEngine' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=$null' } 'Find-VdcIdentity' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=$null' } 'Find-VdcObject' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=$null' } 'Find-VdcVaultId' = @{ 'TppVersion' = '' 'TppTokenScope' = 'restricted=$null' } 'Find-VcObject' = @{ 'TppVersion' = '' 'TppTokenScope' = '' } 'Find-VdcCertificate' = @{ 'TppVersion' = '' 'TppTokenScope' = 'certificate=$null' } 'Get-VdcAttribute' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=$null' } 'Get-VdcClassAttribute' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } 'Get-VdcCredential' = @{ 'TppVersion' = '' 'TppTokenScope' = 'security=manage' } 'Get-VdcCustomField' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } 'Get-VdcEngineFolder' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'Get-VdcIdentityAttribute' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=$null' } 'Get-VdcObject' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } 'Get-VdcPermission' = @{ 'TppVersion' = '' 'TppTokenScope' = 'security=$null' } 'Get-VdcSystemStatus' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } 'Get-VdcVersion' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } 'Get-VdcWorkflowTicket' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } 'Get-VdcCertificate' = @{ 'TppVersion' = '' 'TppTokenScope' = 'certificate=$null' } 'Get-VdcIdentity' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=$null' } 'Get-VdcTeam' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'Import-VdcCertificate' = @{ 'TppVersion' = '' 'TppTokenScope' = 'certificate=discover' } 'Import-VcCertificate' = @{ 'TppVersion' = '' 'TppTokenScope' = '' } 'Invoke-VdcCertificateAction' = @{ 'TppVersion' = '' 'TppTokenScope' = 'certificate=manage for Reset, Renew, Push, and Validate. certificate=revoke for Revoke. certificate=delete for Delete.' } 'Move-VdcObject' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'New-VdcCapiApplication' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'New-VdcCertificate' = @{ 'TppVersion' = '' 'TppTokenScope' = 'certificate=manage' } 'New-VdcCustomField' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'New-VdcDevice' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'New-VdcObject' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage. If a certificate is provided as an attribute, certificate=manage as well.' } 'New-VdcPolicy' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'New-VdcToken' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } 'New-VcCertificate' = @{ 'TppVersion' = '' 'TppTokenScope' = '' } 'New-VcConnector' = @{ 'TppVersion' = '' 'TppTokenScope' = '' } 'New-VenafiSession' = @{ 'TppVersion' = '' 'TppTokenScope' = '' } 'New-VenafiTeam' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'Read-VenafiLog' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } 'Remove-VdcCertificate' = @{ 'TppVersion' = '' 'TppTokenScope' = 'certificate=delete. If using KeepAssociatedApps, configuration=$null,certificate=manage as well.' } 'Remove-VdcCertificateAssociation' = @{ 'TppVersion' = '' 'TppTokenScope' = 'certificate=manage. If using -All, configuration=$null as well.' } 'Remove-VdcClient' = @{ 'TppVersion' = '' 'TppTokenScope' = 'agent=delete' } 'Remove-VdcEngineFolder' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=delete' } 'Remove-VdcObject' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=delete' } 'Remove-VdcPermission' = @{ 'TppVersion' = '' 'TppTokenScope' = 'security=delete' } 'Remove-VenafiTeam' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=delete' } 'Remove-VenafiTeamMember' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'Remove-VenafiTeamOwner' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'Rename-VdcObject' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'Revoke-VdcCertificate' = @{ 'TppVersion' = '' 'TppTokenScope' = 'certificate=revoke' } 'Revoke-VdcGrant' = @{ 'TppVersion' = '22.3' 'TppTokenScope' = 'admin=delete' } 'Revoke-VdcToken' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } 'Search-VdcHistory' = @{ 'TppVersion' = '' 'TppTokenScope' = 'restricted=$null, certificate=$null' } 'Set-VdcAttribute' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=manage' } 'Set-VdcCredential' = @{ 'TppVersion' = '' 'TppTokenScope' = 'security=manage' } 'Set-VdcPermission' = @{ 'TppVersion' = '' 'TppTokenScope' = 'security=manage' } 'Set-VdcWorkflowTicketStatus' = @{ 'TppVersion' = '' 'TppTokenScope' = 'approve with any scope' } 'Test-VdcIdentity' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=$null' } 'Test-VdcObject' = @{ 'TppVersion' = '' 'TppTokenScope' = 'configuration=$null' } 'Test-VdcToken' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } 'Write-VdcLog' = @{ 'TppVersion' = '' 'TppTokenScope' = 'any scope' } } # ModuleVersion will get updated during the build and this will not run # this is only needed during development since all files will be merged into one psm1 if ( $script:DevMode ) { $folders = @('Enum', 'Classes', 'Public', 'Private') $publicFunction = @() foreach ( $folder in $folders) { $files = Get-ChildItem -Path "$PSScriptRoot\$folder\*.ps1" -Recurse Foreach ( $thisFile in $files ) { Try { Write-Verbose ('dot sourcing {0}' -f $thisFile.FullName) . $thisFile.fullname # if ( $folder -eq 'Public' ) { Export-ModuleMember -Function $thisFile.Basename $publicFunction += $thisFile.BaseName # } } Catch { Write-Error ("Failed to import function {0}: {1}" -f $thisFile.fullname, $folder) } } } } #EndRegion './VenafiPS.psm1' 450 # SIG # Begin signature block # MIIhhAYJKoZIhvcNAQcCoIIhdTCCIXECAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCZs0Rju+vAGgeL # sho/h5Bp5iyvksCUy7Ap14+Mll4WgaCCGoMwggd8MIIFZKADAgECAhAD8JaetbYh # gELYx9Duvn5RMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQK # Ew5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBD # b2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwHhcNMjQwODIxMDAw # MDAwWhcNMjUwOTEyMjM1OTU5WjCBgzELMAkGA1UEBhMCVVMxDTALBgNVBAgTBFV0 # YWgxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MRUwEwYDVQQKEwxWZW5hZmksIElu # Yy4xHjAcBgNVBAsTFVByb2Zlc3Npb25hbCBTZXJ2aWNlczEVMBMGA1UEAxMMVmVu # YWZpLCBJbmMuMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxungR693 # DIQWU/77slVOdl/qc5leazfxKxl7tkKdNFwCDFrDOAn4/5lIKCl/DZc9RYL5F7Kd # sdw9Qgi96JWgw0Z29FWcyxYW4xX7IHHhlNzrt/Qc2u+DDk7IZGrMi+OQcGNYxvvG # HkgZ640nTkX/rPcsctOiYMg57vXUjtYS+u5RfhsJCw3cqCWynTzxKxoQxsTR4NK8 # CW4B/6JYh2V2ni17Bbve074PVKY4Hv+Zmc3F5OHrnfEo51Rv/UcrEdoVvq+Qz5tr # 89TAd8/QenZ+oomRXG0EmL5UdRn+1Csdk8xoBhHBhgTRmtH+dYwyBSFdWrJ5yTqC # r198PCe1s4r4eVhrWQdlmI8IWf1uQABq38e/jtLYNJFauurelEN6Fp1bItXuL/Ne # ncPjOQgmxiufVZ+BYjLYSB4N7vudToDV69B3h8qtVyq0TdAEvyYNcla36li3Ob5K # qrop+duc37BmHWasgcDXx+Vo6+SyfSaZVNgvw64ihxoVZr/BCkS57zvE/NBnn5rL # WoVtFWd7tDaoElwCjVbJFNK6RoWCN11aKJKNvUNycb5bR8e3FiuJFZ8rm/4WJvx0 # GNBD53FxKT3fZcZmClb43+C4+s03a6p05X+EIBNDsAlfS44yFy+7t7u8eyM7vmDV # aVPacOo6yYUPTPxQBENoQeGsecQlWuUQPgcCAwEAAaOCAgMwggH/MB8GA1UdIwQY # MBaAFGg34Ou2O/hfEYb7/mF7CIhl9E5CMB0GA1UdDgQWBBTTo4VJ8oyO4K/8Z6vN # vRU44blkbjA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRw # Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM # MAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaowU6BRoE+GTWh0dHA6Ly9jcmwzLmRp # Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNI # QTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRwOi8vY3JsNC5kaWdpY2VydC5jb20v # RGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0Ex # LmNybDCBlAYIKwYBBQUHAQEEgYcwgYQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3Nw # LmRpZ2ljZXJ0LmNvbTBcBggrBgEFBQcwAoZQaHR0cDovL2NhY2VydHMuZGlnaWNl # cnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0 # MjAyMUNBMS5jcnQwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAgEAk5iA6e3z # vlKHWEzVa8GVTb0XfMnSj6UcB8WbKmjFR0FlI33Vy8LvoCyX4TamxGJxmbR/BT6V # lwPMI4UTQCUS4b3N+yGDUBmqqCLqN0W0OJbun6Y0UscEcWr8RsAY0lp3SFjcUa1c # ixLsSI/9cQTV+6bIJUScvlXEOYIenjiIO/RTX9y+8/lfgVBYS69bjDUzU/WxcZ3R # vGZ5sPVko6al7frjz0uL/F/aCbCw2N0eO/sqI4IfWQZ3CVromQjBEzogj7K2OuB3 # V2Gw3IfSvQobmuTtveOhwp/ma+4V46YYx0mQKrDS0jniMGYstoJeFGMhvr9oac0Q # +wO/PmHBp93m9SfoiUTmKYJMIu9+Jd+8rF6m2/SqRESk1HKD+RgGURt6B38K6dcf # URJXY/r/wgnH0Xb2yMorFOKGkyX2D5hMs1pzgvL3F3B2/SmH2RORDA45UfOCtWQE # 6yYnGjZmabCZl4YFWZsoo9pZXXK3b5narfokdh3AEH2RpIEBtWuZYPgqf8X2a5rt # QrskHMEhY3WHZTZNnncsXSe1cAbPlnDge+byzWYyVc1PtiWE9krTdyJ+TKaTeJTU # NW73unKsU5JMwA77ASchFEfPtLBLjKJh44vFzYuRJGIXoUK2bdPk3JLmvApx6Ty5 # PP8HdjkQzchgpQHVVQe3KAR1ppN42x/9ESEwggWNMIIEdaADAgECAhAOmxiO+dAt # 5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBa # Fw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD # ZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3E # MB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKy # unWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsF # xl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU1 # 5zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJB # MtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObUR # WBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6 # nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxB # YKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5S # UUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+x # q4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIB # NjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwP # TzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMC # AYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp # Y2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0 # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB # LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0Nc # Vec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnov # Lbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65Zy # oUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFW # juyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPF # mCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9z # twGpn1eqXijiuZQwggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqG # SIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy # dXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMx # CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy # RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg # Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXH # JQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMf # UBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w # 1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRk # tFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYb # qMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUm # cJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP6 # 5x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzK # QtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo # 80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjB # Jgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXche # MBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB # /wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU # 7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoG # CCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29j # c3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDig # NqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v # dEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZI # hvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd # 4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiC # qBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl # /Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeC # RK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYT # gAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/ # a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37 # xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmL # NriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0 # YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJ # RyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIG # vDCCBKSgAwIBAgIQC65mvFq6f5WHxvnpBOMzBDANBgkqhkiG9w0BAQsFADBjMQsw # CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRp # Z2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENB # MB4XDTI0MDkyNjAwMDAwMFoXDTM1MTEyNTIzNTk1OVowQjELMAkGA1UEBhMCVVMx # ETAPBgNVBAoTCERpZ2lDZXJ0MSAwHgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAg # MjAyNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL5qc5/2lSGrljC6 # W23mWaO16P2RHxjEiDtqmeOlwf0KMCBDEr4IxHRGd7+L660x5XltSVhhK64zi9Ce # C9B6lUdXM0s71EOcRe8+CEJp+3R2O8oo76EO7o5tLuslxdr9Qq82aKcpA9O//X6Q # E+AcaU/byaCagLD/GLoUb35SfWHh43rOH3bpLEx7pZ7avVnpUVmPvkxT8c2a2yC0 # WMp8hMu60tZR0ChaV76Nhnj37DEYTX9ReNZ8hIOYe4jl7/r419CvEYVIrH6sN00y # x49boUuumF9i2T8UuKGn9966fR5X6kgXj3o5WHhHVO+NBikDO0mlUh902wS/Eeh8 # F/UFaRp1z5SnROHwSJ+QQRZ1fisD8UTVDSupWJNstVkiqLq+ISTdEjJKGjVfIcsg # A4l9cbk8Smlzddh4EfvFrpVNnes4c16Jidj5XiPVdsn5n10jxmGpxoMc6iPkoaDh # i6JjHd5ibfdp5uzIXp4P0wXkgNs+CO/CacBqU0R4k+8h6gYldp4FCMgrXdKWfM4N # 0u25OEAuEa3JyidxW48jwBqIJqImd93NRxvd1aepSeNeREXAu2xUDEW8aqzFQDYm # r9ZONuc2MhTMizchNULpUEoA6Vva7b1XCB+1rxvbKmLqfY/M/SdV6mwWTyeVy5Z/ # JkvMFpnQy5wR14GJcv6dQ4aEKOX5AgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMC # B4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAE # GTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3Mp # dpovdYxqII+eyG8wHQYDVR0OBBYEFJ9XLAN3DigVkGalY17uT5IfdqBbMFoGA1Ud # HwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRy # dXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUF # BwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20w # WAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2Vy # dFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZI # hvcNAQELBQADggIBAD2tHh92mVvjOIQSR9lDkfYR25tOCB3RKE/P09x7gUsmXqt4 # 0ouRl3lj+8QioVYq3igpwrPvBmZdrlWBb0HvqT00nFSXgmUrDKNSQqGTdpjHsPy+ # LaalTW0qVjvUBhcHzBMutB6HzeledbDCzFzUy34VarPnvIWrqVogK0qM8gJhh/+q # DEAIdO/KkYesLyTVOoJ4eTq7gj9UFAL1UruJKlTnCVaM2UeUUW/8z3fvjxhN6hdT # 98Vr2FYlCS7Mbb4Hv5swO+aAXxWUm3WpByXtgVQxiBlTVYzqfLDbe9PpBKDBfk+r # abTFDZXoUke7zPgtd7/fvWTlCs30VAGEsshJmLbJ6ZbQ/xll/HjO9JbNVekBv2Tg # em+mLptR7yIrpaidRJXrI+UzB6vAlk/8a1u7cIqV0yef4uaZFORNekUgQHTqddms # PCEIYQP7xGxZBIhdmm4bhYsVA6G2WgNFYagLDBzpmk9104WQzYuVNsxyoVLObhx3 # RugaEGru+SojW4dHPoWrUhftNpFC5H7QEY7MhKRyrBe7ucykW7eaCuWBsBb4HOKR # FVDcrZgdwaSIqMDiCLg4D+TPVgKx2EgEdeoHNHT9l3ZDBD+XgbF+23/zBjeCtxz+ # dL/9NWR6P2eZRi7zcEO1xwcdcqJsyz/JceENc2Sg8h3KeFUCS7tpFk7CrDqkMYIG # VzCCBlMCAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu # Yy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJT # QTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAD8JaetbYhgELYx9Duvn5RMA0GCWCGSAFl # AwQCAQUAoIGIMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCSqGSIb3DQEJ # BTEPFw0yNDExMjMwMTI5MzFaMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEV # MC8GCSqGSIb3DQEJBDEiBCDh6sv93FS+9YOfFC8mxTWpOPd2Nck07VbE3YCBE4JY # cTANBgkqhkiG9w0BAQEFAASCAgCOoPFS2Dt/Rj6XiGekrel4OEPlvbegVmN0D71k # NCqs0QdA5ep70m8QA5d0GH4K7ZEhbipRasiXK839tSPK553xJGRfIgwEdtTF/004 # TNVnmO3iba/CztR+IAoV0ZaCKJXWYRsw0gWfp/zRIYUSZx7bxu4rkLzbISxnFpk1 # bbtOBg97FUr/WcbFd99GmQR9AjeFwgZ2r6zAADEr1KujZ6cc6nkvvXi0aDl3KN2X # AHFYBq8tZkbKQIsuzg31dPpgQhr/JOV+97My5n1Quo8nXt949H0tr6SF11xMwuPm # v6A9iCpvo+l1dytQHicnfanvWqmO+j4mKlT+XcN+qjDb0FOfpYnkKj535RdbS3NT # 0LhmuYGzCF+hBFNfMc1mKmyCbalE8L3NsKd4Oa9c56gMaj+yzhEWqNDxzAV4c6xN # b0hkDSVowLIJpyGpXsIyZdm2D8N2YG07dsJDrMcirqYJaA3j9/4eqOXfG2I6SoyM # BZgwSETE0lVomnmcRQCeG7iI37hpNL421auJvQ3W651owtrP5wf3+B2ZajjI+00m # pd+6EzsJmbcZEB5S8xGcIXoup2eCpuS3ytgvnV82hjd9+XBktlSLiByn0VXemqiA # ab3mO2Xb38smGIb+A+vDVqMjxNvEwxk9TGZR+EeKazISC0MCAfRCzOEP0Mbq7ZbY # MewlEaGCAyAwggMcBgkqhkiG9w0BCQYxggMNMIIDCQIBATB3MGMxCzAJBgNVBAYT # AlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQg # VHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAuuZrxa # un+Vh8b56QTjMwQwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZI # hvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yNDExMjMwMTI5MzJaMC8GCSqGSIb3DQEJ # BDEiBCCiFgfstZdpCjO5kxN984HRUK4RukwDRfjIjayzAEahPjANBgkqhkiG9w0B # AQEFAASCAgAFiU1I17ro3xJCohBjrADywGKWNuofSYjf8RFd4t7TP0aCx3lo98ea # Tvi90BvGDGGdlgWHxjGy7O2Z+pFVbVMMBQy9A6EaoiwNnLvuAdDKk9icy4cYM/Z4 # +C8gIQWBkC0nKhpk7da9oLRtnli1S+FV73E3keOBaoMZJjMtRC3CGRG7JXXW4Z3n # qAHdg/owxNrny/HcqAzyE4ayob+e2Ho6G/oEKJ2rSsIMo7aB9v7m9tA3wTH2VSrX # Tz36kCSZgn84dcVaOdtqyLcL6DjPx0nT+pp6T/G1/BgQ1ukWrfjcv7pdQkifOEsH # QEqurTdsJW1LpjgRKZSTOI41WtCZI8fk29q3F+ZGcAn78glMU0j/jtQrzMkzRhxv # ayqcu/ZPzuSVfGr1kO0ua40GX1qJ5MzIFNApWjzxaG4lvAX4TZUXemF5cG9bWTyC # XYqzwtr/fXHg0jOCqg73Scw3gnCxbbP71h/0/yZ75wc9AE2K9xTqHS+VRogJd04E # ikzdbJWzdkGno7u0VcbgLY+QR60r9ntc3CJ2gyuDcNrWw8keDD255QXL+F+5PukI # Ry6oPtwOGoD61vSp8Qh5VIrbah0f6Lh0QveiFK0fnvT8vqWpWGs71yZc6OKZBZOf # Su2iXPIcqK3VoXmJ+Vg+KomVKUpKrtcYZmcKzbCHg7jbtOTnl/vf5A== # SIG # End signature block |