From 9fb5ab53ec2fd942247a261038f10045603360da Mon Sep 17 00:00:00 2001 From: MrMCake Date: Thu, 30 Jun 2022 00:12:28 +0200 Subject: [PATCH 1/6] Update to latest --- utilities/tools/Set-ModuleReadMe.ps1 | 202 ++++++++++++++++++--------- 1 file changed, 134 insertions(+), 68 deletions(-) diff --git a/utilities/tools/Set-ModuleReadMe.ps1 b/utilities/tools/Set-ModuleReadMe.ps1 index 390ec2413c..050309d7d4 100644 --- a/utilities/tools/Set-ModuleReadMe.ps1 +++ b/utilities/tools/Set-ModuleReadMe.ps1 @@ -351,93 +351,159 @@ function Set-DeploymentExamplesSection { $moduleRoot = Split-Path $TemplateFilePath -Parent $resourceTypeIdentifier = $moduleRoot.Replace('\', '/').Split('/modules/')[1].TrimStart('/') - $parameterFiles = Get-ChildItem (Join-Path $moduleRoot '.test') -Filter '*parameters.json' -Recurse + $resourceType = $resourceTypeIdentifier.Split('/')[1] + $testFilePaths = (Get-ChildItem (Join-Path -Path $moduleRoot -ChildPath '.test') -File).FullName | Where-Object { $_ -match '.+\.[bicep|json]' } $index = 1 - foreach ($parameterFilePath in $parameterFiles.FullName) { - $contentInJSONFormat = Get-Content -Path $parameterFilePath -Encoding 'utf8' | Out-String + foreach ($testFilePath in $testFilePaths) { + + $rawContentArray = Get-Content -Path $testFilePath + $rawContent = Get-Content -Path $testFilePath -Encoding 'utf8' | Out-String $SectionContent += @( - "

Example $index

" + '

Example {0}: {1}

' -f $index, ((Split-Path $testFilePath -Leaf) -split '\.')[0] ) - if ($addJson) { - $SectionContent += @( - '', - '
', - '', - 'via JSON Parameter file', - '', - '```json', - $contentInJSONFormat.TrimEnd(), - '```', - '', - '
' - ) - } + if ((Split-Path $testFilePath -Extension) -eq '.bicep') { + # Bicep to JSON + # ============= + $bicepTestStartIndex = $rawContentArray.IndexOf("module testDeployment '../deploy.bicep' = {") + + + $bicepTestEndIndex = $bicepTestStartIndex + do { + $bicepTestEndIndex++ + } while ($rawContentArray[$bicepTestEndIndex] -ne '}') + + $rawBicepExample = $rawContentArray[$bicepTestStartIndex..$bicepTestEndIndex] + + if ($addBicep) { + $rawBicepExample[0] = "module $resourceType './$resourceTypeIdentifier/deploy.bicep = {'" + $rawBicepExample = $rawBicepExample | Where-Object { $_ -notmatch 'scope: *' } + + + $SectionContent += @( + '', + '
' + '' + 'via Bicep module' + '' + '```bicep', + ($rawBicepExample | ForEach-Object { " $_" }).TrimEnd(), + '```', + '', + '
' + '

' + ) + } + + if ($addJson) { + # TODO: Add JSON support - if ($addBicep) { - $JSONParametersHashTable = (ConvertFrom-Json $contentInJSONFormat -AsHashtable -Depth 99).parameters - - # Handle KeyVaut references - $keyVaultReferences = $JSONParametersHashTable.Keys | Where-Object { $JSONParametersHashTable[$_].Keys -contains 'reference' } - - if ($keyVaultReferences.Count -gt 0) { - $keyVaultReferenceData = @() - foreach ($reference in $keyVaultReferences) { - $resourceIdElem = $JSONParametersHashTable[$reference].reference.keyVault.id -split '/' - $keyVaultReferenceData += @{ - subscriptionId = $resourceIdElem[2] - resourceGroupName = $resourceIdElem[4] - vaultName = $resourceIdElem[-1] - secretName = $JSONParametersHashTable[$reference].reference.secretName - parameterName = $reference + $jsonExample = @() + + $SectionContent += @( + '', + '

' + '' + 'via JSON Parameter file' + '' + '```json', + '{', + ' "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",', + ' "contentVersion": "1.0.0.0",', + ' "parameters": {' + ($jsonExample | ForEach-Object { " $_" }).TrimEnd(), + ' }', + '}', + '```', + '', + '
' + '

' + ) + } + } else { + # JSON to Bicep + # ============= + # TODO: Support JSON test template files? + + if ($addJson) { + $SectionContent += @( + '', + '

', + '', + 'via JSON Parameter file', + '', + '```json', + $rawContent.TrimEnd(), + '```', + '', + '
' + ) + } + + if ($addBicep) { + $JSONParametersHashTable = (ConvertFrom-Json $rawContent -AsHashtable -Depth 99).parameters + + # Handle KeyVaut references + $keyVaultReferences = $JSONParametersHashTable.Keys | Where-Object { $JSONParametersHashTable[$_].Keys -contains 'reference' } + + if ($keyVaultReferences.Count -gt 0) { + $keyVaultReferenceData = @() + foreach ($reference in $keyVaultReferences) { + $resourceIdElem = $JSONParametersHashTable[$reference].reference.keyVault.id -split '/' + $keyVaultReferenceData += @{ + subscriptionId = $resourceIdElem[2] + resourceGroupName = $resourceIdElem[4] + vaultName = $resourceIdElem[-1] + secretName = $JSONParametersHashTable[$reference].reference.secretName + parameterName = $reference + } } } - } - $extendedKeyVaultReferences = @() - $counter = 0 - foreach ($reference in ($keyVaultReferenceData | Sort-Object -Property 'vaultName' -Unique)) { - $counter++ - $extendedKeyVaultReferences += @( - "resource kv$counter 'Microsoft.KeyVault/vaults@2019-09-01' existing = {", + $extendedKeyVaultReferences = @() + $counter = 0 + foreach ($reference in ($keyVaultReferenceData | Sort-Object -Property 'vaultName' -Unique)) { + $counter++ + $extendedKeyVaultReferences += @( + "resource kv$counter 'Microsoft.KeyVault/vaults@2019-09-01' existing = {", (" name: '{0}'" -f $reference.vaultName), (" scope: resourceGroup('{0}','{1}')" -f $reference.subscriptionId, $reference.resourceGroupName), - '}', - '' - ) + '}', + '' + ) - # Add attribute for later correct reference - $keyVaultReferenceData | Where-Object { $_.vaultName -eq $reference.vaultName } | ForEach-Object { - $_['vaultResourceReference'] = "kv$counter" + # Add attribute for later correct reference + $keyVaultReferenceData | Where-Object { $_.vaultName -eq $reference.vaultName } | ForEach-Object { + $_['vaultResourceReference'] = "kv$counter" + } } - } - # Handle VALUE references (i.e. remove them) - $JSONParameters = (ConvertFrom-Json $contentInJSONFormat -Depth 99).PSObject.properties['parameters'].value - $JSONParametersWithoutValue = [ordered]@{} - foreach ($parameter in $JSONParameters.PSObject.Properties) { - if ($parameter.value.PSObject.Properties.name -eq 'value') { - $JSONParametersWithoutValue[$parameter.name] = $parameter.value.PSObject.Properties['value'].value - } else { - # replace key vault references - $matchingTuple = $keyVaultReferenceData | Where-Object { $_.parameterName -eq $parameter.Name } - $JSONParametersWithoutValue[$parameter.name] = "{0}.getSecret('{1}')" -f $matchingTuple.vaultResourceReference, $matchingTuple.secretName + # Handle VALUE references (i.e. remove them) + $JSONParameters = (ConvertFrom-Json $rawContent -Depth 99).PSObject.properties['parameters'].value + $JSONParametersWithoutValue = [ordered]@{} + foreach ($parameter in $JSONParameters.PSObject.Properties) { + if ($parameter.value.PSObject.Properties.name -eq 'value') { + $JSONParametersWithoutValue[$parameter.name] = $parameter.value.PSObject.Properties['value'].value + } else { + # replace key vault references + $matchingTuple = $keyVaultReferenceData | Where-Object { $_.parameterName -eq $parameter.Name } + $JSONParametersWithoutValue[$parameter.name] = "{0}.getSecret('{1}')" -f $matchingTuple.vaultResourceReference, $matchingTuple.secretName + } } - } - $templateParameterObject = $JSONParametersWithoutValue | ConvertTo-Json -Depth 99 - if ($templateParameterObject -ne '{}') { - $contentInBicepFormat = $templateParameterObject -replace '"', "'" # Update any [xyz: "xyz"] to [xyz: 'xyz'] - $contentInBicepFormat = $contentInBicepFormat -replace ',', '' # Update any [xyz: xyz,] to [xyz: xyz] - $contentInBicepFormat = $contentInBicepFormat -replace "'(\w+)':", '$1:' # Update any ['xyz': xyz] to [xyz: xyz] - $contentInBicepFormat = $contentInBicepFormat -replace "'(.+.getSecret\('.+'\))'", '$1' # Update any [xyz: 'xyz.GetSecret()'] to [xyz: xyz.GetSecret()] + $templateParameterObject = $JSONParametersWithoutValue | ConvertTo-Json -Depth 99 + if ($templateParameterObject -ne '{}') { + $contentInBicepFormat = $templateParameterObject -replace '"', "'" # Update any [xyz: "xyz"] to [xyz: 'xyz'] + $contentInBicepFormat = $contentInBicepFormat -replace ',', '' # Update any [xyz: xyz,] to [xyz: xyz] + $contentInBicepFormat = $contentInBicepFormat -replace "'(\w+)':", '$1:' # Update any ['xyz': xyz] to [xyz: xyz] + $contentInBicepFormat = $contentInBicepFormat -replace "'(.+.getSecret\('.+'\))'", '$1' # Update any [xyz: 'xyz.GetSecret()'] to [xyz: xyz.GetSecret()] - $bicepParamsArray = $contentInBicepFormat -split ('\n') - $bicepParamsArray = $bicepParamsArray[1..($bicepParamsArray.count - 2)] + $bicepParamsArray = $contentInBicepFormat -split ('\n') + $bicepParamsArray = $bicepParamsArray[1..($bicepParamsArray.count - 2)] + } } - $resourceType = $resourceTypeIdentifier.Split('/')[1] $SectionContent += @( '', From f7eabf6ed5ac19a8d49f3925e2149e7138846b49 Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Thu, 30 Jun 2022 08:02:12 +0200 Subject: [PATCH 2/6] Fixed incorrect param file ref (#1626) --- modules/.global/global.module.tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/.global/global.module.tests.ps1 b/modules/.global/global.module.tests.ps1 index e8b08a8ea0..f81f6efe87 100644 --- a/modules/.global/global.module.tests.ps1 +++ b/modules/.global/global.module.tests.ps1 @@ -931,7 +931,7 @@ Describe 'Deployment template tests' -Tag Template { foreach ($moduleFolderPath in $moduleFolderPaths) { if (Test-Path (Join-Path $moduleFolderPath '.test')) { - $testFilePaths = (Get-ChildItem (Join-Path -Path $moduleFolderPath -ChildPath '.testeters.json') -Recurse -Force).FullName + $testFilePaths = (Get-ChildItem (Join-Path -Path $moduleFolderPath -ChildPath '.parameters.json') -Recurse -Force).FullName foreach ($testFilePath in $testFilePaths) { foreach ($token in $enforcedTokenList.Keys) { $parameterFileTokenTestCases += @{ From 92986a3699417e00e5bf78eb237d1f6ec8b3a7db Mon Sep 17 00:00:00 2001 From: MrMCake Date: Thu, 30 Jun 2022 10:03:11 +0200 Subject: [PATCH 3/6] Further updates --- utilities/tools/Set-ModuleReadMe.ps1 | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/utilities/tools/Set-ModuleReadMe.ps1 b/utilities/tools/Set-ModuleReadMe.ps1 index 050309d7d4..2251df9824 100644 --- a/utilities/tools/Set-ModuleReadMe.ps1 +++ b/utilities/tools/Set-ModuleReadMe.ps1 @@ -321,6 +321,9 @@ Optional. A switch to control whether or not to add a ARM-JSON-Parameter file ex .PARAMETER addBicep Optional. A switch to control whether or not to add a Bicep deployment example. Defaults to true. +.PARAMETER ProjectSettings +Optional. Projects settings to draw information from. For example the `namePrefix`. + .EXAMPLE Set-DeploymentExamplesSection -TemplateFileContent @{ resource = @{}; ... } -ReadMeFileContent @('# Title', '', '## Section 1', ...) @@ -342,6 +345,9 @@ function Set-DeploymentExamplesSection { [Parameter(Mandatory = $false)] [bool] $addBicep = $true, + [Parameter(Mandatory = $false)] + [hashtable] $ProjectSettings = @{}, + [Parameter(Mandatory = $false)] [string] $SectionStartIdentifier = '## Deployment examples' ) @@ -377,11 +383,21 @@ function Set-DeploymentExamplesSection { $rawBicepExample = $rawContentArray[$bicepTestStartIndex..$bicepTestEndIndex] + # Replace placeholders + $namePrefix = ($ProjectSettings.parameterFileTokens.localTokens | Where-Object { $_.name -eq 'namePrefix' }).value + $serviceShort = ([regex]::Match($rawContent, "(?m)^param serviceShort string = '(.+)'\s*$")).Captures.Groups[1].Value + + $rawBicepExampleString = ($rawBicepExample | Out-String) + $rawBicepExampleString = $rawBicepExampleString -replace '\$\{serviceShort\}', $serviceShort + $rawBicepExampleString = $rawBicepExampleString -replace '\$\{namePrefix\}', $namePrefix + + $rawBicepExample = $rawBicepExampleString -split '\n' + + # Generate content if ($addBicep) { $rawBicepExample[0] = "module $resourceType './$resourceTypeIdentifier/deploy.bicep = {'" $rawBicepExample = $rawBicepExample | Where-Object { $_ -notmatch 'scope: *' } - $SectionContent += @( '', '
' @@ -707,6 +723,15 @@ function Set-ModuleReadMe { $fullResourcePath = (Split-Path $TemplateFilePath -Parent).Replace('\', '/').split('/modules/')[1] + $root = (Get-Item $PSScriptRoot).Parent.Parent.FullName + $projectSettingsPath = Join-Path $root 'settings.json' + if (Test-Path $projectSettingsPath) { + $projectSettings = Get-Content $projectSettingsPath | ConvertFrom-Json -AsHashtable + } else { + Write-Warning "No settings file found in path [$projectSettingsPath]" + $projectSettings = @{} + } + # Check readme if (-not (Test-Path $ReadMeFilePath) -or ([String]::IsNullOrEmpty((Get-Content $ReadMeFilePath -Raw)))) { # Create new readme file @@ -790,6 +815,7 @@ function Set-ModuleReadMe { $inputObject = @{ ReadMeFileContent = $readMeFileContent TemplateFilePath = $TemplateFilePath + ProjectSettings = $projectSettings } $readMeFileContent = Set-DeploymentExamplesSection @inputObject } From 619e68df479e9bf288f0f8daf316b04c13857b74 Mon Sep 17 00:00:00 2001 From: MrMCake Date: Thu, 30 Jun 2022 10:08:16 +0200 Subject: [PATCH 4/6] Further updates --- .../pipelineTemplates/jobs.validateModuleDeployment.yml | 4 ++-- .github/actions/templates/validateModuleDeployment/action.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml b/.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml index bc521b9e03..f03517b844 100644 --- a/.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml +++ b/.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml @@ -253,7 +253,7 @@ jobs: if ($testTemplatePossibleParameters -contains 'namePrefix') { $functionInput['additionalParameters'] += @{ - namePrefix = $projectSettings.parameterFileTokens.localTokens[0].value + namePrefix = ($projectSettings.parameterFileTokens.localTokens | Where-Object { $_.name -eq 'namePrefix' }).value } } } @@ -344,7 +344,7 @@ jobs: if ($testTemplatePossibleParameters -contains 'namePrefix') { $functionInput['additionalParameters'] += @{ - namePrefix = $projectSettings.parameterFileTokens.localTokens[0].value + namePrefix = ($projectSettings.parameterFileTokens.localTokens | Where-Object { $_.name -eq 'namePrefix' }).value } } } diff --git a/.github/actions/templates/validateModuleDeployment/action.yml b/.github/actions/templates/validateModuleDeployment/action.yml index be516ed43a..116d82a934 100644 --- a/.github/actions/templates/validateModuleDeployment/action.yml +++ b/.github/actions/templates/validateModuleDeployment/action.yml @@ -247,7 +247,7 @@ runs: if ($testTemplatePossibleParameters -contains 'namePrefix') { $functionInput['additionalParameters'] += @{ - namePrefix = $projectSettings.parameterFileTokens.localTokens[0].value + namePrefix = ($projectSettings.parameterFileTokens.localTokens | Where-Object { $_.name -eq 'namePrefix' }).value } } } @@ -343,7 +343,7 @@ runs: if ($testTemplatePossibleParameters -contains 'namePrefix') { $functionInput['additionalParameters'] += @{ - namePrefix = $projectSettings.parameterFileTokens.localTokens[0].value + namePrefix = ($projectSettings.parameterFileTokens.localTokens | Where-Object { $_.name -eq 'namePrefix' }).value } } } From fedee62e12dc32676b3e7cb799155fb8378f69f8 Mon Sep 17 00:00:00 2001 From: MrMCake Date: Thu, 30 Jun 2022 15:41:01 +0200 Subject: [PATCH 5/6] Updated tool --- utilities/tools/Set-ModuleReadMe.ps1 | 86 ++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 12 deletions(-) diff --git a/utilities/tools/Set-ModuleReadMe.ps1 b/utilities/tools/Set-ModuleReadMe.ps1 index 2251df9824..1561b1c3d4 100644 --- a/utilities/tools/Set-ModuleReadMe.ps1 +++ b/utilities/tools/Set-ModuleReadMe.ps1 @@ -360,14 +360,14 @@ function Set-DeploymentExamplesSection { $resourceType = $resourceTypeIdentifier.Split('/')[1] $testFilePaths = (Get-ChildItem (Join-Path -Path $moduleRoot -ChildPath '.test') -File).FullName | Where-Object { $_ -match '.+\.[bicep|json]' } - $index = 1 + $pathIndex = 1 foreach ($testFilePath in $testFilePaths) { $rawContentArray = Get-Content -Path $testFilePath $rawContent = Get-Content -Path $testFilePath -Encoding 'utf8' | Out-String $SectionContent += @( - '

