如何将秘密变量与内联Powershell脚本一起使用

时间:2020-02-20 03:24:19

标签: powershell ado azure-deployment

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

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

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

我尝试通过上面的链接中所述的各种方式来访问它:

$ MYSECRET

$ env:MYSECRET

$($ MYSECRET)

$($ env:MYSECRET)

$(MYSECRET)

$(env:MYSECRET)

(以下所有内容均包含Param和param)

param([string] $ mySecret)

param($ mySecret)

param($ MYSECRET)

param($ env:mySecret)

param($ env:MYSECRET)

所有这些都返回一个“ Param不是公认的函数”,根据这些,通常是由于param不是脚本中的第一个单词,对我而言不是这种情况,我已经检查过,仔细检查过,将文本提取到记事本,记事本++(以防万一)中并进行比较,并验证它确实是脚本中的第一个单词:

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问题1083。

我发布的任何链接中的任何建议或答案都没有起作用。

我遇到的另一个链接建议创建另外三个部署步骤来创建变量,将它们从ADO环境中拉出,执行直接解密和赋值。我认为应该在此处完全超出顶部。另一个建议是创建一个额外的步骤来创建一个temp函数,以提取秘密并将其与具有几个不同的起始值和结束值的子字符串进行解析,并将它们组合在一起,因为子字符串函数显然可以看到超出加密的范围。即使这样做确实可行,这也是荒谬的。因此,我没有尝试过最后2条建议。如果真的是这样,我希望有人指出我的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
} 

2 个答案:

答案 0 :(得分: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在这里不是必需的,似乎只是一个标准。我已经成功使用CAPS版本和“ TaskPass”进行了部署。我之所以这样说,是因为我在上面发布的几个链接看起来像它们。

名称:TASKPASS

值$(ScheduledTaskPass)

还要注意,MS最好向您隐藏此值。即使您将其设置为本地脚本变量并尝试输出该值(如我出于确认目的而尝试执行的操作),您仍然只会得到星号。但是,我/他们保证确实在那里。

答案 1 :(得分:0)

在经典类型中, 为了在嵌入式Powershell脚本中访问秘密变量,

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

第2步:添加/设置环境变量(在可选的内联脚本下方)以重新映射您的秘密变量(因为您无法直接在脚本中访问秘密变量(ref:MSdocs)),例如ex名称:PASSWORD值:$(PASSWORD)

第3步:在脚本访问中使用此变量时,例如$ env:密码