From 6ca69de2da9a20c07a91a5a16b0449a3f10347ad Mon Sep 17 00:00:00 2001 From: Shawn Melton <11204251+wsmelton@users.noreply.github.com> Date: Tue, 10 Aug 2021 16:54:13 -0500 Subject: [PATCH] Search-TssSystemLog - new command --- .vscode/tss.code-snippets | 19 ++-- .../diagnostics/Search-TssSystemLog.md | 105 ++++++++++++++++++ docs/getting_started/compatibility.md | 6 + src/Thycotic.SecretServer.Format.ps1xml | 37 ++++++ src/Thycotic.SecretServer.psd1 | 13 ++- .../classes/diagnostics/SystemLog.cs | 17 +++ src/Thycotic.SecretServer/enums/LogLevel.cs | 19 ++++ .../diagnostics/Search-TssSystemLog.ps1 | 94 ++++++++++++++++ .../diagnostics/Search-TssSystemLog.Tests.ps1 | 24 ++++ 9 files changed, 318 insertions(+), 16 deletions(-) create mode 100644 docs/commands/diagnostics/Search-TssSystemLog.md create mode 100644 src/Thycotic.SecretServer/classes/diagnostics/SystemLog.cs create mode 100644 src/Thycotic.SecretServer/enums/LogLevel.cs create mode 100644 src/functions/diagnostics/Search-TssSystemLog.ps1 create mode 100644 tests/diagnostics/Search-TssSystemLog.Tests.ps1 diff --git a/.vscode/tss.code-snippets b/.vscode/tss.code-snippets index 8b9818fb..58565093 100644 --- a/.vscode/tss.code-snippets +++ b/.vscode/tss.code-snippets @@ -98,13 +98,13 @@ " ${2:Short of what command does}", "", " .DESCRIPTION", - " ${3:Longer of what command does}", + " ${2}", "", " .LINK", - " https://thycotic-ps.github.io/thycotic.secretserver/commands/${7}/Search-Tss${1}", + " https://thycotic-ps.github.io/thycotic.secretserver/commands/${3:tag name}/Search-Tss${1}", "", " .LINK", - " https://github.com/thycotic-ps/thycotic.secretserver/blob/main/src/functions/${7:Folder name}/Search-Tss${1}.ps1", + " https://github.com/thycotic-ps/thycotic.secretserver/blob/main/src/functions/${3}/Search-Tss${1}.ps1", "", " .EXAMPLE", " \\$session = New-TssSession -SecretServer https://alpha -Credential \\$ssCred", @@ -116,7 +116,7 @@ " Requires TssSession object returned by New-TssSession", " #>", " [CmdletBinding()]", - " [OutputType('Tss${7}')]", + " [OutputType('${7:Class name}')]", " param (", " # TssSession object created by New-TssSession for authentication", " [Parameter(Mandatory,ValueFromPipeline,Position = 0)]", @@ -124,8 +124,8 @@ " \\$TssSession,", "", " # Short description for parameter", - " [Alias(\"${1}Id\")]", - " [int]", + " [Alias(\"${8:alias if desired}\")]", + " [${9:Class/Type}]", " \\$${4},", "", " # Sort by specific property, default ${1}Name", @@ -140,14 +140,13 @@ " Write-Verbose \"Provided command parameters: \\$(. \\$GetInvocation \\$PSCmdlet.MyInvocation)\"", " if (\\$tssParams.ContainsKey('TssSession') -and \\$TssSession.IsValidSession()) {", " . \\$CheckVersion \\$TssSession '10.9.000000' \\$PSCmdlet.MyInvocation", - " \\$restResponse = \\$null", - " \\$uri = \\$TssSession.ApiUrl, '${1}s' -join '/'", + " \\$uri = \\$TssSession.ApiUrl, '${10:endpoint}' -join '/'", " \\$uri = \\$uri, \"sortBy[0].direction=asc&sortBy[0].name=\\$SortBy&take=\\$(\\$TssSession.Take)\" -join '?'", " \\$invokeParams.Method = 'GET'", "", " \\$filters = @()", " switch (\\$tssParams.Keys) {", - " '${4} { \\$filters += \"filter.${4}=\\$${4}\" }", + " '${4}' { \\$filters += \"filter.${4}=\\$${4}\" }", " }", " if (\\$filters) {", " \\$uriFilter = \\$filters -join '&'", @@ -170,7 +169,7 @@ " Write-Warning \"No ${1} found\"", " }", " if (\\$restResponse.records) {", - " [Tss${7}[]]\\$restResponse.records", + " [${9}[]]\\$restResponse.records", " }", " } else {", " Write-Warning \"No valid session found\"", diff --git a/docs/commands/diagnostics/Search-TssSystemLog.md b/docs/commands/diagnostics/Search-TssSystemLog.md new file mode 100644 index 00000000..45125680 --- /dev/null +++ b/docs/commands/diagnostics/Search-TssSystemLog.md @@ -0,0 +1,105 @@ +# Search-TssSystemLog + +## SYNOPSIS +Search the Secret Server System Log + +## SYNTAX + +``` +Search-TssSystemLog [-TssSession] [-SearchText ] [-LogLevel ] [-SortBy ] + [] +``` + +## DESCRIPTION +Search the Secret Server System Log + +## EXAMPLES + +### EXAMPLE 1 +``` +$session = New-TssSession -SecretServer https://alpha -Credential $ssCred +Search-TssSystemLog -TssSession $session -SearchText "powershell" +``` + +Return Log messages matching the text "powershell" + +## PARAMETERS + +### -TssSession +TssSession object created by New-TssSession for authentication + +```yaml +Type: Session +Parameter Sets: (All) +Aliases: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -SearchText +Text to search for in System Log + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -LogLevel +Log Level to filter on + +```yaml +Type: LogLevel +Parameter Sets: (All) +Aliases: +Accepted values: Emergency, Alert, Critical, Error, Warning, Notice, Information, Debug + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -SortBy +Sort by specific property, default SystemLogName + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: SystemLogName +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +## OUTPUTS + +### Thycotic.PowerShell.Diagnostics.SystemLog +## NOTES +Requires TssSession object returned by New-TssSession + +## RELATED LINKS + +[https://thycotic-ps.github.io/thycotic.secretserver/commands/diagnostics/Search-TssSystemLog](https://thycotic-ps.github.io/thycotic.secretserver/commands/diagnostics/Search-TssSystemLog) + +[https://github.com/thycotic-ps/thycotic.secretserver/blob/main/src/functions/diagnostics/Search-TssSystemLog.ps1](https://github.com/thycotic-ps/thycotic.secretserver/blob/main/src/functions/diagnostics/Search-TssSystemLog.ps1) + diff --git a/docs/getting_started/compatibility.md b/docs/getting_started/compatibility.md index ae833a1e..45a7bb96 100644 --- a/docs/getting_started/compatibility.md +++ b/docs/getting_started/compatibility.md @@ -24,6 +24,9 @@ Secret Server REST API was first released with version 9.0. The API has grown si | [Search-TssMetadata] | 10.9.000064 | | [Get-TssFolder] (-FolderPath param) | 11.0.000000 | | [Get-TssSecret] (-Path param) | 11.0.000000 | +| [Get-TssSecretPolicy] | 11.0.000000 | +| [Set-TssSecretPolicy] | 11.0.000000 | +| [Search-TssSystemLog] | 11.0.000000 | [Get-TssSecretAudit]:/thycotic.secretserver/commands/secrets/Get-TssSecretAudit [Get-TssUserRoleAssigned]:/thycotic.secretserver/commands/users/Get-TssUserRoleAssigned @@ -33,3 +36,6 @@ Secret Server REST API was first released with version 9.0. The API has grown si [Search-TssMetadata]:/thycotic.secretserver/commands/metadata/Search-TssMetadata [Get-TssFolder]:/thycotic.secretserver/commands/folders/Get-TssFolder [Get-TssSecret]:/thycotic.secretserver/commands/secrets/Get-TssSecret +[Get-TssSecretPolicy]:/thycotic.secretserver/commands/secret-policies/Get-TssSecretPolicy +[Set-TssSecretPolicy]:/thycotic.secretserver/commands/secret-policies/Set-TssSecretPolicy +[Search-TssSystemLog]:/thycotic.secretserver/commands/diagnostics/Search-TssSystemLog \ No newline at end of file diff --git a/src/Thycotic.SecretServer.Format.ps1xml b/src/Thycotic.SecretServer.Format.ps1xml index e3408c16..f907b4a2 100644 --- a/src/Thycotic.SecretServer.Format.ps1xml +++ b/src/Thycotic.SecretServer.Format.ps1xml @@ -2544,5 +2544,42 @@ + + + + Diagnostics.SystemLog + + Thycotic.PowerShell.Diagnostics.SystemLog + + + + + Left + + + Center + + + Left + + + + + + + DateRecorded + + + LogLevel + + + LogMessage + + + + + + + diff --git a/src/Thycotic.SecretServer.psd1 b/src/Thycotic.SecretServer.psd1 index 6a45c302..5fa42c1d 100644 --- a/src/Thycotic.SecretServer.psd1 +++ b/src/Thycotic.SecretServer.psd1 @@ -3,7 +3,7 @@ # # Generated by: Shawn Melton # -# Generated on: 8/9/2021 +# Generated on: 8/10/2021 # @{ @@ -122,11 +122,12 @@ FunctionsToExport = 'Add-TssEventPipeline', 'Add-TssFolderPermission', 'Search-TssSecretAccessRequest', 'Search-TssSecretDependency', 'Search-TssSecretHook', 'Search-TssSecretPermission', 'Search-TssSecretPolicy', 'Search-TssSecretTemplate', - 'Search-TssUser', 'Search-TssWorkflowTemplate', 'Set-TssFolder', - 'Set-TssSecret', 'Set-TssSecretExpiration', 'Set-TssSecretField', - 'Set-TssSecretPolicy', 'Set-TssSecretRpcAssociated', - 'Set-TssSecretRpcPrivileged', 'Set-TssSecretSecurity', - 'Set-TssSecretTemplate', 'Show-TssCurrentUser', 'Start-TssDiscovery', + 'Search-TssSystemLog', 'Search-TssUser', 'Search-TssWorkflowTemplate', + 'Set-TssFolder', 'Set-TssSecret', 'Set-TssSecretExpiration', + 'Set-TssSecretField', 'Set-TssSecretPolicy', + 'Set-TssSecretRpcAssociated', 'Set-TssSecretRpcPrivileged', + 'Set-TssSecretSecurity', 'Set-TssSecretTemplate', + 'Show-TssCurrentUser', 'Start-TssDiscovery', 'Start-TssSecretChangePassword', 'Start-TssSecretDependency', 'Start-TssSecretHeartbeat', 'Stop-TssSecretChangePassword', 'Test-TssFolderAction', 'Test-TssSdkClient', 'Test-TssSecretAction', diff --git a/src/Thycotic.SecretServer/classes/diagnostics/SystemLog.cs b/src/Thycotic.SecretServer/classes/diagnostics/SystemLog.cs new file mode 100644 index 00000000..1620ad8c --- /dev/null +++ b/src/Thycotic.SecretServer/classes/diagnostics/SystemLog.cs @@ -0,0 +1,17 @@ +using System; +using System.Threading.Tasks; +using System.Management.Automation; +using System.Management.Automation.Runspaces; +using Thycotic.PowerShell.Enums; + +namespace Thycotic.PowerShell.Diagnostics +{ + public class SystemLog + { + public string CorrelationId { get; set; } + public DateTime? DateRecorded { get; set; } + public LogLevel LogLevel { get; set; } + public string LogMessage { get; set; } + public string MachineName { get; set; } + } +} \ No newline at end of file diff --git a/src/Thycotic.SecretServer/enums/LogLevel.cs b/src/Thycotic.SecretServer/enums/LogLevel.cs new file mode 100644 index 00000000..dfd6ad79 --- /dev/null +++ b/src/Thycotic.SecretServer/enums/LogLevel.cs @@ -0,0 +1,19 @@ +using System; +using System.Threading.Tasks; +using System.Management.Automation; +using System.Management.Automation.Runspaces; + +namespace Thycotic.PowerShell.Enums +{ + public enum LogLevel + { + Emergency, + Alert, + Critical, + Error, + Warning, + Notice, + Information, + Debug + } +} \ No newline at end of file diff --git a/src/functions/diagnostics/Search-TssSystemLog.ps1 b/src/functions/diagnostics/Search-TssSystemLog.ps1 new file mode 100644 index 00000000..d5657b43 --- /dev/null +++ b/src/functions/diagnostics/Search-TssSystemLog.ps1 @@ -0,0 +1,94 @@ +function Search-TssSystemLog { + <# + .SYNOPSIS + Search the Secret Server System Log + + .DESCRIPTION + Search the Secret Server System Log + + .LINK + https://thycotic-ps.github.io/thycotic.secretserver/commands/diagnostics/Search-TssSystemLog + + .LINK + https://github.com/thycotic-ps/thycotic.secretserver/blob/main/src/functions/diagnostics/Search-TssSystemLog.ps1 + + .EXAMPLE + $session = New-TssSession -SecretServer https://alpha -Credential $ssCred + Search-TssSystemLog -TssSession $session -SearchText "powershell" + + Return Log messages matching the text "powershell" + + .EXAMPLE + $session = New-TssSession -SecretServer https://alpha -Credential $ssCred + Search-TssSystemLog -TssSession $session -SearchText "Azure AD" + + Return Log messages matching the text "Azure AD" + + .NOTES + Requires TssSession object returned by New-TssSession + #> + [CmdletBinding()] + [OutputType('Thycotic.PowerShell.Diagnostics.SystemLog')] + param ( + # TssSession object created by New-TssSession for authentication + [Parameter(Mandatory,ValueFromPipeline,Position = 0)] + [Thycotic.PowerShell.Authentication.Session] + $TssSession, + + # Text to search for in System Log + [string] + $SearchText, + + # Log Level to filter on + [Thycotic.PowerShell.Enums.LogLevel] + $LogLevel, + + # Sort by specific property, default DateRecorded + [string] + $SortBy = 'DateRecorded' + ) + begin { + $tssParams = $PSBoundParameters + $invokeParams = . $GetInvokeApiParams $TssSession + } + process { + Write-Verbose "Provided command parameters: $(. $GetInvocation $PSCmdlet.MyInvocation)" + if ($tssParams.ContainsKey('TssSession') -and $TssSession.IsValidSession()) { + . $CheckVersion $TssSession '11.0.000000' $PSCmdlet.MyInvocation + $uri = ($TssSession.ApiUrl -replace 'v1','v2'), 'diagnostics', 'system-logs' -join '/' + $uri = $uri, "sortBy[0].direction=desc&sortBy[0].name=$SortBy&take=$($TssSession.Take)" -join '?' + $invokeParams.Method = 'GET' + + $filters = @() + switch ($tssParams.Keys) { + 'SearchText' { $filters += "filter.searchTerm=$SearchText" } + 'LogLevel' { $filters += "filter.logLevel=$LogLevel"} + } + if ($filters) { + $uriFilter = $filters -join '&' + Write-Verbose "Filters: $uriFilter" + $uri = $uri, $uriFilter -join '&' + } + $invokeParams.Uri = $uri + + Write-Verbose "Performing the operation $($invokeParams.Method) $uri" + try { + $apiResponse = Invoke-TssApi @invokeParams + $restResponse = . $ProcessResponse $apiResponse + } catch { + Write-Warning "Issue on search request" + $err = $_ + . $ErrorHandling $err + } + + if ($restResponse.records.Count -le 0 -and $restResponse.records.Length -eq 0) { + Write-Warning "No messages found in the System Log" + } + if ($restResponse.records) { + [Thycotic.PowerShell.Diagnostics.SystemLog[]]$restResponse.records + } + } else { + Write-Warning "No valid session found" + } + } +} \ No newline at end of file diff --git a/tests/diagnostics/Search-TssSystemLog.Tests.ps1 b/tests/diagnostics/Search-TssSystemLog.Tests.ps1 new file mode 100644 index 00000000..44e5766c --- /dev/null +++ b/tests/diagnostics/Search-TssSystemLog.Tests.ps1 @@ -0,0 +1,24 @@ +BeforeDiscovery { + $commandName = Split-Path ($PSCommandPath.Replace('.Tests.ps1','')) -Leaf +} +Describe "$commandName verify parameters" { + BeforeDiscovery { + [object[]]$knownParameters = 'TssSession', 'SearchText', 'LogLevel', 'SortBy' + [object[]]$currentParams = ([Management.Automation.CommandMetaData]$ExecutionContext.SessionState.InvokeCommand.GetCommand($commandName,'Function')).Parameters.Keys + [object[]]$commandDetails = [System.Management.Automation.CommandInfo]$ExecutionContext.SessionState.InvokeCommand.GetCommand($commandName,'Function') + $unknownParameters = Compare-Object -ReferenceObject $knownParameters -DifferenceObject $currentParams -PassThru + } + Context "Verify parameters" -Foreach @{currentParams = $currentParams } { + It "$commandName should contain <_> parameter" -TestCases $knownParameters { + $_ -in $currentParams | Should -Be $true + } + It "$commandName should not contain parameter: <_>" -TestCases $unknownParameters { + $_ | Should -BeNullOrEmpty + } + } + Context "Command specific details" { + It "$commandName should set OutputType to Thycotic.PowerShell.Diagnostics.SystemLog" -TestCases $commandDetails { + $_.OutputType.Name | Should -Be 'Thycotic.PowerShell.Diagnostics.SystemLog' + } + } +} \ No newline at end of file