Generates Magic Dash widget(s) displaying upcoming expirations (article, website, and assets).
Features
Displays upcoming expirations in an organized table view; sorted by soonest to expire with direct links to the item.
Selectively choose whether to include all upcoming expirations in a single widget or run separately to generate separate Magic Dashes.
Choose desired timeframe to display all items expiring within X amount of days.
Choose whether or not already-expired items show up in the results.
# Expirations_dash.ps1
# Generates Magic Dash widget(s) displaying upcoming expirations (article, website, and assets)
# Usage: ./expirations_dash.ps1
# -------------------------------------------------------------------------
# User Environment
# -------------------------------------------------------------------------
# Before starting, you'll need to set 3 variables, just below their explanations.
# 1. Set your Azure Key Vault name
# 2. Set the name of your secret (which holds Hudu API key)
# 3. Set the URL of your Hudu instance-
$AzVault_Name = "ENTER YOUR KEY VAULT NAME HERE"
$AzVault_HuduSecretName = "ENTER YOUR KEY VAULT SECRET NAME HERE"
$HuduBaseURL = "HTTPS://YOUR.HUDU.DOMAIN"
# Set customization options
# Change $withinDays to increase or decrease the timeframe of which expirations show up.
# Change the $Include_ variables to $true or $false to customize the Magic Dash widgets.
$withinDays = 90
$Include_Websites = $true
$Include_Articles = $true
$Include_Assets = $true
$Include_Expired = $false
# Print User-Decision Message,
$Dash_Inclusions=@()
if (($false -eq $Include_Websites) -and ($false -eq $Include_Articles) -and ($false -eq $Include_Assets)) {
Write-Host "No expirations are enabled! Please enable one or more of the following: Articles, Assets, Expirations"
exit 1
}
$currentDate = Get-Date
$futureDate = ($currentDate).AddDays($withinDays)
if ($true -eq $Include_Articles) {
$Dash_Inclusions += "Articles"
}
if ($true -eq $Include_Assets) {
$Dash_Inclusions += "Assets"
}
if ($true -eq $Include_Websites) {
$Dash_Inclusions += "Websites"
}
if ($true -eq $Include_Expired) {
Write-Host "We'll be focusing on any expiration types- ($($Dash_Inclusions -join ", ")), which are set to expire within $withinDays days, or at $futureDate... (this *includes* expired items)"
} else {
Write-Host "We'll be focusing on any expiration types- ($($Dash_Inclusions -join ", ")), which are set to expire within $withinDays days, or at $futureDate... (this *does not include* expired items)"
}
# Magic Dash Styling
$STD_Newline=@"
<br>
"@
$STD_Rule=@"
<hr>
"@
# -------------------------------------------------------------------------
# Init Modules and Sign-In
# -------------------------------------------------------------------------
foreach ($module in @('Az.keyvault', 'HuduAPI')) {
if (Get-Module -ListAvailable -Name $module) {
Write-Host "Importing module, $module...";
Install-Module $module -Force -AllowClobber;
Import-Module $module
} else {
Write-Host "Installing and importing module $module...";
Install-Module $module -Force -AllowClobber;
Import-Module $module
}
}
if (-not (Get-AzContext)) {
Connect-AzAccount };
# Configure Hudu API connection
New-HuduAPIKey "$(Get-AzKeyVaultSecret -VaultName "$AzVault_Name" -Name "$AzVault_HuduSecretName" -AsPlainText)"
New-HuduBaseUrl $HuduBaseURL
# Fetch all expirations for the specified company
# Filter valid expirations (non-archived and valid expirationable_id)
$all_companies = $(get-huducompanies)
# Add a pre-parsed datetime member to all expirations
$all_expirations = Get-HuduExpirations | ForEach-Object {
$_ | Add-Member -MemberType NoteProperty -Name ParsedExpirationDate -Value ([DateTime]::ParseExact($_.date, "yyyy-MM-dd", $null)) -PassThru
} | Sort-Object ParsedExpirationDate
function GetFormattedExpirationsForCompany {
param (
[string]$CompanyName,
[int32]$CompanyId
)
$ValidExpirations = $($all_expirations | Where-Object {$_.company_id -eq $CompanyId} )
# Initialize variables
$WebsitesExpirations = @"
<div style=><h1>$CompanyName Expirations-Websites</h1></div>
<table id="$CompanyName-Websites">
<thead>
<tr>
<th><h2>Details</h2></th>
<th><h2>Expiry Date</h2></th>
<th><h2>External Link</h2></th>
<th><h2>Internal Link</h2></th>
</tr>
</thead>
"@
$AssetsExpirations = @"
<div style=><h1>$CompanyName Expirations-Assets</h1></div>
<table id="$CompanyName-Assets">
<thead>
<tr>
<th><h2>Details</h2></th>
<th><h2>Expiry Date</h2></th>
<th><h2>Asset Type</h2></th>
<th><h2>Internal Link</h2></th>
</tr>
</thead>
"@
$ArticlesExpirations = @"
<div style=><h1>$CompanyName Expirations-Articles</h1></div>
<table id="$CompanyName-Articles">
<thead>
<tr>
<th><h2>Details</h2></th>
<th><h2>Expiry Date</h2></th>
<th><h2>Internal Link</h2></th>
<th><h2>Updated At</h2></th>
</tr>
</thead>
"@
$Websites_count=0
$Assets_count=0
$Articles_count=0
# Process each expiration
foreach ($expiration in $ValidExpirations) {
Write-Host $expiration
$date_expires=[DateTime]::ParseExact($expiration.date, "yyyy-MM-dd", $null)
if ($null -ne $expiration.discarded_at) {
Write-Host "$($expiration.expirationable_type) was discarded at $($expiration.discarded_at). (expired $($expiration.date))"
continue
}
if ($date_expires -lt $currentDate) {
$status = "EXPIRED $($expiration.date)"
$Descriptor = "Please Review $($expiration.expirationable_type)."
if ($true -ne $Include_Expired) {
Write-Host "Include_Expired=$Include_Expired. Excluding table-listing for $($Item.name), a $($expiration.expirationable_type) from $CompanyName "
continue
}
} elseif ($date_expires -le $futureDate) {
$status = "Warning, expires on $($expiration.date)"
$Descriptor = "$($expiration.expirationable_type) will expire within the next $withinDays days."
} else {
$status = "Good until $($expiration.date)"
$Descriptor = "$($expiration.expirationable_type) won't expire for more than $withinDays days from now."
Write-Host "$Status - $Descriptor"
continue
}
if ($expiration.expirationable_type -eq 'Website') {
$Item = if ($null -ne $expiration.expirationable_id) {Get-HuduWebsites -WebsiteId $expiration.expirationable_id} else {$null}
Write-Host "expirational, $($expiration.expirationable_id). Item: $($Item.id): $Item"
if ($null -ne $Item) {
$WebsitesExpirations += @"
<tr>
<td>$($status) - $($Descriptor)<br>Monitoring Status: $($Item.monitoring_status)</td>
<td>$($expiration.date) - Refreshed At $($Item.refreshed_at)</td>
<td><a href="$($Item.name)" target="_blank">External Link for $($Item.name)</a></td>
<td><a href="$($HuduBaseURL)$($Item.url)" target="_blank">$($Item.name)- Internal Link</a></td>
</tr>
"@
$Websites_count=$Websites_count+1
}
}
elseif ($expiration.expirationable_type -eq 'Asset') {
$Item = if ($null -ne $expiration.expirationable_id) {Get-HuduAssets -Id $expiration.expirationable_id} else {$null}
Write-Host "expirational, $($expiration.expirationable_id). Item: $($Item.id): $Item"
if ($null -ne $Item) {
$AssetsExpirations += @"
<tr>
<td>$($status)<br>$($Descriptor)</td>
<td>$($expiration.date) - Refreshed At: $($Item.updated_at)</td>
<td>$($Item.asset_type)</td>
<td><a href="$($Item.url)" target="_blank">$($Item.name)</a>
</tr>
"@
$Assets_count=$Assets_count+1
}
}
elseif ($expiration.expirationable_type -eq 'Article') {
$Item = if ($null -ne $expiration.expirationable_id) {$(Get-HuduArticles -Id $expiration.expirationable_id).article} else {$null}
if ($null -ne $Item) {
Write-Host "expirational, $($expiration.expirationable_id). Item: $($Item.id): $Item"
$archived_notice = if ($true -eq $item.archived) {" (Archived)"} else {""}
$public_photos_count = if ($item.public_photos.Count -gt 0) {" $($item.public_photos.Count) Public Photos"} else {""}
$Articles_count=$Articles_count+1
$Article_link=if ($null -ne $Item.url) {
@"
<a href="$($Item.url)" target="_blank">Article - $($Item.name)$archived_notice</a>
"@
} elseif ($null -ne $Item.slug) {
{@"
<a href="$($HuduBaseURL)/kba/$($item.slug)" target="_blank">Article - $($Item.name).</a>
"@}
} elseif ($null -ne $Item.slug) {
{@"
<a href="$($item.share_url)" target="_blank">Article - $($Item.name) (Share URL).</a>
"@}
} else {@"
<a href="#$CompanyName-Articles" target="_blank">Article - $($Item.name) Removed.</a>
"@}
$ArticlesExpirations += @"
<tr>
<td>$($status)<br>$($Descriptor) $($archived_notice)$($public_photos_count)</td>
<td>$($expiration.date)</td>
<td>$Article_link<td>
<td>$(if ($null -ne $Item.updated_at) {"Updated At $($item.updated_at)"} elseif ($null -ne $($article.created_at)) {"Created At $($article.created_at)"} else {"N/A"})</td>
</tr>
"@
} } }
# Close the lists
$WebsitesExpirations += @"
</table>
$STD_Rule
"@
$AssetsExpirations += @"
</table>
$STD_Rule
"@
$ArticlesExpirations += @"
</table>
$STD_Rule
"@
return $WebsitesExpirations, $AssetsExpirations, $ArticlesExpirations
}
foreach ($company in $all_companies) {
$LocalWebsites, $LocalAssets, $LocalArticles = GetFormattedExpirationsForCompany -CompanyName $company.Name -CompanyId $company.id
$MessageLines=""
$Dash_Inclusions=@()
if ($true -eq $Include_Articles) {
$MessageLines += $LocalArticles + $STD_Newline
$Dash_Inclusions += "Articles"
}
if ($true -eq $Include_Assets) {
$MessageLines += $LocalAssets + $STD_Newline
$Dash_Inclusions += "Assets"
}
if ($true -eq $Include_Websites) {
$MessageLines += $LocalWebsites + $STD_Newline
$Dash_Inclusions += "Websites"
}
$DashTitle= "$($company.name) Expirations - $($Dash_Inclusions -join ", ")"
Write-Host "Magic Dash items result:"
Write-Host $MessageLines
Set-HuduMagicDash -Title "$DashTitle" `
-CompanyName $company.name `
-Message "Expirations - $($Dash_Inclusions -join ", ")" `
-Content $MessageLines `
-Shade "success"
}
Remove-HuduAPIKey
Prerequisites
Powershell 7 or above
HuduAPI Powershell module installed