We have a build pipeline that includes an Azure File Copy task which copies some files from our build output to an Azure VM.
Every day now for at least a week this task has been failing with the following error:
##[error]Failed to enable copy prerequisites. Multiple VMExtensions per handler not supported for OS type 'Windows'. VMExtension
'WinRMCustomScriptExtension' with handler
'Microsoft.Compute.CustomScriptExtension' already added or specified
in input.
We have had this issue before a few times, however, the problem has, up until now seamed to corrected itself without any changes by us. This time however, it does not look like the problem is going to resolve itself without some changes or intevention.
Can you help?
Could you please provide some more information?
Which version of Copy Files are you using?
Are you using Classic or Azure Pipelines?
Which agent pool are you using?
Can you post the yaml of the Task here like this:
steps:
- task: CopyFiles#2
displayName: 'Copy Files to: 123'
inputs:
TargetFolder: /output
Azure File Copy task might fail to remove a custom extension after finishing using it. You can refer to an issue reported here.
You can try using the newest version of task Azure File Copy. Or try running below scripts to uninstall the extension before using this task as suggested in the issue thread above..
$ExtensionName = Get-AzureRmVMExtension -ResourceGroupName $VM.ResourceGroupName -VMName $VM.Name -Name WinRMCustomScriptExtension
Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $VM.ResourceGroupName -VmName $VM.Name -Name $ExtensionName
Related
Trying to deploy to Azure using a bicep template that I'm calling from PowerShell within VSCode as follows:
New-AzResourceGroupDeployment -Name Deployment1 -ResourceGroupName $resourceGroupName -TemplateFile $templateFile -TemplateParameterFile $parameterFile
This has been working fine but when I added the following lines (to create a blob container)
resource callDataContainer 'Microsoft.Storage/storageAccounts/blobServices/containers#2021-04-01' = {
name: '${storageAccountName}/default/call-data'
}
It fails with:
Cannot find path 'C:\Users\<user>\AppData\Local\Temp\<guid>\<template>.json
I've proved that the bicep template is ok with:
az bicep build --file .\<template>.bicep
and this compiles to a json arm template ok
Since the "Cannot find path" error message is a little unhelpful any ideas what else I can do to figure out the cause?
Juts came back to this after the weekend and it worked fine 🤔
I hit this problem again (v0.4.613 of the Bicep CLI). This time it was because I'd changed the name used for an output param of a called module. I found that even though the bicep file compiled ok, when I checked the created json it still had the old name - even after deleting and re-creating the json file.
The error message when calling the deployment from the PowerShell command "New-AzResourceGroupDeployment" was not helpful but when using the Azure CLI equivalent "az deployment group create" this did point me at the cause of the problem.
I am trying to SysPrep a VM in Azure via Azure DevOps YAML pipelines. In the same pipeline (previous stage), I am deploying the VM via Azure Resource Manager (ARM) templates and copying scripts and files to the machine. I want to automate the whole process so RDP'ing into the machine is not an option. When I run SysPrep on the VM, I am getting the following error message:
##[error]The remote session query failed for <insertMyFQDN>.eastus.cloudapp.azure.com with the following error message: Access is denied.
From my repo I have a couple of files, including a PowerShell script that SysPreps the machine (sysPrepvm.ps1) - taken from Run SysPrep remotely through commands from Azure powershell. The script works when I am logged in on the machine and run in manually.
sysPrepvm.ps1
$sysPrepPath = 'C:\Windows\System32\Sysprep\Sysprep.exe'
$arguments = '/generalize /oobe /shutdown /quiet'
Invoke-Command -ScriptBlock {param($sysPrepPath,$arguments) Start-Process -FilePath $sysPrepPath -ArgumentList $arguments} -ArgumentList $sysPrepPath,$arguments
I am using the built-in task in Azure DevOps, "Powershell on Target Machines", with which I am able to invoke other commands or scripts, so I am confident that the task works.
My Stage in the YAML Pipeline looks like this:
- stage:
displayName: SysPrep
variables:
azFQDN: $[stageDependencies.Connect.connect.outputs['SetEnvVars.azFQDN']]
jobs:
- job: SysPrepVhD
steps:
- task: PowerShellOnTargetMachines#3
inputs:
Machines: '$(azFQDN)' # FQDN on the machine
UserName: '$(adminUser)'
UserPassword: '$(adminPw)'
ScriptType: 'FilePath'
ScriptPath: 'C:\Windows\System32\Sysprep\fishtank\sysPrepvm.ps1'
Is there a limitation of running this remotely? I haven't been able to find a work-around yet, so any answer is greatly appreciated.
Edit
I have also tried running the script with -Verb RunAs, as an Inline script instead of File, as well as tried the accepted answer on the previous post:
Sysprep an Azure VM using PowerShell task in a pipeline
I managed to find a way using Custom Script Extension instead. I didn't think of doing this at first, since the ARM template I am using already has a Custom Script Extension on the machine to enable WinRM, and cannot have multiple Custom Script Extensions installed at the same time. Also, I didn't want to execute SysPrep as soon as the machine booted because it had to run other scripts and settings first. In my YAML pipeline, I managed to remove the existing one to redeploy a new Custom Script Extension with the script included.
I posted the entire solution on GitHub - https://github.com/Crytlig/azsysprep - for anyone in interested. It obviously needs a bit of cleaning but it works as is.
My (dotNET) application is built (using a Windows Hosted agent), from a build pipeline, and in the subsequent Release pipeline, I provision a 16GB-Win2016 VM (enabling RDP, HTTP, HTTPS, WinRM and SSH), into which I RDP manually (there is a Manual Intervention task here), and configure WinRM (following this article: https://learn.microsoft.com/en-us/azure/marketplace/cloud-partner-portal/virtual-machine/cpp-configure-winrm-after-vm-creation#configure-vm-to-enable-winrm). Everything is fine until here. The next task is a Azure File Copy task, which essentially copies the Build artifacts (from $(System.DefaultWorkingDirectory)) and pastes into a directory I specify. Works like a charm. The next task I have is to create a VHD of this whole VM (essentially after the copying is done).
I know I can manually RDP into the VM (again) and sysprep (with oobe/generalize/shutdown), then maybe go back to the Azure Portal and Disk Export the OS Disk (specifying the SAS URL expiration time at whatever (36000 per the article)) BUT can this all be automated?
So, long story short - I'd like to know if sysprep oobe/generalize/shutdown can be performed remotely preferably over a PS task. I understand the other part of it (exporting the disk and all) can be, but if sysprep can be done remotely nothing like it.
I tried this and got what I wanted:
$sysprep= 'C:\Windows\System32\Sysprep\Sysprep.exe'
$arg1 = '/generalize'
$arg2 = '/oobe'
$arg3 = '/shutdown'
$arg4 = '/quiet'
& $sysprep $arg1 $arg2 $arg3 $arg4 -Wait
Make sure you do NOT use Azure custom script extension to run sysprep.
Azure scripts run under the LocalSystem user context: source
Custom Script Extension will run under the LocalSystem Account
This is problematic because sysprep does NOT support running under a system user context: source
Sysprep cannot be run under the context of a System account. Running Sysprep under the context of System account by using Task Scheduler or PSExec, for example, is not supported.
Providing this so that people avoid my mistake :)
So, you dont have to configure winrm manually, you can script it\configure it while provisioning the vm. and if\when winrm is working you can just use powershell remoting to issue a command against the vm with:
Invoke-Command -ComputerName dnsname\ipaddress_goes_hehe
-ScriptBlock { sysprep /shutdown /generalise}
https://github.com/Azure/azure-quickstart-templates/tree/master/201-vm-winrm-windows
You can implement this using an Azure custom script extension. There is a github project:
https://github.com/jlongo62/AzureVMToImage containing powershell scripts to image a VM. These scripts were built to preserve VM when creating an image, instead of destroying the original VM. The scripts can be called from Azure Devops. There is no need to authenticate against the VM.
The meat of what you need is:
1- create a storageaccount blob containing the following script (the -Wait is very important):
Start-Process -FilePath C:\Windows\System32\Sysprep\Sysprep.exe -ArgumentList '/generalize /oobe /quiet /quit' -Wait
2 - invoke it on the VM:
$response = Set-AzureRmVMCustomScriptExtension `
-ResourceGroupName $vm.ResourceGroupName `
-VMName $vm.Name `
-Location $vm.Location `
-Name $ExtensionName `
-FileUri $blobUri `
-Run $FileName
I created azure vm scale set with custom script extension. After some time I updated custom script extension and wanted to apply changes on each virtual machine on scale set. However nothing is changing. To update VM Scale Set I used Update-AzureRmVmss command in powershell. There is not any error message, command executes successfully
I would say you VMSS is set to update mode manual, so you need to force the node update.
https://learn.microsoft.com/en-us/powershell/module/azurerm.compute/update-azurermvmssinstance?view=azurermps-6.4.0
another thing you are missing: forceUpdateTag. check this: How to force VM created with an ARM template + CustomScriptExtension to redownload the script and run it?
It sounds like you need to update the "forceUpdateTag" property in the scale set extension profile. You can do this in your ARM template by adding this property at the same level as "publisher" and giving it any value you want (as long as it's different from the previous value). You can also do the same in Powershell and Az CLI using code like the following:
Powershell:
$vmss = Get-AzureRmVmss -ResourceGroupName YOUR_RG_NAME -Name YOUR_VMSS_NAME
$vmss.VirtualMachineProfile.ExtensionProfile.Extensions[0].ForceUpdateTag="1"
Update-AzureRmVmss -ResourceGroupName YOUR_RG_NAME -VMScaleSetName YOUR_VMSS_NAME -VirtualMachineScaleSet $vmss
CLI:
# run the first time
az vm extension set -g ...
# run again
az vm extension set --force-update -g ...
It's a bit complicated in some cases, so I threw together a quick blog post describing it:
https://negatblog.wordpress.com/2018/07/11/rerun-extensions-in-azure/
Hope this helps! :)
-Neil
I have found azure slot swapping via powershell seems to be unrealiable (I imagine it is giving an error response that I can't see or is silently failing but claiming success). The slots being swapped are between two non production slots as shown in the script. About 10% of the time it seems to succeed. Im not sure why it succeeds or fails, hopefully someone can shed some light on what I am doing wrong here.
I have a script I have made that runs on a build job on Teamcity and the script is as follows:
param ([string]$publishFilePath = "%system.teamcity.build.checkoutDir%\3.
deployment\Fu.publishsettings")
Import-AzurePublishSettingsFile $publishFilePath;
Select-AzureSubscription "Visual Studio Professional with MSDN";
Set-AzureSubscription -SubscriptionName "Visual Studio Professional with MSDN";
Switch-AzureWebsiteSlot -Name FuWebsite -Slot1 Build-Automation -Slot2 Staging -Force -Verbose
Switch-AzureWebsiteSlot -Name FuServices -Slot1 Build-Automation -Slot2 Staging -Force -Verbose
The only logs I get are:
[10:20:12][Step 5/5] VERBOSE: Performing the operation "Swapping website
production slot ..." on
[10:20:12][Step 5/5] target "FuWebsite".
[10:21:16][Step 5/5] VERBOSE: Performing the operation "Swapping website production slot ..." on
[10:21:16][Step 5/5] target "FuMeServices".
[10:22:19][Step 5/5]
[10:22:19][Step 5/5]
[10:22:19][Step 5/5] Process exited with code 0
About 10% of the time it seems to succeed. Im not sure why it succeeds or fails
If you not sure whether it succeed or fail. I would suggest you test below code with -Debug mode.
Switch-AzureWebsiteSlot -Name FuWebsite -Slot1 Build-Automation -Slot2 Staging -Force -Verbose -Debug
Here is the result I get on my side:
The detailed information will help you to find out the solution.
In addtion, if you execute the swap command, however the site does not change. Please try to clean IE sessions and cookies then try again. Or use KUDU to see the original file is changed or not.