如何使用 Powershell 在 Azure Function 中引用应用程序设置(密钥保管库引用)
How to reference application settings (key vault references) in Azure Function using Powershell
我正在 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 脚本中引用这些变量?我在我的代码中尝试了不同的变体,但 none 似乎有效。示例:
$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 中的应用程序设置,以便我可以在我的程序中使用存储的机密?
请帮忙!非常感谢!
要访问应用程序设置,无论是否使用 keyvault,您都必须通过以下方式检索它:$env:APPSETTING_YourSettingName
因此,对于您的 keyvault 引用的秘密,您可以通过以下变量访问它。
$env:APPSETTING_SecretUserName
$env:APPSETTING_SecretPassword
$env:APPSETTING_SecretSAS
如果您需要列出它们。
Get-ChildItem env:APPSETTING_*
请注意,值 returned 将是纯文本未加密字符串。
因此,在您的代码中,这个:
$uSecret = (Get-ChildItem ENV:SecretUsername).SecretValueText
变成:
$uSecret = $env:APPSETTING_SecretUserName
补充说明
既然评论里都提到了,那我就提一下。
我根本不提倡在应用程序设置中使用明文秘密。
应用程序设置应该是任何敏感数据的 keyvault 引用。
我只是说它可以在运行时通过 $env:APPSETTING_YourSettingName
变量在函数中检索为 clear-text。
示例:
AppSetting 名称:MySecretUser
AppSetting 值:@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931)
实际秘密值(在密钥库中):I_AM_Secret
在运行时,获取 $env:APPSETTING_MySecretUser
的值将 return 一个值为 I_AM_Secret
的字符串对象
我正在 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 脚本中引用这些变量?我在我的代码中尝试了不同的变体,但 none 似乎有效。示例:
$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 中的应用程序设置,以便我可以在我的程序中使用存储的机密?
请帮忙!非常感谢!
要访问应用程序设置,无论是否使用 keyvault,您都必须通过以下方式检索它:$env:APPSETTING_YourSettingName
因此,对于您的 keyvault 引用的秘密,您可以通过以下变量访问它。
$env:APPSETTING_SecretUserName
$env:APPSETTING_SecretPassword
$env:APPSETTING_SecretSAS
如果您需要列出它们。
Get-ChildItem env:APPSETTING_*
请注意,值 returned 将是纯文本未加密字符串。 因此,在您的代码中,这个:
$uSecret = (Get-ChildItem ENV:SecretUsername).SecretValueText
变成:
$uSecret = $env:APPSETTING_SecretUserName
补充说明
既然评论里都提到了,那我就提一下。 我根本不提倡在应用程序设置中使用明文秘密。
应用程序设置应该是任何敏感数据的 keyvault 引用。
我只是说它可以在运行时通过 $env:APPSETTING_YourSettingName
变量在函数中检索为 clear-text。
示例: AppSetting 名称:MySecretUser AppSetting 值:@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931) 实际秘密值(在密钥库中):I_AM_Secret
在运行时,获取 $env:APPSETTING_MySecretUser
的值将 return 一个值为 I_AM_Secret