Public/Connect-LMAccount.ps1
<# .SYNOPSIS Connect to a specified LM portal to run commands against .DESCRIPTION Connect to a specified LM portal which will allow you run the other LM commands associated with the Logic.Monitor PS module. Used in conjunction with Disconnect-LMAccount to close a session previously connected via Connect-LMAccount .PARAMETER AccessId Access ID from your API credential acquired from the LM Portal .PARAMETER AccessKey Access Key from your API credential acquired from the LM Portal .PARAMETER AccountName The subdomain for your LM portal, the name before ".logicmonitor.com" (subdomain.logicmonitor.com) .PARAMETER UseCachedCredential This will list all cached account for you to pick from. This parameter is optional .PARAMETER CachedAccountName Name of cached account you wish to connect to. This parameter is optional and can be used in place of UseCachedCredential .PARAMETER DisableConsoleLogging Disables on stdout messages from displaying for any subsequent commands are run. Useful when building scripted logicmodules and you want to suppress unwanted output. Console logging is enabled by default. .EXAMPLE Connect-LMAccount -AccessId xxxxxx -AccessKey xxxxxx -AccountName subdomain .EXAMPLE Connect-LMAccount -UseCachedCredential .NOTES You must run this command before you will be able to execute other commands included with the Logic.Monitor module. .INPUTS None. You cannot pipe objects to this command. .LINK Module repo: https://github.com/stevevillardi/Logic.Monitor .LINK PSGallery: https://www.powershellgallery.com/packages/Logic.Monitor #> Function Connect-LMAccount { [CmdletBinding()] Param ( [Parameter(Mandatory, ParameterSetName = 'Manual')] [String]$AccessId, [Parameter(Mandatory, ParameterSetName = 'Manual')] [String]$AccessKey, [Parameter(Mandatory, ParameterSetName = 'Manual')] [String]$AccountName, [Parameter(ParameterSetName = 'Cached')] [Switch]$UseCachedCredential, [Parameter(ParameterSetName = 'Cached')] [String]$CachedAccountName, [Switch]$DisableConsoleLogging ) If ($UseCachedCredential -or $CachedAccountName) { Try { $ExistingVault = Get-SecretInfo -Name Logic.Monitor -WarningAction Stop Write-Host "Existing vault Logic.Monitor already exists, skipping creation" -ForegroundColor Yellow } Catch { If($_.Exception.Message -like "*There are currently no extension vaults registered*") { Write-Host "Credential vault for cached accounts does not currently exist, creating credential vault: Logic.Monitor" -ForegroundColor Yellow Register-SecretVault -Name Logic.Monitor -ModuleName Microsoft.PowerShell.SecretStore Get-SecretStoreConfiguration | Out-Null } } $CredentialPath = Join-Path -Path $Home -ChildPath "Logic.Monitor.json" If ((Test-Path -Path $CredentialPath)) { Write-Host "Previous version of cached accounts detected, migrating to secret store..." -ForegroundColor Yellow $CredentialFile = Get-Content -Path $CredentialPath | ConvertFrom-Json | Sort-Object -Property Modified -Descending $MigrationComplete = $true Foreach ($Credential in $CredentialFile) { $CurrentDate = Get-Date [Hashtable]$Metadata = @{ Portal = [String]$Credential.Portal Id = [String]$Credential.Id Modified = [DateTime]$CurrentDate } Try{ Set-Secret -Name $Credential.Portal -Secret $Credential.Key -Vault Logic.Monitor -Metadata $Metadata -NoClobber Write-Host "Successfully migrated cached account secret for portal: $($Credential.Portal)" -ForegroundColor Yellow } Catch{ Write-Error $_.Exception.Message $MigrationComplete = $false } } If($MigrationComplete){ Remove-Item -Path $CredentialPath -Confirm:$false Write-Host "Successfully migrated cached accounts into secret store, your legacy account cache hes been removed." -ForegroundColor Yellow } Else{ $NewName = Join-Path -Path $Home -ChildPath "Logic.Monitor-Migrated.json" Rename-Item -Path $CredentialPath -Confirm:$false -NewName $NewName Write-Host "Unable to fully migrate cached accounts into secret store, your legacy account cache has been archived at: $NewName. No other attemps will be made to migrate any failed accounts." -ForegroundColor Red } } If($CachedAccountName){ #If supplied and account name just use that vs showing a list of accounts $CachedAccountSecrets = Get-SecretInfo -Vault Logic.Monitor $CachedAccountIndex = $CachedAccountSecrets.Name.IndexOf($CachedAccountName) If($CachedAccountIndex -ne -1){ $AccountName = $CachedAccountSecrets[$CachedAccountIndex].Metadata["Portal"] [SecureString]$AccessKey = Get-Secret -Vault "Logic.Monitor" -Name $CachedAccountName -AsPlainText | ConvertTo-SecureString $AccessId = $CachedAccountSecrets[$CachedAccountIndex].Metadata["Id"] } Else{ Write-Error "Entered CachedAccountName ($CachedAccountName) does not match one of the stored credentials, please check the selected entry and try again" Return } } Else{ #List out current portals with saved credentials and let users chose which to use $i = 0 $CachedAccountSecrets = Get-SecretInfo -Vault Logic.Monitor If($CachedAccountSecrets){ Write-Host "Selection Number | Portal Name" Foreach ($Credential in $CachedAccountSecrets) { Write-Host "$i) $($Credential.Name)" $i++ } $StoredCredentialIndex = Read-Host -Prompt "Enter the number for the cached credential you wish to use" If ($CachedAccountSecrets[$StoredCredentialIndex]) { $AccountName = $CachedAccountSecrets[$StoredCredentialIndex].Metadata["Portal"] [SecureString]$AccessKey = Get-Secret -Vault "Logic.Monitor" -Name $AccountName -AsPlainText | ConvertTo-SecureString $AccessId = $CachedAccountSecrets[$StoredCredentialIndex].Metadata["Id"] } Else { Write-Error "Entered value does not match one of the listed credentials, please check the selected entry and try again" Return } } Else{ Write-Error "No entries currently found in secret vault Logic.Monitor" Return } } } Else { #Convert to secure string [SecureString]$AccessKey = $AccessKey | ConvertTo-SecureString -AsPlainText -Force } #Create Credential Object for reuse in other functions $Script:LMAuth = [PSCustomObject]@{ Id = $AccessId Key = $AccessKey Portal = $AccountName Valid = $false Logging = !$DisableConsoleLogging.IsPresent } #Check for newer version of Logic.Monitor module Update-LogicMonitorModule -CheckOnly Try { #Set valid flag so we dont prompt for auth details on future requests $Script:LMAuth.Valid = $true #Collect portal info and api username and roles $ApiInfo = Get-LMAPIToken -Filter @{accessId = $AccessId } -ErrorAction SilentlyContinue If ($ApiInfo) { $PortalInfo = Get-LMPortalInfo -ErrorAction Stop Write-LMHost "Connected to LM portal $($PortalInfo.companyDisplayName) using account $($ApiInfo.adminName) with assigned roles: $($ApiInfo.roles -join ",") - ($($PortalInfo.numberOfDevices) devices | $($PortalInfo.numOfWebsites) websites)." -ForegroundColor Green Return } Else { Try{ $PortalInfo = Get-LMPortalInfo -ErrorAction Stop Write-LMHost "Connected to LM portal $($PortalInfo.companyDisplayName) using access id $AccessId - ($($PortalInfo.numberOfDevices) devices | $($PortalInfo.numOfWebsites) websites)." -ForegroundColor Green Return } Catch { throw "Unable to validate API token info" } } } Catch { Try{ $DeviceInfo = Get-LMDevice -ErrorAction Stop If($DeviceInfo){ Write-LMHost "Connected to LM portal $AccountName with limited permissions, ensure your api token has the necessary rights needed to run desired commands." -ForegroundColor Yellow Return } Else{ throw "Unable to verify api token permission levels, ensure api token has rights to view all/select resources or at minimum view access for Account Information" } } Catch{ Write-Error "Unable to login to account, please ensure your access info and account name are correct: $($_.Exception.Message)" #Clear credential object from environment Remove-Variable LMAuth -Scope Global -ErrorAction SilentlyContinue } Return } } |