【问题标题】:How do I use secret variables with inline powershell scripts如何将秘密变量与内联 powershell 脚本一起使用
【发布时间】:2020-02-20 03:24:19
【问题描述】:

所以我有一些我试图在 ADO 部署期间用来设置计划任务的 powershell。为了将任务设置为“无论用户是否登录都运行”,我需要根据这些使用用户和密码来创建它:

Set a Scheduled Task to run when user isn't logged in

Schedule task creation with option ""Run whether user is logged in or not"" using powershell

https://docs.microsoft.com/en-us/powershell/module/scheduledtasks/new-scheduledtaskprincipal?view=win10-ps

还有其他几个。

因此,根据公司的安全规则,来自 ADO 的所有密码都必须位于秘密变量中。当基本上从脚本中调用时,这些不会解密,您将获得空值。根据这些,您必须将它们作为环境变量和/或参数传递给脚本:

https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=classic%2Cbatch

https://github.com/Microsoft/azure-pipelines-tasks/issues/8345

VSTS: Pass build/release variables into Powershell script task

https://github.com/microsoft/azure-pipelines-agent/issues/145

https://adamtheautomator.com/azure-devops-variables-complete-guide/

其中许多也只显示 yaml 方面,但我使用的是经典,所以这没有用,我怀疑根据下一个链接不相关,然后与他们说你只能在文件基础脚本上使用参数而不是内联:

https://github.com/MicrosoftDocs/vsts-docs/issues/1083

我已经为变量使用的 MS 链接设置了一个环境变量,作为 ADO 步骤的一部分,其中我有一个名称和一个定义为 $(mySecret) 的值。

我已经尝试通过上面链接中描述的各种方式访问​​它:

$我的秘密

$env:我的秘密

$($MYSECRET)

$($env:MYSECRET)

$(我的秘密)

$(env:MYSECRET)

(以下所有参数都带有Param和param)

param([string]$mySecret)

参数($mySecret)

参数($MYSECRET)

参数($env:mySecret)

参数($env:MYSECRET)

所有这些都返回一个“参数不是一个可识别的函数”,根据这些,通常是由于参数不是脚本中的第一个单词,这对我来说不是这样,我已经检查过,仔细检查过,把文字拉到记事本,notepad++(都是为了以防万一)比较,验证确实是脚本中的第一个字:

PowerShell 2.0 and "The term 'Param' is not recognized as the name of a cmdlet, function, script file, or operable program"

PowerShell parameters - "The term 'param' is not recognized as the name of a cmdlet"

powershell unable to recognize parameter

我什至尝试复制和粘贴上面建议的一些 Param 解决方案,甚至从 ADO git 中复制和粘贴,但它们都失败了。我相信是因为上面链接的 git issue 1083。

我发布的任何链接中的建议或答案均无效。

我遇到的其他链接之一建议创建最多三个其他部署步骤来创建变量、从 ADO 环境中提取变量、执行直接解密和赋值。我认为这里应该需要的东西完全超出了顶部。另一个建议是创建一个额外的步骤来创建一个临时函数来提取秘密并使用具有几个不同开始和结束值的子字符串解析它,并将它们重新组合在一起,因为显然子字符串函数可以看到加密之外的内容。即使这确实有效,那也是荒谬的。因此,我没有尝试过最后两个建议。如果真的是这样的话,我希望有人指出我的 git 文档这样说明,或者需要在上面写一个错误。

我简直不知所措。我只需要在 ADO 部署期间为单个任务访问内联 powershell 脚本中的秘密变量,有谁知道如何实现这一点。请注意,当我为用户和密码使用纯文本输入时,下面的任务创建代码确实有效,但这违反了政策,因此不是一个选项。

这是我的脚本:

param($taskPass)

$taskName = $env:ScheduledTaskName
$taskExists = Get-ScheduledTask | Where-Object {$_.TaskName -like $taskName }

