lib/Projects.ps1
## Projects <# .SYNOPSIS Gets the projects from a TM instance. .DESCRIPTION The `Get-TMProject` function gets projects from a TM instance specified in a TMSession object. By default it calls the REST endpoint of a TM server. A value of "$false" can be passed to the -UseAPI parameter to call the Web Service endpoint instead. .PARAMETER TMSession Specifies the name of the TMSession whose projects will be fetched. .PARAMETER CurrentProject Gets the TMSession.UserContext.Project property of a TMSession object and returns a corresponding TMProject object. .PARAMETER UseAPI If a value of $false is passed to this parameter, the function uses web service calls to get the project data. NOTE:Currently, the REST Endpoint and the Web Services endpoint return different set of properties. For more information check the TMProject class source code. .PARAMETER Project Gets a project where the Project Name or Project Code matches the specified value. .PARAMETER ResetIDs .NOTES An existing TMSession needs to be created before Get-TMProject can be used. .INPUTS You can pipe a TMSession object or a string with the name of an existing TMSession. .OUTPUTS [TMProject] This function outputs a TMProject class object. .EXAMPLE Get the current project, as specified in the TMSession.UserContext.Project property of the TMSession Get-TM-Project -Current .EXAMPLE Get a list of projects from a TMSession named 'Default' Get-TMProject -TMSession 'Default' .EXAMPLE Get a list of projects from a TMSession named 'Default', using web service calls instead of a REST endpoint. Get-TMProject -TMSession 'Default' #> Function Get-TMProject { [CmdletBinding()] param( [Parameter(Mandatory = $false)][String]$TMSession = "Default", [Alias("Current")][Parameter(Mandatory = $false)][Switch]$CurrentProject, [Parameter(Mandatory = $false)][Bool]$UseAPI = $true, [Alias("Name", "ProjectCode", "ProjectName")][Parameter(Mandatory = $false, Position = 0)][String]$Project, [Parameter(Mandatory = $false)][String]$Server = $global:TMSessions[$TMSession].TMServer, [Parameter(Mandatory = $false)]$AllowInsecureSSL = $global:TMSessions[$TMSession].AllowInsecureSSL, [Parameter(Mandatory = $false)][Switch]$ResetIDs ) begin { $PSBoundParameters.Remove("UseWebServices") | Out-Null } process { try { if ($UseAPI) { Get-TMProjectRestApi @PSBoundParameters } else { Get-TMProjectWebService @PSBoundParameters } } catch { throw $_ } } end { } } Function Enter-TMProject { param( [Parameter(Mandatory = $false)][String]$TMSession = "Default", [Parameter(Mandatory = $false, ParameterSetName = "ByProjectId", Position = 0)][Int]$ProjectID, [Alias("Project")][Parameter( Mandatory = $false, HelpMessage = 'Enter the Project Name or Project Code', ParameterSetName = "ByProjectNameOrCode", Position = 0)][String]$ProjectNameOrCode ) ## Get Session Configuration $TMSessionConfig = $global:TMSessions[$TMSession] if (-not $TMSessionConfig) { Write-Host 'TMSession: [' -NoNewline Write-Host $TMSession -ForegroundColor Cyan Write-Host '] was not Found. Please use the New-TMSession command.' Throw "TM Session Not Found. Use New-TMSession command before using features." } #Honor SSL Settings if ($TMSessionConfig.AllowInsecureSSL) { $TMCertSettings = @{SkipCertificateCheck = $true } } else { $TMCertSettings = @{SkipCertificateCheck = $false } } ## If either the Project ID or Project Code were known, they could be used. However, support for changing based just on the project name is possible if (-not $ProjectID) { ## Get the Project by Name or Code $Project = Get-TMProject -Project $ProjectNameOrCode -TMSession $TMSession $ProjectID = $Project.id if (!$ProjectID) { throw "Project [" + $ProjectNameOrCode + "] does not exist. Please create it and run the script again." } } ## 4.4, 4.5, 4.6 if ($global:TMSessions[$TMSession].TMVersion -in @('4.4.3', '4.5.9' , '4.6.3') ) { $uri = "https://" $uri += $TMSessionConfig.TMServer $uri += '/tdstm/project/addUserPreference/' + $ProjectID } ## 4.7.0+ else { $uri = "https://" $uri += $TMSessionConfig.TMServer $uri += '/tdstm/ws/project/viewEditProject/' + $ProjectID } try { $response = Invoke-WebRequest -Method Get -Uri $uri -WebSession $TMSessionConfig.TMWebSession @TMCertSettings } catch { return $_ } if ($response.StatusCode -in @(200, 204)) { $newProject = ($Response.Content | ConvertFrom-Json).data.projectInstance $global:TMSessions[$TMSession].UserContext.project.id = $newProject.id $global:TMSessions[$TMSession].UserContext.project.name = $newProject.name ## The code property has not been consistent in builds between 4.7 -> 6.0-alpha. Simply force it Add-Member -InputObject $global:TMSessions[$TMSession].UserContext.Project -NotePropertyName 'code' -NotePropertyValue $newProject.projectCode -Force if ($VerbosePreference -eq 'Continue') { Write-Host 'Project has been changed to: ' -NoNewline Write-Host $ProjectName -ForegroundColor Cyan } } else { throw "Unable to Set Projects." } } Function New-TMProject { param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [String]$Company, [Parameter(Mandatory = $false)] [ValidateLength(1, 20)] [String]$Code, [Parameter(Mandatory = $false)] [String]$TMSession = "Default", [Parameter(Mandatory = $false)] [String]$Server = $global:TMSessions[$TMSession].TMServer, [Parameter(Mandatory = $false)] $AllowInsecureSSL = $global:TMSessions[$TMSession].AllowInsecureSSL, [Parameter(Mandatory = $false)] [DateTime]$StartDate, [Parameter(Mandatory = $false)] [DateTime]$EndDate, [Parameter(Mandatory = $false)] [Switch]$Passthru ) ## Get Session Configuration $TMSessionConfig = $global:TMSessions[$TMSession] if (-not $TMSessionConfig) { Write-Host 'TMSession: [' -NoNewline Write-Host $TMSession -ForegroundColor Cyan Write-Host '] was not Found. Please use the New-TMSession command.' throw "TM Session Not Found. Use New-TMSession command before using features." } #Honor SSL Settings $TMCertSettings = @{ SkipCertificateCheck = $TMSessionConfig.AllowInsecureSSL } # Check if the project already exists $ExistingProject = Get-TMProject -Name $Name -TMSession $TMSession if ($ExistingProject) { if ($Passthru) { return $ExistingProject } else { return } } # Make sure the Provider exists $Client = Get-TMCompany -Name $Company -TMSession $TMSession if (!$Client) { throw "The company '$Company' does not exist." } $instance = $Server.Replace('/tdstm', '').Replace('https://', '').Replace('http://', '') $uri = "https://$instance/tdstm/ws/project/saveProject/" Set-TMHeaderContentType -ContentType 'JSON' -TMSession $TMSession if (!$StartDate) { $StartDate = (Get-Date -AsUTC).ToString('yyyy-MM-ddTHH:mm:ssZ') } if (!$EndDate) { $EndDate = (Get-Date -AsUTC).AddDays(365).ToString('yyyy-MM-ddTHH:mm:ssZ') } if (!$Code) { $FormattedCode = $Name.Trim().Replace(' - ', '-').Replace('- ', '-').Replace(' ', '-') $Code = $FormattedCode.Length -gt 20 ? $FormattedCode.Substring(0, 20) : $FormattedCode } # Format the body of the request $Project = [PSCustomObject]@{ clientId = $Client.id startDate = $StartDate completionDate = $EndDate projectCode = $Code defaultBundleName = "TBD" description = "" collectMetrics = $true timeZone = "GMT" projectManagerId = 0 comment = "" projectType = "Standard" } # Format the name property based on the TM version $NameKey = $Global:TMSessions[$TMSession].TMVersion -like '4.*' ? 'projectName' : 'name' $Project | Add-Member -Name $NameKey -Value $Name -MemberType NoteProperty $PostJson = $Project | ConvertTo-Json try { $response = Invoke-WebRequest -Method Post -Uri $uri -WebSession $TMSessionConfig.TMWebSession -Body $PostJson @TMCertSettings } catch { return $_ } if ($response.StatusCode -in @(200, 204)) { if ($Passthru) { return (Get-TMProject -Name $Name -TMSession $TMSession) } } else { throw "Unable to create Project." } } function Get-TMProjectWebService { [CmdletBinding()] param ( [Parameter(Mandatory = $false)][String]$TMSession = "Default", [Alias("Name", "ProjectCode", "ProjectName")][Parameter(Mandatory = $false, Position = 0)][String]$Project, [Parameter(Mandatory = $false)][String]$Server = $global:TMSessions[$TMSession].TMServer, [Parameter(Mandatory = $false)]$AllowInsecureSSL = $global:TMSessions[$TMSession].AllowInsecureSSL, [Parameter(Mandatory = $false)][Switch]$ResetIDs ) begin { ## Get Session Configuration $TMSessionConfig = $global:TMSessions[$TMSession] if (-not $TMSessionConfig) { Write-Host 'TMSession: [' -NoNewline Write-Host $TMSession -ForegroundColor Cyan Write-Host '] was not Found. Please use the New-TMSession command.' Throw "TM Session Not Found. Use New-TMSession command before using features." } #Honor SSL Settings $TMCertSettings = @{SkipCertificateCheck = $TMSessionConfig.AllowInsecureSSL } # Format the uri $instance = $Server.Replace('/tdstm', '').Replace('https://', '').Replace('http://', '') $uri = "https://$instance/tdstm/ws/projects" } process { try { $response = Invoke-WebRequest -Method Get -Uri $uri -WebSession $TMSessionConfig.TMWebSession @TMCertSettings } catch { throw $_ } if ($response.StatusCode -in 200, 204) { $Results = ($response.Content | ConvertFrom-Json).data | ForEach-Object { [TMProject]::New($_) } } else { throw "Unable to collect Projects." } if ($ResetIDs) { ## Version 4.6.3 is legacy and has a different data structure. All forward versions are the same if ($global:TMSessions[$TMSession].TMVersion -eq '4.6.3') { ## Clear All projects (No nesting here) for ($i = 0; $i -lt $Results.Count; $i++) { $Results[$i].id = $null } # 4.7.1+ } else { ## Clear Active Projects for ($i = 0; $i -lt $Results.Count; $i++) { $Results[$i].id = $null } } } if ($Project) { $NameKey = $Global:TMSessions[$TMSession].TMVersion -like '4.*' ? 'projectName' : 'name' $CodeKey = "projectCode" $Results = $Results | Where-Object { $_.$NameKey -eq $Project -or $_.$CodeKey -eq $Project } } return $Results } end { } } function Get-TMProjectRestApi { [CmdletBinding()] param ( [Parameter(Mandatory = $false)][String]$TMSession = "Default", [Alias("Current")][Parameter(Mandatory = $false)][Switch]$CurrentProject, [Alias("Name", "ProjectCode", "ProjectName")][Parameter(Mandatory = $false, Position = 0)][String]$Project, [Parameter(Mandatory = $false)][Switch]$ResetIDs ) begin { ## Get Session Configuration $TMSessionConfig = $global:TMSessions[$TMSession] if (-not $TMSessionConfig) { Write-Host 'TMSession: [' -NoNewline Write-Host $TMSession -ForegroundColor Cyan Write-Host '] was not Found. Please use the New-TMSession command.' Throw "TM Session Not Found. Use New-TMSession command before using features." } # Format the uri $Instance = $TMSessionConfig.TMServer $RestParams = @{ SkipCertificateCheck = $TMSessionConfig.AllowInsecureSSL Headers = $TMSessionConfig.TMRestSession.Headers Uri = "https://$Instance/tdstm/api/project" Method = "Get" StatusCodeVariable = "ResponseStatusCode" } if ($CurrentProject) { $RestParams.Uri = $RestParams.Uri.Replace('project', "project/$($TMSessionConfig.userContext.Project.id)") } } process { try { $Response = Invoke-RestMethod @RestParams } catch { throw $_ } if ($ResponseStatusCode -in 200, 204) { $Results = $Response | ForEach-Object { [TMProject]::New($_) } } else { return "Unable to collect Projects." } if ($ResetIDs) { ## Version 4.6.3 is legacy and has a different data structure. All forward versions are the same if ($global:TMSessions[$TMSession].TMVersion -eq '4.6.3') { ## Clear All projects (No nesting here) for ($i = 0; $i -lt $Results.Count; $i++) { $Results[$i].id = $null } # 4.7.1+ } else { ## Clear Active Projects for ($i = 0; $i -lt $Results.Count; $i++) { $Results[$i].id = $null } } } if ($Project) { $NameKey = $Global:TMSessions[$TMSession].TMVersion -like '4.*' ? 'projectName' : 'name' $CodeKey = "projectCode" $Results = $Results | Where-Object { $_.$NameKey -eq $Project -or $_.$CodeKey -eq $Project } } return $Results } end { } } |