【问题标题】:How to reference application settings (key vault references) in Azure Function using Powershell如何使用 Powershell 在 Azure Function 中引用应用程序设置(密钥保管库引用)
【发布时间】:2020-09-05 09:43:02
【问题描述】:

我正在 Powershell 中编写一个小程序,该程序连接到 Office 365 以下载审核日志、进行一些更改,然后将 CSV 导出到 Azure Data Lake Storage 帐户。为了按计划运行此过程,我创建了一个 Azure Function 应用程序(计时器模板)来运行该程序。为了避免硬编码凭据,我创建了一个 Azure Key Vault 来存储凭据机密。我在 Azure Function 中创建了一个托管标识,在 Azure Key Vault 中使用凭据创建了机密,然后在 Azure Function 中的“配置”下创建了三个应用程序设置,其 URL 指向存储在 Azure Key Vault 中的机密。

三个应用程序设置称为“SecretUsername”、“SecretPassword”(指向 Office 365)和“SecretSAS”(将 CSV 存储在 ADLS 中)。

如何在我的 Powershell 脚本中引用这些变量?我在我的代码中尝试了不同的变体,但似乎都不起作用。例子:

  • $uSecret = $SecretUsername

  • $uSecret = $ENV:SecretUsername

  • $uSecret = ENV:SecretUsername

  • $uSecret = (Get-ChildItem ENV:SecretUsername).SecretValueText

     # Input bindings are passed in via param block.
     param($Timer)
    
     # Get the current universal time in the default string format.
     $currentUTCtime = (Get-Date).ToUniversalTime()
    
     # The 'IsPastDue' property is 'true' when the current function invocation is later than scheduled.
     if ($Timer.IsPastDue) {
         Write-Host "PowerShell timer is running late!"
     }
    
     # Write an information log with the current time.
     Write-Host "PowerShell timer trigger function ran! TIME: $currentUTCtime"
    
     Set-ExecutionPolicy AllSigned 
     Set-Item ENV:\SuppressAzurePowerShellBreakingChangeWarnings "true"
    
     $uSecret = (Get-ChildItem ENV:SecretUsername).SecretValueText 
     $pSecret = (Get-ChildItem ENV:SecretPassword).SecretValueText 
     $sasSecret = (Get-ChildItem ENV:SecretSAS).SecretValueText 
     $securePassword = ConvertTo-SecureString -String $pSecret -AsPlainText -Force
     $UserCredential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $uSecret, $securePassword
    
     $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
     Import-PSSession $session
    
     $startDate=(get-date).AddDays(-10)
     $endDate=(get-date)
     $scriptStart=(get-date)
    
     $sessionName = (get-date -Format 'u')+'pbiauditlog'
    
     $aggregateResults = @()
     $i = 0 # Loop counter
     Do { 
         $currentResults = Search-UnifiedAuditLog -StartDate $startDate -EndDate $enddate -SessionId $sessionName -SessionCommand ReturnLargeSet -ResultSize 1000 -RecordType PowerBIAudit
         if ($currentResults.Count -gt 0) {
             Write-Host ("Finished {3} search #{1}, {2} records: {0} min" -f [math]::Round((New-TimeSpan -Start $scriptStart).TotalMinutes,4), $i, $currentResults.Count, $user.UserPrincipalName )
             # Accumulate the data.
             $aggregateResults += $currentResults
             # No need to do another query if the # records returned <1000 - should save around 5-10 seconds per user.
             if ($currentResults.Count -lt 1000) {
                 $currentResults = @()
             } else {
                 $i++
             }
         }
     } Until ($currentResults.Count -eq 0) # End of Session Search Loop.
    
     $data=@()
    
     foreach ($auditlogitem in $aggregateResults) {
         $datum = New-Object -TypeName PSObject  
         $d = ConvertFrom-json $auditlogitem.AuditData
         $datum | Add-Member -MemberType NoteProperty -Name Id -Value $d.Id
         $datum | Add-Member -MemberType NoteProperty -Name CreationTDateTime -Value $d.CreationDate
         $datum | Add-Member -MemberType NoteProperty -Name CreationTime -Value $d.CreationTime
         $datum | Add-Member -MemberType NoteProperty -Name RecordType -Value $d.RecordType
         $datum | Add-Member -MemberType NoteProperty -Name Operation -Value $d.Operation
         $datum | Add-Member -MemberType NoteProperty -Name OrganizationId -Value $d.OrganizationId
         $datum | Add-Member -MemberType NoteProperty -Name UserType -Value $d.UserType
         $datum | Add-Member -MemberType NoteProperty -Name UserKey -Value $d.UserKey
         $datum | Add-Member -MemberType NoteProperty -Name Workload -Value $d.Workload        
         $datum | Add-Member -MemberType NoteProperty -Name UserId -Value $d.UserId
         $datum | Add-Member -MemberType NoteProperty -Name ClientIPAddress -Value $d.ClientIPAddress
         $datum | Add-Member -MemberType NoteProperty -Name UserAgent -Value $d.UserAgent
         $datum | Add-Member -MemberType NoteProperty -Name Activity -Value $d.Activity
         $datum | Add-Member -MemberType NoteProperty -Name ItemName -Value $d.ItemName
         $datum | Add-Member -MemberType NoteProperty -Name WorkSpaceName -Value $d.WorkSpaceName
         $datum | Add-Member -MemberType NoteProperty -Name DashboardName -Value $d.DashboardName
         $datum | Add-Member -MemberType NoteProperty -Name DatasetName -Value $d.DatasetName
         $datum | Add-Member -MemberType NoteProperty -Name ReportName -Value $d.ReportName
         $datum | Add-Member -MemberType NoteProperty -Name WorkspaceId -Value $d.WorkspaceId
         $datum | Add-Member -MemberType NoteProperty -Name ObjectId -Value $d.ObjectId
         $datum | Add-Member -MemberType NoteProperty -Name DashboardId -Value $d.DashboardId
         $datum | Add-Member -MemberType NoteProperty -Name DatasetId -Value $d.DatasetId
         $datum | Add-Member -MemberType NoteProperty -Name ReportId -Value $d.ReportId
         $datum | Add-Member -MemberType NoteProperty -Name OrgAppPermission -Value $d.OrgAppPermission
    
         # Option to include the below JSON column however for large amounts of data it may be difficult for PBI to parse
         $datum | Add-Member -MemberType NoteProperty -Name Datasets -Value (ConvertTo-Json $d.Datasets)
    
         # Below is a simple PowerShell statement to grab one of the entries and place in the DatasetName if any exist
         foreach ($dataset in $d.datasets) {
             $datum.DatasetName = $dataset.DatasetName
             $datum.DatasetId = $dataset.DatasetId
         }
         $data+=$datum
     }
    
     $dateTimestring = $startDate.ToString("yyyyMMdd") + "_" + (Get-Date -Format "yyyyMMdd") + "_" + (Get-Date -Format "HHmm")
     $fileName = ($dateTimestring + ".csv")
     Write-Host ("Writing to file {0}" -f $fileName) 
     $filePath = "$Env:temp/" + $fileName
     $data | Export-csv -Path $filePath
    
     Connect-AzAccount -Credential $UserCredential
     Get-AzVM -ResourceGroupName "Audit" -status
     $Context = New-AzStorageContext -StorageAccountName "auditingstorage" -StorageAccountKey $sasSecret
     Set-AzStorageBlobContent -Force -Context $Context -Container "auditlogs" -File $filePath -Blob $filename 
    
     Remove-PSSession -Id $Session.Id
    

