Public/Import-TMCActionRequest.ps1
Function Import-TMCActionRequest { param( [Parameter(Mandatory = $false)][String]$FromB64, [Parameter(Mandatory = $false)][String]$SerializedActionRequestObject, [Parameter(Mandatory = $false)][PSObject]$PSObjectActionRequest, [Parameter(Mandatory = $false)][String]$FromFile, [Parameter(Mandatory = $false)][Switch]$PassThru, [Parameter(Mandatory = $false)][Switch]$SkipProviderLoad ) if ($FromFile) { $ActionRequest = (Get-Content -Path $FromFile | ConvertFrom-Json) } elseif ($SerializedActionRequestObject) { $ActionRequest = [System.Management.Automation.PSSerializer]::Deserialize($SerializedActionRequestObject) } elseif ($PSObjectActionRequest) { $ActionRequest = $PSObjectActionRequest } elseif ($FromB64) { $ActionRequest = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($FromB64)) | ConvertFrom-Json } else { throw 'Unable to create Action Request Object.' } ## Make sure we created a new ActionRequest, ## use it as a container to populate the runspace with some variables if ($ActionRequest) { ## Create the TM Session Callback options for the Task Update functions $TMDCallbackOptions = @{ SiteURL = $ActionRequest.options.callback.siteUrl; BearerToken = $ActionRequest.options.callback.token; ProjectID = $ActionRequest.options.projectId; TaskID = $ActionRequest.task.id; } ## Handle Credential Creation for items passed from Credentials if ($null -ne $ActionRequest.options.credentials) { ## Extract the Username and and Encrypt the password $Username = $ActionRequest.options.credentials.username $EncryptedPassword = ConvertTo-SecureString $ActionRequest.options.credentials.password -AsPlainText -Force ## Remove the credentials object from the $ActionRequest $ActionRequest.options.credentials = $null ## Create a new Credential and assign it to the $Credential variable in the current scope (session) $PSCredential = New-Object System.Management.Automation.PSCredential ($Username, $EncryptedPassword) $ActionRequest | Add-Member -NotePropertyName 'PSCredential' -NotePropertyValue $PSCredential | Out-Null New-Variable -Name 'Credential' -Value $PSCredential -Force -Scope Global } ## Handle Credential Creation within any Parameters that defined a credential $suppliedCredentials = $ActionRequest.Params.PSObject.Properties | Where-Object { $_.Name -like 'supplied_credential_*' } ## Convert any 'supplied_credential_' objects into their appropriate PSObject format. if ($suppliedCredentials.count -gt 0) { $suppliedCredentials | ForEach-Object { $suppliedCredential = $_ ## Remove the credentials object from the parameter $ActionRequest.Params.PSObject.Properties.Remove($suppliedCredential.Name) ## Extract the Username and and Encrypt the password $Username = $suppliedCredential.value.username $EncryptedPassword = ConvertTo-SecureString $suppliedCredential.value.password -AsPlainText -Force $ConvertedCredential = New-Object System.Management.Automation.PSCredential ($Username, $EncryptedPassword) ## Add the converted credential to the Params $ActionRequest.Params | Add-Member -NotePropertyName ($suppliedCredential.Name -replace 'supplied_credential_', '' ) -NotePropertyValue $ConvertedCredential -Force } } ## Handle Credential Creation within any Parameters that defined a credential $storedCredentials = $ActionRequest.Params.PSObject.Properties | Where-Object { $_.Name -like 'use_storedcredential_*' } ## Retrieve any 'use_stored_credential_' objects from local storage into their appropriate PSObject format. if ($storedCredentials.count -gt 0) { $storedCredentials | ForEach-Object { $storedCredential = $_ ## Remove the credentials object from the parameter $ActionRequest.Params.PSObject.Properties.Remove($storedCredential.Name) $RetrievedCredential = Get-StoredCredential -CredentialName $storedCredential.Value ## Add the converted credential to the Params $ActionRequest.Params | Add-Member -NotePropertyName ($storedCredential.Name -replace 'use_storedcredential_', '' ) -NotePropertyValue $RetrievedCredential -Force } } ## Remove any leftover 'get_' parameter names $ActionRequest.Params.PSObject.Properties.Name | Where-Object { $_ -like 'get_*' } | ForEach-Object { $ActionRequest.Params.PSObject.Properties.Remove($_) } ## Allow Required Modules to be imported automatically $PSModuleAutoloadingPreference = 'All' $Global:PSModuleAutoloadingPreference = 'All' ## Import the remaining Variables New-Variable -Name 'ActionRequest' -Value $ActionRequest -Force -Scope Global New-Variable -Name 'Params' -Value $ActionRequest.Params -Force -Scope Global New-Variable -Name 'TMDCallbackOptions' -Value $TMDCallbackOptions -Force -Scope Global ## If we have any params with spaces in their name, copy them with a no-spaces name foreach ($property in $Params.PSObject.properties | Where-Object Name -Like "* *") { $Params | Add-Member -MemberType NoteProperty -Name ($property.Name -replace ' ') -Value $Params.($property.Name) } ## Compute a Project root folder from the Server, Project and Event $TMServerUrl = ([uri]$ActionRequest.Options.Callback.SiteUrl).Host $TMProjectName = $ActionRequest.Task.Project.Name $TMEventName = $ActionRequest.task.event.name $ProjectRootFolder = Join-Path -Path $Global:userPaths.root -ChildPath ($TMServerUrl -replace '.transitionmanager.net', '') -AdditionalChildPath $TMProjectName, $TMEventName ## Create a Convenient TM Object with useful details $TM = [pscustomobject]@{ Server = @{ Url = $TMServerUrl Version = [Version]::parse(($ActionRequest.tmUserSession.tmVersion -split '-')[0]) } Project = @{ Id = $ActionRequest.task.project.id Name = $TMProjectName } Event = [pscustomobject]@{ Id = $ActionRequest.task.event.id Name = $TMEventName Bundles = $ActionRequest.task.event.bundles } Provider = @{ Id = $ActionRequest.options.apiAction.provider.id Name = $ActionRequest.options.apiAction.provider.name } Action = @{ Id = $ActionRequest.options.apiAction.id Name = $ActionRequest.options.apiAction.name } Task = [pscustomobject]@{ Id = $ActionRequest.task.id Title = $ActionRequest.task.title TaskNumber = $ActionRequest.task.taskNumber Invoker = $ActionRequest.task.assignedTo.name Team = $ActionRequest.task.team } Asset = $ActionRequest.task.asset User = @{ Id = $ActionRequest.tmUserSession.userContext.user.id Username = $ActionRequest.tmUserSession.userContext.user.username Name = $ActionRequest.tmUserSession.userContext.person.fullName } Paths = @{ debug = Join-Path $ProjectRootFolder "Debug" logs = Join-Path $ProjectRootFolder "Logs" queue = Join-Path $ProjectRootFolder "Queue" config = Join-Path $ProjectRootFolder "Config" input = Join-Path $ProjectRootFolder "Input" output = Join-Path $ProjectRootFolder "Output" credentials = Join-Path $ProjectRootFolder "Credentials" git = Join-Path $ProjectRootFolder "Git" referencedesigns = Join-Path $ProjectRootFolder "Reference Designs" } } ## Scope the variable as global so the user will have access to it New-Variable -Name 'TM' -Value $TM -Scope Global -Force # Add a variable New-Variable -Name 'TMCRunningAction' -Value $true -Scope Global -Force ## Add a 'Default' TMSession Write-Verbose 'Creating TMSession created for the TMConsole User Context' $NewSession = [TMSession]::new($ActionRequest) $Global:TMSessions.Default = $NewSession } else { ## The result of the script didn't produce an ActionRequest object throw 'Unable to create an $ActionRequest object' } if ($PassThru) { $ActionRequest } } |