Example {0}: {1}

' -f $index, ((Split-Path $testFilePath -Leaf) -split '\.')[0] + '

Example {0}: {1}

' -f $pathIndex, ((Split-Path $testFilePath -Leaf) -split '\.')[0] ) if ((Split-Path $testFilePath -Extension) -eq '.bicep') { @@ -414,9 +414,77 @@ function Set-DeploymentExamplesSection { } if ($addJson) { - # TODO: Add JSON support - $jsonExample = @() + $paramStartIndex = 0 + do { + $paramStartIndex++ + } while ($rawBicepExample[$paramStartIndex] -notmatch '\s+params: {') + + $paramBlockIndent = ([regex]::Match($rawBicepExample[$paramStartIndex], '^(\s+).*')).Captures.Groups[1].Value.Length + + $paramEndIndex = 0 + do { + $paramEndIndex++ + } while ($rawBicepExample[$paramEndIndex] -notmatch "^\s{$paramBlockIndent}\}\s*$") + + $paramBlock = $rawBicepExample[($paramStartIndex + 1)..($paramEndIndex - 1)] + + $paramInJsonFormat = @( + '{', + $paramBlock + '}' + ) | Out-String + + # Formatting + $paramInJsonFormat = $paramInJsonFormat -replace "'", '"' + $paramInJsonFormat = $paramInJsonFormat -replace '([0-9a-zA-Z]+):', '"$1":' + + $paramInJSONFormatArray = $paramInJsonFormat -split '\n' | Where-Object { $_ } + + + # Replace resource IDs + for ($index = 0; $index -lt $paramInJSONFormatArray.Count; $index++) { + if ($paramInJSONFormatArray[$index] -like '*:*' -and ($paramInJSONFormatArray[$index] -split ':')[1].Trim() -notmatch '".+"' -and $paramInJSONFormatArray[$index] -like '*.*') { + # In case of a reference like : "virtualWanId": resourceGroupResources.outputs.virtualWWANResourceId + $paramInJSONFormatArray[$index] = '{0}: "<{1}>"' -f ($paramInJSONFormatArray[$index] -split ':')[0], ([regex]::Match(($paramInJSONFormatArray[$index] -split ':')[0], '"(.+)"')).Captures.Groups[1].Value + } + if ($paramInJSONFormatArray[$index] -notlike '*:*' -and $paramInJSONFormatArray[$index] -notlike '*"*"*' -and $paramInJSONFormatArray[$index] -like '*.*') { + # In case of a reference like : [ \n resourceGroupResources.outputs.managedIdentityPrincipalId \n ] + $paramInJSONFormatArray[$index] = '"{0}"' -f $paramInJSONFormatArray[$index].Split('.')[-1].Trim() + } + } + + # Handle comma + for ($index = 0; $index -lt $paramInJSONFormatArray.Count; $index++) { + if ($paramInJSONFormatArray[$index] -match '[\{|\[]') { + # If we're just opening an object/array, skip + continue + } else { + if ((($index -lt $paramInJSONFormatArray.Count - 1) -and $paramInJSONFormatArray[$index + 1] -match '[\]|\}]') -or ($index -eq $paramInJSONFormatArray.Count - 1)) { + # -or ($index -eq $paramInJSONFormatArray.Count - 2 -and $paramInJSONFormatArray[$index + 1] -eq '')) { + # If the next item closes an object/array, or is the last line, skip + continue + } + $paramInJSONFormatArray[$index] = '{0},' -f $paramInJSONFormatArray[$index].Trim() + } + } + + # Add 'value' middle-layer for top-level parameters + $paramInJsonFormatObject = $paramInJSONFormatArray | Out-String | ConvertFrom-Json -AsHashtable -Depth 99 + $paramInJsonFormatObjectWithValue = @{} + foreach ($paramKey in $paramInJsonFormatObject.Keys) { + $paramInJsonFormatObjectWithValue[$paramKey] = @{ + value = $paramInJsonFormatObject[$paramKey] + } + } + + $jsonExample = [ordered]@{ + '$schema' = 'https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#' + contentVersion = '1.0.0.0' + parameters = $paramInJsonFormatObjectWithValue + } + + $jsonExample = ($jsonExample | ConvertTo-Json -Depth 99) -split '\n' $SectionContent += @( '', @@ -425,13 +493,7 @@ function Set-DeploymentExamplesSection { 'via JSON Parameter file' '' '```json', - '{', - ' "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",', - ' "contentVersion": "1.0.0.0",', - ' "parameters": {' - ($jsonExample | ForEach-Object { " $_" }).TrimEnd(), - ' }', - '}', + $jsonExample '```', '', '
' @@ -546,7 +608,7 @@ function Set-DeploymentExamplesSection { '' ) - $index++ + $pathIndex++ } # Build result From acb009ca5a518d3a9a1274d27d5b1c0cf8a8fc4f Mon Sep 17 00:00:00 2001 From: MrMCake Date: Thu, 30 Jun 2022 15:53:48 +0200 Subject: [PATCH 6/6] Upper case title update --- utilities/tools/Set-ModuleReadMe.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utilities/tools/Set-ModuleReadMe.ps1 b/utilities/tools/Set-ModuleReadMe.ps1 index 1561b1c3d4..e0dbe22354 100644 --- a/utilities/tools/Set-ModuleReadMe.ps1 +++ b/utilities/tools/Set-ModuleReadMe.ps1 @@ -366,8 +366,11 @@ function Set-DeploymentExamplesSection { $rawContentArray = Get-Content -Path $testFilePath $rawContent = Get-Content -Path $testFilePath -Encoding 'utf8' | Out-String + $exampleTitle = ((Split-Path $testFilePath -LeafBase) -replace '\.', ' ') -replace ' parameters', '' + $TextInfo = (Get-Culture).TextInfo + $exampleTitle = $TextInfo.ToTitleCase($exampleTitle) $SectionContent += @( - '

Example {0}: {1}

' -f $pathIndex, ((Split-Path $testFilePath -Leaf) -split '\.')[0] + '

Example {0}: {1}

' -f $pathIndex, $exampleTitle ) if ((Split-Path $testFilePath -Extension) -eq '.bicep') {