Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

azure devops - Upgrade AzureRM Powershell on Hosted 2017 Agent (VSTS - Visual Studio Team Services)

I am using release management through Visual Studio Teams Services (online). We use Hosted build Agents and I really want to avoid the overhead of managing custom agents.

One item I do need is the AzureRM PowerShell module. Versions up to 5.1.1 are available on the agent but I need 6.0.0.

What I would like to do is use a step in my release process (PowerShell) to aquire version 6.0.0 and use thart instead, however I cant quite get it to work. I have tried a few approaches that have all come unstuck, the current one is:

Write-Output "------------------ Install package provider ------------------"
Find-PackageProvider -Name "NuGet" | Install-PackageProvider -Scope CurrentUser -Force

Write-Output "------------------ Remove Modules ------------------"
Get-Module -ListAvailable | Where-Object {$_.Name -like 'AzureRM*'} | Remove-Module

Write-Output "------------------ Install the AzureRM version we want - 6.0.1!  ------------------"
Install-Package AzureRM -RequiredVersion 6.0.1 -Scope CurrentUser -Force

Write-Output "------------------ Import AzureRM 6.0.1  ------------------"
Import-Module AzureRM -RequiredVersion 6.0.1

This all works fine (i.e. does not crash...) but then when I try and use one of the 6.0.1 cmdlets I get an error.

Get-AzureRmADGroup : The Azure PowerShell session has not been properly initialized. Please import the module and try again.

Any idea of where I am going wrong or alternate strategies I can use to deploy AzureRM 6.0.1 and use it on a hosted agent?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Thanks to Murray for the initial point in the right direction, to show what I was hoping to do wasn't impossible!

I initially tried to do this within the Azure PowerShell task and got pretty far but hit a dead end with AzureRm.Profile as you cannot unload an old version.

The trick was to understanding how the AzureRM VSTS task does it's dependency setup, it effectively takes the "Azure Powershell Version" string in the VSTS UI and uses it to define an additional search path in the PSModules environmental variable i.e. C:Modulesazurerm_5.1.1.

It will look in that directory, before searching the user profile, then the global modules path.

As soon as it finds the module it performs the Azure login, which will hamper any hope of removing the module after.

So if you instead use a plain powershell task i.e. one that AzureRM isn't loaded into (as Murray also concluded):

Plain Powershell Task

Install-PackageProvider -Name NuGet -Force -Scope CurrentUser
Install-Module -Name AzureRM -RequiredVersion 6.2.1 -Force -Scope CurrentUser -AllowClobber

Notably install-module won't be installing to c:modules like the vsts image generation project.

I seemed to need AllowClobber to get around problems overriding old powershell versions when experimenting, but I suspect I don't need that anymore.

The elegant solution kicks in when next using the Azure PowerShell script.

Azure PowerShell Task

The preferred powershell version field filled in with 6.2.1 will add C:Modulesazurerm_6.2.1 to the PSModules path. This doesn't exist, but thankfully because PSModules still includes the user specific modules path, so our 6.2.1 is loaded by itself!

Luckily the AzureRM.Profile from 5.1.1 is forwards compatible enough that the service principal login performed by the Azure Powershell task still works.

Running

Get-Module AzureRm 
Get-AzureRmContext

Will output the versions you are hoping for:

VSTS azure rm powershell versions

Notably if it weren't able to login, I think System.AccessToken could be used (if the option is switched on in the agent phase level).

Diagnostic Techniques if the workaround needs tweaking:

Things that helped greatly, reading through the code that loads in AzureRM in the task:

https://github.com/Microsoft/vsts-tasks/blob/master/Tasks/AzurePowerShellV3/AzurePowerShell.ps1#L80

https://github.com/Microsoft/vsts-tasks/blob/0703b8869041d64db994934bde97de167787ed2e/Tasks/Common/VstsAzureHelpers_/ImportFunctions.ps1

https://github.com/Microsoft/vsts-tasks/blob/master/Tasks/AzurePowerShellV3/Utility.ps1#L18

And also how the VSTS image is generated:

https://github.com/Microsoft/vsts-image-generation/blob/2f57db26dc30ae0f257a3415d26eaa8eea0febf9/images/win/scripts/Installers/Install-AzureModules.ps1

Enabing System.Debug = true as a environment release variable. Then using VSCode's Log File Highlighter plugin


I'd encourage anyone who's interested to vote in: https://github.com/Microsoft/vsts-image-generation/issues/149

As the AzureRM version at the time of writing is waaaay out of date on the VSTS Hosted 2017 agent.

Unfortunately I can't submit a PR to upgrade it, as it's pulled in via a zip file hosted privately.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...