AppianPS.psm1
$Script:PSModuleRoot = $PSScriptRoot $Script:ModuleName = "AppianPS" $Script:APAppDataPath = [Environment]::GetFolderPath('ApplicationData') $Script:ModuleDataRoot = (Join-Path -Path $Script:APAppDataPath -ChildPath $Script:ModuleName) $Script:ModuleDataPath = (Join-Path -Path $Script:ModuleDataRoot -ChildPath "ModuleData.json") if (-not (Test-Path $Script:ModuleDataRoot)) {New-Item -ItemType Directory -Path $Script:ModuleDataRoot -Force} # Imported from [D:\a\1\s\AppianPS\Private] # Get-APNApiEndpoint.ps1 function Get-APNApiEndpoint { <# .SYNOPSIS Returns the api uri endpoint. .DESCRIPTION Returns the api uri endpoint base on the api type. .PARAMETER ApiType Type of the api endpoint to use. .OUTPUTS String, The uri endpoint that will be used by Set-APNUri. .EXAMPLE Returns the api endpoint for 'deployments' Get-APApiEndpoint -ApiType deployments .LINK https://docs.appian.com/suite/help/22.1/Deployment_Rest_API.html #> [CmdletBinding()] Param ( [Parameter(Mandatory)] [string] $ApiType ) begin { } process { Switch ($ApiType) { 'deployments' { return '/suite/deployment-management/v1/deployments' } 'deployments-id' { return '/suite/deployment-management/v1/deployments/{0}' } 'deployments-log' { return '/suite/deployment-management/v1/deployments/{0}/log' } 'inspections' { return '/suite/deployment-management/v1/inspections' } 'inspections-id' { return '/suite/deployment-management/v1/inspections/{0}' } default { Write-Error "[$($MyInvocation.MyCommand.Name)]: [$ApiType] is not supported" -ErrorAction Stop } } } end { } } # Set-APNAuthenticationType.ps1 function Set-APNAuthenticationType { <# .SYNOPSIS Sets the authentication type used by Invoke-APRestMethod. .DESCRIPTION Sets the authentication type used by Invoke-APRestMethod. Default authentication will use the pesonal access token that is stored in session data, unless a credential is provided. .PARAMETER InputObject The splat parameters used by Invoke-APRestMethod. .PARAMETER Credential Specifies a user account that has permission to send the request. .OUTPUTS PSObject, The modifed inputobject. .EXAMPLE Set-APAuthenticationType -InputObject $inputObject .EXAMPLE Sets the AP authentication to the credential provided for the input object. Set-APNAuthenticationType -InputObject $inputObject -Credential $pscredential .EXAMPLE Sets the AP authentication to the personal access token provided for the input object. Set-APNAuthenticationType -InputObject $inputObject -ApiKey $mySecureToken .LINK https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/authentication-guidance?view=vsts #> [CmdletBinding()] param ( [Parameter(Mandatory)] [PSObject] $InputObject, [Parameter()] [Security.SecureString] $ApiKey, [Parameter()] [pscredential] $Credential ) begin { } process { If ($Credential) { Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Authenticating with the provided credential." $InputObject.Credential = $Credential } elseIf ($ApiKey) { Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Authenticating with the stored api key." $apiKeyToken = Unprotect-APNSecureApiKey -ApiKey $ApiKey $InputObject.Headers = @{'Appian-API-Key' = $apiKeyToken } } else { Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Authenticating with default credentials" $InputObject.UseDefaultCredentials = $true } } end { return $InputObject } } # Set-APNUri.ps1 function Set-APNUri { <# .SYNOPSIS Sets the uri used by Invoke-APNRestMethod. .DESCRIPTION Sets the uri used by Invoke-APNRestMethod. .PARAMETER Domain The Appian site domain. .PARAMETER ApiEndpoint The api endpoint provided by Get-APNApiEndpoint. .OUTPUTS Uri, The uri that will be used by Invoke-APNRestMethod. .EXAMPLE Set-APNUri -Domain 'myAppianDomain' -ApiEndpoint suite/deployment-management/v1/deployments .LINK https://docs.appian.com/suite/help/22.1/Deployment_Rest_API.html #> [CmdletBinding()] Param ( [Parameter()] [string] $Domain, [Parameter(Mandatory)] [string] $ApiEndpoint ) begin { } process { return 'https://{0}{1}' -f $Domain, $ApiEndpoint } end { } } # Unprotect-APNSecureApiKey.ps1 Function Unprotect-APNSecureApiKey { <# .SYNOPSIS Returns decrypted personal access token. .DESCRIPTION Returns decrypted personal access token that is stored in the session data. .PARAMETER ApiKey Personal access token used to authenticate that has been converted to a secure string. It is recomended to uses an Azure Pipelines PS session to pass the personal access token parameter among funcitons, See New-APNSession. https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=vsts .OUTPUTS String, unsecure personal access token. .EXAMPLE Unprotects the personal access token from secure string to plain text. Unprotect-SecureApiKey -ApiKey $mySecureToken .LINK https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/authentication-guidance?view=vsts #> [CmdletBinding()] Param ( [Parameter(Mandatory)] [Security.SecureString] $ApiKey ) Process { $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($ApiKey) $plainText = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) if ([environment]::OSVersion.Platform -eq "Unix") { $plainText = [System.Net.NetworkCredential]::new("", $ApiKey).Password } return $plainText } } # Imported from [D:\a\1\s\AppianPS\Public] # ConvertTo-APNMarkdownDeploymentReport.ps1 function ConvertTo-APNMarkdownDeploymentReport { <# .SYNOPSIS Converts Appian deployment or inspection results to a markdown table. .DESCRIPTION Converts Appian deployment or inspection results to a markdown table. .PARAMETER DeploymentResults The report to format. .PARAMETER DeploymentLog The deployment log to format .OUTPUTS String, The deployment or inspection results in markdown table format .EXAMPLE $report = Get-APNDeploymentResults -Session 'mySession -DeploymentId '834895a6-6d2f-4180-b396-b9ifb4f38b0f' $log = Get-APNDeploymentLog -Session 'mySession' -DeploymentId '834895a6-6d2f-4180-b396-b9ifb4f38b0f' ConvertTo-APNMarkdownDeploymentReport -DeploymentReport $report -DeploymentLog $log .LINK https://docs.appian.com/suite/help/22.1/Deployment_Rest_API.html #> [CmdletBinding()] Param ( [Parameter(Mandatory)] [PSObject[]] $DeploymentResults, [Parameter()] [string] $DeploymentLog ) begin { $databaseScripts = $DeploymentResults.summary.databaseScripts $objects = $DeploymentResults.summary.objects } process { '# Deployment Results' '## Database Scripts' "- Total $databaseScripts" '## Objects Expected' "- Total $($objects.Total)" "- Imported $($objects.Imported)" "- Failed $($objects.Failed)" "- Skipped $($objects.Skipped)" # Log '# Deployment Log' $Log } end { } } # ConvertTo-APNMarkdownInspectionReport.ps1 function ConvertTo-APNMarkdownInspectionReport { <# .SYNOPSIS Converts Appian inspection results to a markdown table. .DESCRIPTION Converts Appian inspection results to a markdown table. .PARAMETER InputObject The input object to convert. .OUTPUTS String, The inspection results in markdown table format .EXAMPLE $content = Get-Content -Path $pathToFile ConvertTo-APNMarkdownInspectionReport -InputObject $content .LINK https://docs.appian.com/suite/help/22.1/Deployment_Rest_API.html #> [CmdletBinding()] Param ( [Parameter(Mandatory)] [PSObject[]] $InputObject ) begin { $objectsExpected = $InputObject.summary.objectsExpected $problems = $InputObject.summary.problems $errorRows = @() $errorColumns = @{ } $errorHeaderOrder = @( 'objectName' 'errorMessage' 'objectUuid' ) $warningRows = @() $warningColumns = @{ } $warningHeaderOrder = @( 'objectName' 'warningMessage' 'objectUuid' ) } process { foreach ($row in $problems.errors) { $errorRows += $row foreach ($property in $row.PSObject.Properties) { if ($null -ne $property.Value) { if (-not $errorColumns.ContainsKey($property.Name) -or $errorColumns[$property.Name] -lt $property.Value.ToString().Length) { $errorColumns[$property.Name] = $property.Value.ToString().Length } } } } $errorRows = $errorRows | Sort-Object 'objectName' foreach ($row in $problems.warnings) { $warningRows += $row foreach ($property in $row.PSObject.Properties) { if ($null -ne $property.Value) { if (-not $warningColumns.ContainsKey($property.Name) -or $warningColumns[$property.Name] -lt $property.Value.ToString().Length) { $warningColumns[$property.Name] = $property.Value.ToString().Length } } } } $warningRows = $warningRows | Sort-Object 'objectName' } end { # Summary '# Summary' '## Objects Expected' "- Total $($objectsExpected.Total)" "- Imported $($objectsExpected.Imported)" "- Failed $($objectsExpected.Failed)" "- Skipped $($objectsExpected.Skipped)" # Problems '# Problems' "- Total Errors $($problems.totalErrors)" "- Total Warnings $($problems.totalWarnings)" If ($problems.totalErrors -gt 0) { '## Errors' # Column width foreach ($key in $($errorColumns.Keys)) { $errorColumns[$key] = [Math]::Max($errorColumns[$key], $key.Length) } # Header $header = @() $sortedKeys = $errorColumns.Keys | Sort-Object { $errorHeaderOrder.IndexOf($PSitem) } foreach ($key in $sortedKeys) { $header += ('{0,-' + $errorColumns[$key] + '}') -f $key } $header -join ' | ' # Separator $separator = @() foreach ($key in $sortedKeys) { $separator += '-' * $errorColumns[$key] } $separator -join ' | ' # Rows foreach ($row in $errorRows) { $values = @() foreach ($key in $sortedKeys) { $values += ('{0,-' + $errorColumns[$key] + '}') -f $row.($key) } $values -join ' | ' } } If ($problems.totalWarnings -gt 0) { '## Warnings' foreach ($key in $($warningColumns.Keys)) { $warningColumns[$key] = [Math]::Max($warningColumns[$key], $key.Length) } # Header $header = @() $sortedKeys = $warningColumns.Keys | Sort-Object { $warningHeaderOrder.IndexOf($PSitem) } foreach ($key in $sortedKeys) { $header += ('{0,-' + $warningColumns[$key] + '}') -f $key } $header -join ' | ' # Separator $separator = @() foreach ($key in $sortedKeys) { $separator += '-' * $warningColumns[$key] } $separator -join ' | ' # Rows foreach ($row in $warningRows) { $values = @() foreach ($key in $sortedKeys) { $values += ('{0,-' + $warningColumns[$key] + '}') -f $row.($key) } $values -join ' | ' } } } } # Get-APNDeploymentLog.ps1 function Get-APNDeploymentLog { <# .SYNOPSIS Returns Appian deployment log. .DESCRIPTION Returns Appian deployment log based on the deployment id. The deployment id is returned in the response of New-APNDeployment. .PARAMETER Domain The Appian site domain. .PARAMETER ApiKey The Appian api key. The API key can be created in the Appian Administration Console, and then configured to secure external deployments. .PARAMETER Credential Specifies a user account that has permission to send the request. .PARAMETER Proxy Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server. .PARAMETER ProxyCredential Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user. .PARAMETER Session Azure DevOps PS session, created by New-APNSession. .PARAMETER DeploymentId The id of the deployment .PARAMETER Wait Flag to wait for summary status to not be 'IN_PROGRESS'. .PARAMETER TimeoutSeconds The number of seconds to wait before timing out. Defaults to 120. .PARAMETER SleepSeconds The number of seconds to sleep inbetween requests. Defaults to 1. .INPUTS None, does not support pipeline. .OUTPUTS String, Appian deployment log. .EXAMPLE Returns the Appian deployment log. Get-APNDeploymentLog -Domain 'myAppianDomain' -ApiKey '*******' -DeploymentId '834895a6-6d2f-4180-b396-b9ifb4f38b0f' .LINK https://docs.appian.com/suite/help/22.1/Get_Deployment_Log_API.html #> [CmdletBinding(DefaultParameterSetName = 'ByApiKey')] Param ( [Parameter(Mandatory, ParameterSetName = 'ByApiKey')] [Parameter(Mandatory, ParameterSetName = 'ByCredential')] [string] $Domain, [Parameter(ParameterSetName = 'ByApiKey')] [Security.SecureString] $ApiKey, [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $Credential, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [string] $Proxy, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $ProxyCredential, [Parameter(Mandatory, ParameterSetName = 'BySession')] [object] $Session, [Parameter(Mandatory)] [string] $DeploymentId, [Parameter()] [bool] $Wait, [Parameter()] [int] $TimeoutSeconds = 120, [Parameter()] [int] $SleepSeconds = 1 ) begin { $timeoutIterations = $TimeoutSeconds / $SleepSeconds If ($PSCmdlet.ParameterSetName -eq 'BySession') { $currentSession = $Session | Get-APNSession If ($currentSession) { $Domain = $currentSession.Domain $ApiKey = $currentSession.ApiKey $Credential = $currentSession.Credential $Proxy = $currentSession.Proxy $ProxyCredential = $currentSession.ProxyCredential } } } process { $apiEndpoint = (Get-APNApiEndpoint -ApiType 'deployments-log') -f $DeploymentId $setAPNUriSplat = @{ Domain = $Domain ApiEndpoint = $apiEndpoint } [uri] $uri = Set-APNUri @setAPNUriSplat $invokeAPNRestMethodSplat = @{ Method = 'GET' Uri = $uri Credential = $Credential ApiKey = $ApiKey Proxy = $Proxy ProxyCredential = $ProxyCredential } $results = Invoke-APNRestMethod @invokeAPNRestMethodSplat If ($Wait) { $i = 0 while (($results.Status -eq 'IN_PROGRESS') -or ($results.Status -eq 'PENDING_REVIEW')) { Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Sleeping for $SleepSeconds seconds" Start-Sleep -Seconds $SleepSeconds $i = $i + 1 If ($i -gt $timeoutIterations) { Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Timeout reached it's maximum of $TimeoutSeconds seconds." break } $results = Get-APNDeploymentLog @PSBoundParameters } } return $results } end { } } # Get-APNDeploymentResults.ps1 function Get-APNDeploymentResults { <# .SYNOPSIS Returns Appian deployment results. .DESCRIPTION Returns Appian deployment results based on the deployment id. The deployment id is returned in the response of New-APNDeployment. .PARAMETER Domain The Appian site domain. .PARAMETER ApiKey The Appian api key. The API key can be created in the Appian Administration Console, and then configured to secure external deployments. .PARAMETER Credential Specifies a user account that has permission to send the request. .PARAMETER Proxy Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server. .PARAMETER ProxyCredential Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user. .PARAMETER Session Azure DevOps PS session, created by New-APNSession. .PARAMETER DeploymentId The id of the deployment. .PARAMETER Wait Flag to wait for summary status to not be 'IN_PROGRESS'. .PARAMETER TimeoutSeconds The number of seconds to wait before timing out. Defaults to 120. .PARAMETER SleepSeconds The number of seconds to sleep inbetween requests. Defaults to 1. .INPUTS None, does not support pipeline. .OUTPUTS String, Appian deployment results. .EXAMPLE Returns the Appian deployment results. Get-APNDeploymentResults -Domain 'myAppianDomain' -ApiKey '*******' -DeploymentId '834895a6-6d2f-4180-b396-b9ifb4f38b0f' .LINK https://docs.appian.com/suite/help/22.1/Get_Deployment_Results_API.html #> [CmdletBinding(DefaultParameterSetName = 'ByApiKey')] Param ( [Parameter(Mandatory, ParameterSetName = 'ByApiKey')] [Parameter(Mandatory, ParameterSetName = 'ByCredential')] [string] $Domain, [Parameter(ParameterSetName = 'ByApiKey')] [Security.SecureString] $ApiKey, [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $Credential, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [string] $Proxy, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $ProxyCredential, [Parameter(Mandatory, ParameterSetName = 'BySession')] [object] $Session, [Parameter(Mandatory)] [string] $DeploymentId, [Parameter()] [bool] $Wait, [Parameter()] [int] $TimeoutSeconds = 120, [Parameter()] [int] $SleepSeconds = 1 ) begin { $timeoutIterations = $TimeoutSeconds / $SleepSeconds If ($PSCmdlet.ParameterSetName -eq 'BySession') { $currentSession = $Session | Get-APNSession If ($currentSession) { $Domain = $currentSession.Domain $ApiKey = $currentSession.ApiKey $Credential = $currentSession.Credential $Proxy = $currentSession.Proxy $ProxyCredential = $currentSession.ProxyCredential } } } process { $apiEndpoint = (Get-APNApiEndpoint -ApiType 'deployments-id') -f $DeploymentId $setAPNUriSplat = @{ Domain = $Domain ApiEndpoint = $apiEndpoint } [uri] $uri = Set-APNUri @setAPNUriSplat $invokeAPNRestMethodSplat = @{ Method = 'GET' Uri = $uri Credential = $Credential ApiKey = $ApiKey Proxy = $Proxy ProxyCredential = $ProxyCredential } $results = Invoke-APNRestMethod @invokeAPNRestMethodSplat If ($Wait) { $i = 0 while (($results.Status -eq 'IN_PROGRESS') -or ($results.Status -eq 'PENDING_REVIEW')) { Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Sleeping for $SleepSeconds seconds" Start-Sleep -Seconds $SleepSeconds $i = $i + 1 If ($i -gt $timeoutIterations) { Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Timeout reached it's maximum of $TimeoutSeconds seconds." break } $results = Get-APNDeploymentResults @PSBoundParameters } } return $results } end { } } # Get-APNInspectionResults.ps1 function Get-APNInspectionResults { <# .SYNOPSIS Returns Appian inspection results. .DESCRIPTION Returns Appian inspection results based on the inspection id. The inspection id is returned in the response of New-APNinspection. .PARAMETER Domain The Appian site domain. .PARAMETER ApiKey The Appian api key. The API key can be created in the Appian Administration Console, and then configured to secure external deployments. .PARAMETER Credential Specifies a user account that has permission to send the request. .PARAMETER Proxy Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server. .PARAMETER ProxyCredential Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user. .PARAMETER Session Azure DevOps PS session, created by New-APNSession. .PARAMETER InspectionId The id of the inspection .PARAMETER Wait Flag to wait for summary status to not be 'IN_PROGRESS'. .PARAMETER TimeoutSeconds The number of seconds to wait before timing out. Defaults to 120. .PARAMETER SleepSeconds The number of seconds to sleep inbetween requests. Defaults to 1. .INPUTS None, does not support pipeline. .OUTPUTS String, Appian inspection results. .EXAMPLE Returns the Appian inspection results. Get-APNInspectionResults -Domain 'myAppianDomain' -ApiKey '*******' -InspectionId '834895a6-6d2f-4180-b396-b9ifb4f38b0f' .LINK https://docs.appian.com/suite/help/22.1/Get_Inspection_Results_API.html #> [CmdletBinding(DefaultParameterSetName = 'ByApiKey')] Param ( [Parameter(Mandatory, ParameterSetName = 'ByApiKey')] [Parameter(Mandatory, ParameterSetName = 'ByCredential')] [string] $Domain, [Parameter(ParameterSetName = 'ByApiKey')] [Security.SecureString] $ApiKey, [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $Credential, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [string] $Proxy, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $ProxyCredential, [Parameter(Mandatory, ParameterSetName = 'BySession')] [object] $Session, [Parameter(Mandatory)] [string] $InspectionId, [Parameter()] [bool] $Wait, [Parameter()] [int] $TimeoutSeconds = 120, [Parameter()] [int] $SleepSeconds = 1 ) begin { $timeoutIterations = $TimeoutSeconds / $SleepSeconds If ($PSCmdlet.ParameterSetName -eq 'BySession') { $currentSession = $Session | Get-APNSession If ($currentSession) { $Domain = $currentSession.Domain $ApiKey = $currentSession.ApiKey $Credential = $currentSession.Credential $Proxy = $currentSession.Proxy $ProxyCredential = $currentSession.ProxyCredential } } } process { $apiEndpoint = (Get-APNApiEndpoint -ApiType 'inspections-id') -f $InspectionId $setAPNUriSplat = @{ Domain = $Domain ApiEndpoint = $apiEndpoint } [uri] $uri = Set-APNUri @setAPNUriSplat $invokeAPNRestMethodSplat = @{ Method = 'GET' Uri = $uri Credential = $Credential ApiKey = $ApiKey Proxy = $Proxy ProxyCredential = $ProxyCredential } $results = Invoke-APNRestMethod @invokeAPNRestMethodSplat If ($Wait) { $i = 0 while ($results.Status -eq 'IN_PROGRESS') { Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Sleeping for $SleepSeconds seconds" Start-Sleep -Seconds $SleepSeconds $i = $i + 1 If ($i -gt $timeoutIterations) { Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Timeout reached it's maximum of $TimeoutSeconds seconds." break } $results = Get-APNInspectionResults @PSBoundParameters } } return $results } end { } } # Get-APNSession.ps1 Function Get-APNSession { <# .SYNOPSIS Returns Appian session data. .DESCRIPTION Returns Appian session data that has been stored in the users local application data. Use Save-APNSession to persist the session data to disk. The sensetive data is returned encrypted. .PARAMETER Id Session id. .PARAMETER SessionName The friendly name of the session. .PARAMETER Path The path where session data will be stored, defaults to $Script:ModuleDataPath. .LINK Save-APNSession Remove-APNSession .INPUTS None, does not support pipeline. .OUTPUTS PSObject. Get-APNSession returns a PSObject that contains the following: Domain ApiKey .EXAMPLE Returns all Appian sessions saved or in memory. Get-APNSession .EXAMPLE Returns Appian session with the session name of 'myFirstSession'. Get-APNSession -SessionName 'myFirstSession' #> [CmdletBinding()] Param ( [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $SessionName, [Parameter(ParameterSetName = 'ById', ValueFromPipeline, ValueFromPipelineByPropertyName)] [int] $Id, [Parameter()] [string] $Path = $Script:ModuleDataPath ) Process { # Process memory sessions $_sessions = @() If ($null -ne $Global:_APNSessions) { Foreach ($_memSession in $Global:_APNSessions) { $_sessions += $_memSession } } # Process saved sessions If (Test-Path $Path) { $data = Get-Content -Path $Path -Raw | ConvertFrom-Json Foreach ($_data in $data.SessionData) { $_object = New-Object -TypeName PSCustomObject -Property @{ Id = $_data.Id Domain = $_data.Domain SessionName = $_data.SessionName Saved = $_data.Saved } If ($_data.ApiKey) { $_object | Add-Member -NotePropertyName 'ApiKey' -NotePropertyValue ($_data.ApiKey | ConvertTo-SecureString) } If ($_data.Credential) { $_psCredentialObject = [pscredential]::new($_data.Credential.Username, ($_data.Credential.Password | ConvertTo-SecureString)) $_object | Add-Member -NotePropertyName 'Credential' -NotePropertyValue $_psCredentialObject } If ($_data.Proxy) { $_object | Add-Member -NotePropertyName 'Proxy' -NotePropertyValue $_data.Proxy } If ($_data.ProxyCredential) { $_psProxyCredentialObject = [pscredential]::new($_data.ProxyCredential.Username, ($_data.ProxyCredential.Password | ConvertTo-SecureString)) $_object | Add-Member -NotePropertyName 'ProxyCredential' -NotePropertyValue $_psProxyCredentialObject } $_sessions += $_object } } If ($PSCmdlet.ParameterSetName -eq 'ById') { $_sessions = $_sessions | Where-Object { $PSItem.Id -eq $Id } } If ($SessionName) { $_sessions = $_sessions | Where-Object { $PSItem.SessionName -eq $SessionName } If (-not($_sessions)) { Write-Error "[$($MyInvocation.MyCommand.Name)]: Unable to locate a session by the name of [$SessionName]" -ErrorAction 'Stop' } } return $_sessions } } # Invoke-APNPackageDeployment.ps1 function Invoke-APNPackageDeployment { <# .SYNOPSIS Starts the Appian package deployment process. .DESCRIPTION Starts the Appian package deployment process by running the following commands. 1. New-APNPackageDeployment - Creates a package deployment request 2. Get-APNDeploymentResults - Waits for the deployment results, then returns the summary 3. ConvertTo-APNMarkdownTable - Converts the summary to a markdown table and writes it to file. .PARAMETER Domain The Appian site domain. .PARAMETER ApiKey The Appian api key. The API key can be created in the Appian Administration Console, and then configured to secure external deployments. .PARAMETER Credential Specifies a user account that has permission to send the request. .PARAMETER Proxy Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server. .PARAMETER ProxyCredential Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user. .PARAMETER Name Name of the deployment. This name will appear in the deployments view in Appian Designer. .PARAMETER Description Description of the deployment. This description will appear in the deployments view in Appian Designer. .PARAMETER Session Azure DevOps PS session, created by New-APNSession. .PARAMETER PackageFilePath The local path to the package. .PARAMETER CustomizationFilePath The local path to the import customization file (.properties). .PARAMETER OutputFormat Format to use when outputing the deployment results. PSObject or Markdown. Defaults to PSObject. .PARAMETER OutputPath The file path to write the summary report to. Only used when OutputFormat is set to Markdown. .PARAMETER Wait Flag to wait for summary status to not be 'In Progress'. .PARAMETER TimeoutSeconds The number of seconds to wait before timing out. Defaults to 120. .PARAMETER SleepSeconds The number of seconds to sleep inbetween requests. Defaults to 1. .INPUTS None, does not support pipeline. .OUTPUTS PSObject, Appian deployment object .EXAMPLE Invokes the Appian package deployment process. $splat = @{ Session = 'mySession' PackageFilePath = ".\myZipPackage.zip" CustomizationFilePath = '.\DEV.properties' OutputFormat = 'Markdown' OutputPath = '.\Report.md' Verbose = $true } Invoke-APNPackageDeployment @splat .LINK https://docs.appian.com/suite/help/22.1/Inspect_Package_API.html #> [CmdletBinding(DefaultParameterSetName = 'ByApiKey')] Param ( [Parameter(Mandatory, ParameterSetName = 'ByApiKey')] [Parameter(Mandatory, ParameterSetName = 'ByCredential')] [string] $Domain, [Parameter(ParameterSetName = 'ByApiKey')] [Security.SecureString] $ApiKey, [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $Credential, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [string] $Proxy, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $ProxyCredential, [Parameter(Mandatory, ParameterSetName = 'BySession')] [object] $Session, [Parameter(Mandatory)] [string] $Name, [Parameter()] [string] $Description, [Parameter(Mandatory)] [string] $PackageFilePath, [Parameter()] [string] $CustomizationFilePath, [Parameter()] [ValidateSet('PSObject', 'Markdown')] [string] $OutputFormat = 'PSObject', [Parameter()] [string] $OutputPath, [Parameter()] [bool] $Wait, [Parameter()] [int] $TimeoutSeconds = 120, [Parameter()] [int] $SleepSeconds = 1 ) begin { If ($PSCmdlet.ParameterSetName -eq 'BySession') { $currentSession = $Session | Get-APNSession If ($currentSession) { $Domain = $currentSession.Domain $ApiKey = $currentSession.ApiKey $Credential = $currentSession.Credential $Proxy = $currentSession.Proxy $ProxyCredential = $currentSession.ProxyCredential } } } process { $splat = @{ Domain = $Domain Proxy = $Proxy ProxyCredential = $ProxyCredential } If ($ApiKey) { $splat.ApiKey = $ApiKey } If ($Credential) { $splat.Credential = $Credential } Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Invoking New-APNPackageDeployment" $results = New-APNPackageDeployment @splat -Name $Name -Description $Description -PackageFilePath $PackageFilePath -CustomizationFilePath $CustomizationFilePath -DataSource $DataSource Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Invoking Get-APNDeploymentResults" $report = Get-APNDeploymentResults @splat -DeploymentId $results.UUID -Wait $true Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Invoking Get-APNDeploymentLog" $log = Get-APNDeploymentLog @splat -DeploymentId $results.UUID If ($OutputFormat -eq 'Markdown') { Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Invoking ConvertTo-APNMarkdownDeploymentReport" $formattedReport = ConvertTo-APNMarkdownDeploymentReport -DeploymentResults $report -DeploymentLog $log If ($OutputPath) { $formattedReport | Out-File $OutputPath } } return @{ report = $report log = $log UUID = $results.UUID } } end { } } # Invoke-APNPackageInspection.ps1 function Invoke-APNPackageInspection { <# .SYNOPSIS Starts the Appian package inspection process. .DESCRIPTION Starts the Appian package inspection process by running the following commands. 1. New-APNPackageInspection - Creates a package inspection request 2. Get-APNInspectionResults - Waits for the inspection results, then returns the summary 3. ConvertTo-APNMarkdownTable - Converts the summary to a markdown table and writes it to file. .PARAMETER Domain The Appian site domain. .PARAMETER ApiKey The Appian api key. The API key can be created in the Appian Administration Console, and then configured to secure external inspections. .PARAMETER Credential Specifies a user account that has permission to send the request. .PARAMETER Proxy Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server. .PARAMETER ProxyCredential Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user. .PARAMETER Session Azure DevOps PS session, created by New-APNSession. .PARAMETER PackageFilePath The local path to the package. .PARAMETER CustomizationFilePath The local path to the import customization file (.properties). .PARAMETER OutputFormat Format to use when outputing the inspection results. PSObject or Markdown. Defaults to PSObject. .PARAMETER OutputPath The file path to write the summary report to. Only used when OutputFormat is set to Markdown. .PARAMETER Wait Flag to wait for summary status to not be 'In Progress'. .PARAMETER TimeoutSeconds The number of seconds to wait before timing out. Defaults to 120. .PARAMETER SleepSeconds The number of seconds to sleep inbetween requests. Defaults to 1. .INPUTS None, does not support pipeline. .OUTPUTS PSObject, Appian inspection object .EXAMPLE Invokes the Appian package inspection process. $splat = @{ Session = 'mySession' PackageFilePath = ".\myZipPackage.zip" CustomizationFilePath = '.\DEV.properties' OutputFormat = 'Markdown' OutputPath = '.\Report.md' Verbose = $true } Invoke-APNPackageInspection @splat .LINK https://docs.appian.com/suite/help/22.1/Inspect_Package_API.html #> [CmdletBinding(DefaultParameterSetName = 'ByApiKey')] Param ( [Parameter(Mandatory, ParameterSetName = 'ByApiKey')] [Parameter(Mandatory, ParameterSetName = 'ByCredential')] [string] $Domain, [Parameter(ParameterSetName = 'ByApiKey')] [Security.SecureString] $ApiKey, [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $Credential, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [string] $Proxy, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $ProxyCredential, [Parameter(Mandatory, ParameterSetName = 'BySession')] [object] $Session, [Parameter(Mandatory)] [string] $PackageFilePath, [Parameter()] [string] $CustomizationFilePath, [Parameter()] [ValidateSet('PSObject', 'Markdown')] [string] $OutputFormat = 'PSObject', [Parameter()] [string] $OutputPath, [Parameter()] [bool] $Wait, [Parameter()] [int] $TimeoutSeconds = 120, [Parameter()] [int] $SleepSeconds = 1 ) begin { If ($PSCmdlet.ParameterSetName -eq 'BySession') { $currentSession = $Session | Get-APNSession If ($currentSession) { $Domain = $currentSession.Domain $ApiKey = $currentSession.ApiKey $Credential = $currentSession.Credential $Proxy = $currentSession.Proxy $ProxyCredential = $currentSession.ProxyCredential } } } process { $splat = @{ Domain = $Domain Proxy = $Proxy ProxyCredential = $ProxyCredential } If ($ApiKey) { $splat.ApiKey = $ApiKey } If ($Credential) { $splat.Credential = $Credential } Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Invoking New-APNPackageInspection" $results = New-APNPackageInspection @splat -PackageFilePath $PackageFilePath -CustomizationFilePath $CustomizationFilePath Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Invoking Get-APNInspectionResults" $report = Get-APNInspectionResults @splat -InspectionId $results.UUID -Wait $true If ($OutputFormat -eq 'Markdown') { Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Invoking ConvertTo-APNMarkdownInspectionReport" $formattedReport = ConvertTo-APNMarkdownInspectionReport -InputObject $report If ($OutputPath) { $formattedReport | Out-File $OutputPath } } return @{ report = $report UUID = $results.UUID } } end { } } # Invoke-APNRestMethod.ps1 function Invoke-APNRestMethod { <# .SYNOPSIS Invokes an Appian rest method. .DESCRIPTION Invokes an Appian rest method. .PARAMETER Method Specifies the method used for the web request. .PARAMETER Body Specifies the body of the request. The body is the content of the request that follows the headers. .PARAMETER Form Converts a dictionary to a multipart/form-data submission. Form may not be used with Body. If ContentType is used, it's ignored. .PARAMETER ContentType Specifies the content type of the web request. If this parameter is omitted and the request method is POST, Invoke-RestMethod sets the content type to application/x-www-form-urlencoded. Otherwise, the content type is not specified in the call. .PARAMETER Uri Specifies the Uniform Resource Identifier (URI) of the Internet resource to which the web request is sent. This parameter supports HTTP, HTTPS, FTP, and FILE values. .PARAMETER ApiKey The Appian api key. The API key can be created in the Appian Administration Console, and then configured to secure external deployments. .PARAMETER Credential Specifies a user account that has permission to send the request. .PARAMETER Proxy Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server. .PARAMETER ProxyCredential Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user. .PARAMETER Path The directory to output files to. .PARAMETER Infile The fullname/path to the file that will be uploaded. .OUTPUTS System.Int64, System.String, System.Xml.XmlDocument, The output of the cmdlet depends upon the format of the content that is retrieved. .OUTPUTS PSObject, If the request returns JSON strings, Invoke-RestMethod returns a PSObject that represents the strings. .EXAMPLE NA .LINK https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-6 #> [CmdletBinding()] Param ( [Parameter(Mandatory)] [string] $Method, [Parameter()] [object] $Body, [Parameter()] [object] $Form, [Parameter(Mandatory)] [uri] $Uri, [Parameter()] [string] $ContentType, [Parameter()] [Security.SecureString] $ApiKey, [Parameter()] [pscredential] $Credential, [Parameter()] [string] $Proxy, [Parameter()] [pscredential] $ProxyCredential, [Parameter()] [string] $Path, [Parameter()] [string] $InFile ) begin { } process { $invokeRestMethodSplat = @{ Method = $Method Uri = $uri.AbsoluteUri } If ($Body) { $invokeRestMethodSplat.ContentType = $ContentType } If ($Body) { $invokeRestMethodSplat.Body = ConvertTo-Json -InputObject $Body -Depth 20 } If ($Form) { $invokeRestMethodSplat.Form = $Form } If ($Proxy) { $invokeRestMethodSplat.Proxy = $Proxy If ($ProxyCredential) { $invokeRestMethodSplat.ProxyCredential = $ProxyCredential } else { $invokeRestMethodSplat.ProxyUseDefaultCredentials = $true } } If ($Path) { $invokeRestMethodSplat.OutFile = $Path } If ($InFile) { $invokeRestMethodSplat.InFile = $InFile } $authenticatedRestMethodSplat = Set-APNAuthenticationType -InputObject $invokeRestMethodSplat -Credential $Credential -ApiKey $ApiKey Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Invoking $($uri.AbsoluteUri)" return Invoke-RestMethod @authenticatedRestMethodSplat } end { } } # New-APNPackageDeployment.ps1 function New-APNPackageDeployment { <# .SYNOPSIS Creates an Appian package deployment. .DESCRIPTION Creates an Appian package deployment. .PARAMETER Domain The Appian site domain. .PARAMETER ApiKey The Appian api key. The API key can be created in the Appian Administration Console, and then configured to secure external deployments. .PARAMETER Credential Specifies a user account that has permission to send the request. .PARAMETER Proxy Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server. .PARAMETER ProxyCredential Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user. .PARAMETER Session Azure DevOps PS session, created by New-APNSession. .PARAMETER Name Name of the deployment. This name will appear in the deployments view in Appian Designer. .PARAMETER Description Description of the deployment. This description will appear in the deployments view in Appian Designer. .PARAMETER PackageFilePath The local path to the package. .PARAMETER CustomizationFilePath The local path to the import customization file (.properties). .PARAMETER DataSource Name or UUID of the data source. If the data source is connected through the Administration Console, use the value in the Name field. If the data source is connected through a data source connected system, use the UUID of the connected system. .PARAMETER DatabaseScripts Array of data; each of the database scripts to be executed and their order. [ { "fileName": "Create Tables.sql", "orderId": "1" }, { "fileName": "Update Reference Data.sql", "orderId": "2" } ] .INPUTS None, does not support pipeline. .OUTPUTS PSObject, Appian deployment object .EXAMPLE .LINK https://docs.appian.com/suite/help/22.1/Deploy_Package_API.html #> [CmdletBinding(DefaultParameterSetName = 'ByApiKey')] Param ( [Parameter(Mandatory, ParameterSetName = 'ByApiKey')] [Parameter(Mandatory, ParameterSetName = 'ByCredential')] [string] $Domain, [Parameter(ParameterSetName = 'ByApiKey')] [Security.SecureString] $ApiKey, [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $Credential, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [string] $Proxy, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $ProxyCredential, [Parameter(Mandatory, ParameterSetName = 'BySession')] [object] $Session, [Parameter(Mandatory)] [string] $Name, [Parameter()] [string] $Description, [Parameter(Mandatory)] [string] $PackageFilePath, [Parameter()] [string] $CustomizationFilePath, [Parameter()] [string] $DataSource ) begin { If ($PSCmdlet.ParameterSetName -eq 'BySession') { $currentSession = $Session | Get-APNSession If ($currentSession) { $Domain = $currentSession.Domain $ApiKey = $currentSession.ApiKey $Credential = $currentSession.Credential $Proxy = $currentSession.Proxy $ProxyCredential = $currentSession.ProxyCredential } } } process { $package = Get-Item -Path $PackageFilePath $json = @{ name = $Name packageFileName = $package.Name } if ($Description) { $json.description = $Description } if ($DataSource) { $json.dataSource = $DataSource } $form = @{ zipFile = $package } if ($CustomizationFilePath) { $propertiesFile = Get-Item -Path $CustomizationFilePath $json.customizationFileName = $propertiesFile.Name $form.propertiesFile = $propertiesFile } $form.json = $json | ConvertTo-Json $apiEndpoint = Get-APNApiEndpoint -ApiType 'deployments' $setAPNUriSplat = @{ Domain = $Domain ApiEndpoint = $apiEndpoint } [uri] $uri = Set-APNUri @setAPNUriSplat $invokeAPNRestMethodSplat = @{ Form = $form Method = 'POST' Uri = $uri Credential = $Credential ApiKey = $ApiKey Proxy = $Proxy ProxyCredential = $ProxyCredential } $results = Invoke-APNRestMethod @invokeAPNRestMethodSplat return $results } end { } } # New-APNPackageInspection.ps1 function New-APNPackageInspection { <# .SYNOPSIS Creates an Appian package inspection. .DESCRIPTION Creates an Appian package inspection. .PARAMETER Domain The Appian site domain. .PARAMETER ApiKey The Appian api key. The API key can be created in the Appian Administration Console, and then configured to secure external inspections. .PARAMETER Credential Specifies a user account that has permission to send the request. .PARAMETER Proxy Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server. .PARAMETER ProxyCredential Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user. .PARAMETER Session Azure DevOps PS session, created by New-APNSession. .PARAMETER PackageFilePath The local path to the package. .PARAMETER CustomizationFilePath The local path to the import customization file (.properties). .INPUTS None, does not support pipeline. .OUTPUTS PSObject, Appian inspection object .EXAMPLE .LINK https://docs.appian.com/suite/help/22.1/Inspect_Package_API.html #> [CmdletBinding(DefaultParameterSetName = 'ByApiKey')] Param ( [Parameter(Mandatory, ParameterSetName = 'ByApiKey')] [Parameter(Mandatory, ParameterSetName = 'ByCredential')] [string] $Domain, [Parameter(ParameterSetName = 'ByApiKey')] [Security.SecureString] $ApiKey, [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $Credential, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [string] $Proxy, [Parameter(ParameterSetName = 'ByApiKey')] [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $ProxyCredential, [Parameter(Mandatory, ParameterSetName = 'BySession')] [object] $Session, [Parameter(Mandatory)] [string] $PackageFilePath, [Parameter()] [string] $CustomizationFilePath ) begin { If ($PSCmdlet.ParameterSetName -eq 'BySession') { $currentSession = $Session | Get-APNSession If ($currentSession) { $Domain = $currentSession.Domain $ApiKey = $currentSession.ApiKey $Credential = $currentSession.Credential $Proxy = $currentSession.Proxy $ProxyCredential = $currentSession.ProxyCredential } } } process { $package = Get-Item -Path $PackageFilePath $json = @{ packageFileName = $package.Name } $form = @{ zipFile = $package } if ($CustomizationFilePath) { $propertiesFile = Get-Item -Path $CustomizationFilePath $json.customizationFileName = $propertiesFile.Name $form.propertiesFile = $propertiesFile } $form.json = $json | ConvertTo-Json $apiEndpoint = Get-APNApiEndpoint -ApiType 'inspections' $setAPNUriSplat = @{ Domain = $Domain ApiEndpoint = $apiEndpoint } [uri] $uri = Set-APNUri @setAPNUriSplat $invokeAPNRestMethodSplat = @{ Form = $form Method = 'POST' Uri = $uri Credential = $Credential ApiKey = $ApiKey Proxy = $Proxy ProxyCredential = $ProxyCredential } $results = Invoke-APNRestMethod @invokeAPNRestMethodSplat return $results } end { } } # New-APNSession.ps1 Function New-APNSession { <# .SYNOPSIS Creates an Appian session. .DESCRIPTION Creates an Appian session. Use Save-APNSession to persist the session data to disk. Save the session to a variable to pass the session to other functions. .PARAMETER SessionName The friendly name of the session. .PARAMETER Domain The Appian site domain. Example 'mydomain.appiancloud.com' .PARAMETER ApiKey The Appian api key. The API key can be created in the Appian Administration Console, and then configured to secure external inspections. .PARAMETER Credential Specifies a user account that has permission to the project. .PARAMETER Proxy Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server. .PARAMETER ProxyCredential Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user. .PARAMETER Path The path where module data will be stored, defaults to $Script:ModuleDataPath. .LINK Save-APNSession Remove-APNSession .INPUTS None, does not support pipeline. .OUTPUTS PSObject. New-APNSession returns a PSObject that contains the following: Domain ApiKey .EXAMPLE Creates a Appian session names 'myFirstSession' New-APNSession -SessionName 'myFirstSession' -Domain 'myAppianDomain.appiancloud.com' -ApiKey '********' #> [CmdletBinding(DefaultParameterSetName = 'ByApiKey')] Param ( [Parameter(Mandatory)] [string] $SessionName, [Parameter(Mandatory)] [string] $Domain, [Parameter(ParameterSetName = 'ByApiKey')] [string] $ApiKey, [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $Credential, [Parameter()] [string] $Proxy, [Parameter()] [pscredential] $ProxyCredential, [Parameter()] [string] $Path = $Script:ModuleDataPath ) Process { [int] $_sessionIdcount = (Get-APNSession | Sort-Object -Property 'Id' | Select-Object -Last 1 -ExpandProperty 'Id') + 1 $_session = New-Object -TypeName PSCustomObject -Property @{ Domain = $Domain SessionName = $SessionName Id = $_sessionIdcount } If ($ApiKey) { $securedPat = (ConvertTo-SecureString -String $ApiKey -AsPlainText -Force) $_session | Add-Member -NotePropertyName 'ApiKey' -NotePropertyValue $securedPat } If ($Credential) { $_session | Add-Member -NotePropertyName 'Credential' -NotePropertyValue $Credential } If ($Proxy) { $_session | Add-Member -NotePropertyName 'Proxy' -NotePropertyValue $Proxy } If ($ProxyCredential) { $_session | Add-Member -NotePropertyName 'ProxyCredential' -NotePropertyValue $ProxyCredential } If ($null -eq $Global:_APNSessions) { $Global:_APNSessions = @() } $Global:_APNSessions += $_session return $_session } } # Remove-APNSession.ps1 Function Remove-APNSession { <# .SYNOPSIS Removes an Appian session. .DESCRIPTION Removes an Appian session. If the session is saved, it will be removed from the saved sessions as well. .PARAMETER Id Session id. .PARAMETER Path The path where session data will be stored, defaults to $Script:ModuleDataPath. .LINK Save-APNSession Remove-APNSession .INPUTS PSObject. Get-APNSession .OUTPUTS None. Does not supply output. .EXAMPLE Deletes AP session with the id of '2'. Remove-APNSession -Id 2 .EXAMPLE Deletes all AP sessions in memory and stored on disk. Remove-APNSession #> [CmdletBinding()] Param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [int] $Id, [Parameter()] [string] $Path = $Script:ModuleDataPath ) Process { $sessions = Get-APNSession -Id $Id Foreach ($session in $sessions) { If ($session.Saved -eq $true) { $newData = @{SessionData = @() } $data = Get-Content -Path $Path -Raw | ConvertFrom-Json Foreach ($_data in $data.SessionData) { If ($_data.Id -eq $session.Id) { Continue } else { $newData.SessionData += $_data } } $newData | ConvertTo-Json -Depth 5 | Out-File -FilePath $Path } [array] $Global:_APNSessions = $Global:_APNSessions | Where-Object { $PSItem.Id -ne $session.Id } } } } # Save-APNSession.ps1 Function Save-APNSession { <# .SYNOPSIS Saves an Appian session to disk. .DESCRIPTION Saves an Appian session to disk. The sensetive data is encrypted and stored in the users local application data. These saved sessions will be available next time the module is imported. .PARAMETER Session Appian session, created by New-APNSession. .PARAMETER Path The path where session data will be stored, defaults to $Script:ModuleDataPath. .PARAMETER PassThru Returns the saved session object. .INPUTS PSbject. Get-APNSession, New-APNSession .OUTPUTS None. Save-APNSession does not generate any output. .EXAMPLE Creates a session with the name of 'myFirstSession' and saves it to disk. $newAPNSession = @{ SessionName = 'myFirstSession' Domain = 'myAppianDomain.appiancloud.com' ApiKey = '********' } New-APNSession @newAPNSession | Save-APNSession #> [CmdletBinding()] Param ( [Parameter(Mandatory, ValueFromPipeline)] [object] $Session, [Parameter()] [string] $Path = $Script:ModuleDataPath ) Begin { If (-not(Test-Path $Path)) { $data = @{SessionData = @() } } else { $data = Get-Content -Path $Path -Raw | ConvertFrom-Json } } Process { If ($data.SessionData.Id -notcontains $session.Id) { $_object = @{ Domain = $session.Domain SessionName = $session.SessionName Id = $Session.Id Saved = $true } If ($Session.ApiKey) { $_object.ApiKey = ($Session.ApiKey | ConvertFrom-SecureString) } If ($Session.Credential) { $_credentialObject = @{ Username = $Session.Credential.UserName Password = ($Session.Credential.GetNetworkCredential().SecurePassword | ConvertFrom-SecureString) } $_object.Credential = $_credentialObject } If ($Session.Proxy) { $_object.Proxy = $Session.Proxy } If ($Session.ProxyCredential) { $_proxyCredentialObject = @{ Username = $Session.ProxyCredential.UserName Password = ($Session.ProxyCredential.GetNetworkCredential().SecurePassword | ConvertFrom-SecureString) } $_object.ProxyCredential = $_proxyCredentialObject } $data.SessionData += $_object $session | Remove-APNSession -Path $Path } } End { $data | ConvertTo-Json -Depth 5 | Out-File -FilePath $Path Write-Verbose "[$($MyInvocation.MyCommand.Name)]: [$SessionName]: Session data has been stored at [$Path]" } } # Update-APNSession.ps1 Function Update-APNSession { <# .SYNOPSIS Updates an Appian session. .DESCRIPTION Updates an Appian session. The sensetive data is encrypted and stored in the users local application data. These updated sessions are available immediately. If the session was previously saved is will remain saved. .PARAMETER SessionName The friendly name of the session. .PARAMETER Domain The Appian site domain. Example 'mydomain.appiancloud.com' .PARAMETER ApiKey The Appian api key. The API key can be created in the Appian Administration Console, and then configured to secure external inspections. .PARAMETER Credential Specifies a user account that has permission to the project. .PARAMETER Proxy Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server. .PARAMETER ProxyCredential Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user. .PARAMETER Path The path where module data will be stored, defaults to $Script:ModuleDataPath. .INPUTS PSbject. Get-APNSession, New-APNSession .OUTPUTS None. Update-APNSession does not generate any output. .EXAMPLE Updates the Appian session named 'myFirstSession'. Update-APNSession -SessionName 'myFirstSession' -ApiKey '*******' #> [CmdletBinding(DefaultParameterSetName = 'ByApiKey')] Param ( [Parameter(Mandatory)] [string] $SessionName, [Parameter()] [string] $Domain, [Parameter(ParameterSetName = 'ByApiKey')] [string] $ApiKey, [Parameter(ParameterSetName = 'ByCredential')] [pscredential] $Credential, [Parameter()] [string] $Proxy, [Parameter()] [pscredential] $ProxyCredential, [Parameter()] [string] $Path = $Script:ModuleDataPath ) Begin { } Process { $getAPSessionSplat = @{ SessionName = $SessionName } If ($Id) { $getAPSessionSplat.Id = $Id } $existingSessions = Get-APNSession @getAPSessionSplat If ($existingSessions) { Foreach ($existingSession in $existingSessions) { $newAPSessionSplat = @{ SessionName = $SessionName } If ($Domain) { $newAPSessionSplat.Domain = $Domain } else { If ($existingSession.Domain) { $newAPSessionSplat.Domain = $existingSession.Domain } } If ($ApiKey) { $newAPSessionSplat.ApiKey = $ApiKey } else { If ($existingSession.ApiKey) { $newAPSessionSplat.ApiKey = $existingSession.ApiKey } } If ($Credential) { $_credentialObject = @{ Username = $Session.Credential.UserName Password = ($Session.Credential.GetNetworkCredential().SecurePassword | ConvertFrom-SecureString) } $newAPSessionSplat.Credential = $_credentialObject } else { If ($existingSession.Credential) { $newAPSessionSplat.Credential = $existingSession.Credential } } If ($Proxy) { $newAPSessionSplat.Proxy = $Session.Proxy } else { If ($existingSession.Proxy) { $newAPSessionSplat.Proxy = $existingSession.Proxy } } If ($ProxyCredential) { $_proxyCredentialObject = @{ Username = $Session.ProxyCredential.UserName Password = ($Session.ProxyCredential.GetNetworkCredential().SecurePassword | ConvertFrom-SecureString) } $newAPSessionSplat.ProxyCredential = $_proxyCredentialObject } else { If ($existingSession.ProxyCredential) { $newAPSessionSplat.ProxyCredential = $existingSession.ProxyCredential } } If ($existingSession.Saved) { $existingSession | Remove-APNSession -Path $Path $session = New-APNSession @newAPSessionSplat | Save-APNSession } else { $existingSession | Remove-APNSession -Path $Path $session = New-APNSession @newAPSessionSplat } } } else { Write-Error "[$($MyInvocation.MyCommand.Name)]: Unable to locate an AP session with the name [$SessionName]." -ErrorAction Stop } } End { } } # Imported from [D:\a\1\s\AppianPS\Tests] |