如何引用 Azure Function 中的应用程序设置,以便可以在我的程序中使用存储的机密?

请帮忙!非常感谢!

【问题讨论】:

    标签: powershell azure-functions azure-keyvault azure-function-app


    【解决方案1】:

    要访问应用程序设置,无论是否使用 keyvault,您都必须通过以下方式检索它:$env:APPSETTING_YourSettingName

    因此,对于您的 keyvault 引用的秘密,您可以通过以下变量访问它。

    $env:APPSETTING_SecretUserName
    $env:APPSETTING_SecretPassword
    $env:APPSETTING_SecretSAS
    

    如果您需要列出它们。

    Get-ChildItem env:APPSETTING_*
    

    注意,返回的值将是纯文本未加密的字符串。 因此,在您的代码中:

     $uSecret = (Get-ChildItem ENV:SecretUsername).SecretValueText 
    

    变成:

     $uSecret = $env:APPSETTING_SecretUserName
    

    补充说明

    由于在 cmets 中已指出,我将提及它。 我根本不提倡在应用设置中使用明文密码。

    应用设置应该是任何敏感数据的密钥库引用。 我只是说明它可以在运行时通过$env:APPSETTING_YourSettingName 变量在函数内以明文形式检索。

    示例: 应用设置名称:MySecretUser AppSetting 值:@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931) 实际密钥值(在密钥库中):I_AM_Secret

    在运行时,获取$env:APPSETTING_MySecretUser 的值将返回一个值为I_AM_Secret

    的字符串对象

    【讨论】:

    • @KrishnenduGhosh-MSFT 我相信你误解了我的回答。我不建议 OP 将他的秘密以明文形式显示(任何机密数据都不应如此)。应通过 keyvault 引用在 AppSettings 中引用 Secret。这已经是 OP 正在做的事情。我只是说,无论何时添加 keyvault 引用,例如 @Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931),它都可以通过 $env:AppSetting_SecretName 变量在您的函数中使用。
    • $env:AppSetting_SecretName 确实包含应用设置中包含的 keyvault 引用的明文值。
    • 谢谢@sagepourpre $env:APPSETTING_ 效果很好!一直以来,我一直认为“APPSETTING”应该被替换为变量的名称,但我没有意识到它是一个关键字。我还提出了一个单独但相关的question,我需要帮助。如果你有时间,请看一下!谢谢
    猜你喜欢
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 2021-08-25
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多