tl;dr
Azure 扩展了$(System.DefaultWorkingDirectory) before PowerShell 看到了结果命令;如果扩展的$(...) 值被PowerShell 视为字符串,则必须将其括在引号中('$(...)'):
Shayki Abramczyk's answer 提供了一个有效的解决方案,但让我提供一些背景信息:
Azure 通过宏语法 ($(...)) 执行的变量扩展(替换)类似于预处理器:它将引用的变量替换为其逐字值。
您需要确保此逐字值在语法上在目标命令的上下文中起作用。
如目前所写:
$SourceDirectoryPath = $(System.DefaultWorkingDirectory) + "/solution/project/bin/Debug"
变成下面的命令PowerShell看到的,假设Azure属性System.DefaultWorkingDirectory的值为d:\a\r1\a:
$SourceDirectoryPath = d:\a\r1\a + "/solution/project/bin/Debug"
这是一个损坏的 PowerShell 命令,因为 d:\a\r1\a - 由于缺少引用 - 被解释为 命令名称或路径;也就是说,尝试执行假定的可执行文件d:\a\r1\a - 请参阅about_Parsing。
因此,为了让 PowerShell 将 Azure 扩展值 d:\a\r1\a 识别为 字符串,您需要 引用它 -见about_Quoting_Rules。
由于按 Azure 扩展的值不需要进一步插值,单引号是最佳选择(实际上对于两个操作数):
$SourceDirectoryPath = '$(System.DefaultWorkingDirectory)' + '/solution/project/bin/Debug'
事实上,您根本不需要字符串连接 (+):
$SourceDirectoryPath = '$(System.DefaultWorkingDirectory)/solution/project/bin/Debug'
您甚至可以将其与可扩展的 PowerShell 字符串 ("...") 结合使用,只要 Azure 扩展值不包含 PowerShell 最终可能解释的带有 $ 前缀的标记(除非这是您的(不寻常的)意图)。
警告类似于"$(System.DefaultWorkingDirectory)/$projectRoot/bin/Debug"(将 Azure 扩展值与 PowerShell 变量引用混合)是 Azure 的 macro syntax ($(...)) 看起来与 PowerShell 的相同拥有subexpression operator,通常(但不完全)用于将表达式嵌入到可扩展字符串中(例如,在纯 PowerShell 代码中,"1 + 1 equals $(1 + 1)")。
在撰写本文时,Define variables Azure 帮助主题并未详细说明,但基于 official comment in a GitHub docs issue,避免歧义如下:
-
有没有转义机制;相反,不引用 Azure 变量的 $(...) 构造保持不变,因此通过传递给 PowerShell。
-
在典型情况下,PowerShell 表达式不会看起来像 Azure 变量引用(例如,$($foo.bar) 而不是 $(foo.bar)),尽管假设可能存在歧义:$(hostname),其中是一个有效的 PowerShell 子表达式,如果定义了 hostname Azure 变量,则可以被 Azure 抢占。
- 在这种极端情况下,解决方案是避免使用内联脚本,而是将代码放在外部脚本文件中。