if(!$taskExists) {
     $Trigger = New-ScheduledTaskTrigger -Daily -At 3am
     $Actions = (New-ScheduledTaskAction -Execute "powershell curl -Method POST -Uri $env:VarURL"),
                (New-ScheduledTaskAction -Execute "powershell Invoke-Sqlcmd -ServerInstance $env:Server -Database 'MyDB' -Query 'EXEC NightlyProc'")

    #The following was suggested from here http://duffney.io/Create-ScheduledTasks-SecurePassword
     $SecurePassword = "$taskPass"
     Write-Host "Pass: $SecurePassword"
     $Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $env:ScheduledTaskUser, $SecurePassword
     $Password = $Credentials.GetNetworkCredential().Password 

     $Task = New-ScheduledTask -Action $Actions -Trigger $Trigger
     $Task | Register-ScheduledTask -TaskName $taskName -User $env:ScheduledTaskUser -Password $Password
} 

【问题讨论】:

  • 非常有兴趣看看如何解决这个问题。
  • @Jawad 是的,这是 Azure 上的管道版本。我在此版本的其他几个地方使用了秘密变量,无论是在 SQL 脚本执行的方向上,还是在所服务的 ASP 应用程序的配置选项中。正如您在引用“使它们可用于管道中的任务”部分中所述。这是管道中的一项任务。我知道的第二部分。正如我链接 5 个站点的部分所述,它们需要在脚本的参数中或根据“设置秘密变量”部分下的 microsoft 链接分配给环境变量。
  • @Jawad 它不在脚本的中间,它是脚本的第一个单词。如上代码所示。
  • 这听起来像是文件编码问题。当我将类似的脚本保存为没有 BOM 标头的 PC UTF-16 或 UTF-16BE(使用 TextPad)时,我可以复制您的错误。如果我包含 BOM 标头,或者使用 DOS、ANSI 或 UTF-8 编码保存文件,它似乎可以在没有 param() 错误的情况下工作。希望这会有所帮助。

标签: powershell ado azure-deployment


【解决方案1】:

好的,所以我终于解决了这个问题。我使用 YAML 查看器比较了经典界面创建的内容与 MS 链接所说的内容。这涉及将环境变量设置为 $(mySecret) 格式的值(没有 $env: 这里只是变量名)。然后在脚本中使用 $env:MYSECRET 格式。但也没有来自 duffney.io 网站的所有凭据/密码操作。只需将新任务的 -Password 参数直接设置为 $env:MYSECRET 变量。不需要参数。正如预期的那样,任务创建为“即使用户未登录也运行”。最终代码:

$taskName = $env:ScheduledTaskName
$taskExists = Get-ScheduledTask | Where-Object {$_.TaskName -like $taskName }

if(!$taskExists) {
     $Trigger = New-ScheduledTaskTrigger -Daily -At 3am
     $Actions = (New-ScheduledTaskAction -Execute "powershell curl -Method POST -Uri $env:URL"),
 (New-ScheduledTaskAction -Execute "powershell Invoke-Sqlcmd -ServerInstance $env:Server -Database 'MyDB' -Query 'EXEC NightlyCache'")

     $Task = New-ScheduledTask -Action $Actions -Trigger $Trigger
     $Task | Register-ScheduledTask -TaskName $taskName -User $env:ScheduledTaskUser -Password  $env:TASKPASS
} 

确保将环境变量设置为以下值:

注意:这里不需要名称上的大写字母,似乎只是一个标准。我已经成功部署了 CAPS 版本和“TaskPass”。我这样说是因为我在上面发布的几个链接看起来像是。

名称:TASKPASS

值 $(ScheduledTaskPass)

另外请注意,MS 最好对您隐藏此值。即使您将其设置为本地脚本变量并尝试输出该值,正如我为确认目的所做的那样,您仍然只会得到星号。但它确实存在,我/他们保证。

【讨论】:

    【解决方案2】:

    在经典类型中, 为了访问内联 powershell 脚本中的秘密变量,

    步骤1:定义一个变量并将其设置为秘密变量(使用锁定图标)(例如名称:密码值:********)

    步骤 2:添加/设置一个环境变量(下面的内联脚本作为一个选项可用)以重新映射您的秘密变量[因为您不能直接在脚本中访问秘密变量(参考:MSdocs)] 就像 ex 名称:密码值:$(PASSWORD)

    第三步:在脚本访问中使用此变量时,如 $env: PASSWORD

    【讨论】:

      猜你喜欢
      • 2017-08-06
      • 1970-01-01
      • 2019-10-27
      • 2017-10-14
      • 2021-09-20
      • 1970-01-01
      • 1970-01-01
      • 2019-11-08
      • 2015-10-01
      相关资源
      最近更新 更多