当不同的计算机访问虚拟机时,Azure Devops 代理在托管虚拟机上的不同行为

different behaviour of azure devops agents on hosted vm when different computer access the vm

编辑:经过大量测试后,我们设法找到了机器之间的一个共同点,当使用 RDP 连接到我们的环境时,它中断了从调用的 excel 功能的执行由 azure devops 代理启动的 powershell 脚本:所有这些机器都有触摸屏,没有触摸屏的机器不会破坏它(尝试使用 3 台带触摸屏的机器、不同的构造器和 4 台没有触摸屏的机器)

编辑 2:当触摸屏被禁用并通过 RDP 连接到机器时,不要再破坏脚本了

我正在使用 AzureDevops 代理在云托管环境中执行 powershell 任务,该任务非常简单,只需创建一个工作簿并保存即可:

try{
    write-host 'initalized excel' 
    $Excel = New-Object -ComObject Excel.Application
    write-host 'adding WB'
    $Workbook = $Excel.Workbooks.Add()
    write-host 'Saving Wb'
    $Workbook.SaveAs('C:\test\test.xlsx')
 }
finally{
write-host 'quitting excel'
$Excel.quit()
}

这是 devops 任务的输出:

##[section]Starting: PowerShell Script
==============================================================================
Task         : PowerShell
Description  : Run a PowerShell script on Linux, macOS, or Windows
Version      : 2.151.2
Author       : Microsoft Corporation
Help         : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/powershell
==============================================================================
Generating script.
========================== Starting Command Output ===========================
##[command]"C:\windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command ". 'C:\agent\_work\_temped6d09-53ba-427a-a7ac-ea425a98767c.ps1'"
initalized excel
adding WB
quitting excel
Exception from HRESULT: 0x800A03EC
At C:\agent\_work\_temped6d09-53ba-427a-a7ac-ea425a98767c.ps1:6 char:5
+     $Workbook = $Excel.Workbooks.Add()
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], COMException
    + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException

这是当我的同事连接到代理执行脚本的虚拟机时发生的情况。我的同事正在使用 windows 远程桌面工具连接。

当我使用 RDP 连接到 VM 时,它工作正常:

##[section]Starting: PowerShell Script
==============================================================================
Task         : PowerShell
Description  : Run a PowerShell script on Linux, macOS, or Windows
Version      : 2.151.2
Author       : Microsoft Corporation
Help         : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/powershell
==============================================================================
Generating script.
========================== Starting Command Output ===========================
##[command]"C:\windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command ". 'C:\agent\_work\_temp6b2d56-2a41-4f75-97bb-01d4c41407e6.ps1'"
initalized excel
adding WB
Saving Wb
quitting excel
##[section]Finishing: PowerShell Script

我的同事和我使用完全相同的用户 RDP 到虚拟机。

我们尝试在另一个虚拟机上使用另一个 devops 代理,同样的问题出现了。

我有点迷茫,我根本不知道如何解决这个问题,如果您对标题有任何其他建议,我会采纳所有建议。

编辑:

我们还尝试将此脚本放入一个循环中,并在成功或失败时写入,当我 rdp 到虚拟机时,它可以工作,如果我断开连接它可以工作,只要我的同事 RDP 进入虚拟机它开始失败,如果我重新连接(从而断开我的同事)它再次工作。 (我们与同一用户进行 RDP)

编辑2: 我收到了一个注意到我的人的编辑建议:

From the user's comment->' when the agent is already running and creating excel files in a loop, the simple fact my colleague rdp to the vm breaks the excel file creation.' This issue seems to have nothing to do with azure devops. The reason for the problem is due to rdp

嗯,这也是一个 azure devops 代理问题,因为 运行 脚本对我们双方都适用。这是一个 RDP 问题,导致 Devops 代理无法使用某些 excel-powershell 功能,所以我认为 Azure Devops 标记仍然准确

编辑:

In the finally block try outputting the full error stack with: $Error | Format-List -Force – HAL9256

这是错误:

