问题
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://docs.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.
回答1:
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
回答2:
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 :)
回答3:
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
回答4:
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
来源:https://stackoverflow.com/questions/59908086/sysprep-an-azure-vm-using-powershell-task-in-a-pipeline