From 7d90e81b01106b48088aca83830c7d5fb0df9b90 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 1 Dec 2025 09:44:48 +0000 Subject: [PATCH 1/4] Initial plan From f32f0f3bd9b67e68f16c9f96d541f26bdd5d4a36 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 1 Dec 2025 09:52:12 +0000 Subject: [PATCH 2/4] Add VssClientCredentials support for ClientOM 19+ with TfsClientCredentials fallback Co-authored-by: MantavyaDh <145761344+MantavyaDh@users.noreply.github.com> --- powershell/VstsTaskSdk/ServerOMFunctions.ps1 | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/powershell/VstsTaskSdk/ServerOMFunctions.ps1 b/powershell/VstsTaskSdk/ServerOMFunctions.ps1 index 6fd19ea13..6feccf091 100644 --- a/powershell/VstsTaskSdk/ServerOMFunctions.ps1 +++ b/powershell/VstsTaskSdk/ServerOMFunctions.ps1 @@ -104,6 +104,8 @@ Gets a credentials object that can be used with the TFS extended client SDK. .DESCRIPTION The agent job token is used to construct the credentials object. The identity associated with the token depends on the scope selected in the build/release definition (either the project collection build/release service identity, or the project build/release service identity). +For ClientOM 19 and later, VssClientCredentials is used. For older SDK versions, TfsClientCredentials is used as a fallback. + Refer to Get-VstsTfsService for a more simple to get a TFS service object. *** DO NOT USE Agent.ServerOMDirectory *** See https://github.com/Microsoft/azure-pipelines-task-lib/tree/master/powershell/Docs/UsingOM.md for reliable usage when working with the TFS extended client SDK from a task. @@ -164,6 +166,26 @@ function Get-TfsClientCredentials { } [System.AppDomain]::CurrentDomain.add_AssemblyResolve($onAssemblyResolve) + # Check if VssClientCredentials is available (ClientOM 19+). + # This type replaces TfsClientCredentials in newer SDK versions. + if ((Get-OMType -TypeName 'Microsoft.VisualStudio.Services.Client.VssClientCredentials' -OMKind 'ExtendedClient' -OMDirectory $OMDirectory)) { + # Check if VssOAuthAccessTokenCredential is available. + if ((Get-OMType -TypeName 'Microsoft.VisualStudio.Services.OAuth.VssOAuthAccessTokenCredential' -OMKind 'ExtendedClient' -OMDirectory $OMDirectory)) { + $federatedCredential = New-Object Microsoft.VisualStudio.Services.OAuth.VssOAuthAccessTokenCredential($endpoint.auth.parameters.AccessToken) + } else { + # Fallback to VssOAuthCredential. + $null = Get-OMType -TypeName 'Microsoft.VisualStudio.Services.Client.VssOAuthCredential' -OMKind 'ExtendedClient' -OMDirectory $OMDirectory -Require + $federatedCredential = New-Object Microsoft.VisualStudio.Services.Client.VssOAuthCredential($endpoint.auth.parameters.AccessToken) + } + + # Construct and return VssClientCredentials. + return New-Object Microsoft.VisualStudio.Services.Client.VssClientCredentials( + (New-Object Microsoft.VisualStudio.Services.Common.WindowsCredential($false)), # Do not use default credentials. + $federatedCredential, + [Microsoft.VisualStudio.Services.Common.CredentialPromptType]::DoNotPrompt) + } + + # Fallback to TfsClientCredentials for older SDK versions. # Validate the type can be found. $null = Get-OMType -TypeName 'Microsoft.TeamFoundation.Client.TfsClientCredentials' -OMKind 'ExtendedClient' -OMDirectory $OMDirectory -Require From 230f274682ed23bd2884dc3c23cdf1e034c87427 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 1 Dec 2025 09:54:07 +0000 Subject: [PATCH 3/4] Address code review: use graceful fallback instead of -Require flag Co-authored-by: MantavyaDh <145761344+MantavyaDh@users.noreply.github.com> --- powershell/VstsTaskSdk/ServerOMFunctions.ps1 | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/powershell/VstsTaskSdk/ServerOMFunctions.ps1 b/powershell/VstsTaskSdk/ServerOMFunctions.ps1 index 6feccf091..0947b39d0 100644 --- a/powershell/VstsTaskSdk/ServerOMFunctions.ps1 +++ b/powershell/VstsTaskSdk/ServerOMFunctions.ps1 @@ -169,20 +169,24 @@ function Get-TfsClientCredentials { # Check if VssClientCredentials is available (ClientOM 19+). # This type replaces TfsClientCredentials in newer SDK versions. if ((Get-OMType -TypeName 'Microsoft.VisualStudio.Services.Client.VssClientCredentials' -OMKind 'ExtendedClient' -OMDirectory $OMDirectory)) { + $federatedCredential = $null + # Check if VssOAuthAccessTokenCredential is available. if ((Get-OMType -TypeName 'Microsoft.VisualStudio.Services.OAuth.VssOAuthAccessTokenCredential' -OMKind 'ExtendedClient' -OMDirectory $OMDirectory)) { $federatedCredential = New-Object Microsoft.VisualStudio.Services.OAuth.VssOAuthAccessTokenCredential($endpoint.auth.parameters.AccessToken) - } else { - # Fallback to VssOAuthCredential. - $null = Get-OMType -TypeName 'Microsoft.VisualStudio.Services.Client.VssOAuthCredential' -OMKind 'ExtendedClient' -OMDirectory $OMDirectory -Require + } + # Fallback to VssOAuthCredential. + elseif ((Get-OMType -TypeName 'Microsoft.VisualStudio.Services.Client.VssOAuthCredential' -OMKind 'ExtendedClient' -OMDirectory $OMDirectory)) { $federatedCredential = New-Object Microsoft.VisualStudio.Services.Client.VssOAuthCredential($endpoint.auth.parameters.AccessToken) } - # Construct and return VssClientCredentials. - return New-Object Microsoft.VisualStudio.Services.Client.VssClientCredentials( - (New-Object Microsoft.VisualStudio.Services.Common.WindowsCredential($false)), # Do not use default credentials. - $federatedCredential, - [Microsoft.VisualStudio.Services.Common.CredentialPromptType]::DoNotPrompt) + if ($federatedCredential) { + # Construct and return VssClientCredentials. + return New-Object Microsoft.VisualStudio.Services.Client.VssClientCredentials( + (New-Object Microsoft.VisualStudio.Services.Common.WindowsCredential($false)), # Do not use default credentials. + $federatedCredential, + [Microsoft.VisualStudio.Services.Common.CredentialPromptType]::DoNotPrompt) + } } # Fallback to TfsClientCredentials for older SDK versions. From c8855e1d0800ffc20f00b762b26781065cab31dc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 1 Dec 2025 09:55:49 +0000 Subject: [PATCH 4/4] Add verbose logging when falling back from VssClientCredentials to TfsClientCredentials Co-authored-by: MantavyaDh <145761344+MantavyaDh@users.noreply.github.com> --- powershell/VstsTaskSdk/ServerOMFunctions.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/powershell/VstsTaskSdk/ServerOMFunctions.ps1 b/powershell/VstsTaskSdk/ServerOMFunctions.ps1 index 0947b39d0..4fee87df0 100644 --- a/powershell/VstsTaskSdk/ServerOMFunctions.ps1 +++ b/powershell/VstsTaskSdk/ServerOMFunctions.ps1 @@ -187,6 +187,8 @@ function Get-TfsClientCredentials { $federatedCredential, [Microsoft.VisualStudio.Services.Common.CredentialPromptType]::DoNotPrompt) } + + Write-Verbose "VssClientCredentials is available but no compatible OAuth credential type was found. Falling back to TfsClientCredentials." } # Fallback to TfsClientCredentials for older SDK versions.