【问题标题】:Sysprep an Azure VM using PowerShell task in a pipeline在管道中使用 PowerShell 任务对 Azure VM 进行 Sysprep
【发布时间】:2020-01-25 09:42:02
【问题描述】:

我的(dotNET)应用程序是从构建管道构建的(使用 Windows 托管代理),在随后的发布管道中,我配置了一个 16GB-Win2016 虚拟机(启用 RDP、HTTP、HTTPS、WinRM 和 SSH),我手动 RDP 进入其中(这里有一个手动干预任务),并配置 WinRM(在本文之后:https://docs.microsoft.com/en-us/azure/marketplace/cloud-partner-portal/virtual-machine/cpp-configure-winrm-after-vm-creation#configure-vm-to-enable-winrm)。一切都很好,直到这里。下一个任务是 Azure 文件复制任务,它实质上是复制构建工件(来自 $(System.DefaultWorkingDirectory))并粘贴到我指定的目录中。奇迹般有效。我的下一个任务是创建整个 VM 的 VHD(基本上是在复制完成之后)。

我知道我可以手动 RDP 到 VM(再次)和 sysprep(使用 oobe/generalize/shutdown),然后可能返回 Azure 门户和磁盘导出操作系统磁盘(指定 SAS URL 到期时间随便(每篇文章 36000))但是这一切都可以自动化吗?

所以,长话短说 - 我想知道 sysprep oobe/generalize/shutdown 是否可以通过 PS 任务远程执行。我知道它的另一部分(导出磁盘和所有)可以,但是如果 sysprep 可以远程完成,那就没有了。

【问题讨论】:

    标签: azure azure-devops continuous-deployment azure-virtual-machine sysprep


    【解决方案1】:

    我试过了,得到了我想要的:

    $sysprep= 'C:\Windows\System32\Sysprep\Sysprep.exe'
    $arg1 = '/generalize'
    $arg2 = '/oobe'
    $arg3 = '/shutdown'
    $arg4 = '/quiet'
    
    & $sysprep $arg1 $arg2 $arg3 $arg4 -Wait
    

    【讨论】:

    • 非常感谢您在这里分享您的解决方案。你能接受它作为答案吗?更方便一些和你有类似困惑的用户可以直接知道这是一种工作方式:-)
    【解决方案2】:

    确保不使用 Azure 自定义脚本扩展来运行 sysprep。

    Azure 脚本在 LocalSystem 用户上下文下运行:source

    自定义脚本扩展将在 LocalSystem 帐户下运行

    这是有问题的,因为 sysprep 不支持在系统用户上下文下运行:source

    Sysprep 不能在系统帐户的上下文中运行。例如,不支持使用任务计划程序或 PSExec 在系统帐户的上下文中运行 Sysprep。

    提供这个是为了让人们避免我的错误:)

    【讨论】:

      【解决方案3】:

      因此,您不必手动配置 winrm,您可以在配置 vm 时编写脚本\配置它。如果\当 winrm 工作时,您可以使用 powershell remoting 对 vm 发出命令:

      Invoke-Command -ComputerName dnsname\ipaddress_goes_hehe
          -ScriptBlock { sysprep /shutdown /generalise}
      

      https://github.com/Azure/azure-quickstart-templates/tree/master/201-vm-winrm-windows

      【讨论】:

      • 谢谢。所以这基本上是我为 WinRM 部分手动做的事情?对吗?
      • 哦,不。我无法执行github.com/Azure/azure-quickstart-templates/tree/master/… 中的建议。使用Get-Credential 会弹出凭证窗口。由于我是通过发布管道执行所有这些操作,因此我认为我无法实现它。但我可以手动执行此操作 - 只需 3 分钟。 5顶。所以在这一点上,一切都归结为:sysprep 如何在发布管道中执行 PS 任务?
      • 您可以静默创建凭证对象:github.com/4c74356b41/powershell/blob/master/…。要调用 sysprep,只需像往常一样从 powershell 调用 sysprep。更新了答案
      【解决方案4】:

      您可以使用 Azure 自定义脚本扩展来实现这一点。有一个github项目: https://github.com/jlongo62/AzureVMToImage 包含用于对 VM 进行映像的 powershell 脚本。构建这些脚本是为了在创建映像时保留 VM,而不是破坏原始 VM。可以从 Azure Devops 调用这些脚本。无需针对 VM 进行身份验证。

      你需要的肉是:

      1- 创建一个包含以下脚本的 storageaccount blob(-Wait 非常重要):

      Start-Process -FilePath C:\Windows\System32\Sysprep\Sysprep.exe -ArgumentList '/generalize /oobe /quiet /quit'  -Wait 
      

      2 - 在 VM 上调用它:

      $response = Set-AzureRmVMCustomScriptExtension  `
                      -ResourceGroupName  $vm.ResourceGroupName `
                      -VMName $vm.Name `
                      -Location $vm.Location `
                      -Name $ExtensionName  `
                      -FileUri $blobUri  `
                      -Run $FileName 
      

      【讨论】:

      • 嗨。有一个后续问题。什么是-等待?我理解它“等待”,但通过 VM 本身为我的机器进行 sysprep 会在 2 到 3 分钟内完成(意味着它会关闭)。在 PowerShell 中,没有 -Wait 需要相同的时间,但使用 -Wait 似乎需要很长时间。那么,它有什么用呢?
      • 当通过自定义脚本扩展调用脚本时,如果没有 -Wait,PS 命令永远不会得到响应; -Wait 强制代理等待命令完成;你给了我一个想法:因为我现在使用 C# 而不是 PS,所以我可以在没有 -Wait 的情况下发出命令;然后轮询要解除分配的机器。
      猜你喜欢
      • 1970-01-01
      • 2020-08-27
      • 2016-06-04
      • 2022-01-24
      • 2020-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-09
      相关资源
      最近更新 更多