Search code examples
azurepowershellazure-devopsvirtual-machinesysprep

Sysprep Azure VM with Remote PowerShell


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


Solution

  • 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.