Summary
AzurePowerShell@5 tasks with pwsh: true fail unconditionally on current PowerShell 7 builds (confirmed on 7.6.5, not on 7.6.2) with:
WARNING: Proxy creation has been skipped for the following command: 'ConvertFrom-SecureString, ConvertTo-SecureString, Get-Acl, Get-AuthenticodeSignature, Get-CmsMessage, Get-Credential, Get-ExecutionPolicy, Get-PfxCertificate, New-FileCatalog, Protect-CmsMessage, Set-Acl, Set-AuthenticodeSignature, Set-ExecutionPolicy, Test-FileCatalog, Unprotect-CmsMessage', because it would shadow an existing local command. Use the AllowClobber parameter if you want to shadow existing local commands.
##[error]Failed to generate proxies for remote module 'Microsoft.PowerShell.Security'. No command proxies have been created, because all of the requested remote commands would shadow existing local commands. Use the AllowClobber parameter if you want to shadow existing local commands.
##[error]PowerShell exited with code '1'.
The task fails before the user's own Inline/ScriptPath content ever runs — the error originates in VstsTaskSdk.psm1, which is dot-sourced (via ImportVstsTaskSdk.ps1) as the very first thing AzurePowerShellV5's generated script does, before InitializeAz.ps1 or any pipeline-authored code.
Root cause
VstsTaskSdk.psm1 contains:
# Load the module that contains ConvertTo-SecureString.
if (!(Get-Module -Name Microsoft.PowerShell.Security)) {
Write-Verbose "Importing the module 'Microsoft.PowerShell.Security'."
Import-Module -Name Microsoft.PowerShell.Security 2>&1 |
ForEach-Object {
if (`$_ -is [System.Management.Automation.ErrorRecord]) {
Write-Verbose `$_.Exception.Message
} else {
,`$_
}
}
}
On a fresh -NoProfile -NonInteractive pwsh session where Microsoft.PowerShell.Security isn't already loaded, this plain Import-Module call — with no -UseWindowsPowerShell and no -AllowClobber — ends up routed through Windows PowerShell Compatibility on current PS7 builds, and hits WinCompat's hard-coded no-clobber protection for that module (one of the 7 "core" modules protected since PS 7.1 per about_Windows_PowerShell_Compatibility). The if (!(Get-Module ...)) guard means this only fires when the module genuinely isn't pre-loaded yet — which is exactly the state of a freshly-started task process.
Minimal repro
No Azure auth, no Az module, no pipeline needed — reproduces standalone:
pwsh -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command "if (!(Get-Module -Name Microsoft.PowerShell.Security)) { Import-Module -Name Microsoft.PowerShell.Security -ErrorAction Stop }; Write-Output 'SUCCEEDED'"
- PowerShell 7.6.2: prints
SUCCEEDED.
- PowerShell 7.6.5: throws the exact error above.
Important nuance found during investigation
This only reproduces on a real, deployed/specialized Windows instance — we could not reproduce it on a freshly-provisioned VM that had never been through Windows sysprep/generalize + first-boot specialize (both 7.6.2 and 7.6.5 succeed there). Once deployed from a captured, sysprepped image, both PS7 builds we tested reproduce the clobber depending on version as above. We don't have a root cause for why sysprep state matters here, but it's a precondition worth knowing when trying to reproduce this.
Impact
Any AzurePowerShell@5 task with pwsh: true fails immediately and unconditionally, regardless of the task's own script content, service connection type, or Az module version (LatestVersion vs pinned) — because the failure happens in VstsTaskSdk.psm1, before InitializeAz.ps1 (which handles the actual azurePowerShellVersion module selection) even runs.
Workaround
We worked around this by switching the affected tasks from AzurePowerShell@5 to AzureCLI@2 (scriptType: pscore), bridging the az CLI's own service-connection auth into an Az PowerShell context manually via Connect-AzAccount -AccessToken .... AzureCLI@2's PowerShell invocation (ScriptType.ts) never dot-sources VstsTaskSdk, so it isn't exposed to this bug at all. This is a functional workaround, not a fix — ideally AzurePowerShellV5 shouldn't fail here in the first place.
Suggested fix
The Import-Module -Name Microsoft.PowerShell.Security call in VstsTaskSdk.psm1 only exists to guarantee ConvertTo-SecureString is available (per its own comment). Since Microsoft.PowerShell.Security is a native, bundled PS7 module and this failure mode only occurs via a clobber-protection false-positive, either:
- Wrap the call with
-ErrorAction SilentlyContinue (the module's cmdlets are used elsewhere unconditionally regardless, so a failed proxy-generation attempt for an already-available native module shouldn't be fatal to the whole task), or
- Check for the specific cmdlet (
Get-Command ConvertTo-SecureString -ErrorAction SilentlyContinue) rather than the module, since PS7 natively provides it without needing this import at all.
Environment
- Task:
AzurePowerShellV5
- Agent: Windows, self-hosted Azure DevOps Managed DevOps Pool
- PowerShell: 7.6.5 (repros), 7.6.2 (does not repro)
pwsh: true, azurePowerShellVersion: LatestVersion
Summary
AzurePowerShell@5tasks withpwsh: truefail unconditionally on current PowerShell 7 builds (confirmed on 7.6.5, not on 7.6.2) with:The task fails before the user's own
Inline/ScriptPathcontent ever runs — the error originates inVstsTaskSdk.psm1, which is dot-sourced (viaImportVstsTaskSdk.ps1) as the very first thingAzurePowerShellV5's generated script does, beforeInitializeAz.ps1or any pipeline-authored code.Root cause
VstsTaskSdk.psm1contains:On a fresh
-NoProfile -NonInteractivepwsh session whereMicrosoft.PowerShell.Securityisn't already loaded, this plainImport-Modulecall — with no-UseWindowsPowerShelland no-AllowClobber— ends up routed through Windows PowerShell Compatibility on current PS7 builds, and hits WinCompat's hard-coded no-clobber protection for that module (one of the 7 "core" modules protected since PS 7.1 per about_Windows_PowerShell_Compatibility). Theif (!(Get-Module ...))guard means this only fires when the module genuinely isn't pre-loaded yet — which is exactly the state of a freshly-started task process.Minimal repro
No Azure auth, no Az module, no pipeline needed — reproduces standalone:
SUCCEEDED.Important nuance found during investigation
This only reproduces on a real, deployed/specialized Windows instance — we could not reproduce it on a freshly-provisioned VM that had never been through Windows sysprep/generalize + first-boot specialize (both 7.6.2 and 7.6.5 succeed there). Once deployed from a captured, sysprepped image, both PS7 builds we tested reproduce the clobber depending on version as above. We don't have a root cause for why sysprep state matters here, but it's a precondition worth knowing when trying to reproduce this.
Impact
Any
AzurePowerShell@5task withpwsh: truefails immediately and unconditionally, regardless of the task's own script content, service connection type, or Az module version (LatestVersionvs pinned) — because the failure happens inVstsTaskSdk.psm1, beforeInitializeAz.ps1(which handles the actualazurePowerShellVersionmodule selection) even runs.Workaround
We worked around this by switching the affected tasks from
AzurePowerShell@5toAzureCLI@2(scriptType: pscore), bridging the az CLI's own service-connection auth into an Az PowerShell context manually viaConnect-AzAccount -AccessToken ....AzureCLI@2's PowerShell invocation (ScriptType.ts) never dot-sourcesVstsTaskSdk, so it isn't exposed to this bug at all. This is a functional workaround, not a fix — ideallyAzurePowerShellV5shouldn't fail here in the first place.Suggested fix
The
Import-Module -Name Microsoft.PowerShell.Securitycall inVstsTaskSdk.psm1only exists to guaranteeConvertTo-SecureStringis available (per its own comment). SinceMicrosoft.PowerShell.Securityis a native, bundled PS7 module and this failure mode only occurs via a clobber-protection false-positive, either:-ErrorAction SilentlyContinue(the module's cmdlets are used elsewhere unconditionally regardless, so a failed proxy-generation attempt for an already-available native module shouldn't be fatal to the whole task), orGet-Command ConvertTo-SecureString -ErrorAction SilentlyContinue) rather than the module, since PS7 natively provides it without needing this import at all.Environment
AzurePowerShellV5pwsh: true,azurePowerShellVersion: LatestVersion