pscodebeamer.psm1
class CBQL : System.Management.Automation.IValidateSetValuesGenerator { [String[]] GetValidValues() { $serverListWithLogPath = Join-Path -Path $env:appDATA -ChildPath \pscodebeamer\config.json $request = ([System.IO.File]::ReadAllText($serverListWithLogPath) | ConvertFrom-Json).CBQLQuery return $request } } function New-CBSession { <# .SYNOPSIS Creates a new session variable with the specified server using provided credentials which can be used acrossed other PSCodebeamer Fuctions .DESCRIPTION The `New-CBSession` function creates a Variable necessary for interacting with the specified server. By using the credentials provided (or prompting for them if not specified), it constructs an authorization header and other session-specific information required for subsequent requests to the server. Common use cases for this function include preparing session details for REST API requests or for applications requiring user authentication. .NOTES - This function is designed for environments where Basic Authentication over HTTPS is supported. Ensure your server is configured to handle authentication securely. - This function may not work on non-Windows environments due to differences in handling credentials and HTTP headers. - The function assumes the server requires JSON content-type for requests .EXAMPLE Value of -Server Parameter: if your company uses 'https://yourcompanydomain/cb/api/v3/users/groups PS> $session = New-CBSession -Server "yourcompanydomain" -Credential (Get-Credential) Result: Creates a session object with headers including Basic Authorization for use in API requests. .EXAMPLE PS> $session = New-CBSession -Server "yourcompanydomain" Explanation: Prompts for credentials if not provided and returns the session object configured for interactions with the specified server. .OUTPUTS pscustomobject #> [CmdletBinding()] param ( [Parameter(Mandatory)] [string]$Server, [Parameter(ValueFromPipeline)] [pscredential]$Credential ) $cred = if ($Credential) { $Credential } else { Get-Credential -Message "Please Enter Credentials for $Server" } $pass = $cred.GetNetworkCredential().Password $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $cred.UserName, $pass))) $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $headers.Add('Authorization', ('Basic {0}' -f $base64AuthInfo)) $headers.Add('content-type', 'application/json') try { $uri = "https://{0}/cb/api/v3/projects" -f $server Write-Debug "uri: $uri" Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ErrorAction Stop -SessionVariable codebeamerSession | Out-Null $codebeamerSession | Add-Member -NotePropertyName Server -NotePropertyValue $Server Write-Output -InputObject $codebeamerSession } catch { $fullError = $_ switch -Wildcard ($_.ErrorDetails.Message) { "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.." { Write-Error "Test Connection to Server failed. Please recheck your server parameter value: $Server" ; break } "*Not authenticated*" { Write-Error "Test Connection to Server: $server failed. User or Password is incorrect." ; break } default { Write-Error $fullError } } } } function Get-CBProject { <# .SYNOPSIS Retrieves project details from a CodeBeamer server, including optional Project details and tracker list if a ProjectID is specified. .DESCRIPTION The Get-CBProject function is designed to interact with a CodeBeamer server's API to fetch information about projects. You can specify a particular project by providing its ProjectID to retrieve detailed information about that specific project, including its trackers. If no ProjectID is supplied, the function returns a list of all available projects. .PARAMETER ProjectID An optional parameter that specifies the identifier for a particular project you want to fetch from the CB server. If omitted, the function retrieves all available projects. .PARAMETER CBSession A mandatory parameter, which is an alias `cbs`, representing the session object required for connection to the CB server. This must include server information and necessary headers for authentication. .INPUTS None. .OUTPUTS PSCustomObject. Returns the project details. If a ProjectID is specified, the output also includes trackers associated with the project. .EXAMPLE PS> Get-CBProject -CBSession $session .EXAMPLE PS> Get-CBProject -ProjectID '12345' -CBSession $session .NOTES Ensure that the CBSession object is valid, and the server and headers are correctly populated to authenticate against the CB API. This function uses Invoke-RestMethod, so make sure your environment is configured to allow outbound HTTP requests. .LINK More information about API Endpoint: https://codebeamer.com/cb/wiki/11375774#section-Getting+the+list+of+available+projects #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline, Position = 0)] [string]$ProjectID, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) process { try { switch ($ProjectID) { { -not ([string]::IsNullOrEmpty($_)) } { $uri = "https://{0}/cb/api/v3/projects/{1}" -f $CBSession.Server, $_ $uriProjectTrakcers = "https://{0}/cb/api/v3/projects/{1}/trackers" -f $CBSession.Server, $_ Write-Debug $uri Write-Debug $uriProjectTrakcers $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop $projectTracker = Invoke-RestMethod -Uri $uriProjectTrakcers -Method Get -Headers $CBSession.headers -ErrorAction Stop $result | Add-Member -NotePropertyName Trackers -NotePropertyValue $projectTracker Write-Output $result ; break } { [string]::IsNullOrEmpty($_) } { $uri = "https://{0}/cb/api/v3/projects" -f $CBSession.Server Write-Debug $uri $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop Write-Output $result ; break } } } catch { switch -Wildcard ($_.ErrorDetails.Message) { "*Project is not found*" { Write-Error "Project with ID: $ProjectID does not exist on Server: $($CBSession.Server). Please Recheck Project ID" } default { Write-Error $_ } } } } } function Get-CBProjectTrackerList { <# .SYNOPSIS Retrieves the list of trackers for a specified project from a CB server. .DESCRIPTION The Get-CBProjectTrackerList function interacts with the CB server's API to fetch all trackers associated with a specific project. You must specify the ProjectID of the project whose trackers you wish to retrieve. .PARAMETER ProjectID The identifier for the specific project from which to retrieve trackers. This is a mandatory parameter. .PARAMETER CBSession A mandatory parameter that serves as an alias `cbs`, representing the session object required for connection to the CB server. This must include server information and necessary headers for authentication. .OUTPUTS System.Array. Returns a list of trackers associated with the specified project. .EXAMPLE Example 1: Retrieve trackers for a specific project PS> Get-CBProjectTrackerList -ProjectID '12345' -CBSession $session id name type -- ---- ---- 3346 Change Requests Tracker TrackerReference 3348 Change Requests TrackerReference 3348 Release TrackerReference 3349 Releases TrackerReference 3354 Receive TrackerReference .NOTES Ensure that the CBSession object is valid, and the server and headers are correctly populated to authenticate against the CB API. This function uses Invoke-RestMethod, so make sure your environment is configured to allow outbound HTTP requests. .LINK More information about API Endpoint: https://codebeamer.com/cb/wiki/11375774#section-Getting+the+list+of+trackers+in+a+specific+project #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline, Position = 0)] [string]$ProjectID, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) process { try { $uri = "https://{0}/cb/api/v3/projects/{1}/trackers" -f $CBSession.Server, $ProjectID Write-Debug $uri $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop Write-Output $result } catch { switch -Wildcard ($_.ErrorDetails.Message) { "*Project is not found*" { Write-Error "Project with ID: $ProjectID does not exist on Server: $($CBSession.Server). Please Recheck Project ID" } default { Write-Error $_ } } } } } function Get-CBProjectMemberList { <# .SYNOPSIS Retrieves the list of members for a specified project from a CodeBeamer server, with pagination options. .DESCRIPTION The Get-CBProjectMemberList function interacts with the CodeBeamer server's API to fetch all members associated with a specific project. It provides options for pagination through the Page and Size parameters. .PARAMETER ProjectID The identifier for the specific project from which to retrieve members. This is a mandatory parameter. .PARAMETER CBSession A mandatory parameter, which is an alias `cbs`, representing the session object required for connection to the CB server. This must include server information and necessary headers for authentication. .PARAMETER Page Optional parameter that sets the page number for pagination. Defaults to page 1. .PARAMETER Size Optional parameter that sets the size of the page for pagination. Defaults to a maximum of 500 members per page and accepts values between 1 and 500. .INPUTS None. .OUTPUTS PSCustomObject. Returns a list of members associated with the specified project. .EXAMPLE PS> Get-CBProjectMemberList -ProjectID '12345' -CBSession $session .EXAMPLE PS> Get-CBProjectMemberList -ProjectID '12345' -CBSession $session -InformationAction Continue Command Information: "Page: 1, Page Size: 500, Total: 18, Project ID: 3" id name type -- ---- ---- 1 user1 UserReference 6 user2 UserReference 7 user3 UserReference 8 user4 UserReference 9 user5 UserReference .NOTES Ensure that the CBSession object is valid, and the server and headers are correctly populated to authenticate against the CB API. This function uses Invoke-RestMethod, so make sure your environment is configured to allow outbound HTTP requests. #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline, Position = 0)] [int]$ProjectID, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession, [Parameter()] [int]$Page = 1, [Parameter()] [ValidateRange(1, 500)] [int]$Size = 500 ) process { try { $uri = "https://{0}/cb/api/v3/projects/{1}/members?page={2}&pageSize={3}" -f $CBSession.Server, $ProjectID, $Page, $Size Write-Debug "Uri: $uri" $result = Invoke-RestMethod -uri $uri -Headers $CBSession.headers Write-Output $result.members $messageData = @" Command Information: "Page: $($result.page), Page Size: $($result.pageSize), Total: $($result.total), Project ID: $ProjectID" "@ Write-Information -MessageData $messageData } catch { switch -Wildcard ($_.ErrorDetails.Message) { "*Project is not found*" { Write-Error "Project with ID: $ProjectID does not exist on Server: $($CBSession.Server). Please Recheck Project ID" } default { Write-Error $_ } } } } } function Get-CBTrackerOutline { <# .SYNOPSIS Retrieves the outline (hierarchical structure) of items in a tracker from the Codebeamer server. .DESCRIPTION The `Get-CBTrackerOutline` function fetches the outline of items for a specified tracker. You can filter by parent item, depth. This is useful for visualizing or processing the hierarchical structure of tracker items. .PARAMETER TrackerID The ID of the tracker whose outline you want to retrieve. This parameter is mandatory. .PARAMETER ParentItemID (Optional) The ID of the parent item to start the outline from. If not specified, the outline starts from the root. .PARAMETER DepthFilter (Optional) Limits the depth of the outline returned. .PARAMETER CBSession The session object containing server URL and headers. This parameter is mandatory and can be accessed using the alias 'cbs'. .EXAMPLE Get-CBTrackerOutline -TrackerID 12345 -CBSession $cbSession Retrieves the full outline for tracker ID 12345. .EXAMPLE Get-CBTrackerOutline -TrackerID 12345 -ParentItemID 67890 -DepthFilter 2 -CBSession $cbSession Retrieves the outline for tracker ID 12345, starting from parent item 67890, limited to 2 levels deep. .NOTES - Returns the outline structure as provided by the Codebeamer REST API. - Handles errors for invalid tracker IDs or inaccessible items. #> [CmdletBinding()] param ( [Parameter(Mandatory, Position = 0)] [int]$TrackerID, [Parameter(Position = 1)] [int]$ParentItemID, [Parameter()] [int]$DepthFilter, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) try { $uri = switch ($true) { { $PSBoundParameters.ContainsKey('ParentItemID') -and (-not $PSBoundParameters.ContainsKey('DepthFilter')) } { "https://{0}/cb/api/v3/trackers/{1}/outline?parentItemId={2}" -f $CBSession.Server, $TrackerID, $ParentItemID } { $PSBoundParameters.ContainsKey('ParentItemID') -and $PSBoundParameters.ContainsKey('DepthFilter') } { "https://{0}/cb/api/v3/trackers/{1}/outline?parentItemId={2}&resultDepthFilter={3}" -f $CBSession.Server, $TrackerID, $ParentItemID, $DepthFilter } { $PSBoundParameters.ContainsKey('TrackerID') -and $PSBoundParameters.ContainsKey('DepthFilter') -and (-not $PSBoundParameters.ContainsKey('ParentItemID')) } { "https://{0}/cb/api/v3/trackers/{1}/outline?resultDepthFilter={2}" -f $CBSession.Server, $TrackerID, $DepthFilter } Default { "https://{0}/cb/api/v3/trackers/{1}/outline" -f $CBSession.Server, $TrackerID } } Write-Debug "uri: $uri" $result = Invoke-RestMethod -uri $uri -Headers $CBSession.headers -Method Get Write-Output $result } catch { $fullError = $_ switch -Wildcard ($_.ErrorDetails.Message) { "*Tracker is not found.*" { Write-Error "Tracker ID: $TrackerID most likely doesn't exist. Please recheck Tracker ID or Server." } "*Not accessible tracker item ids*" { $message = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message Write-Error -Message $message } Default { Write-Error $fullError } } } } function Get-CBTrackerChild { <# .SYNOPSIS Retrieves child items for a specified tracker in a Codebeamer Server. .DESCRIPTION The `Get-CBTrackerChild` function fetches items associated with a specific tracker ID in the Codebeamer Server. Results are paged, allowing control over the amount of data returned at once. .PARAMETER TrackerID The unique identifier of the tracker whose child items are to be retrieved. This parameter is mandatory and accepts input from the pipeline. .PARAMETER Page Specifies the page number to retrieve from the query results. Defaults to the first page (i.e., 1). This parameter is optional. .PARAMETER Size Determines the number of items per page to retrieve. The default value is 500, accommodating efficient data retrieval. This parameter is optional. .PARAMETER CBSession Represents the CB Session object containing necessary connection details such as server URL and headers. This session enables authentication and interaction with the CB API. It is mandatory and accessible via the alias 'cbs'. .EXAMPLE Get-CBTrackerChild -TrackerID 12344 -CBSession $cbSession This example fetches child items linked to the specified tracker ID on the server Codebeamer Server, starting from the first page with a default page size. .NOTES - The function outputs child item references retrieved from the tracker. - Error handling incorporates specific checks for tracker availability, enhancing reliability in usage. - Information messages provide details about the request's results and context. #> [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline, Position = 0)] [string]$TrackerID, [Parameter()] [int]$Page = 1, [Parameter()] [int]$Size = 500, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) process { try { $uri = "https://{0}/cb/api/v3/trackers/{1}/items?page={2}&pageSize={3}" -f $CBSession.Server, $TrackerID, $Page, $Size $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers $result.itemRefs $messageData = @" Command Information: "Page: $($result.page), Page Size: $($result.pageSize), Total: $($result.total), Tricker Item ID: $($TrackerID)" "@ Write-Information -MessageData $messageData } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Tracker is not found.*" } { Write-Error "Tracker ID: $TrackerID most likely doesn't exist. Please recheck Tracker ID or Server." } Default { Write-Error $fullError } } } } } function Get-CBItem { <# .SYNOPSIS Retrieves configuration item details from a specified server using various parameter sets. .DESCRIPTION The `Get-CBItem` function fetches details of a configuration item from Codebeamer using different parameter sets: DefaultSet, BaseLine, or Version. Each set retrieves data based on distinct criteria using corresponding API calls. .PARAMETER ItemID Specifies the unique identifier of the item to be fetched. This parameter is required and must be provided from the pipeline. .PARAMETER CBSession Specifies the session object containing details like server URL and headers. This parameter is mandatory for all parameter sets. .PARAMETER BaselineID Specifies the baseline identifier for fetching item details in the BaseLine parameter set. This parameter is optional and only used in the BaseLine set. .PARAMETER Version Specifies the version of the item to retrieve in the Version parameter set. This parameter is optional and only used in the Version set. .PARAMETERSET DefaultSet Fetches details of the item using its ItemID without any additional filter criteria. .PARAMETERSET BaseLine Fetches item details using ItemID and filters based on the provided BaselineID. .PARAMETERSET Version Fetches item information using ItemID and filters based on the specified Version. .EXAMPLE Get-CBItem -ItemID "12345" -CBSession $session Fetches details of item with ID 12345 using the DefaultSet parameter set. .EXAMPLE Get-CBItem -ItemID "12345" -CBSession $session -BaselineID 123 Retrieves details of item 12345 using the BaseLine set with BaselineID `123`. .EXAMPLE Get-CBItem -ItemID "12345" -CBSession $session -Version 1 Fetches the version-specific details of item 12345 using Version set with version `1`. .EXAMPLE 123,343,456 | Get-CBItem -CBSession $session -Version 1 | Select-Object id,typename,status id typeName status -- -------- ------ 123 Requirement @{id=1; name=New; type=ChoiceOptionReference} 343 Requirement @{id=1; name=In Progress; type=ChoiceOptionReference} 456 Requirement @{id=1; name=New; type=ChoiceOptionReference} .NOTES - Ensure that `$CBSession` contains correct server and headers data. - Debug messages indicate the process flow and constructed URIs. - Errors are handled to provide specific feedback based on the error conditions encountered. #> [CmdletBinding(DefaultParameterSetName = 'DefaultSet')] param ( [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = 'DefaultSet')] [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = 'BaseLine')] [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = 'Version')] [int]$ItemID, [Parameter(Mandatory, ParameterSetName = 'DefaultSet')] [Parameter(Mandatory, ParameterSetName = 'BaseLine')] [Parameter(Mandatory, ParameterSetName = 'Version')] [Alias("cbs")] [pscustomobject]$CBSession, [Parameter(ParameterSetName = 'BaseLine')] [int]$BaselineID, [Parameter(ParameterSetName = 'Version')] [int]$Version ) process { foreach ($header in $CBSession.headers.getEnumerator() ) { Write-Debug "Key: $($header.Key) Value: $($header.Value)" } try { switch ($PSCmdlet.ParameterSetName) { "DefaultSet" { $uri = "https://{0}/cb/api/v3/items/{1}" -f $CBSession.Server, $ItemID Write-Debug "uri: $uri" Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop ; break } "BaseLine" { $uriBaseline = "https://{0}/cb/api/v3/items/{1}?baselineId={2}" -f $CBSession.Server, $ItemID, $BaselineID Write-Debug "uri: $uriBaseline" Invoke-RestMethod -Uri $uriBaseline -Method Get -Headers $CBSession.headers -ErrorAction Stop ; break } "Version" { $uriVersion = "https://{0}/cb/api/v3/items/{1}?version={2}" -f $CBSession.Server, $ItemID, $Version Write-Debug "uri: $uriVersion" Invoke-RestMethod -Uri $uriVersion -Method Get -Headers $CBSession.headers -ErrorAction Stop ; break } } } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Tracker item is not found.*" -and $PSCmdlet.ParameterSetName -eq "Version" } { Write-Error "Version: $Version of Item $itemID most likely doesn't exist. Please recheck Version." } { $_ -like "*BaseLine*" } { Write-Error "BaseLineID: $BaselineID of Item $itemID most likely doesn't exist. Please recheck BaseLine." } Default { Write-Error $fullError } } } } } function Get-CBTrackerTransition { <# .SYNOPSIS Retrieves the transition details of a specified tracker from a CB server. .DESCRIPTION The Get-CBTrackerTransition function is designed to interact with a CB server's API to fetch transition information associated with a specific tracker. The transitions provide details on the status changes within the tracker. .PARAMETER TrackerID The identifier for the specific tracker whose transition details are to be retrieved. This is a mandatory parameter. .PARAMETER CBSession A mandatory parameter, which is an alias `cbs`, representing the session object required for connection to the CB server. This must include server information and necessary headers for authentication. .INPUTS None. .OUTPUTS PSCustomObject. Returns transition details associated with the specified tracker. .EXAMPLE Example: Retrieve transition details for a specific tracker Get-CBTrackerTransition -TrackerID 67890 -CBSession $session .NOTES Ensure that the CBSession object is valid, and the server and headers are correctly populated to authenticate against the CB API. This function uses Invoke-RestMethod, so make sure your environment is configured to allow outbound HTTP requests. #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline, Position = 0)] [int]$TrackerID, [Parameter(Mandatory)] [Alias("cbs")] [pscustomobject]$CBSession ) process { try { $uri = "https://{0}/cb/api/v3/trackers/{1}/transitions" -f $CBSession.Server, $TrackerID Write-Debug "uri: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -errorAction Stop Write-Output $result } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Tracker is not found*" } { Write-Error "Tracker ID: $TrackerID most likely doesn't exist. Please recheck Tracker ID or Server." } Default { Write-Error $fullError } } } } } function Get-CbTrackerSchema { <# .SYNOPSIS Retrieves the schema for a specified tracker in the Codebeamer Server. .DESCRIPTION The `Get-CbTrackerSchema` function is designed to obtain the schema associated with a particular tracker ID in the Codebeamer Server. The schema provides structural details of the tracker, including its fields and configurations. .PARAMETER TrackerID Represents the unique identifier of the tracker for which the schema is to be retrieved. This parameter is mandatory and accepts input directly from the pipeline. .PARAMETER CBSession A mandatory parameter that specifies the CB Session object, containing connection details such as server URL and headers. This object facilitates authentication and API communication with the server. It can be accessed using the alias 'cbs'. .EXAMPLE Get-CbTrackerSchema -TrackerID $trackerID -CBSession $cbSession id : 0 name : ID type : IntegerField hidden : False valueModel : IntegerFieldValue mandatoryInStatuses : {} sharedFields : {} legacyRestName : id trackerItemField : id id : 1 name : Tracker type : ReferenceField hidden : False valueModel : NotSupportedFieldValue mandatoryInStatuses : {} sharedFields : {} legacyRestName : tracker trackerItemField : tracker id : 2 name : Business Value type : OptionChoiceField hidden : False valueModel : ChoiceFieldValue<ChoiceOptionReference> title : BV mandatoryInStatuses : {} multipleValues : False options : {@{id=0; name=Unset; type=ChoiceOptionReference}, @{id=1; name=Must have; type=ChoiceOptionReference}, @{id=3; name=Should have; type=ChoiceOptionReference}, @{id=5; name=Nice to have; type=ChoiceOptionReference}} sharedFields : {} legacyRestName : priority trackerItemField : priority referenceType : ChoiceOptionReference .... This example fetches the schema for the tracker with ID 'Tracker5678' from the server Codebeamer Server. .NOTES - The function outputs the schema structure of the specified tracker. - Debugging information provides insight into the request URI for troubleshooting. - Error management includes a specific check to verify tracker existence, guiding users on potential issues. #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline, Position = 0)] [string]$TrackerID, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) process { try { $uri = "https://{0}/cb/api/v3/trackers/{1}/schema" -f $CBSession.Server, $TrackerID Write-Debug "uri: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -errorAction Stop Write-Output $result } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Tracker is not found*" } { Write-Error "Tracker ID: $TrackerID most likely doesn't exist. Please recheck Tracker ID or Server." } Default { Write-Error $fullError } } } } } function Get-CBTrackerField { <# .SYNOPSIS Retrieves field information for a specific tracker from a Codebeamer server, with options for detailed output or filtering by field ID or field name. .DESCRIPTION The Get-CBTrackerField function interacts with a Codebeamer server's API to fetch field information associated with a specific tracker. It allows users to retrieve fields by specifying the field ID or name, request detailed information for all fields, or get all fields of the tracker. .PARAMETER TrackerID The identifier for the specific tracker whose field data is to be retrieved. This is a mandatory parameter for all parameter sets. .PARAMETER ID Used in the 'ByID' parameter set to specify the identifier of a particular field to retrieve. .PARAMETER Name Used in the 'ByName' parameter set to specify the name of a particular field to retrieve. .PARAMETER AllDetails Used in the 'DetailSet' parameter set to request detailed information for all fields within the specified tracker. .PARAMETER CBSession A mandatory parameter representing the session object required for connection to the CB server. This must include server information and headers necessary for authentication. This parameter is applicable across all parameter sets. .INPUTS None. .OUTPUTS PSCustomObject. Returns field details associated with the specified tracker, potentially filtered by field ID or name, or including all details. .EXAMPLE Example 1: Retrieve all fields for a tracker Get-CBTrackerField -TrackerID 12345 -CBSession $session .EXAMPLE Example 2: Retrieve a field by ID Get-CBTrackerField -TrackerID 12345 -ID 'fieldID123' -CBSession $session .EXAMPLE Example 3: Retrieve a field by name Get-CBTrackerField -TrackerID 12345 -Name 'FieldName' -CBSession $session .EXAMPLE Example 4: Retrieve detailed information for all fields Get-CBTrackerField -TrackerID 12345 -AllDetails -CBSession $session .NOTES Ensure the CBSession object is valid, and the server and headers are correctly populated to authenticate against the CB API. This function uses Invoke-RestMethod, so your environment must allow outbound HTTP requests. .LINK More information about API Endpoint: https://codebeamer.com/cb/wiki/11375774#section-Getting+detailed+information+about+a+field+in+a+specific+tracker #> [CmdletBinding(DefaultParameterSetName = 'DefaultSet')] param ( [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = 'DefaultSet')] [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = 'DetailSet')] [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = 'ByID')] [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = 'ByName')] [string]$TrackerID, [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ByID')] [string]$ID, [Parameter(ParameterSetName = 'ByName')] [string]$Name, [Parameter(ParameterSetName = 'DetailSet')] [switch]$AllDetails, [Parameter(Mandatory, ParameterSetName = 'DefaultSet')] [Parameter(Mandatory, ParameterSetName = 'DetailSet')] [Parameter(Mandatory, ParameterSetName = 'ByID')] [Parameter(Mandatory, ParameterSetName = 'ByName')] [pscustomobject]$CBSession ) process { try { switch ($PSCmdlet.ParameterSetName) { 'ByID' { $uri = "https://{0}/cb/api/v3/trackers/{1}/fields/{2}" -f $CBSession.Server, $TrackerID , $ID Write-Debug "URI: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop $result } 'ByName' { $uri = "https://{0}/cb/api/v3/trackers/{1}/fields/{2}" -f $CBSession.Server, $TrackerID, $ID Write-Debug "URI: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop $ID = ($result | Where-Object { $_.name -eq $name }).id if ($ID) { $uriField = "https://{0}/cb/api/v3/trackers/{1}/fields/{2}" -f $CBSession.Server, $TrackerID, $ID Write-Debug "URI: $uriField" $result = Invoke-RestMethod -Uri $uriField -Method Get -Headers $CBSession.headers -ErrorAction Stop $result } else { $notExsisting = [PSCustomObject]@{ Name = $name TrackerID = $TrackerID Exist = $false } Write-Output $notExsisting } } 'DetailSet' { $uri = "https://{0}/cb/api/v3/trackers/{1}/fields" -f $CBSession.Server, $TrackerID Write-Debug "URI: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop foreach ($id in $result.ID) { $uri = "https://{0}/cb/api/v3/trackers/{1}/fields/{2}" -f $CBSession.Server, $TrackerID, $id $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop $result | Add-Member -NotePropertyName trackerid -NotePropertyValue $TrackerID Write-Output $result } } Default { $uri = "https://{0}/cb/api/v3/trackers/{1}/fields" -f $CBSession.Server, $TrackerID Write-Debug "uri: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop Write-Output $result } } } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Field is not found.*" } { Write-Error "Field ID: $ID most likely doesn't exist. Please recheck Field ID or Server." } { $_ -like "*Tracker is not found.*" } { Write-Error "Tracker ID: $TrackerID most likely doesn't exist. Please recheck Tracker ID or Server." } Default { Write-Error $fullError } } } } } function Get-CBItemField { <# .SYNOPSIS Retrieves field information for a specified item in a Codebeamer server. .DESCRIPTION The `Get-CBItemField` function accesses and retrieves fields associated with a specific item from a Codebeamer server using the provided session. It supports fetching either all fields or specific fields based on the parameters specified. .PARAMETER ItemID The unique identifier for the item whose fields are to be retrieved. This parameter is mandatory and must be supplied. It is expected to be an integer. .PARAMETER Field Specifies one or more fields whose values you wish to retrieve for the item. This parameter is optional and should be used in conjunction with the `ItemID` parameter if you want to limit the results to specific fields. .PARAMETER ExcludeField It will exclude Fields and return any other field found on Tracker item .PARAMETER CBSession A custom object containing the connection session details for interacting with the Codebeamer server. This parameter is mandatory and should contain properties such as `Server` and headers required for API access. .EXAMPLE Get-CBItemField -ItemID 1234 -CBSession $session Retrieves all fields for the item with ID 1234 using the specified CB session. .EXAMPLE Get-CBItemField -ItemID 1234 -Field "Summary", "Description" -CBSession $session fieldId name sharedFieldNames type ------- ---- ---------------- ---- 10003 Summary {} TextFieldValue 80 Description {} WikiTextFieldValue .NOTES This function requires appropriate permissions and a valid session to interact with the Codebeamer Server's API. Ensure the session object (`CBSession`) is correctly populated with necessary headers and server information prior to executing the function. Conversion of `DateFieldValue` types to a standard date format is handled internally. #> [CmdletBinding(DefaultParameterSetName = "Default")] param ( [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = "Default")] [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = "Field")] [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = "ExcludeField")] [int]$ItemID, [Parameter(ParameterSetName = "Field")] [string[]]$Field, [Parameter(ParameterSetName = "ExcludeField")] [string[]]$ExcludeField, [Parameter(ParameterSetName = "Default")] [switch]$EditableFields, [Parameter(Mandatory, ParameterSetName = "Default")] [Parameter(Mandatory, ParameterSetName = "Field")] [Parameter(Mandatory, ParameterSetName = "ExcludeField")] [Alias("cbs")] [pscustomobject]$CBSession ) process { try { $outputArr = New-Object -TypeName System.Collections.ArrayList $uri = "https://{0}/cb/api/v3/items/{1}/fields" -f $CBSession.Server, $ItemID Write-Debug "URI: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop # Convert the date value to the specific format required by Codebeamer # Format: 'yyyy-MM-ddThh:mm:ss.fff' (e.g., 2023-08-15T14:30:00.123) $result.editableFields | ForEach-Object { if ($_.type -eq "DateFieldValue" -and $null -ne $_.value) { $_.value = $_.value | Get-date -Format 'yyyy-MM-ddThh:mm:ss.fff' } } # Convert the date value to the specific format required by Codebeamer # Format: 'yyyy-MM-ddThh:mm:ss.fff' (e.g., 2023-08-15T14:30:00.123) $result.readOnlyFields | ForEach-Object { if ($_.type -eq "DateFieldValue" -and $null -ne $_.value) { $_.value = $_.value | Get-date -Format 'yyyy-MM-ddThh:mm:ss.fff' } } Write-Debug "ParameterSetName: $($PSCmdlet.ParameterSetName)" switch ($PSCmdlet.ParameterSetName) { "Default" { $outputFields = if ($editableFields.IsPresent) { $result.editableFields } else { $result } Write-Output $outputFields } "Field" { $outputArr.AddRange($result.editableFields) $outputArr.AddRange($result.readOnlyFields) Write-Debug "Field from Parameter: $fieldName" $outputArr | Where-Object { $_.name -in $Field } } "ExcludeField" { $outputArr.AddRange($result.editableFields) $outputArr.AddRange($result.readOnlyFields) Write-Debug "Exluded Field from Parameter: $ExcludeField" $outputArr | Where-Object { $_.name -notin $ExcludeField } } Default { "Unknown Parameter Set Name $($PSCmdlet.ParameterSetName)" } } } catch { $fullError = $_ switch -Wildcard ($_.ErrorDetails.Message) { "*Not accessible tracker item ids*" { $message = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message Write-Error -Message $message } default { Write-Error $fullError } } } } } function Get-CBItemFieldOptions { <# .SYNOPSIS Retrieves options for fields of a specified item in the Codebeamer server. .DESCRIPTION The `Get-CBItemFieldOptions` function is designed to obtain available options for specified fields within an item in the Codebeamer server. The function supports both field name and field ID for querying field options, allowing for versatility and precision in data retrieval. .PARAMETER ItemID Specifies the item ID for which field options are to be retrieved. This parameter is mandatory and is available across all parameter sets. .PARAMETER FieldName Specifies the field name for which to retrieve options. This parameter is part of the 'FieldName' parameter set and is optional based on the parameter set being used. .PARAMETER FieldID Represents the field ID for which to retrieve options. This parameter is part of the 'FieldID' parameter set and is optional based on the parameter set being used. .PARAMETER Page Specifies the page number to retrieve for field options. Defaults to 1 for the first page. This parameter is optional across all parameter sets. .PARAMETER Size Determines the number of field options per page. The default value is 500, with a valid range between 1 and 500. This parameter is optional across all parameter sets. .PARAMETER CBSession A mandatory parameter representing the CB Session object, containing connection details such as server URL and headers. This session facilitates authentication and communication with the CB API. It is accessible using the alias 'cbs' and is mandatory in all parameter sets. .EXAMPLE get-CbitemFieldOptions -ItemID 7890 -FieldName Status -CBSession $session id name type -- ---- ---- 0 Unset ChoiceOptionReference 1 To Do ChoiceOptionReference 2 In Progress ChoiceOptionReference 3 Implemented ChoiceOptionReference 4 Done ChoiceOptionReference 5 Draft ChoiceOptionReference 6 Rejected ChoiceOptionReference 7 Accepted ChoiceOptionReference 8 Verified ChoiceOptionReference .EXAMPLE Get-CBItemFieldOptions -ItemID 7890 -FieldID 123 -CBSession $cbSession id name type -- ---- ---- 0 Unset ChoiceOptionReference 1 To Do ChoiceOptionReference 2 In Progress ChoiceOptionReference 3 Implemented ChoiceOptionReference 4 Done ChoiceOptionReference 5 Draft ChoiceOptionReference 6 Rejected ChoiceOptionReference 7 Accepted ChoiceOptionReference 8 Verified ChoiceOptionReference .NOTES - The function supports dynamic evaluation of fields, leveraging conditional logic based on input parameters. - URI requests are dynamically constructed, with debugging information assisting in troubleshooting processes. - Comprehensive error handling provides insight into common issues, including incorrect item IDs and inaccessible items. #> [CmdletBinding(DefaultParameterSetName = "Default")] param ( [Parameter(Mandatory, Position = 0, ParameterSetName = "Default")] [Parameter(Mandatory, Position = 0, ParameterSetName = "FieldName")] [Parameter(Mandatory, Position = 0, ParameterSetName = "FieldID")] [int]$ItemID, [Parameter(Position = 1, ParameterSetName = "FieldName")] [string]$FieldName, [Parameter(ParameterSetName = "FieldID")] [int]$FieldID, [Parameter(ParameterSetName = "Default")] [Parameter(ParameterSetName = "FieldName")] [Parameter(ParameterSetName = "FieldID")] [int]$Page = 1, [Parameter(ParameterSetName = "Default")] [Parameter(ParameterSetName = "FieldName")] [Parameter(ParameterSetName = "FieldID")] [ValidateRange(1, 500)] [int]$Size = 500, [Parameter(Mandatory, ParameterSetName = "Default")] [Parameter(Mandatory, ParameterSetName = "FieldName")] [Parameter(Mandatory, ParameterSetName = "FieldID")] [Alias("cbs")] [pscustomobject]$CBSession ) try { switch ($PSCmdlet.ParameterSetName) { "FieldID" { $uri = "https://{0}/cb/api/v3/items/{1}/fields/{2}/options?Page={3}&pageSize={4}" -f $CBSession.Server, $ItemID, $FieldID, $Page, $Size Write-Debug "uri: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers Write-Output $result.references $messageData = @" Command Information: "Page: $($result.page), Page Size: $($result.pageSize), Total: $($result.total), Field ID: $($FieldID)" "@ Write-Information -MessageData $messageData } "FieldName" { $uriFields = "https://{0}/cb/api/v3/items/{1}/fields" -f $CBSession.Server, $ItemID Write-Debug "URI: $uriFields" $fields = Invoke-RestMethod -Uri $uriFields -Method Get -Headers $CBSession.headers -ErrorAction Stop $allfields = New-Object -TypeName System.Collections.ArrayList $allfields.AddRange($fields.readOnlyFields) $allfields.AddRange($fields.editableFields) $fieldObject = $allfields | Where-Object { $_.name -eq $FieldName } if ($fieldObject) { $uriId = "https://{0}/cb/api/v3/items/{1}/fields/{2}/options?Page={3}&pageSize={4}" -f $CBSession.Server, $ItemID, $fieldObject.fieldId, $Page, $Size Write-Debug "uri: $uriId" $result = Invoke-RestMethod -Uri $uriId -Method Get -Headers $CBSession.headers $messageData = @" Command Information: "Page: $($result.page), Page Size: $($result.pageSize), Total: $($result.total), Field Name: $FieldName" "@ Write-Information -MessageData $messageData Write-Output $result.references } else { throw "Field Name:$FieldName appears to not exist." } } Default { "Unknown Parameter Set Name $($PSCmdlet.ParameterSetName) " } } } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Not accessible tracker item*" } { Write-Error ($fullError.ErrorDetails.Message | ConvertFrom-Json).message } { $_ -like "*Tracker item is not found.*" } { Write-Error "Item ID is incorrect: Item $ItemID most likely doesn't exist. Please recheck ItemID" } Default { Write-Error $fullError } } } } function Export-CBAttachment { [CmdletBinding()] param ( [Parameter(Mandatory, Position = 0)] [string]$AttachmentID, [Parameter(Mandatory, Position = 1)] [string]$OutFile, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) try { $uri = "https://{0}/cb/api/v3/attachments/{1}/content" -f $CBSession.Server, $AttachmentID Write-Debug "URI: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop -OutFile $OutFile Write-Output $result } catch { $fullError = $_ switch -Wildcard ($_.ErrorDetails.Message) { "*Attachment*revision*is not found*" { Write-Error ($fullError.ErrorDetails.Message | ConvertFrom-Json).message } Default { Write-Error $fullError } } } } function Set-CBItem { <# .SYNOPSIS Updates fields of an item in the Codebeamer Server. .DESCRIPTION The `Set-CBItem` function is designed to update specified fields of an item identified by its ID in a Codebeamer Server. It uses RESTful API calls to make the necessary updates and optionally provides verbose feedback. .PARAMETER ItemID Specifies the unique identifier of the item to be updated. This parameter is mandatory. .PARAMETER FieldValues Specifies an array of field values to be updated for the given item. Each field value should be a PSCustomObject containing the necessary fields and corresponding values. This parameter is mandatory. .PARAMETER QuietMode A switch parameter to enable or disable quiet mode. When enabled, updates might not trigger certain notifications or callbacks. This parameter is optional. .PARAMETER CBSession Specifies the CB Session object that includes necessary connection details such as server URL and headers. This object should contain the Server and headers properties. This parameter is mandatory and can be accessed through the alias 'cbs'. .EXAMPLE $fields = Get-CBItemField -ItemID 90812 -CBSession $cbSession -Field "Name","Action" Set-CBItem -ItemID 1234 -FieldValues $fieldValues -CBSession $cbSession Result will be updated Item Objects .NOTES - The function supports confirmation with the ShouldProcess method, allowing for simulation of operation before execution. - Error handling in this function checks specifically for locking issues, providing user information about who currently holds the lock. - Ensure the CBSession object is properly constructed to allow successful API communication. #> [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory, Position = 0)] [int]$ItemID, [Parameter(Mandatory)] [pscustomobject[]]$FieldValues, [Parameter()] [switch]$QuietMode, [Parameter(Mandatory)] [Alias("cbs")] [pscustomobject]$CBSession ) begin { $body = [PSCustomObject]@{} $arrayList = New-Object System.Collections.ArrayList $FieldValues | ForEach-Object { $arrayList.Add($_) | Out-Null } $body | Add-Member -NotePropertyName fieldValues -NotePropertyValue $arrayList } process { try { $json = $body | ConvertTo-Json -Depth 20 $uri = "https://{0}/cb/api/v3/items/{1}/fields?quietMode={2}" -f $CBSession.Server, $ItemID , $QuietMode Write-Debug "uri: $uri" Write-Debug "body: $json" if ($PSCmdlet.ShouldProcess($ItemID, "You will edit Fields $(($FieldValues.name -join ","))")) { $result = Invoke-RestMethod -Uri $uri -Method Put -Body $json -Headers $CBSession.headers -ErrorAction Stop Write-Output $result } } catch { $fullError = $_ switch -Wildcard ($_.ErrorDetails.Message) { "*currently locked by*" { $user = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message -split "by " $message = "Item ID: $ItemID is currently locked by $($user[1])" Write-Error -Message $message } "*is not found in tracker*" { $message = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message Write-Error -Message $message } "*Not accessible tracker item ids*" { $message = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message Write-Error -Message $message } default { Write-Error $fullError } } } } } function Invoke-CBQL { <# .SYNOPSIS Executes a CBQL query against a Codebeamer Server and retrieves item information. .DESCRIPTION The `Invoke-CBQL` function allows users to perform CBQL queries, optionally using an established baseline ID for reference. Results are paged, and the function supports dynamic query construction using passed parameters. .PARAMETER cbQLString Represents the CBQL query string to execute. This parameter is optional, and if not supplied, the function will default to retrieving information based on other parameters. .PARAMETER BaseLineID Specifies the baseline ID to use for the query. This can influence what items are retrieved based on this baseline. This parameter is optional. .PARAMETER Page Indicates the page number to retrieve from the query results. Defaults to the first page (i.e., 1). This parameter is optional. .PARAMETER Size Defines the number of items per page to retrieve. The default value is set to 500, and the range is restricted from 1 to 500 for efficiency. This parameter is optional. .PARAMETER CBSession A mandatory parameter representing the CB Session object containing connection details such as server URL and headers. This session provides authentication and server details necessary for API interaction. This can be accessed through the alias 'cbs'. .EXAMPLE Invoke-CBQL -cbQLString "tracker.id=130673 AND modifiedby ='youusername'" -CBSession $cbSession This example executes a CBQL query to find items containing 'Test' in their name, using the specified baseline ID, on page 1 with a default page size. .EXAMPLE IT is possible to run query with Baseline Parameter Invoke-CBQL -cbQLString "tracker.id=130673 AND modifiedby ='youusername'" -BaseLineID 13047 -CBSession $cbSession WARNING!!! Ensure Baseline ID is correct Codebeamer will return head revision if wrong Basline is used. Yes there will be no error. .NOTES - Queries are URL-encoded to ensure proper transmission across web requests. - Error handling captures and returns API-related issues that may arise during execution. - Debug logs are available for internal tracking of URI and CBQL parameters. - For complete output information including page and size, use the Write-Information output. .LINK Every Query from official Codebeamer Site can be used https://codebeamer.com/cb/wiki/871101#section-Current+Item+Placeholder #> [CmdletBinding()] param ( [Parameter()] [string]$cbQLString, [Parameter()] [string]$BaseLineID, [Parameter()] [int]$Page = 1, [Parameter()] [ValidateRange(1, 500)] [int]$Size = 500, [Parameter(Mandatory)] [Alias("cbs")] [pscustomobject]$CBSession ) try { $urlEncoded = [System.Web.HttpUtility]::UrlEncode($cbqlString) $uri = if ($BaseLineID) { "https://{0}/cb/api/v3/items/query?baselineId={1}&page={2}&pageSize={3}&queryString={4}" -f $CBSession.Server, $BaseLineID, $Page, $Size, $urlEncoded } else { "https://{0}/cb/api/v3/items/query?page={1}&pageSize={2}&queryString={3}" -f $CBSession.Server, $Page, $Size, $urlEncoded } Write-Debug "CBQL: $urlEncoded" Write-Debug "URI: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers Write-Output $result.items $messageData = @" Command Information: "Page: $($result.page), Page Size: $($result.pageSize), Total: $($result.total), CBQL String: $cbqlString" "@ Write-Information -MessageData $messageData } catch { Write-Error $_ } } function Find-CBUser { <# .SYNOPSIS Searches for users in the Codebeamer Server based on various criteria. .DESCRIPTION The `Find-CBUser` function allows users to search for specific users within the Codebeamer Server by utilizing different attributes such as name, email, first name, last name, user status, and project ID. Results are pageable, providing flexible navigation through large data sets. .PARAMETER Name Specifies the user's name for search criteria. This parameter is optional. .PARAMETER Email Defines the user's email address for search criteria. This parameter is optional. .PARAMETER FirstName Filters users by their first name. This parameter is optional. .PARAMETER LastName Filters users based on their last name. This parameter is optional. .PARAMETER UserStatus Filters users by their status, which can be 'ACTIVATED', 'DISABLED', or 'INACTIVATION'. This parameter is optional. .PARAMETER ProjectId Matches users associated with a specific project ID. This parameter is optional. .PARAMETER Page Indicates the page number to retrieve from the query results. The default is 1 for the first page. This parameter is optional. .PARAMETER Size Determines the number of users per page to retrieve. The default is 500, with a valid range between 1 and 500. This parameter is optional. .PARAMETER CBSession A mandatory parameter, representing the CB Session object, containing server URL and headers for API interaction. This object is accessed using the alias 'cbs'. .EXAMPLE Find-CBUser -Name "John Doe" -CBSession $searchSession .NOTES - The function constructs a dynamic JSON payload based on the provided parameters to query the Codebeamer Server. - Debugging information includes URI and payload details for troubleshooting. - Error handling ensures smooth execution, reporting issues encountered during API requests. #> [CmdletBinding()] param ( [Parameter()] [string]$name, [Parameter()] [string]$email, [Parameter()] [string]$firstName, [Parameter()] [string]$lastName, [Parameter()] [ValidateSet("ACTIVATED", "DISABLED", "INACTIVATION")] [string]$userStatus, [Parameter()] [int]$projectId, [Parameter()] [int]$Page = 1, [Parameter()] [ValidateRange(1, 500)] [int]$Size = 500, [Parameter(Mandatory)] [Alias("cbs")] [pscustomobject]$CBSession ) try { $valuesToRemove = "Page", "Size", "Server", "Debug", "asAdmin", "InformationAction", "CBSession" foreach ($removeValue in $valuesToRemove) { $PSBoundParameters.Remove($removeValue) | Out-Null } $body = $PSBoundParameters | ConvertTo-Json $uri = "https://{0}/cb/api/v3/users/search?page={1}&pageSize={2}" -f $CBSession.Server, $Page, $Size Write-Debug "URI:$uri" Write-Debug "Json Payload:$body" $result = Invoke-RestMethod -Uri $uri -Method Post -Headers $CBSession.headers -Body $body Write-Output $result.users $messageData = @" Command Information: "Page: $($result.page), Page Size: $($result.pageSize), Total: $($result.total)" "@ Write-Information $messageData } catch { $fullError = $_ switch -Wildcard ($_.ErrorDetails.Message) { "*At least one filtering criteria must be provided*" { $message = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message Write-Error -Message $message } default { Write-Error $fullError } } } } function Get-CBItemReference { <# .SYNOPSIS Retrieves reference information for a specified item in the Codebeamer Server. .DESCRIPTION The `Get-CBItemReference` function provides detailed reference data for a given item ID in the Codebeamer Server. Users can optionally provide a baseline ID, and the function supports paginated results for efficient data retrieval. .PARAMETER ItemID Represents the unique identifier of the item for which reference data is to be retrieved. This parameter is mandatory and accepts input from the pipeline. .PARAMETER BaseLineID Specifies the baseline ID to refine the reference data fetched. This parameter is optional and can alter the scope of the returned reference information. .PARAMETER Page Indicates the page number to retrieve in the query results. Defaults to the first page (i.e., 1). This parameter is optional. .PARAMETER Size Defines the number of references per page to retrieve. The default value is set to 500, with a range constraint between 1 and 500. This parameter is optional. .PARAMETER CBSession A mandatory parameter representing the CB Session object containing server URL and headers for API interaction. This session manages authentication and communication with the Codebeamer Server. It is accessible through the alias 'cbs'. .EXAMPLE Get-CBItemReference -ItemID 3885071 -CBSession $cbSession ItemID : 3885071 DownstreamReferences : {} UpstreamReferences : {@{id=13111092; itemRevision=; type=UpstreamTrackerItemReference}, @{id=13111091; itemRevision=; type=UpstreamTrackerItemReference}} IncomingAssociations : {} OutgoingAssociations : {} ItemCount : 2 IsLastPage : True .EXAMPLE Get-CBItemReference -ItemID 4567 -BaseLineID 123 -CBSession $cbSession This example fetches reference information using a specific baseline ID .NOTES - The function constructs an ordered dictionary to standardize output, encapsulating various reference aspects. - Debugging information includes the constructed URI for better traceability. - Error handling caters specifically to accessibility and baseline specification issues, guiding users on potential resolutions. #> [CmdletBinding()] param( [Parameter(ValueFromPipeline, Mandatory, Position = 0)] [int]$ItemID, [Parameter()] [int]$BaseLineID, [Parameter()] [int]$Page = 1, [Parameter()] [ValidateRange(1, 500)] [int]$Size = 500, [Parameter(Mandatory)] [Alias("cbs")] [pscustomobject]$CBSession ) process { try { $uri = if ($BaseLineID) { "https://{0}/cb/api/v3/items/{1}/relations?baselineId={2}&page={3}&pageSize={4}" -f $CBSession.Server, $ItemID, $BaseLineID, $Page, $Size } else { "https://{0}/cb/api/v3/items/{1}/relations?page={2}&pageSize={3}" -f $CBSession.Server, $ItemID, $Page, $Size } Write-Debug "Uri: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers $referenceItem = [ordered]@{ ItemID = $ItemID DownstreamReferences = $result.downstreamReferences UpstreamReferences = $result.upstreamReferences IncomingAssociations = $result.incomingAssociations OutgoingAssociations = $result.outgoingAssociations ItemCount = $result.itemCount IsLastPage = $result.isLastPage } $output = New-Object -TypeName psobject -Property $referenceItem Write-Output $output } catch { $fullError = $_ switch -Wildcard ($_.ErrorDetails.Message) { "*Not accessible tracker item ids*" { $message = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message Write-Error -Message $message } "*Baseline*" { $message = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message Write-Error -Message $message } default { Write-Error $fullError } } } } } function Open-Codebeamer { <# .SYNOPSIS Opens Codebeamer URLs based on specified parameters. .DESCRIPTION The `Open-Codebeamer` function facilitates the opening of Codebeamer links directly from the command line based on given item ID or tracker ID. It defaults to opening the main Codebeamer page if neither item nor tracker ID is specified. .PARAMETER Server Specifies the Codebeamer server to connect to. This parameter is mandatory and must be a valid CBServer name. .PARAMETER ItemID Represents the item ID within Codebeamer that should be opened. If provided, the function navigates directly to the specified item. This parameter is optional. .PARAMETER TrackerID Indicates the tracker ID within Codebeamer that should be opened. If provided, the function navigates directly to the specified tracker view. This parameter is optional. .EXAMPLE Open-Codebeamer -Server my-codebeamer.com:8080" -ItemID "12345" This example opens the specified item with ID "12345" on the Codebeamer server my-codebeamer.com:8080". .EXAMPLE Open-Codebeamer -Server my-codebeamer.com:8080" -TrackerID "6789" This example opens the tracker view with ID "6789" on the Codebeamer server my-codebeamer.com:8080". .EXAMPLE Open-Codebeamer -Server my-codebeamer.com:8080" This example opens the main page of the Codebeamer server my-codebeamer.com:8080" as no specific item or tracker ID was provided. .NOTES - The function utilizes Start-Process to open URLs directly in the default web browser. - Ensure valid Server is specified from the set of allowed CBServer names to prevent navigation errors. - The ValidateSet attribute should include appropriate values for CBServer which are predefined externally. #> [CmdletBinding()] param ( [Parameter(Mandatory, Position = 0)] [string]$Server, [Parameter()] [string]$ItemID, [Parameter()] [string]$TrackerID ) switch ($true) { { -not [string]::IsNullOrEmpty($ItemID) } { start-Process ("https://{0}/cb/issue/{1}" -f $server, $ItemID) ; break } { -not [string]::IsNullOrEmpty($TrackerID) } { start-Process ("https://{0}/cb/tracker/{1}?workingSetId=-1&layout_name=document&view_id=-11" -f $server, $TrackerID) ; break } Default { Start-Process "https://$Server/cb/"; break } } } function New-CBItem { <# .SYNOPSIS Creates a new item in a specified tracker from a CodeBeamer server .DESCRIPTION The New-CBItem function allows you to create a new item within a given tracker. It requires a Tracker ID and an active session (`CBSession`). You can specify field values, including default fields like Summary and Description, as well as custom fields. .PARAMETER TrackerID Mandatory parameter specifying the ID of the tracker where the item will be created. .PARAMETER FieldValues Optional array of PSCustomObjects representing fields and their values for the new item. Each object should have 'name' and 'value' properties. Default fields are 'Summary' and 'Description'. .PARAMETER CBSession Mandatory parameter, a PSCustomObject representing the session context. It should contain properties like 'Server' and 'headers' necessary for making API requests. .EXAMPLE #Creating a new item with a summary and description $fieldValues = @( [PSCustomObject]@{ name = "Summary"; value = "New Item Summary" }, [PSCustomObject]@{ name = "Description"; value = "Detailed description of the new item." } ) New-CBItem -TrackerID "12345" -FieldValues $fieldValues -CBSession $cbSession .EXAMPLE # Creating a new item with custom fields $fields = get-cbitemField -ItemID 388408 -CBSession $test -Field Name,description 12:13:33 $fields fieldId : 3 name : Name value : Default TextFieldValue Generated on: 2025-05-19T10:13:08.378 sharedFieldNames : {} type : TextFieldValue fieldId : 80 name : Description value : Test of tracker Item sharedFieldNames : {} type : WikiTextFieldValue You can Edit the object "Value" with further script or in Terminal $fields[0].value = "NEW VALUE" $fields[1].value = "NEW VALUE of description" New-CBItem -TrackerID "67890" -FieldValues $fields -CBSession $cbSession .NOTES You must have appropriate permissions in the CBSession context to successfully create items. #> [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory, Position = 0)] [string]$TrackerID, [Parameter()] [PSCustomObject[]]$FieldValues, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) try { if ($FieldValues) { $defaultFields = @("Summary", "Description") $arrayList = New-Object System.Collections.ArrayList $payload = [pscustomobject]@{} $payload | Add-member -NotePropertyName name -NotePropertyValue ($FieldValues | Where-Object { $_.name -eq "Summary" } | Select-Object -ExpandProperty value) $payload | Add-member -NotePropertyName description -NotePropertyValue ($FieldValues | Where-Object { $_.name -eq "Description" } | Select-Object -ExpandProperty value) $FieldValues | ForEach-Object { if ($_.name -notin $defaultFields) { $arrayList.Add($_) | Out-Null } } $payload | Add-Member -NotePropertyName customFields -NotePropertyValue $arrayList } else { $payload = @{} } $body = $payload | ConvertTo-Json -Depth 100 Write-Debug -Message "Body: $body" $uri = "https://{0}/cb/api/v3/trackers/{1}/items" -f $CBSession.Server, $TrackerID Write-Debug -Message "uri: $uri" $result = Invoke-RestMethod -Uri $uri -Method POST -Headers $CBSession.headers -Body $body -erroraction Stop Write-Output $result } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Tracker is not found.*" } { Write-Error "Tracker ID: $TrackerID most likely doesn't exist. Please recheck Tracker ID or Server." } Default { Write-Error $fullError } } } } function Get-CBItemHistory { <# .SYNOPSIS Retrieves the version history for a specified item in the Codebeamer Server. .DESCRIPTION The `Get-CBItemHistory` function fetches the version history of a given item ID from the Codebeamer Server. It utilizes a RESTful API call to acquire all historical versions of the specified item. .PARAMETER ItemID Represents the unique identifier of the item whose history is to be retrieved. This parameter is mandatory and accepts input from the pipeline. .PARAMETER CBSession Represents the CB Session object containing necessary connection details such as server URL and headers. This session facilitates authentication and interaction with the Codebeamer Server's API. It is mandatory and accessible using the alias 'cbs'. .EXAMPLE Get-CBItemHistory -ItemID 1234 -CBSession $cbSession itemRevision changes modifiedBy modifiedAt ------------ ------- ---------- ---------- @{id=1234; version=1} {} @{id=4911; name=user; type=UserReference; email=user@company.com} 5/22/2025 12:06:44 PM (...) .NOTES - The function outputs the version data, allowing users to track changes over time. - Debugging information includes the constructed URI for transparency and troubleshooting. - Error handling manages accessibility issues specifically, providing user-friendly messages when failures occur. #> [CmdletBinding()] param( [parameter(Mandatory, ValueFromPipeline, Position = 0)] [int]$ItemID, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) process { try { $uri = "https://{0}/cb/api/v3/items/{1}/history" -f $CBSession.Server, $ItemID Write-Debug "uri: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop Write-Output $result.versions } catch { $fullError = $_ switch -Wildcard ($_.ErrorDetails.Message) { "*Not accessible tracker item ids*" { $message = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message Write-Error -Message $message } default { Write-Error $fullError } } } } } function Copy-CBItem { <# .SYNOPSIS Copies specified fields from one item to another within the Codebeamer Server. .DESCRIPTION The `Copy-CBItem` function is engineered to copy fields from a source item to a destination item within the Codebeamer Server. It supports selective field copying and utilizes a REST API to perform the operation, with options for quiet mode execution. .PARAMETER ItemID Specifies the ID of the source item from which fields are to be copied. This parameter is mandatory. .PARAMETER DestinationItemID Indicates the ID of the destination item to which fields are to be copied. This parameter is mandatory. .PARAMETER Fields An optional parameter that contains an array of field names to copy from the source to the destination item. If not specified, all editable fields are copied. .PARAMETER QuietMode A switch parameter that, when specified, minimizes notifications and callbacks during the copy process. This parameter is optional. .PARAMETER CBSession Represents the CB Session object containing necessary connection details such as server URL and headers. This session facilitates authentication and API interaction. It is mandatory and can be accessed using the alias 'cbs'. .EXAMPLE This will copy all editable fields from item 1234 to 5678 Copy-CBItem -ItemID 1234 -DestinationItemID 5678 -CBSession $cbSession .EXAMPLE Copy-CBItem -ItemID 1234 -DestinationItemID 5678 -Fields "Field1", "Field2" -CBSession $cbSession This example copies "Field1" and "Field2" from the item with ID 1234 to the item with ID 5678 on the server .EXAMPLE Copy-CBItem -ItemID 1234 -DestinationItemID 5678 -QuietMode -CBSession $cbSession This example copies all editable fields from item 1234 to item 5678, executing the operation in quiet mode. .NOTES - The function handles date field values specifically to ensure correct format during transfer. - Error handling includes checks for access issues and item existence, reporting meaningful errors where applicable. - Debug logs provide insights into URI construction and JSON payloads for improved traceability. #> [CmdletBinding()] param( [parameter(Mandatory, Position = 0)] [int]$ItemID, [parameter(Mandatory, Position = 1)] [int]$DestinationItemID, [Parameter()] [string[]]$Fields, [Parameter()] [switch]$QuietMode, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) try { $uri = "https://{0}/cb/api/v3/items/{1}/fields" -f $CBSession.Server, $ItemID Write-Debug "URI: $uri" $valueToCopy = (Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop).editableFields if ($Fields) { $valueToCopy = foreach ($field in $Fields) { $valueToCopy | Where-Object { $_.name -eq $field } } } foreach ($copyValue in $valueToCopy) { if ($copyValue.type -eq "DateFieldValue" -and $null -ne $copyValue.value) { $copyValue.value = $copyValue.value | Get-date -Format 'yyyy-MM-ddThh:mm:ss.fff' } } $body = [PSCustomObject]@{} $arrayList = New-Object System.Collections.ArrayList $valueToCopy | ForEach-Object { $arrayList.Add($_) | Out-Null } $body | Add-Member -NotePropertyName fieldValues -NotePropertyValue $arrayList $json = $body | ConvertTo-Json -Depth 10 Write-Debug "$json" $uriCopy = "https://{0}/cb/api/v3/items/{1}/fields?quietMode={2}" -f $CBSession.Server, $DestinationItemID, $QuietMode Write-Debug "URI: $uriCopy" Invoke-RestMethod -Uri $uriCopy -Method PUT -Body $json -Headers $CBSession.headers -ErrorAction Stop } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Not accessible tracker item ids*" } { $message = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message Write-Error $message } { $_ -like "*Tracker item is not found.*" } { Write-Error "Item $itemID most likely doesn't exist. Please recheck Item ID." } Default { Write-Error $fullError } } } } function Find-CBUserRole { <# .SYNOPSIS Retrieves the roles of a specified user across projects in the Codebeamer Server. .DESCRIPTION The `Find-CBUserRole` function searches for a user's roles in all projects within the Codebeamer Server. It operates by first retrieving the user's ID and then querying each project to list roles associated with the user. .PARAMETER UserName Specifies the name of the user whose roles are to be retrieved. This parameter is mandatory. .PARAMETER CBSession Represents the CB Session object containing necessary connection details such as server URL and headers for API interaction. This session manages authentication and communication with the Codebeamer Server. It is mandatory and accessible through the alias 'cbs'. .EXAMPLE Find-CBUserRole -UserName "john.doe" -CBSession $cbSession ProjectID Project Roles UserName --------- ------- ----- -------- 2 Sandbox Agile Scrum Project Admin john.doe 41 Project Planning Project Admin john.doe 42 Software Development Project Admin john.doe 43 Project Management Project Admin john.doe This example searches for the roles of user "john.doe" across all projects on the Codebeamer server .NOTES - The function loops through all projects, reporting each found role for the given user and displaying progress. - User names are converted to lowercase to standardize search queries, ensuring case-insensitive matches. - Error handling gracefully manages any API-related issues and provides meaningful error messages when failures occur. - Progress is displayed using the Write-Progress cmdlet, giving real-time updates on the search operation. #> [CmdletBinding()] param ( [Parameter(Mandatory, Position = 0)] [string]$UserName, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) try { $UserName = $UserName.ToLower() $userIDuri = "https://{0}/cb/api/v3/users/findByName?name={1}" -f $CBSession.Server, $UserName $userID = (Invoke-RestMethod -Uri $userIDuri -Method Get -Headers $CBSession.headers -ErrorAction Stop).id $getProjectsIDuri = "https://{0}/cb/api/v3/projects" -f $CBSession.Server $projectInfo = Invoke-RestMethod -Uri $getProjectsIDuri -Method Get -Headers $CBSession.headers -ErrorAction Stop $percentage = (100 / $projectInfo.length) $percentage = [Math]::Floor($percentage) foreach ($project in $projectInfo) { $OuterLoopProgressParameters = @{ Activity = 'Searching in Projects...' Status = " Progress... -> $($_.Name)" PercentComplete = $percent += $percentage } $uri = "https://{0}/cb/api/v3/projects/{1}/members/{2}/permissions" -f $CBSession.Server, $project.id, $userID Write-Progress @OuterLoopProgressParameters $projects = (Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers).roles $roles = [ordered]@{ ProjectID = $project.ID Project = $project.Name Roles = $projects.name UserName = $UserName } $userRole = New-Object -TypeName psobject -Property $roles Write-Output $userRole } } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*User is not found by name*" } { $message = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message Write-Error $message } Default { Write-Error $fullError } } } } function Get-CBGroup { <# .SYNOPSIS Retrieves all user groups from the Codebeamer Server. .DESCRIPTION The `Get-CBGroup` function accesses the Codebeamer Server to fetch a list of user groups. It utilizes REST API calls to obtain the group information from the specified server. .PARAMETER CBSession Represents the CB Session object containing the necessary connection details such as server URL and headers. This facilitates the authentication process and enables communication with the CB API. It is mandatory and can be accessed using the alias 'cbs'. .EXAMPLE PS > Get-CBGroup -CBSession $cbSession id name type -- ---- ---- 1000 sysadmin UserGroupReference 1004 Support User UserGroupReference 4882 New User UserGroupReference 26511 Team UserGroupReference 28470 Project Admin UserGroupReference 34114 Rest API User UserGroupReference .NOTES - The function simply fetches and outputs the group data as returned by the API, providing quick access to group information. - Error handling is in place to manage API-related issues, ensuring meaningful error messages are relayed to the user. - The function utilizes `Invoke-RestMethod` for API interaction, expecting headers containing authentication details. #> [CmdletBinding()] param ( [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) try { $uri = "https://{0}/cb/api/v3/users/groups" -f $CBSession.Server $groups = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop Write-Output $groups } catch { Write-Error $_ } } function Get-CBItemAcessibility { <# .SYNOPSIS Retrieves accessibility information for fields of a specified item in the Codebeamer Server. .DESCRIPTION The `Get-CBItemAccessibility` function fetches information about field accessibility for a given item ID in the Codebeamer Server. The output includes field IDs, names, and their accessibility attributes such as visibility, mandatory status, and editability. Users can filter the result to show only mandatory fields. .PARAMETER ItemID Specifies the ID of the item from which field accessibility details are to be retrieved. This parameter is mandatory. .PARAMETER Mandatory A switch parameter that, when specified, filters the output to include only fields marked as mandatory. This parameter is optional. .PARAMETER CBSession Represents the CB Session object containing the necessary connection details such as server URL and headers. This session facilitates authentication and API communication. It is mandatory and can be accessed using the alias 'cbs'. .EXAMPLE Get-CBItemAccessibility -ItemID 1234 -CBSession $cbSession FieldID : 0 FieldName : ID visible : True mandatory : False editable : False FieldID : 76 FieldName : Parent visible : True mandatory : False editable : True FieldID : 1 FieldName : Tracker visible : True mandatory : False editable : False FieldID : 2 FieldName : Business Value visible : True mandatory : False editable : True (...) .EXAMPLE This Exmaple retrives only Mandatory Fields of Tracker Item Get-CBItemAccessibility -ItemID 1234 -Mandatory -CBSession $cbSession FieldID : 3 FieldName : Summary visible : True mandatory : True editable : True FieldID : 80 FieldName : Description visible : True mandatory : True editable : True .NOTES - The function processes and outputs selected field properties, including visibility and editability status. - Error handling accommodates specific checks for item existence and returns meaningful error messages in case of issues. - The switch parameter allows flexibility, enabling selective filtering of output results. #> [CmdletBinding()] param ( [Parameter(Mandatory, Position = 0)] [int]$ItemID, [Parameter()] [switch]$Mandatory, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) try { $uri = "https://{0}/cb/api/v3/items/{1}/fields/accessibility" -f $CBSession.Server, $ItemID $result = (Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers).fields | Select-Object @{N = "FieldID"; E = { $_.field.ID } }, @{N = "FieldName"; E = { $_.field.name } }, visible, mandatory, editable $output = switch ($true) { $Mandatory.IsPresent { $result | Where-Object { $_.Mandatory -eq $true } } Default { $result } } Write-Output $output } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Tracker item is not found.*" } { Write-Error "Item ID is incorrect: Item $itemID most likely doesn't exist. Please recheck ItemID" } Default { Write-Error $fullError } } } } function Get-CBTrackerTree { <# .SYNOPSIS Retrieves the tracker tree structure for a specified project in the Codebeamer Server. .DESCRIPTION The `Get-CBTrackerTree` function accesses the Codebeamer Server to fetch the hierarchical structure of trackers within a given project. It utilizes RESTful API calls to obtain detailed tracker information associated with the project ID. .PARAMETER ProjectID Specifies the ID of the project for which the tracker tree is to be retrieved. This parameter is mandatory. .PARAMETER CBSession Represents the CB Session object containing necessary connection details such as server URL and headers for API interaction. This session manages authentication and communication with the Codebeamer Server. It is mandatory and can be accessed using the alias 'cbs'. .EXAMPLE Get-CBTrackerTree -ProjectID 5678 -CBSession $cbSession isFolder text children -------- ---- -------- True Work Items {@{trackerId=3521503}, @{trackerId=3541396}, @{trackerId=3542177}} True Tasks {@{trackerId=3531966}} True Config Items {@{trackerId=3521502}, @{trackerId=3525112}, @{trackerId=3521511}, @{trackerId=11661406}…} {@{trackerId=13010422},@{trackerId=12919923},@{trackerId=12991240},@{trackerId=12919184}…} .NOTES - The function outputs the hierarchical tracker structure associated with the given project. - Debugging information includes the constructed URI for increased transparency and troubleshooting. - Proper error handling ensures informative messages are provided in case of API-related issues. #> [CmdletBinding()] param( [parameter(Mandatory, Position = 0)] [int]$ProjectID, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) try { $uri = "https://{0}/cb/api/v3/trackers/tree?projectId={1}" -f $CBSession.Server, $ProjectID Write-Debug "uri: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop Write-Output $result } catch { $fullError = $_ switch -Wildcard ($_.ErrorDetails.Message) { "*Project not found*" { $message = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message $errorMEssage = "{0} Please recheck Project ID: {1}" -f $message, $ProjectID Write-Error $errorMEssage } Default { Write-Error $fullError } } } } function Get-CBTrackerConfiguration { <# .SYNOPSIS Retrieves the configuration details for a specified tracker in the Codebeamer Server. .DESCRIPTION The `Get-CBTrackerConfiguration` function accesses the Codebeamer Server to fetch configuration information for a given tracker ID. Users can opt to filter results to return only mandatory fields associated with the tracker. .PARAMETER TrackerID Specifies the unique identifier of the tracker for which configuration details are to be retrieved. This parameter is mandatory. .PARAMETER MandatoryFields A switch parameter that, when specified, filters the output to include only fields marked as mandatory within the tracker. This parameter is optional. .PARAMETER CBSession Represents the CB Session object containing necessary connection details such as server URL and headers for API interaction. This session facilitates authentication and API communication. It is mandatory and accessible using the alias 'cbs'. .EXAMPLE Get-CBTrackerConfiguration -TrackerID 1234 -CBSession $cbSession This example retrieves the configuration details for tracker ID 1234 on the Codebeamer server .EXAMPLE Get-CBTrackerConfiguration -TrackerID 1234 -MandatoryFields -CBSession $cbSession This example fetches only mandatory field configurations for tracker ID 1234. .NOTES - The function provides comprehensive configuration data unless filtered by the `MandatoryFields` switch. - Debug information includes the URI utilized for the API request, aiding in troubleshooting. - Error handling manages common issues like invalid Tracker IDs, ensuring meaningful error messages are relayed to the user. #> [CmdletBinding()] param ( [Parameter(Mandatory, Position = 0)] [int]$TrackerID, [Parameter()] [switch]$MandatoryFields, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) try { $uri = "https://{0}/cb/api/v3/tracker/{1}/configuration" -f $CBSession.Server, $TrackerID Write-Debug "uri: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop switch ($true) { $MandatoryFields.IsPresent { $mandatory = ($result.fields | Where-Object { $_.Mandatory -eq $true }) Write-Output $mandatory if (-not $mandatory) { $message = "Tracker: $TrackerID does not have Mandatory Fields!" Write-Information $message } } Default { Write-Output $result } } } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Tracker not found*" } { Write-Error "Tracker ID: $TrackerID most likely doesn't exist. Please recheck Tracker ID or Server." } Default { Write-Error $fullError } } } } function Update-CBTrackerConfiguration { <# .SYNOPSIS Updates the configuration for a specified tracker in the Codebeamer Server. .DESCRIPTION The `Update-CBTrackerConfiguration` function updates the configuration of a tracker within the Codebeamer Server. It accepts a tracker configuration object and utilizes a RESTful API call to submit the changes, providing confirmation before executing the operation. .PARAMETER TrackerConfiguration Represents the configuration object containing details to update the specified tracker. This parameter is mandatory. .PARAMETER CBSession Specifies the CB Session object containing necessary connection details such as server URL and headers. This session facilitates authentication and API communication. It is mandatory and accessible using the alias 'cbs'. .EXAMPLE $config = get-cbTrackerConfiguration -TrackerID 13127411 -CBSession $cbSession # Clear Tracker ID $config.basicInformation.trackerId = "" # Change Project ID where you want to have tracker $config.basicInformation.projectId = 46 Update-CBTrackerConfiguration -TrackerConfiguration 4Config -CBSession $cbSession This example updates the configuration for tracker ID 1234 in project ID 5678 on the Codebeamer server .NOTES - The function supports `ShouldProcess`, allowing for confirmation before the update operation is executed. - Error handling ensures any execution issues are captured and meaningful error messages are provided. - Ensure the configuration object is constructed correctly to avoid JSON serialization issues during API submission. #> [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory, Position = 0)] [PSCustomObject]$TrackerConfiguration, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) try { if ($PSCmdlet.ShouldProcess($CBSession.Server, ("You will updated Project id {1} and Tracker ID {0} " -f $TrackerConfiguration.basicInformation.ID, $TrackerConfiguration.basicInformation.projectID))) { $body = $TrackerConfiguration | ConvertTo-Json -Depth 100 $uri = "https://{0}/cb/api/v3/tracker/configuration" -f $CBSession.Server Invoke-RestMethod -Uri $uri -Method Post -Body $body -Headers $CBSession.headers } } catch { Write-Error $_ } } function Remove-CBItem { <# .SYNOPSIS Removes an item from a specified tracker using the CBSession context. .DESCRIPTION The Remove-CBItem function allows you to delete an item from a tracker by specifying its Item ID and an active session (`CBSession`). It supports pipeline input for Item IDs and includes functionality to confirm the deletion action. .PARAMETER ItemID The ID of the item to be removed. This parameter supports pipeline input. .PARAMETER CBSession A mandatory PSCustomObject representing the session context. It should contain properties like 'Server' and 'headers' necessary for making API requests. .EXAMPLE #Removing an item using an ItemID Remove-CBItem -ItemID 54321 -CBSession $cbSession .NOTES Ensure the CBSession is valid and has appropriate permissions to delete items from the specified tracker. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(ValueFromPipeline, Position = 0)] [string]$ItemID, [Parameter(Mandatory)] [Alias("cbs")] [pscustomobject]$CBSession ) process { try { if ($PSCmdlet.ShouldProcess($CBSession.Server, ("Item {0} will be deleted" -f $ItemID))) { $uri = "https://{0}/cb/api/v3/items/{1}" -f $CBSession.Server, $ItemID Invoke-RestMethod -Uri $uri -Method Delete -Body $body -Headers $CBSession.headers } } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Not accessible tracker item ids*" } { $message = ($fullError.ErrorDetails.Message | ConvertFrom-Json).message Write-Error $message } Default { Write-Error $fullError } } } } } function Get-CBItemLock { <# .SYNOPSIS Retrieves lock information for a specified item in the Codebeamer Server. .DESCRIPTION The `Get-CBItemLock` function queries the Codebeamer Server to check and retrieve lock status information for a given item ID. This can be useful for understanding if the item is locked, and if so, by whom. .PARAMETER ItemID Represents the unique identifier of the item whose lock status is to be retrieved. This parameter can accept input from the pipeline. .PARAMETER CBSession Represents the CB Session object containing necessary connection details such as server URL and headers. This session enables authentication and communication with the CB API. It is mandatory and can be accessed using the alias 'cbs'. .EXAMPLE get-CBItemLock -ItemID 12345 -cbsession $cbSession user expires ---- ------- @{id=41; name=idOfUserWhoLockedItem; type=UserReference; email=emailOfUserWhoLockedItem} True .NOTES - Debugging information includes the constructed URI for enhanced troubleshooting. - Error handling provides specific checks for item accessibility and existence, ensuring meaningful feedback when issues are encountered. - Make sure the `CBSession` object is correctly formed to enable API communication without errors. #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline, Position = 0)] [string]$ItemID, [Parameter(Mandatory)] [Alias("cbs")] [pscustomobject]$CBSession ) process { try { $uri = "https://{0}/cb/api/v3/items/{1}/lock" -f $CBSession.Server, $ItemID Write-Debug "URI: $uri" Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Not accessible tracker item*" } { Write-Error ($fullError.ErrorDetails.Message | ConvertFrom-Json).message } { $_ -like "*Tracker item is not found.*" } { Write-Error "Item ID is incorrect: Item $itemID most likely doesn't exist. Please recheck ItemID" } Default { Write-Error $fullError } } } } } function Set-CBItemLock { <# .SYNOPSIS Manages the lock state of a specified item in the Codebeamer Server. .DESCRIPTION The `Set-CBItemLock` function allows users to either lock or unlock an item in the Codebeamer Server. Locking an item can be done for a specific duration, and unlocking removes any existing locks on the item. The function uses RESTful API calls to perform the actions specified by the user. .PARAMETER ItemID Specifies the ID of the item for which the lock state is to be managed. This parameter is mandatory in both parameter sets: 'Lock' and 'Unlock'. .PARAMETER Lock A switch parameter used to set the lock on an item. This parameter is part of the 'Lock' parameter set. .PARAMETER Duration Indicates the duration for which the item should be locked. Accepted formats are '1:30h' for one and a half hours and '1d' for one day. This parameter is optional and part of the 'Lock' parameter set. .PARAMETER Unlock A switch parameter used to remove the lock from an item. This parameter is part of the 'Unlock' parameter set. .PARAMETER CBSession Represents the CB Session object containing necessary connection details such as server URL and headers. This session facilitates authentication and communication with the CB API. It is mandatory and accessible using the alias 'cbs'. .EXAMPLE Set-CBItemLock -ItemID 1234 -Lock -Duration '1d' -CBSession $cbSession 1234 Locked .EXAMPLE Set-CBItemLock -ItemID 1234 -Unlock -CBSession $cbSession 1234 Unlocked .NOTES - The function employs multiple parameter sets to distinguish lock and unlock operations, ensuring clear command execution. - Debugging information includes constructed URIs and JSON payloads for monitoring API requests. - Error handling addresses item accessibility and existence as well as duration validity, providing informative error messages. #> [CmdletBinding()] param ( [Parameter(Mandatory, Position = 0, ParameterSetName = 'Lock')] [Parameter(Mandatory, Position = 0, ParameterSetName = 'Unlock')] [int]$ItemID, [Parameter(ParameterSetName = 'Lock')] [switch]$Lock, [Parameter(ParameterSetName = 'Lock')] [ArgumentCompletions('1:30h', '1d')] [String]$Duration, [Parameter(ParameterSetName = 'Unlock')] [switch]$Unlock, [Parameter(Mandatory)] [Alias("cbs")] [pscustomobject]$CBSession ) process { try { switch ($PSCmdlet.ParameterSetName) { "Lock" { $lockDetails = [PSCustomObject]@{ duration = $Duration hard = $false } $uri = "https://{0}/cb/api/v3/items/{1}/lock" -f $CBSession.Server, $ItemID Write-Debug $uri $json = $lockDetails | ConvertTo-Json Write-Debug $json Invoke-RestMethod -Uri $uri -Method Put -Headers $CBSession.headers -Body $json -ErrorAction Stop Write-Output "$ItemID Locked" } "Unlock" { $uri = "https://{0}/cb/api/v3/items/{1}/lock" -f $CBSession.Server, $ItemID Write-Debug $uri Invoke-RestMethod -Uri $uri -Method Delete -Headers $CBSession.headers -ErrorAction Stop Write-Output "$ItemID Unlocked" } Default { throw "Unknown Parameter Set: $($PSCmdlet.ParameterSetName))" } } } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Not accessible tracker item*" } { Write-Error ($fullError.ErrorDetails.Message | ConvertFrom-Json).message } { $_ -like "*Tracker item is not found.*" } { Write-Error "Item ID is incorrect: Item $itemID most likely doesn't exist. Please recheck Version or ItemID" } { $_ -like "*Tracker item lock duration*" } { Write-Error ($fullError.ErrorDetails.Message | ConvertFrom-Json).message } Default { Write-Error $fullError } } } } } function Get-CBReport { <# .SYNOPSIS Retrieves the results of a specified report from the Codebeamer Server. .DESCRIPTION The `Get-CBReport` function accesses the Codebeamer Server to fetch results for a given report ID. It employs RESTful API calls to acquire the report data, which is then outputted for user review. .PARAMETER ReportID Specifies the unique identifier for the report whose results are to be retrieved. This parameter is mandatory. .PARAMETER CBSession Represents the CB Session object containing necessary connection details such as server URL and headers. This session facilitates authentication and communication with the CB API. It is mandatory and accessible using the alias 'cbs'. .EXAMPLE Get-CBReport -ReportID 789 -CBSession $cbSession report : @{id=789; name=Administrator TEST; type=ReportReference} cbQL : project.id IN (436) AND tracker.id IN (3539166,3525013) AND workItemStatus NOT IN ('Resolved','Closed') AND '46.352503.status' NOT IN ('Done','Rejected') ORDER BY modifiedAt ASC columns : {@{columnRef=0-3; field=; name=Summary; type=text; columnWidthPercentage=50; columnIndex=0}, @{columnRef=0-7; field=; name=Status; type=choice; columnWidthPercentage=50; columnIndex=1}} pagingInformation : @{page=1; pageSize=25; pageCount=2} data : @{type=ReportGroupWithRows; header=Grand Total; count=25; rows=System.Object[]} showAllChildren : False This example retrieves the results for report ID 789 from the Codebeamer server. .NOTES - The function outputs the report data retrieved from the API, allowing users to analyze the report's contents. - Debug information includes the constructed URI to assist in troubleshooting and understanding API interactions. - Error handling manages common issues such as incorrect report IDs, ensuring informative feedback is provided in case of errors. #> [CmdletBinding()] param ( [Parameter(Mandatory, Position = 0)] [int]$ReportID, [Parameter(Mandatory)] [Alias("cbs")] [pscustomobject]$CBSession ) try { $uri = "https://{0}/cb/api/v3/reports/{1}/results" -f $CBSession.Server, $ReportID Write-Debug "uri: $uri" $report = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop Write-Output $report } catch { $fullError = $_ switch -Wildcard ($_.ErrorDetails.Message) { "*Couldn\u0027t find report*" { Write-Error ($fullError.ErrorDetails.Message | ConvertFrom-Json).message } Default { Write-Error $fullError } } } } function Get-CBRole { <# .SYNOPSIS Retrieves role information from the Codebeamer Server. .DESCRIPTION The `Get-CBRole` function fetches all roles, a specific role by ID, or searches for a role by name from the Codebeamer Server using the provided session. .PARAMETER RoleID The ID of the role to retrieve. Optional. .PARAMETER RoleName The name of the role to search for. Optional. .PARAMETER CBSession The session object containing server URL and headers. Mandatory. .EXAMPLE Get-CBRole -CBSession $cbSession Retrieves all roles from the server. .EXAMPLE Get-CBRole -RoleID 123 -CBSession $cbSession Retrieves the role with ID 123. .EXAMPLE Get-CBRole -RoleName "Admin" -CBSession $cbSession Searches for roles with "Admin" in the name. .NOTES - Requires a valid CBSession object. - Returns role objects as provided by the Codebeamer REST API. #> [CmdletBinding(DefaultParameterSetName = "Default")] param ( [Parameter(Position = 0, ParameterSetName = "RoleID")] [int]$RoleID, [Parameter(ParameterSetName = "RoleName")] [string]$RoleName, [Parameter(Mandatory, ParameterSetName = "Default")] [Parameter(Mandatory, ParameterSetName = "RoleID")] [Parameter(Mandatory, ParameterSetName = "RoleName")] [Alias("cbs")] [pscustomobject]$CBSession ) try { $output = switch ($PSCmdlet.ParameterSetName) { "Default" { $uri = "https://{0}/cb/api/v3/roles" -f $CBSession.Server Write-Debug $uri Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop } "RoleID" { $uri = "https://{0}/cb/api/v3/roles/{1}" -f $CBSession.Server, $RoleID Write-Debug $uri Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop } "RoleName" { $uri = "https://{0}/cb/api/v3/roles" -f $CBSession.Server Write-Debug $uri (Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop) | Where-Object { $_.name -like "*$RoleName*" } } Default { "Unknown Parameter Set $($PSCmdlet.ParameterSetName)" } } Write-Output $output } catch { Write-Error $_ } } function Get-CBTrackerPermission { [CmdletBinding()] param ( [Parameter(Mandatory, Position = 0)] [int]$TrackerID, [Parameter(Mandatory)] [Alias("cbs")] [pscustomobject]$CBSession ) try { $uri = "https://{0}/cb/api/v3/trackers/{1}/permissions" -f $CBSession.Server, $TrackerID Write-debug "uri: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop Write-Output $result } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Tracker*is not found*" } { Write-Error "Tracker ID: $TrackerID most likely doesn't exist. Please recheck Tracker ID or Server." } Default { Write-Error $fullError } } } } function Reset-CBItem { <# .SYNOPSIS Resets fields of one or more tracker items in Codebeamer to a specified baseline or version. .DESCRIPTION The `Reset-CBItem` function restores selected fields of one or more tracker items to their values from a given baseline or version. You can specify which fields to reset, or reset all editable fields except for a set of uneditable fields. The function supports both baseline and version-based resets and handles computed fields appropriately. .PARAMETER ItemID The ID(s) of the item(s) to reset. Accepts an array of integers and supports pipeline input. .PARAMETER TrackerID The ID of the tracker containing the items to reset. Mandatory for both parameter sets. .PARAMETER ToBaseline The baseline ID to which the item(s) should be reset. Mandatory for the 'ToBaseLine' parameter set. .PARAMETER ToVersion The version number to which the item(s) should be reset. Mandatory for the 'ToVersion' parameter set. .PARAMETER Fields (Optional) An array of field names to reset. If not specified, all editable fields (except uneditable ones) are reset. .PARAMETER CBSession The session object containing server URL and headers. Mandatory and can be accessed using the alias 'cbs'. .EXAMPLE Reset-CBItem -ItemID 12345 -TrackerID 67890 -ToBaseline 111 -CBSession $cbSession Resets all editable fields of item 12345 in tracker 67890 to their values from baseline 111. .EXAMPLE Reset-CBItem -ItemID 12345,12346 -TrackerID 67890 -ToVersion 2 -Fields "Summary","Status" -CBSession $cbSession Resets the "Summary" and "Status" fields of items 12345 and 12346 in tracker 67890 to their values from version 2. .NOTES - Computed fields are not reset and will be recalculated by Codebeamer. - Error handling provides feedback for missing fields, invalid tracker/item IDs, or inaccessible items. - Progress is displayed for long-running operations. #> [CmdletBinding(DefaultParameterSetName = "ToBaseLine")] param ( [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = "ToBaseLine")] [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = "ToVersion")] [int[]]$ItemID, [Parameter(Mandatory, ParameterSetName = "ToBaseLine")] [Parameter(Mandatory, ParameterSetName = "ToVersion")] [int]$TrackerID, [Parameter(Mandatory, ParameterSetName = "ToBaseLine")] [int]$ToBaseline, [Parameter(Mandatory, ParameterSetName = "ToVersion")] [int]$ToVersion, [Parameter(ParameterSetName = "ToBaseLine")] [Parameter(ParameterSetName = "ToVersion")] [String[]]$Fields, [Parameter(Mandatory, ParameterSetName = "ToBaseLine")] [Parameter(Mandatory, ParameterSetName = "ToVersion")] [Alias("cbs")] [pscustomobject]$CBSession ) begin { $uneditableFields = @("ID", "Tracker", "Submitted at", "Submitted by", "Modified at", "Closed at", "Modified by", "Attachments") try { $rawObjectList = New-Object 'System.Collections.Generic.List[psobject]' $ItemTemplate = (Get-CBTrackerChild -TrackerID $TrackerID -Size 1 -CBSession $CBSession).id Write-Debug "Template item ID: $ItemTemplate" $uriCopyTemplate = "https://{0}/cb/api/v3/items/{1}/fields" -f $CBSession.Server, $ItemTemplate Write-Debug "uriCopyTemplate: $uriCopyTemplate" $copyTemplate = Invoke-RestMethod -Uri $uriCopyTemplate -Method Get -Headers $CBSession.headers -ErrorAction Stop $uriTrackerfieldList = "https://{0}/cb/api/v3/trackers/{1}/fields" -f $CBSession.Server, $TrackerID Write-Debug "uriTrackerfieldList: $uriTrackerfieldList" $trackerFields = Invoke-RestMethod -Uri $uriTrackerfieldList -Method Get -Headers $CBSession.headers -ErrorAction Stop $listoftrackerFields = $trackerFields | Where-Object { $_.name -notin $uneditableFields } $listoftrackerFields = if ($Fields) { foreach ($field in $Fields) { $listoftrackerFields | Where-Object { $_.name -eq $field } } } else { $listoftrackerFields } $percentage = (100 / $listoftrackerFields.length) $percentage = [Math]::Floor($percentage) $percent = 0 $trackerFieldsMapping = foreach ($field in $listoftrackerFields) { $OuterLoopProgressParameters = @{ Activity = 'Gathering Information about tracker {0}...' -f $TrackerID Status = " About... -> $($field.Name)" PercentComplete = $percent += $percentage } Write-Progress @OuterLoopProgressParameters $uriFieldProperties = "https://{0}/cb/api/v3/trackers/{1}/fields/{2}" -f $CBSession.Server, $TrackerID, $field.id Write-Debug "uriFieldPropertie: $uriFieldProperties" Invoke-RestMethod -Uri $uriFieldProperties -Method Get -Headers $CBSession.headers -ErrorAction Stop } $computedFields = $trackerFieldsMapping | Where-Object { $_.formula } if ($computedFields) { $Message = "Computed Fields Found: $($computedFields.Name -join ", "). Value will be recalculated according to field Formula by Codebeamer" Write-Warning $message } $rawObject = @{ trackerFieldsMapping = $trackerFieldsMapping versionedItem = $null copyTemplate = $copyTemplate ItemID = 0 computedFields = $computedFields chosenFields = $Fields } } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Field is not found.*" } { Write-Error "Field ID: $ID most likely doesn't exist. Please recheck Field ID or Server." } { $_ -like "*Tracker is not found.*" } { Write-Error "Tracker ID: $TrackerID most likely doesn't exist. Please recheck Tracker ID or Server." } Default { Write-Error $fullError } } } } process { try { $versionedItem = foreach ($item in $ItemID) { $messageActivity = 'Analyzing Item {0}...' -f $item Write-Progress -Activity $messageActivity Write-Debug "ParameterSetName: $($PSCmdlet.ParameterSetName)" $uriVersioned = switch ($PSCmdlet.ParameterSetName) { "ToBaseLine" { "https://{0}/cb/api/v3/items/{1}?{2}={3}" -f $CBSession.Server, $item, "baselineId", $ToBaseline ; break } "ToVersion" { "https://{0}/cb/api/v3/items/{1}?{2}={3}" -f $CBSession.Server, $item, "version", $ToVersion ; break } default { Throw "Something Wrong with ParameterSetName $_" } } Write-Debug "uriVersioned: $uriVersioned" Invoke-RestMethod -Uri $uriVersioned -Method Get -Headers $CBSession.headers -ErrorAction Stop } $rawObject["versionedItem"] = $versionedItem $rawObject["ItemID"] = $item $rawObjectList.Add((New-Object -TypeName pscustomobject -Property $rawObject)) } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Not accessible tracker item*" } { Write-Error ($fullError.ErrorDetails.Message | ConvertFrom-Json).message } { $_ -like "*Tracker item is not found.*" } { Write-Error "Version, Baseline or Item ID is incorrect: Item $itemID most likely doesn't exist. Please recheck Version or ItemID" } { $_ -like "*BaseLine*" } { Write-Error ($fullError.ErrorDetails.Message | ConvertFrom-Json).message exit 1 } Default { Write-Error $fullError } } } } end { Write-Progress -Completed # updating Items foreach ($object in $rawObjectList) { $fieldValues = Convertto-CBObjectFieldList -ItemObject $object $body = [PSCustomObject]@{} $arrayList = New-Object System.Collections.ArrayList foreach ($fieldValue in $fieldValues) { if ($null -ne $fieldValue) { $arrayList.Add($fieldValue) | Out-Null } } $body | Add-Member -NotePropertyName fieldValues -NotePropertyValue $arrayList $json = $body | ConvertTo-Json -Depth 20 Write-Debug "body: $json" $uri = "https://{0}/cb/api/v3/items/{1}/fields?quietMode=false" -f $CBSession.Server, $object.ItemID Write-Debug "uri: $uri" $result = Invoke-RestMethod -Uri $uri -Method Put -Body $json -Headers $CBSession.headers -errorAction Stop Write-Output $result } } } function Convertto-CBObjectFieldList { [CmdletBinding()] param ( [Parameter(Mandatory)] [PSCustomObject]$ItemObject ) $result = New-Object 'System.Collections.Generic.List[psobject]' $legacyObject = foreach ($editableField in $ItemObject.Copytemplate.editableFields) { $ItemObject.trackerFieldsMapping | Where-Object { $_.name -eq $editableField.name } | Select-Object id, legacyRestName, name, trackerItemField } foreach ($legacy in $legacyObject) { foreach ($property in $ItemObject.versionedItem.psobject.Properties) { if ($legacy.legacyRestName -eq $property.name -or $legacy.trackerItemField -eq $property.name) { $field = $ItemObject.Copytemplate.editableFields | Where-Object { $_.name -eq $legacy.name } if ($field.psobject.Properties.name -contains "values") { [array]$field.values = $property.value } if ($field.psobject.Properties.name -contains "value") { $field.value = $property.value } if ($field.psobject.Properties.name -notcontains "value" -and $field.psobject.Properties.name -notcontains "values" -and $property.value ) { Write-Debug "No Value Property on Field Object: $($field.name) but versioned Item has value $($property.value)" $field | Add-member -NotePropertyName value -NotePropertyValue $property.value } Write-Debug "versioned field: $($field.name)" $result.add($field) } } } # powershell is wrongly parsing date so we need to iterate of custom fields to format it correctly foreach ($editableField in $ItemObject.versionedItem.customFields) { if ($editableField.type -eq "DateFieldValue" -and $null -ne $editableField.value) { $editableField.value = $editableField.value | Get-date -Format 'yyyy-MM-ddThh:mm:ss.fff' } Write-Debug "Custom Fields in Versioned editableField.name: $($editableField.name)" Write-Debug "Custom Fields in Versioned editableField.id: $($editableField.fieldId)" Write-Debug "Custom Fields in ItemObject.computedFields.id: $($ItemObject.computedFields.id)" #computed Fields cannot be edited so it has to be removed if ($editableField.fieldId -in $ItemObject.computedFields.id) { Write-Debug "Computed Field Found $($editableField.name)" $editableField = $null } $result.add($editableField) } # need to fake a field if on versioned item there are no significant change for me it means all needs to be reset, if ($result.Count -eq 0) { $fakeField = [PSCustomObject]@{ Name = "Fake Field" } $result.add($fakeField) } if ($result.name) { $fieldsNotFound = (compare-Object -ReferenceObject $result.name -DifferenceObject $ItemObject.Copytemplate.editableFields.name).InputObject foreach ($notFound in $fieldsNotFound) { $notfoundfield = $ItemObject.Copytemplate.editableFields | Where-Object { $_.name -eq $notFound } if ($notfoundfield.psobject.Properties.name -contains "values") { [array]$notfoundfield.values = @() } if ($notfoundfield.psobject.Properties.name -contains "value") { $notfoundfield.value = "" if ($notfoundfield.type -eq "DateFieldValue") { $notfoundfield = $notfoundfield | Select-Object -ExcludeProperty value } } Write-Debug "notfound : $($notfoundfield.name)" $result.add($notfoundfield) } } if ($ItemObject.chosenFields) { $chosenfieldlist = New-Object 'System.Collections.Generic.List[psobject]' Write-debug "Fields Choosen by User: $($ItemObject.chosenFields)" foreach ($fieldObject in $result) { if ($fieldObject.name -in $ItemObject.chosenFields) { Write-Debug "fieldObject: $fieldObject" $chosenfieldlist.Add($fieldObject ) } } $result = $chosenfieldlist } Write-Output -InputObject $result } function Get-CBTrackerBaseLine { <# .SYNOPSIS Retrieves all baselines for a specified tracker from the Codebeamer server. .DESCRIPTION The `Get-CBTrackerBaseLine` function fetches the list of baselines associated with a given tracker ID in Codebeamer. It returns references to each baseline and provides information about the result set, such as page, page size, and total count. .PARAMETER TrackerID The ID of the tracker for which to retrieve baselines. This parameter is mandatory. .PARAMETER CBSession The session object containing server URL and headers. This parameter is mandatory and can be accessed using the alias 'cbs'. .EXAMPLE Get-CBTrackerBaseLine -TrackerID 12345 -CBSession $cbSession Retrieves all baselines for tracker ID 12345. .NOTES - Returns baseline references as provided by the Codebeamer REST API. - Writes informational output about the result set. - Handles errors for invalid tracker IDs. #> [CmdletBinding()] param ( [Parameter(Mandatory, Position = 0)] [string]$TrackerID, [Parameter(Mandatory)] [Alias("cbs")] [pscustomobject]$CBSession ) try { $uri = "https://{0}/cb/api/v3/trackers/{1}/baselines" -f $CBSession.Server, $TrackerID Write-Debug -Message "uri: $uri" $result = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -ErrorAction Stop $result.references $messageData = @" Command Information: "Page: $($result.page), Page Size: $($result.pageSize), Total: $($result.total), Tricker Item ID: $($TrackerID)" "@ Write-Information -MessageData $messageData } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Tracker is not found.*" } { Write-Error "Tracker ID: $TrackerID most likely doesn't exist. Please recheck Tracker ID or Server." } Default { Write-Error $fullError } } } } function New-CBBaseline { <# .SYNOPSIS Creates a new baseline in the Codebeamer Server within a specified project and tracker. .DESCRIPTION The `New-CBBaseline` function establishes a new baseline within a given project, optionally associated with a tracker, in the Codebeamer Server. It leverages a RESTful API call to perform the operation, allowing users to specify various attributes for the baseline. .PARAMETER ProjectID Specifies the ID of the project where the baseline will be created. This parameter is mandatory. .PARAMETER TrackerID Indicates the ID of the tracker linked to the baseline, if applicable. This parameter is optional. .PARAMETER Name Represents the name of the new baseline. This parameter is mandatory. .PARAMETER Description Provides a description for the new baseline. This parameter is mandatory. .PARAMETER CBSession Represents the CB Session object that includes necessary connection details such as server URL and headers. This parameter is mandatory and can be accessed using the alias 'cbs'. .EXAMPLE Creates Basline for whole Project New-CBBaseline -ProjectID 5678 -Name "NewBaseline" -Description "Initial Baseline for Project" -CBSession $cbSession .EXAMPLE This example creates a baseline linked to tracker ID 1234 in project ID 5678, facilitating focused management within the tracker context. New-CBBaseline -ProjectID 5678 -TrackerID 1234 -Name "NewBaselineWithTracker" -Description "Baseline linked to a tracker" -CBSession $cbSession .NOTES - The function supports ShouldProcess, providing confirmation before the creation operation. - Debug information provides insights into URI construction and JSON payload for transparency and troubleshooting. - Error handling accommodates common issues like duplicate baselines, invalid tracker IDs, and project existence, ensuring clear feedback. #> [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory, Position = 0)] [int]$ProjectID, [Parameter(Position = 1)] [int]$TrackerID, [Parameter(Mandatory)] [string]$name, [Parameter(Mandatory)] [string]$Description, [Parameter(Mandatory)] [Alias("cbs")] [PSCustomObject]$CBSession ) try { $basicinfo = @{ description = $Description name = $name project = [PSCustomObject]@{ id = $ProjectID } } if ($TrackerID) { $tracker = [PSCustomObject]@{ id = $TrackerID } $basicinfo.add("tracker", $tracker) } $body = $basicinfo | ConvertTo-Json -Depth 10 if ($PSCmdlet.ShouldProcess($CBSession.Server, "New Baseline will be created in Project ID: $ProjectID")) { $uri = "https://{0}/cb/api/v3/baselines" -f $CBSession.Server Write-Debug "uri: $uri" Write-Debug "body: $body" Invoke-RestMethod -Uri $uri -Method POST -Headers $CBSession.headers -Body $body -ErrorAction Stop } } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Tracker is not found.*" } { Write-Error "Tracker ID: $TrackerID most likely doesn't exist. Please recheck Tracker ID or Server." } { $_ -like "*Baseline already exists*" } { $message = "{0} Please change the name: {1}" -f ($fullError.ErrorDetails.Message | ConvertFrom-Json).message, $name Write-Error $message } { $_ -like "*Project is not found*" } { Write-Error "Project ID: $ProjectID most likely doesn't exist. Please recheck Project ID or Server." } Default { Write-Error $fullError } } } } function Register-CBSecretVault { <# .SYNOPSIS Registers and stores Codebeamer credentials in a secret vault within the local file system. .DESCRIPTION The `Register-CBSecretVault` function prompts users to input credentials for Codebeamer production and administrative access. These credentials are securely stored as JSON objects in the user's application data directory, facilitating future access while maintaining confidentiality. .PARAMETER None The function does not accept any input parameters. It relies on user interaction for credential collection. .EXAMPLE Register-CBSecretVault This example initiates the registration process, prompting the user to input credentials for Codebeamer production and administrative accounts, storing them securely. .NOTES - The function utilizes `Get-Credential` to prompt for and securely collect username and password information. - Secure strings are converted before storage, ensuring the passwords are not stored in plaintext. - Stored credentials are accessible from the JSON file created in the `%APPDATA%\pscodebeamer\cbVault.json` path. - The directory and file are created if they do not exist, ensuring a safe location for credential storage. - Future enhancements may include additional security measures, such as encryption for the storage file itself. #> $info = Get-Credential -Message "Codebeamer Production" $production = $info | Select-Object UserName, @{name = "Password"; Expression = { ConvertFrom-SecureString $_.Password } } $info = Get-Credential -Message "Codebeamer Administrator" $Administration = $info | Select-Object UserName, @{name = "Password"; Expression = { ConvertFrom-SecureString $_.Password } } $Vault = @{ CodebeamerProduction = $production CodebeamerAdministrator = $Administration } $path = Split-Path -Path $env:APPDATA\pscodebeamer\cbVault.json switch (Test-path -Path $path) { $true { $Vault | ConvertTo-Json | Out-File -FilePath $path\cbVault.json -Force ; break } $false { $path = New-Item -Path $env:APPDATA -Name pscodebeamer -ItemType Directory | Resolve-Path $Vault | ConvertTo-Json | Out-File -FilePath $path\cbVault.json ; break } } Write-Output "Vault registered under $($path)\cbVault.json" } function Use-CBCredential { <# .SYNOPSIS Retrieves stored Codebeamer credentials from the local secret vault. .DESCRIPTION The `Use-CBCredential` function loads Codebeamer credentials (production or administrator) from a secure vault stored in the user's AppData directory. It returns a PSCredential object for use in authentication with Codebeamer APIs. If the vault does not exist, it prompts the user for credentials. .PARAMETER CodebeamerAdministrator Retrieves the administrator credentials from the vault. .PARAMETER CodebeamerProduction Retrieves the production credentials from the vault. .PARAMETER asPlainText Returns the password as plain text instead of a secure string. .EXAMPLE Use-CBCredential -CodebeamerProduction Retrieves the production credentials as a PSCredential object. .EXAMPLE Use-CBCredential -CodebeamerAdministrator -asPlainText Retrieves the administrator credentials and returns the password as plain text. .NOTES - The function expects the credential vault to be registered using Register-CBSecretVault. - If the vault is missing, the user will be prompted for credentials. - Credentials are stored in `%APPDATA%\pscodebeamer\cbVault.json`. #> param ( [Parameter(ParameterSetName = "CodebeamerAdministrator")] [switch]$CodebeamerAdministrator, [Parameter(ParameterSetName = "CodebeamerProduction")] [switch]$CodebeamerProduction, [Parameter()] [switch]$asPlainText ) $secretVault = Join-Path -Path $env:APPDATA -ChildPath pscodebeamer\cbVault.json Write-Debug "Vault:$($secretVault)" $credentials = Switch ((Test-Path -Path $secretVault) -eq $false ) { $true { Get-Credential -Message "please Enter Credentials" } $False { switch ($true) { { $CodebeamerAdministrator.IsPresent } { $credentials = Get-Content -Path $secretVault | ConvertFrom-Json | Select-Object -ExpandProperty CodebeamerAdministrator | Select-Object UserName, @{name = "Password" ; Expression = { Convertto-SecureString $_.Password } } New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $credentials.UserName, $credentials.Password } { $CodebeamerProduction.IsPresent } { $credentials = Get-Content -Path $secretVault | ConvertFrom-Json | Select-Object -ExpandProperty CodebeamerProduction | Select-Object UserName, @{name = "Password"; Expression = { Convertto-SecureString $_.Password } } New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $credentials.UserName, $credentials.Password } } } } if ($asPlainText.IsPresent) { $credentials | Select-Object UserName, @{Name = "Password"; Expression = { ConvertFrom-SecureString $_.Password -AsPlainText } } } else { $credentials } } function ConvertTo-CBChoiceField { [CmdletBinding(DefaultParameterSetName = "Field")] param ( [Parameter(ParameterSetName = "Field")] [string[]]$Fields, [Parameter(ParameterSetName = "FieldWithValue")] [hashtable]$FieldWithValue, [Parameter(Mandatory, ParameterSetName = "Field")] [Parameter(Mandatory, ParameterSetName = "FieldWithValue")] [int]$TrackerID, [Parameter(ParameterSetName = "Field")] [Parameter(ParameterSetName = "FieldWithValue")] [switch]$DefaultValues, [Parameter(Mandatory, ParameterSetName = "Field")] [Parameter(Mandatory, ParameterSetName = "FieldWithValue")] [Alias("cbs")] [PSCustomObject]$CBSession ) try { $fieldNames = [ordered]@{} $valueList = New-Object 'System.Collections.Generic.List[psobject]' $uri = "https://{0}/cb/api/v3/trackers/{1}/schema" -f $CBSession.Server, $TrackerID Write-Debug "uri: $uri" $trackerSchema = Invoke-RestMethod -Uri $uri -Method Get -Headers $CBSession.headers -errorAction Stop $fieldLabels = switch ($PSCmdlet.ParameterSetName) { "Field" { $Fields } "FieldWithValue" { $FieldWithValue.Keys } default { "Well something went worng" } } $result = foreach ($field in $fieldLabels) { $fieldProperties = $trackerSchema | Where-Object { $_.name -eq $field } if (-not $fieldProperties) { throw "Field $field does not exist in Tracker: $TrackerID" } switch ($fieldProperties) { { $_.valueModel -eq "NotSupportedFieldValue" } { Write-Debug $_.name Write-Debug $_.id if ($_.name -eq "Parent") { $type = "TrackerItemReference" } else { $message = "Fields $($fieldProperties.name) value model is type of NotSupportedFieldValue and it will be skipped" Write-Warning -Message $message } continue } { $_.valueModel -notlike "ChoiceFieldValue*" } { $message = "Fields $($fieldProperties.name) value model is type of $($fieldProperties.valueModel) and it will be skipped" Write-Warning -Message $message continue } { $fieldProperties.type -eq "MemberField" } { $type = "UserReference" } Default { $type = $_.referenceType } } $valueList = if ($FieldWithValue) { foreach ($value in $FieldWithValue[$field]) { [pscustomobject]@{ id = $value type = $type } } } else { [array]@([pscustomobject]@{ id = $value type = $type } ) } $fieldNames["fieldId"] = $fieldProperties.id $fieldNames["name"] = $fieldProperties.name $fieldNames["values"] = $valueList $fieldNames["sharedFieldName"] = "" $fieldNames["type"] = "ChoiceFieldValue" New-Object -TypeName psobject -Property $fieldNames } Write-Output $result } catch { $fullError = $_ switch ($_.ErrorDetails.Message) { { $_ -like "*Tracker is not found*" } { Write-Error "Tracker ID: $TrackerID most likely doesn't exist. Please recheck Tracker ID or Server." } Default { Write-Error $fullError } } } } $scriptBlock = { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $config = Join-Path -Path $env:appDATA -ChildPath \pscodebeamer\config.json $request = ([System.IO.File]::ReadAllText($config) | ConvertFrom-Json).CBQLQuery | Where-Object -FilterScript { $_ -match $wordToComplete } foreach ( $Project in $request ) { New-CompletionResult -CompletionText $Project -ListItemText $Project } } Register-ArgumentCompleter -CommandName Invoke-CBQL -ParameterName cbQLString -ScriptBlock $scriptBlock |