简化 PowerShell Runbook 以发送电子邮件
Simplify PowerShell runbook to send e-mail
我能否简化我的 PowerShell Azure 运行 书籍,以便从订阅的所有 KV 中收集即将过期的机密和证书(相对于重复代码),并在电子邮件中发送格式化的 table?
当前的 运行 书籍 运行 与配置到订阅中的自动化帐户的相关模块很好,但我肯定有更简洁的方法 运行 这并定期向利益相关者发送格式化的电子邮件。
Param(
[string]$SubscriptionID = "",
[int]$DaysNearExpiration = "30",
[string]$VaultName
)
Get-AzureRmSubscription -SubscriptionId $SubscriptionID | Select-AzureRmSubscription | Format-Table -Autosize
$ExpiredSecrets = @()
$NearExpirationSecrets = @()
#gather all key vaults from subscription
if ($VaultName) {
$KeyVaults = Get-AzureRmKeyVault -VaultName $VaultName
}
else {
$KeyVaults = Get-AzureRmKeyVault
}
#check date which will notify about expiration
$ExpirationDate = (Get-Date (Get-Date).AddDays($DaysNearExpiration) -Format yyyyMMdd)
$CurrentDate = (Get-Date -Format yyyyMMdd)
# iterate across all key vaults in subscription
foreach ($KeyVault in $KeyVaults) {
# gather all secrets in each key vault
$SecretsArray = Get-AzureKeyVaultSecret -VaultName $KeyVault.VaultName
foreach ($secret in $SecretsArray) {
# check if expiration date is set
if ($secret.Expires) {
$secretExpiration = Get-date $secret.Expires -Format yyyyMMdd
# check if expiration date set on secret is before notify expiration date
if ($ExpirationDate -gt $secretExpiration) {
# check if secret did not expire yet but will expire soon
if ($CurrentDate -lt $secretExpiration) {
$NearExpirationSecrets += New-Object PSObject -Property @{
Name = $secret.Name;
Category = 'SecretNearExpiration';
KeyVaultName = $KeyVault.VaultName;
ExpirationDate = $secret.Expires;
}
}
# secret is already expired
else {
$ExpiredSecrets += New-Object PSObject -Property @{
Name = $secret.Name;
Category = 'SecretNearExpiration';
KeyVaultName = $KeyVault.VaultName;
ExpirationDate = $secret.Expires;
}
}
}
}
}
}
Write-Output "Total number of expired secrets: $($ExpiredSecrets.Count)"
$ExpiredSecrets
Write-Output "Total number of secrets near expiration: $($NearExpirationSecrets.Count)"
$NearExpirationSecrets
$ExpiredCertificates = @()
$NearExpirationCertificates = @()
#gather all key vaults from subscription
if ($VaultName) {
$KeyVaults = Get-AzureRmKeyVault -VaultName $VaultName
}
else {
$KeyVaults = Get-AzureRmKeyVault
}
#check date which will notify about expiration
$ExpirationDate = (Get-Date (Get-Date).AddDays($DaysNearExpiration) -Format yyyyMMdd)
$CurrentDate = (Get-Date -Format yyyyMMdd)
# iterate across all key vaults in subscription
foreach ($KeyVault in $KeyVaults) {
# gather all certificates in each key vault
$CertificatesArray = Get-AzureKeyVaultCertificate -VaultName $KeyVault.VaultName
foreach ($Certificate in $CertificatesArray) {
# check if expiration date is set
if ($certificate.Expires) {
$certificateExpiration = Get-date $certificate.Expires -Format yyyyMMdd
# check if expiration date set on certificate is before notify expiration date
if ($ExpirationDate -gt $certificateExpiration) {
# check if secret did not expire yet but will expire soon
if ($CurrentDate -lt $certificateExpiration) {
$NearExpirationCertificates += New-Object PSObject -Property @{
Name = $certificate.Name;
Category = 'CertificateNearExpiration';
KeyVaultName = $KeyVault.VaultName;
ExpirationDate = $certificate.Expires;
}
}
# secret is already expired
else {
$ExpiredCertificates += New-Object PSObject -Property @{
Name = $certificate.Name;
Category = 'CertificateNearExpiration';
KeyVaultName = $KeyVault.VaultName;
ExpirationDate = $certificate.Expires;
}
}
}
}
}
}
Write-Output "Total number of expired certificates: $($ExpiredCertificates.Count)"
$ExpiredCertificates
Write-Output "Total number of certificates near expiration: $($NearExpirationCertificates.Count)"
$NearExpirationCertificates
这是一个可能的重构(未经测试):
Param(
[string]$SubscriptionID = "",
[int]$DaysNearExpiration = "30",
[string]$VaultName
)
Get-AzureRmSubscription -SubscriptionId $SubscriptionID | Select-AzureRmSubscription | Format-Table -Autosize
$ExpiredSecrets = [System.Collections.Generic.List[PSCustomObject]] @()
$NearExpirationSecrets = [System.Collections.Generic.List[PSCustomObject]] @()
#gather all key vaults from subscription
$KeyVaultArgs = if( $VaultName ) { @{ VaultName = $VaultName } } else { @{} }
# In PS 7+ you could write:
# $KeyVaultArgs = $VaultName ? @{ VaultName = $VaultName } : @{}
$KeyVaults = Get-AzureRmKeyVault @KeyVaultArgs
#check date which will notify about expiration
$ExpirationDate = (Get-Date (Get-Date).AddDays($DaysNearExpiration) -Format yyyyMMdd)
$CurrentDate = (Get-Date -Format yyyyMMdd)
# iterate across all key vaults in subscription
foreach ($KeyVault in $KeyVaults) {
# gather all secrets in each key vault
$SecretsArray = Get-AzureKeyVaultSecret -VaultName $KeyVault.VaultName | Where-Object Expires
foreach ($secret in $SecretsArray) {
# check if expiration date is set
$secretExpiration = Get-date $secret.Expires -Format yyyyMMdd
# check if expiration date set on secret is before notify expiration date
if ($ExpirationDate -gt $secretExpiration) {
$secret = [PSCustomObject]@{
Name = $secret.Name
Category = 'SecretNearExpiration'
KeyVaultName = $KeyVault.VaultName
ExpirationDate = $secret.Expires
}
# check if secret did not expire yet but will expire soon
if ($CurrentDate -lt $secretExpiration) {
$NearExpirationSecrets.Add( $secret )
}
# secret is already expired
else {
$ExpiredSecrets.Add( $secret )
}
}
}
}
# omitted unmodified code ...
更改:
- 使用
[System.Collections.Generic.List[PSCustomObject]]
而不是普通数组。当数组可以变大时,这会更有效率。每当使用运算符 +=
时,Powershell 都会重新创建一个大小为 +1 的普通数组。 list
的内部数组将仅调整为 2 的倍数。
$KeyVaultArgs = if ...
使用条件赋值将参数创建为哈希表,然后使用 splatting 只需要一次调用 Get-AzureRmKeyVault
.
$SecretsArray = Get-AzureKeyVaultSecret -VaultName $KeyVault.VaultName | Where-Object Expires
让我们去掉 foreach
中的 if ($secret.Expires)
,减少嵌套层级。
$secret = [PSCustomObject]@{
从下面的 if/else
构造中删除重复代码。语法也比 New-Object PSObject
. 更简洁
$NearExpirationSecrets.Add( $secret )
和 $ExpiredSecrets.Add( $secret )
是必需的,因为 list
不支持 +=
运算符。
我能否简化我的 PowerShell Azure 运行 书籍,以便从订阅的所有 KV 中收集即将过期的机密和证书(相对于重复代码),并在电子邮件中发送格式化的 table?
当前的 运行 书籍 运行 与配置到订阅中的自动化帐户的相关模块很好,但我肯定有更简洁的方法 运行 这并定期向利益相关者发送格式化的电子邮件。
Param(
[string]$SubscriptionID = "",
[int]$DaysNearExpiration = "30",
[string]$VaultName
)
Get-AzureRmSubscription -SubscriptionId $SubscriptionID | Select-AzureRmSubscription | Format-Table -Autosize
$ExpiredSecrets = @()
$NearExpirationSecrets = @()
#gather all key vaults from subscription
if ($VaultName) {
$KeyVaults = Get-AzureRmKeyVault -VaultName $VaultName
}
else {
$KeyVaults = Get-AzureRmKeyVault
}
#check date which will notify about expiration
$ExpirationDate = (Get-Date (Get-Date).AddDays($DaysNearExpiration) -Format yyyyMMdd)
$CurrentDate = (Get-Date -Format yyyyMMdd)
# iterate across all key vaults in subscription
foreach ($KeyVault in $KeyVaults) {
# gather all secrets in each key vault
$SecretsArray = Get-AzureKeyVaultSecret -VaultName $KeyVault.VaultName
foreach ($secret in $SecretsArray) {
# check if expiration date is set
if ($secret.Expires) {
$secretExpiration = Get-date $secret.Expires -Format yyyyMMdd
# check if expiration date set on secret is before notify expiration date
if ($ExpirationDate -gt $secretExpiration) {
# check if secret did not expire yet but will expire soon
if ($CurrentDate -lt $secretExpiration) {
$NearExpirationSecrets += New-Object PSObject -Property @{
Name = $secret.Name;
Category = 'SecretNearExpiration';
KeyVaultName = $KeyVault.VaultName;
ExpirationDate = $secret.Expires;
}
}
# secret is already expired
else {
$ExpiredSecrets += New-Object PSObject -Property @{
Name = $secret.Name;
Category = 'SecretNearExpiration';
KeyVaultName = $KeyVault.VaultName;
ExpirationDate = $secret.Expires;
}
}
}
}
}
}
Write-Output "Total number of expired secrets: $($ExpiredSecrets.Count)"
$ExpiredSecrets
Write-Output "Total number of secrets near expiration: $($NearExpirationSecrets.Count)"
$NearExpirationSecrets
$ExpiredCertificates = @()
$NearExpirationCertificates = @()
#gather all key vaults from subscription
if ($VaultName) {
$KeyVaults = Get-AzureRmKeyVault -VaultName $VaultName
}
else {
$KeyVaults = Get-AzureRmKeyVault
}
#check date which will notify about expiration
$ExpirationDate = (Get-Date (Get-Date).AddDays($DaysNearExpiration) -Format yyyyMMdd)
$CurrentDate = (Get-Date -Format yyyyMMdd)
# iterate across all key vaults in subscription
foreach ($KeyVault in $KeyVaults) {
# gather all certificates in each key vault
$CertificatesArray = Get-AzureKeyVaultCertificate -VaultName $KeyVault.VaultName
foreach ($Certificate in $CertificatesArray) {
# check if expiration date is set
if ($certificate.Expires) {
$certificateExpiration = Get-date $certificate.Expires -Format yyyyMMdd
# check if expiration date set on certificate is before notify expiration date
if ($ExpirationDate -gt $certificateExpiration) {
# check if secret did not expire yet but will expire soon
if ($CurrentDate -lt $certificateExpiration) {
$NearExpirationCertificates += New-Object PSObject -Property @{
Name = $certificate.Name;
Category = 'CertificateNearExpiration';
KeyVaultName = $KeyVault.VaultName;
ExpirationDate = $certificate.Expires;
}
}
# secret is already expired
else {
$ExpiredCertificates += New-Object PSObject -Property @{
Name = $certificate.Name;
Category = 'CertificateNearExpiration';
KeyVaultName = $KeyVault.VaultName;
ExpirationDate = $certificate.Expires;
}
}
}
}
}
}
Write-Output "Total number of expired certificates: $($ExpiredCertificates.Count)"
$ExpiredCertificates
Write-Output "Total number of certificates near expiration: $($NearExpirationCertificates.Count)"
$NearExpirationCertificates
这是一个可能的重构(未经测试):
Param(
[string]$SubscriptionID = "",
[int]$DaysNearExpiration = "30",
[string]$VaultName
)
Get-AzureRmSubscription -SubscriptionId $SubscriptionID | Select-AzureRmSubscription | Format-Table -Autosize
$ExpiredSecrets = [System.Collections.Generic.List[PSCustomObject]] @()
$NearExpirationSecrets = [System.Collections.Generic.List[PSCustomObject]] @()
#gather all key vaults from subscription
$KeyVaultArgs = if( $VaultName ) { @{ VaultName = $VaultName } } else { @{} }
# In PS 7+ you could write:
# $KeyVaultArgs = $VaultName ? @{ VaultName = $VaultName } : @{}
$KeyVaults = Get-AzureRmKeyVault @KeyVaultArgs
#check date which will notify about expiration
$ExpirationDate = (Get-Date (Get-Date).AddDays($DaysNearExpiration) -Format yyyyMMdd)
$CurrentDate = (Get-Date -Format yyyyMMdd)
# iterate across all key vaults in subscription
foreach ($KeyVault in $KeyVaults) {
# gather all secrets in each key vault
$SecretsArray = Get-AzureKeyVaultSecret -VaultName $KeyVault.VaultName | Where-Object Expires
foreach ($secret in $SecretsArray) {
# check if expiration date is set
$secretExpiration = Get-date $secret.Expires -Format yyyyMMdd
# check if expiration date set on secret is before notify expiration date
if ($ExpirationDate -gt $secretExpiration) {
$secret = [PSCustomObject]@{
Name = $secret.Name
Category = 'SecretNearExpiration'
KeyVaultName = $KeyVault.VaultName
ExpirationDate = $secret.Expires
}
# check if secret did not expire yet but will expire soon
if ($CurrentDate -lt $secretExpiration) {
$NearExpirationSecrets.Add( $secret )
}
# secret is already expired
else {
$ExpiredSecrets.Add( $secret )
}
}
}
}
# omitted unmodified code ...
更改:
- 使用
[System.Collections.Generic.List[PSCustomObject]]
而不是普通数组。当数组可以变大时,这会更有效率。每当使用运算符+=
时,Powershell 都会重新创建一个大小为 +1 的普通数组。list
的内部数组将仅调整为 2 的倍数。 $KeyVaultArgs = if ...
使用条件赋值将参数创建为哈希表,然后使用 splatting 只需要一次调用Get-AzureRmKeyVault
.$SecretsArray = Get-AzureKeyVaultSecret -VaultName $KeyVault.VaultName | Where-Object Expires
让我们去掉foreach
中的if ($secret.Expires)
,减少嵌套层级。$secret = [PSCustomObject]@{
从下面的if/else
构造中删除重复代码。语法也比New-Object PSObject
. 更简洁
$NearExpirationSecrets.Add( $secret )
和$ExpiredSecrets.Add( $secret )
是必需的,因为list
不支持+=
运算符。