Exception             : System.Runtime.InteropServices.COMException (0x800706BE): The remote procedure call failed. 
                        (Exception from HRESULT: 0x800706BE)
                           at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, 
                        IntPtr errorInfo)
                           at System.Management.Automation.ComInterop.ComRuntimeHelpers.CheckThrowException(Int32 
                        hresult, ExcepInfo& excepInfo, ComMethodDesc method, Object[] args, UInt32 argErr)
                           at CallSite.Target(Closure , CallSite , ComObject )
                           at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
                           at CallSite.Target(Closure , CallSite , Object )
                           at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
                           at System.Management.Automation.Interpreter.DynamicInstruction`2.Run(InterpretedFrame frame)
                           at 
                        System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame 
                        frame)
TargetObject          : 
CategoryInfo          : OperationStopped: (:) [], COMException
FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
ErrorDetails          : 
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, C:\agent\_work\_temp\fae3ef7a-700d-49c1-8f1f-7f7d2bc0d49e.ps1: line 8
                        at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}
PSMessageDetails      : 

Running Excel under an automated, unattended process (such as an Azure DevOps Agent) in unsupported and can lead to all kinds issues,就像您 运行 喜欢的那些。

官方建议依赖第三方组件,如Excel Package Plus (free), NPOI (free), SpreadSheetGear (Commercial) or Aspose Cells.NET (Commercial). Or to use System.IO.Packaging and edit the XML for the Office document directly。这些不依赖于在您的服务器上安装 Excel,它们实际上是受支持的,并且没有与之相关的各种许可问题。将您的 scrips 迁移到这些其他包类型通常不是很困难,因为它们采用非常相似的 API 可移植性。

除了您遇到的技术问题 运行,许可可能更棘手,因为 Office 不允许 'on behalf of other users' 并且通常不允许 运行 在服务器上。

Besides the technical problems, you must also consider licensing issues. Current licensing guidelines prevent Office applications from being used on a server to service client requests, unless those clients themselves have licensed copies of Office. Using server-side Automation to provide Office functionality to unlicensed workstations is not covered by the End User License Agreement (EULA).

https://support.microsoft.com/en-us/help/257757/considerations-for-server-side-automation-of-office

您可能能够解决一些问题,例如您现在遇到的问题,但您可能会 运行 遇到新的问题。 运行 Azure DevOps 代理可能会有所帮助,这样 Excel 也将在交互式会话中启动,而不是没有真正桌面的受保护的隐藏用户会话。可能发生的情况是,通过 RDP 连接的第二个用户在登录时关闭所有其他会话,或者在注销时锁定所有会话。

here are security risks when you enable automatic logon or disable the screen saver because you enable other users to walk up to the computer and use the account that automatically logs on. If you configure the agent to run in this way, you must ensure the computer is physically protected; for example, located in a secure facility. If you use Remote Desktop to access the computer on which an agent is running with auto-logon, simply closing the Remote Desktop causes the computer to be locked and any UI tests that run on this agent may fail. To avoid this, use the tscon command to disconnect from Remote Desktop. For example:

 %windir%\System32\tscon.exe 1 /dest:console

https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops#interactive-or-service

关于服务器上 excel 自动化的另一个问题是现有的 Excel 实例被重新使用。这可能会导致主机 excel 在与执行自动化的进程不同的凭证下变为 运行。


至 运行 代理以交互方式将服务配置为 auto-logon (this utility encrypts the credentials used) and add run.cmd in the agent folder to the start-up executable list (either in the registry or a shortcut in the start menu). You can also make the agent executable (c:\windows\system32\cmd.exe /c path\to\agent\run.cmd) the default shell. There are quite a few docs on setting a custom shell

您还需要为此会话禁用屏幕保护程序和锁屏,这也需要您对服务器进行物理保护,否则任何有权访问服务器控制台的人都可以访问 运行宁互动环节。

并且您必须确保始终断开远程桌面会话而不锁定它(如上)。

我们最终确定问题仅发生在从具有触摸屏的笔记本电脑上使用 RDP 时。

然后我们使用此文档禁用了触摸屏:[=​​12=]

  1. In the search box on the taskbar, type Device Manager, then select Device Manager.
  2. Select the arrow next to Human Interface Devices and then select HID-compliant touch screen. (There may be more than one listed.)
  3. Select the Action tab at the top of the window.
  4. Select Disable device or Enable device, and then confirm. If there's more than one HID-compliant touchscreen device listed, perform steps 2–3 for that one too.

https://support.microsoft.com/en-us/help/4028019/windows-enable-and-disable-your-touchscreen-in-windows-10

并且脚本不再崩溃。

如果有人想 post 通过调整 RDP 或我们 RDP 到的服务器中的参数来解决这个问题而不禁用触摸屏的答案,我会接受他的答案,因为它更容易更改参数一次比要求人们在 rdp 到我们的机器时禁用他们的触摸屏。