diff --git a/docs-mslearn/toolkit/open-data.md b/docs-mslearn/toolkit/open-data.md
index 42b0fa0e1..afc1f6f4b 100644
--- a/docs-mslearn/toolkit/open-data.md
+++ b/docs-mslearn/toolkit/open-data.md
@@ -4,7 +4,7 @@ description: Use open data to normalize and enhance your FinOps reporting, ensur
ms.topic: concept-article
author: flanakin
ms.author: micflan
-ms.date: 04/01/2026
+ms.date: 04/04/2026
ms.service: finops
ms.subservice: finops-toolkit
ms.reviewer: micflan
@@ -155,7 +155,7 @@ Most mappings can rely on resource type alone. In a future update, we will merge
## Commitment discount eligibility
-Azure meters can be eligible for commitment-based discounts such as reservations and savings plans. The commitment discount eligibility file provides a pre-computed lookup of which meters are eligible for each type, sourced from the [Azure Retail Prices API](https://learn.microsoft.com/rest/api/cost-management/retail-prices/azure-retail-prices).
+Azure meters can be eligible for commitment-based discounts such as reservations and savings plans. The commitment discount eligibility file provides a pre-computed lookup of which meters are eligible for each type, sourced from the [Azure Retail Prices API](/rest/api/cost-management/retail-prices/azure-retail-prices).
Sample data:
diff --git a/docs-wiki/Home.md b/docs-wiki/Home.md
index f01ea041c..3654e3e88 100644
--- a/docs-wiki/Home.md
+++ b/docs-wiki/Home.md
@@ -168,7 +168,7 @@ Please do the following before submitting a pull request:
4. Only address 1 issue per pull request and [link the issue in the pull request](https://github.com/blog/957-introducing-issue-mentions).
5. Be sure to follow our [coding guidelines](./Coding-guidelines.md) and keep code changes as small as possible.
-6. Validate changes by running locally and running [[unit tests]].
+6. Validate changes by running locally and running [[unit tests|Build and test]].
7. Enable the checkbox to [allow maintainer edits](https://docs.github.com/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so the branch can be updated for a merge.
8. Do all of the above before publishing your PR. You are welcome to create a draft PR to share and discuss ideas, but only publish when all code is committed, tested, and ready for review.
9. If you are working with others (especially internal teams), have 2 of your peers review your PRs. This will ensure a quicker turnaround as it is more likely that issues will be addressed before we review the PR.
diff --git a/docs/_docs/services/compute/vritual-machines.md b/docs/_docs/services/compute/vritual-machines.md
deleted file mode 100644
index 2dc78f5b1..000000000
--- a/docs/_docs/services/compute/vritual-machines.md
+++ /dev/null
@@ -1,73 +0,0 @@
----
-title: FinOps best practices for virtual machines
-description: Discover essential FinOps best practices to optimize cost efficiency and governance for your Azure resources.
-author: arclares
-ms.date: 10/17/2024
-ms.service: finops
----
-
-
-# FinOps best practices for virtual machines
-
-
-
-
-
-
-
-
-
-
-
-## Looking for more?
-
-Did we miss anything? Would you like to see something added? We'd love to hear about any questions, problems, or solutions you'd like to see covered here. [Create a new issue](https://aka.ms/ftk/ideas) with the details that you'd like to see either included here.
-
-
-
-## Related content
-
-Related resources:
-
-- [FinOps Framework](../../framework/finops-framework-overview.md)
-
-Related solutions:
-
-- [FinOps toolkit Power BI reports](../_docs/best-practices/power-bi/reports.md)
-- [FinOps hubs](../_docs/best-practices/hubs/finops-hubs-overview.md)
-- [FinOps workbooks](../toolkit/workbooks/finops-workbooks-overview.md)
-- [Optimization engine](../_docs/best-practices/optimization-engine/optimization-engine-overview.md)
-
-
diff --git a/src/powershell/Tests/Unit/DocsLinks.Tests.ps1 b/src/powershell/Tests/Unit/DocsLinks.Tests.ps1
index d69c252fb..5415919a6 100644
--- a/src/powershell/Tests/Unit/DocsLinks.Tests.ps1
+++ b/src/powershell/Tests/Unit/DocsLinks.Tests.ps1
@@ -3,103 +3,225 @@
<#
.SYNOPSIS
- Validates documentation links in the docs-mslearn folder.
+ Validates documentation links across all documentation folders.
.DESCRIPTION
- Tests that internal markdown links resolve to real files and anchors, that no
- https://learn.microsoft.com links appear (they should be root-relative), and
- that no language locale segments appear in MS Learn links.
+ Tests that internal markdown links resolve to real files and anchors across
+ docs-mslearn, docs (Jekyll site), docs-wiki (GitHub Wiki), and root markdown
+ files. Also validates that wiki double-bracket links reference existing pages,
+ that wiki repo-relative links point to real files, that no
+ https://learn.microsoft.com links appear in docs-mslearn (they should be
+ root-relative), and that no language locale segments appear in MS Learn links.
#>
BeforeDiscovery {
$repoRoot = (Get-Item -Path $PSScriptRoot).Parent.Parent.Parent.Parent.FullName
- $docsRoot = Join-Path $repoRoot 'docs-mslearn'
- if (-not (Test-Path $docsRoot))
+ # Helper: Remove HTML comments from content to avoid matching links inside
+ function Remove-HtmlComments([string]$text)
{
- return
+ return [regex]::Replace($text, '', { param($m) "`n" * ($m.Value -split "`n").Count })
}
- # Collect all markdown files
- $mdFiles = Get-ChildItem -Path $docsRoot -Recurse -Include '*.md' | ForEach-Object {
- @{
- FullName = $_.FullName
- RelativePath = $_.FullName.Substring($docsRoot.Length + 1) -replace '\\', '/'
- Content = Get-Content -Path $_.FullName -Raw
+ # Helper: Collect markdown files from a folder
+ function Get-MarkdownFiles([string]$folderPath, [string]$rootForRelative)
+ {
+ if (-not (Test-Path $folderPath)) { return @() }
+ Get-ChildItem -Path $folderPath -Recurse -Include '*.md' | ForEach-Object {
+ @{
+ FullName = $_.FullName
+ RelativePath = $_.FullName.Substring($rootForRelative.Length + 1) -replace '\\', '/'
+ Content = Get-Content -Path $_.FullName -Raw
+ }
}
}
- # Helper: Remove HTML comments from content to avoid matching links inside
- function Remove-HtmlComments([string]$text)
+ # Helper: Extract internal relative markdown links from files
+ function Get-InternalMdLinks([array]$mdFiles)
{
- return [regex]::Replace($text, '', { param($m) "`n" * ($m.Value -split "`n").Count })
+ $links = @()
+ foreach ($file in $mdFiles)
+ {
+ $cleanContent = Remove-HtmlComments $file.Content
+ $linkMatches = [regex]::Matches($cleanContent, '\[([^\]]*)\]\(([^)]+)\)')
+ foreach ($match in $linkMatches)
+ {
+ $linkTarget = $match.Groups[2].Value
+
+ # Skip external links, absolute paths, anchor-only links, special schemes, and Jekyll templates
+ if ($linkTarget -match '^(https?://|mailto:|/|#|\{\{)') { continue }
+
+ # Parse out any anchor
+ $pathPart = $linkTarget -replace '#.*$', ''
+ $anchorPart = if ($linkTarget -match '#(.+)$') { $Matches[1] } else { $null }
+
+ # Skip empty path parts (anchor-only links that somehow got through)
+ if ([string]::IsNullOrEmpty($pathPart) -and -not [string]::IsNullOrEmpty($anchorPart)) { continue }
+
+ # Only check .md files
+ if ($pathPart -and $pathPart -notmatch '\.md$') { continue }
+
+ $links += @{
+ SourceFile = $file.FullName
+ SourceRel = $file.RelativePath
+ LinkText = $match.Groups[1].Value
+ LinkTarget = $linkTarget
+ PathPart = $pathPart
+ AnchorPart = $anchorPart
+ LineNumber = ($file.Content.Substring(0, $match.Index) -split "`n").Count
+ }
+ }
+ }
+ return $links
}
- # Extract internal relative links (not starting with http, /, or #-only)
- $internalLinks = @()
- foreach ($file in $mdFiles)
+ # Helper: Extract all URLs from markdown files
+ function Get-MarkdownUrls([array]$mdFiles)
{
- $cleanContent = Remove-HtmlComments $file.Content
- $linkMatches = [regex]::Matches($cleanContent, '\[([^\]]*)\]\(([^)]+)\)')
- foreach ($match in $linkMatches)
+ $urls = @()
+ foreach ($file in $mdFiles)
{
- $linkTarget = $match.Groups[2].Value
+ $cleanContent = Remove-HtmlComments $file.Content
+ $urlMatches = [regex]::Matches($cleanContent, '\[([^\]]*)\]\((https?://[^)]+)\)')
+ foreach ($match in $urlMatches)
+ {
+ $urls += @{
+ SourceFile = $file.FullName
+ SourceRel = $file.RelativePath
+ LinkText = $match.Groups[1].Value
+ Url = $match.Groups[2].Value
+ LineNumber = ($file.Content.Substring(0, $match.Index) -split "`n").Count
+ }
+ }
+ }
+ return $urls
+ }
- # Skip external links, absolute paths, anchor-only links, and special schemes
- if ($linkTarget -match '^(https?://|mailto:|/|#)') { continue }
+ #region docs-mslearn
+ $mslearnRoot = Join-Path $repoRoot 'docs-mslearn'
+ $mslearnFiles = Get-MarkdownFiles $mslearnRoot $mslearnRoot
+ $mslearnInternalLinks = Get-InternalMdLinks $mslearnFiles
+ $mslearnUrls = Get-MarkdownUrls $mslearnFiles
+ #endregion
- # Parse out any anchor
- $pathPart = $linkTarget -replace '#.*$', ''
- $anchorPart = if ($linkTarget -match '#(.+)$') { $Matches[1] } else { $null }
+ #region docs (Jekyll site)
+ $jekyllRoot = Join-Path $repoRoot 'docs'
+ # Exclude _automation/ (parked files pending migration to docs-mslearn)
+ $jekyllFiles = Get-MarkdownFiles $jekyllRoot $jekyllRoot | Where-Object { $_.RelativePath -notmatch '^_automation/' }
+ $jekyllInternalLinks = Get-InternalMdLinks $jekyllFiles
+ #endregion
- # Skip empty path parts (anchor-only links that somehow got through)
- if ([string]::IsNullOrEmpty($pathPart) -and -not [string]::IsNullOrEmpty($anchorPart)) { continue }
+ #region docs-wiki (GitHub Wiki)
+ $wikiRoot = Join-Path $repoRoot 'docs-wiki'
+ $wikiFiles = Get-MarkdownFiles $wikiRoot $wikiRoot
+ # Exclude ../tree/ and ../wiki/ GitHub navigation links from internal link checks
+ $wikiInternalLinks = Get-InternalMdLinks $wikiFiles | Where-Object { $_.LinkTarget -notmatch '^\.\./tree/' -and $_.LinkTarget -notmatch '^\.\./wiki/' }
- # Only check .md files
- if ($pathPart -and $pathPart -notmatch '\.md$') { continue }
+ # Get all wiki page filenames for case-insensitive lookup
+ $wikiPageFileNames = @()
+ if (Test-Path $wikiRoot)
+ {
+ $wikiPageFileNames = Get-ChildItem -Path $wikiRoot -Filter '*.md' -File | ForEach-Object { $_.Name }
+ }
- $internalLinks += @{
- SourceFile = $file.FullName
- SourceRel = $file.RelativePath
- LinkText = $match.Groups[1].Value
- LinkTarget = $linkTarget
- PathPart = $pathPart
- AnchorPart = $anchorPart
- LineNumber = ($file.Content.Substring(0, $match.Index) -split "`n").Count
+ # Extract wiki double-bracket links: [[Page]] or [[Display|Page]]
+ $wikiPageLinks = @()
+ foreach ($file in $wikiFiles)
+ {
+ $cleanContent = Remove-HtmlComments $file.Content
+ $wikiMatches = [regex]::Matches($cleanContent, '\[\[(?:([^\]|]+)\|)?([^\]]+)\]\]')
+ foreach ($match in $wikiMatches)
+ {
+ $pageName = $match.Groups[2].Value.Trim()
+ $wikiPageLinks += @{
+ SourceFile = $file.FullName
+ SourceRel = $file.RelativePath
+ DisplayText = if ($match.Groups[1].Success) { $match.Groups[1].Value } else { $pageName }
+ PageName = $pageName
+ LineNumber = ($file.Content.Substring(0, $match.Index) -split "`n").Count
}
}
}
- # Extract all URLs from markdown files (excluding HTML comments)
- $allUrls = @()
- foreach ($file in $mdFiles)
+ # Extract wiki ../tree/dev/ repo-relative links
+ $wikiRepoLinks = @()
+ foreach ($file in $wikiFiles)
{
$cleanContent = Remove-HtmlComments $file.Content
- $urlMatches = [regex]::Matches($cleanContent, '\[([^\]]*)\]\((https?://[^)]+)\)')
- foreach ($match in $urlMatches)
+ $repoMatches = [regex]::Matches($cleanContent, '\[([^\]]*)\]\((\.\./tree/dev/[^)]+)\)')
+ foreach ($match in $repoMatches)
{
- $allUrls += @{
- SourceFile = $file.FullName
- SourceRel = $file.RelativePath
- LinkText = $match.Groups[1].Value
- Url = $match.Groups[2].Value
- LineNumber = ($file.Content.Substring(0, $match.Index) -split "`n").Count
+ $linkTarget = $match.Groups[2].Value
+ $repoPath = $linkTarget -replace '^\.\./tree/dev/', '' -replace '#.*$', ''
+ $wikiRepoLinks += @{
+ SourceFile = $file.FullName
+ SourceRel = $file.RelativePath
+ LinkText = $match.Groups[1].Value
+ LinkTarget = $linkTarget
+ RepoPath = $repoPath
+ LineNumber = ($file.Content.Substring(0, $match.Index) -split "`n").Count
}
}
}
+ #endregion
+ #region Root markdown files
+ $rootMdFiles = @()
+ if (Test-Path $repoRoot)
+ {
+ $rootMdFiles = Get-ChildItem -Path $repoRoot -Filter '*.md' -File | ForEach-Object {
+ @{
+ FullName = $_.FullName
+ RelativePath = $_.Name
+ Content = Get-Content -Path $_.FullName -Raw
+ }
+ }
+ }
+ $rootInternalLinks = Get-InternalMdLinks $rootMdFiles
+ #endregion
}
Describe 'Documentation links' {
- Context 'Internal relative links' {
+ BeforeAll {
+ $repoRoot = (Get-Item -Path $PSScriptRoot).Parent.Parent.Parent.Parent.FullName
+ $wikiRoot = Join-Path $repoRoot 'docs-wiki'
+ $wikiPageFileNames = @()
+ if (Test-Path $wikiRoot)
+ {
+ $wikiPageFileNames = Get-ChildItem -Path $wikiRoot -Filter '*.md' -File | ForEach-Object { $_.Name }
+ }
+
+ # Helper: Extract anchors (from headings and HTML elements) from a file
+ function Get-FileAnchors([string]$filePath)
+ {
+ $content = Get-Content -Path $filePath -Raw
+ $headings = [regex]::Matches($content, '(?m)^#{1,6}\s+(.+)$')
+ $anchors = @($headings | ForEach-Object {
+ $heading = $_.Groups[1].Value.Trim()
+ $heading `
+ -replace '', '' `
+ -replace '\[([^\]]*)\]\([^)]*\)', '$1' `
+ -replace '`([^`]*)`', '$1' `
+ -replace '[^a-zA-Z0-9\s\-_]', '' `
+ -replace '\s+', '-' `
+ | ForEach-Object { $_.Trim('-').ToLower() }
+ })
+ $htmlAnchors = [regex]::Matches($content, ': []()' -ForEach $internalLinks {
+ #region docs-mslearn
+
+ Context 'docs-mslearn: Internal relative links' {
+
+ It 'Should resolve to an existing file: : []()' -ForEach $mslearnInternalLinks {
$sourceDir = Split-Path $SourceFile -Parent
if ([string]::IsNullOrEmpty($PathPart))
{
- # Anchor-only link within the same file — the file exists by definition
Set-ItResult -Skipped -Because 'anchor-only link'
return
}
@@ -108,7 +230,7 @@ Describe 'Documentation links' {
$resolvedPath | Should -Not -BeNullOrEmpty -Because "link target '$PathPart' in ${SourceRel}:${LineNumber} should resolve to an existing file"
}
- It 'Should have a valid anchor: : []()' -ForEach ($internalLinks | Where-Object { $_.AnchorPart }) {
+ It 'Should have a valid anchor: : []()' -ForEach ($mslearnInternalLinks | Where-Object { $_.AnchorPart }) {
$sourceDir = Split-Path $SourceFile -Parent
$resolvedPath = Join-Path $sourceDir $PathPart
@@ -118,42 +240,131 @@ Describe 'Documentation links' {
return
}
- $targetContent = Get-Content -Path $resolvedPath -Raw
+ $anchors = Get-FileAnchors $resolvedPath
+ $anchors | Should -Contain $AnchorPart -Because "anchor '#$AnchorPart' should match a heading or HTML anchor in $(Split-Path $resolvedPath -Leaf) (link in ${SourceRel}:${LineNumber})"
+ }
+ }
+
+ Context 'docs-mslearn: No learn.microsoft.com URLs' {
- # Extract anchors from headings (e.g., ## My Heading -> my-heading)
- $headings = [regex]::Matches($targetContent, '(?m)^#{1,6}\s+(.+)$')
- $anchors = @($headings | ForEach-Object {
- $heading = $_.Groups[1].Value.Trim()
- # Convert heading to anchor: lowercase, replace spaces with hyphens, remove special chars
- $heading `
- -replace '', '' `
- -replace '\[([^\]]*)\]\([^)]*\)', '$1' `
- -replace '`([^`]*)`', '$1' `
- -replace '[^a-zA-Z0-9\s\-_]', '' `
- -replace '\s+', '-' `
- | ForEach-Object { $_.Trim('-').ToLower() }
- })
+ It 'Should not contain https://learn.microsoft.com links: :' -ForEach ($mslearnUrls | Where-Object { $_.Url -match 'learn\.microsoft\.com' }) {
+ $Url | Should -Not -Match 'learn\.microsoft\.com' -Because "links in docs-mslearn should use root-relative paths (e.g., /azure/...) instead of full URLs since docs are deployed to learn.microsoft.com (${SourceRel}:${LineNumber})"
+ }
+ }
- # Extract anchors from HTML elements (e.g., or )
- $htmlAnchors = [regex]::Matches($targetContent, ': ' -ForEach ($mslearnUrls | Where-Object { $_.Url -match 'learn\.microsoft\.com/[a-z]{2}-[a-z]{2}/' }) {
+ $Url | Should -Not -Match 'learn\.microsoft\.com/[a-z]{2}-[a-z]{2}/' -Because "MS Learn links should not include language locale segments like /en-us/ (${SourceRel}:${LineNumber})"
+ }
+ }
+
+ #endregion
+
+ #region docs (Jekyll site)
+
+ Context 'docs: Internal relative links' {
+
+ It 'Should resolve to an existing file: : []()' -ForEach $jekyllInternalLinks {
+ $sourceDir = Split-Path $SourceFile -Parent
+
+ if ([string]::IsNullOrEmpty($PathPart))
+ {
+ Set-ItResult -Skipped -Because 'anchor-only link'
+ return
+ }
+
+ $resolvedPath = Join-Path $sourceDir $PathPart | Resolve-Path -ErrorAction SilentlyContinue
+ $resolvedPath | Should -Not -BeNullOrEmpty -Because "link target '$PathPart' in ${SourceRel}:${LineNumber} should resolve to an existing file"
+ }
+
+ It 'Should have a valid anchor: : []()' -ForEach ($jekyllInternalLinks | Where-Object { $_.AnchorPart }) {
+ $sourceDir = Split-Path $SourceFile -Parent
+ $resolvedPath = Join-Path $sourceDir $PathPart
+ if (-not (Test-Path $resolvedPath))
+ {
+ Set-ItResult -Skipped -Because 'target file does not exist (covered by file resolution test)'
+ return
+ }
+
+ $anchors = Get-FileAnchors $resolvedPath
$anchors | Should -Contain $AnchorPart -Because "anchor '#$AnchorPart' should match a heading or HTML anchor in $(Split-Path $resolvedPath -Leaf) (link in ${SourceRel}:${LineNumber})"
}
}
- Context 'No learn.microsoft.com URLs in docs-mslearn' {
+ #endregion
- It 'Should not contain https://learn.microsoft.com links: :' -ForEach ($allUrls | Where-Object { $_.Url -match 'learn\.microsoft\.com' }) {
- $Url | Should -Not -Match 'learn\.microsoft\.com' -Because "links in docs-mslearn should use root-relative paths (e.g., /azure/...) instead of full URLs since docs are deployed to learn.microsoft.com (${SourceRel}:${LineNumber})"
+ #region docs-wiki (GitHub Wiki)
+
+ Context 'docs-wiki: Wiki page links' {
+
+ It 'Should reference an existing wiki page: : [[]]' -ForEach $wikiPageLinks {
+ $pageFileName = ($PageName -replace '\s', '-') + '.md'
+ # Case-insensitive match against actual wiki files
+ $found = $wikiPageFileNames | Where-Object { $_ -ieq $pageFileName }
+ $found | Should -Not -BeNullOrEmpty -Because "wiki link '[[${PageName}]]' in ${SourceRel}:${LineNumber} should reference an existing wiki page (expected file: $pageFileName)"
}
}
- Context 'No language locale in MS Learn links' {
+ Context 'docs-wiki: Repo-relative links' {
- It 'Should not contain language locale in URL: : ' -ForEach ($allUrls | Where-Object { $_.Url -match 'learn\.microsoft\.com/[a-z]{2}-[a-z]{2}/' }) {
- $Url | Should -Not -Match 'learn\.microsoft\.com/[a-z]{2}-[a-z]{2}/' -Because "MS Learn links should not include language locale segments like /en-us/ (${SourceRel}:${LineNumber})"
+ It 'Should resolve to an existing repo path: : []()' -ForEach $wikiRepoLinks {
+ $fullPath = Join-Path $repoRoot $RepoPath
+ $exists = (Test-Path $fullPath) -or (Test-Path "$fullPath.md")
+ $exists | Should -BeTrue -Because "repo-relative link '$RepoPath' in ${SourceRel}:${LineNumber} should point to an existing file or directory"
+ }
+ }
+
+ Context 'docs-wiki: Internal relative links' {
+
+ It 'Should resolve to an existing file: : []()' -ForEach $wikiInternalLinks {
+ $sourceDir = Split-Path $SourceFile -Parent
+
+ if ([string]::IsNullOrEmpty($PathPart))
+ {
+ Set-ItResult -Skipped -Because 'anchor-only link'
+ return
+ }
+
+ $resolvedPath = Join-Path $sourceDir $PathPart | Resolve-Path -ErrorAction SilentlyContinue
+ $resolvedPath | Should -Not -BeNullOrEmpty -Because "link target '$PathPart' in ${SourceRel}:${LineNumber} should resolve to an existing file"
+ }
+ }
+
+ #endregion
+
+ #region Root markdown files
+
+ Context 'Root files: Internal relative links' {
+
+ It 'Should resolve to an existing file: : []()' -ForEach $rootInternalLinks {
+ $sourceDir = Split-Path $SourceFile -Parent
+
+ if ([string]::IsNullOrEmpty($PathPart))
+ {
+ Set-ItResult -Skipped -Because 'anchor-only link'
+ return
+ }
+
+ $resolvedPath = Join-Path $sourceDir $PathPart | Resolve-Path -ErrorAction SilentlyContinue
+ $resolvedPath | Should -Not -BeNullOrEmpty -Because "link target '$PathPart' in ${SourceRel}:${LineNumber} should resolve to an existing file"
+ }
+
+ It 'Should have a valid anchor: : []()' -ForEach ($rootInternalLinks | Where-Object { $_.AnchorPart }) {
+ $sourceDir = Split-Path $SourceFile -Parent
+ $resolvedPath = Join-Path $sourceDir $PathPart
+
+ if (-not (Test-Path $resolvedPath))
+ {
+ Set-ItResult -Skipped -Because 'target file does not exist (covered by file resolution test)'
+ return
+ }
+
+ $anchors = Get-FileAnchors $resolvedPath
+ $anchors | Should -Contain $AnchorPart -Because "anchor '#$AnchorPart' should match a heading or HTML anchor in $(Split-Path $resolvedPath -Leaf) (link in ${SourceRel}:${LineNumber})"
}
}
+ #endregion
}
diff --git a/src/powershell/Tests/Unit/Start-FinOpsCostExport.Tests.ps1 b/src/powershell/Tests/Unit/Start-FinOpsCostExport.Tests.ps1
index d202b86cb..fa07da945 100644
--- a/src/powershell/Tests/Unit/Start-FinOpsCostExport.Tests.ps1
+++ b/src/powershell/Tests/Unit/Start-FinOpsCostExport.Tests.ps1
@@ -78,8 +78,8 @@ Describe 'Start-FinOpsCostExport' {
$params = @{
Name = $exportName
Scope = $scope
- StartDate = (Get-Date).AddDays(-7)
- EndDate = (Get-Date).AddDays(-2)
+ StartDate = Get-Date -Year 2024 -Month 6 -Day 10 -Hour 0 -Minute 0 -Second 0 -Millisecond 0
+ EndDate = Get-Date -Year 2024 -Month 6 -Day 20 -Hour 0 -Minute 0 -Second 0 -Millisecond 0
}
# Act
diff --git a/src/scripts/Test-PowerShell.ps1 b/src/scripts/Test-PowerShell.ps1
index fe2b6c5aa..2f084015a 100644
--- a/src/scripts/Test-PowerShell.ps1
+++ b/src/scripts/Test-PowerShell.ps1
@@ -20,6 +20,9 @@
.PARAMETER Data
Optional. Indicates whether to run open data tests.
+ .PARAMETER Docs
+ Optional. Indicates whether to run documentation link tests.
+
.PARAMETER Exports
Optional. Indicates whether to run Cost Management export tests.
@@ -64,6 +67,9 @@ param (
[switch]
$Data,
+ [switch]
+ $Docs,
+
[switch]
$Exports,
@@ -127,6 +133,7 @@ else
$testsToRun = @()
if ($Cost) { $testsToRun += '*-FinOpsCost*', 'Cost*' }
if ($Data) { $testsToRun += '*-OpenData*', '*-FinOpsPricingUnit*', '*-FinOpsRegion*', '*-FinOpsResourceType*', '*-FinOpsService*' }
+ if ($Docs) { $testsToRun += '*Docs*' }
if ($Exports) { $testsToRun += '*-FinOpsCostExport*', 'CostExports.Tests.ps1' }
if ($FOCUS) { $testsToRun += '*-FinOpsSchema*', 'FOCUS.Tests.ps1' }
if ($Hubs) { $testsToRun += '*-FinOpsHub*', '*-Hub*', 'Hubs*.Tests.ps1' }