Search code examples
powershellazure-devopspipelineexecutionpolicy

Self-hosted agent DevOps pipeline build failing because of powershell execution policy


I have a Self-hosted agent version (3.236.1), have 3 such agents. DevOps pipeline builds are failing with error like below. I went through lots of Microsoft articles to set Execution policy for current user, local machine, Machine policy etc.

If I set the policy for Current user or local machine its not working get same error as below

Build works only with if I set the Machine policy. Using

Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\PowerShell -Name ExectionPolicy -Value ByPass (or RemoteSighed)

However, this setting gets over-written after some time by org group policy.

Our IT is reluctant to change the Machine policy permanently for the agents to work.

Can anyone please suggest a permanent solution or work around for this problem. There are lot of VSBuild scripts inside the parent directory c:\agent\agent01(02,03)_Work\Task...

Thanks

ERROR:

File C:\agent\agent01\_work\_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca411ecda\1.231.0\ps_modules\Vsts
TaskSdk\VstsTaskSdk.psm1 cannot be loaded. The file C:\agent\agent01\_work\_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca
411ecda\1.231.0\ps_modules\VstsTaskSdk\VstsTaskSdk.psm1 is not digitally signed. You cannot run this script on the 
current system. For more information about running scripts and setting execution policy, see about_Execution_Policies 
at https:/go.microsoft.com/fwlink/?LinkID=135170.

##[error]Exit code 1 returned from process: file name 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe', arguments '-NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command ". ([scriptblock]::Create('if ([Console]::InputEncoding -is [Text.UTF8Encoding] -and [Console]::InputEncoding.GetPreamble().Length -ne 0) { [Console]::InputEncoding = New-Object Text.UTF8Encoding $false } if (!$PSHOME) { $null = Get-Item -LiteralPath ''variable:PSHOME'' } else { Import-Module -Name ([System.IO.Path]::Combine($PSHOME, ''Modules\Microsoft.PowerShell.Management\Microsoft.PowerShell.Management.psd1'')) ; Import-Module -Name ([System.IO.Path]::Combine($PSHOME, ''Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1'')) }')) 2>&1 | ForEach-Object { Write-Verbose $_.Exception.Message -Verbose } ; Import-Module -Name 'C:\agent\agent01\_work\_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca411ecda\1.231.0\ps_modules\VstsTaskSdk\VstsTaskSdk.psd1' -ArgumentList @{ NonInteractive = $true } -ErrorAction Stop ; $VerbosePreference = 'Continue' ; $DebugPreference = 'Continue' ; Invoke-VstsTaskScript -ScriptBlock ([scriptblock]::Create('. ''C:\agent\agent01\_work\_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca411ecda\1.231.0\VSBuild.ps1'''))"'.

Solution

  • The cause of the issue is that the psm1 files of the Pipeline task are not signed.

    Can anyone please suggest a permanent solution or work around for this problem.

    Since you don't want to set a policy to bypass it, I suggest you create a certificate to sign the relevant files.

    Here are the steps:

    Step1: Create Certificate on machine

    $authenticode = New-SelfSignedCertificate -Subject “AZUR-SelfhostedAgent” -CertStoreLocation Cert:\\LocalMachine\\My -Type CodeSigningCert 
    

    Step2: Copy Certificate to RootCA-Store

    $rootStore = [System.Security.Cryptography.X509Certificates.X509Store]::new(“Root”,“LocalMachine”)  
    $rootStore.Open(“ReadWrite”)  
    $rootStore.Add($authenticode)  
    $rootStore.Close()
    

    Step3: Copy to TrustedPublisher-Store

    $publisherStore = [System.Security.Cryptography.X509Certificates.X509Store]::new(“TrustedPublisher”,“LocalMachine”)  
    $publisherStore.Open(“ReadWrite”)  
    $publisherStore.Add($authenticode)  
    $publisherStore.Close()
    

    Step4: Check Certificates in all three stores

    Get-ChildItem Cert:\\LocalMachine\\My | Where-Object {$_.Subject -eq “CN=AZUR-SelfhostedAgent”}  
    Get-ChildItem Cert:\\LocalMachine\\Root | Where-Object {$_.Subject -eq “CN=AZUR-SelfhostedAgent”}  
    Get-ChildItem Cert:\\LocalMachine\\TrustedPublisher | Where-Object {$_.Subject -eq “CN=AZUR-SelfhostedAgent”}
    

    For example:

    enter image description here

    Step5: Sign all the .psm1 files and .ps1 files of the Pipeline tasks.

    For example:

    $codeCertificate = Get-ChildItem Cert:\\LocalMachine\\My | Where-Object {$_.Subject -eq “CN=AZUR-SelfhostedAgent”}  
    Set-AuthenticodeSignature -FilePath “C:\agent\agent01\_work\_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca411ecda\1.231.0\ps_modules\Vsts
    TaskSdk\*.ps*” -Certificate $codeCertificate  
    Set-AuthenticodeSignature -FilePath “C:\agent\agent01\_work\_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca411ecda\1.231.0\*.ps1” -Certificate $codeCertificate  
      
    

    Result sample:

    enter image description here

    Note: You need to run these commands in PowerShell Administrator mode.