Variables - Find Unreplaced

Octopus.Script exported 2021-09-14 by harrisonmeister belongs to ‘Octopus’ category.

Searches Web.config or App.config files looking for Octopus Deploy variables that have not been replaced. Alternatively, any arbitrary file can be checked.

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

Path

Path

The folders to search for files in. Enter multiple paths on separate lines.

Files

Files = *.config

An array of all the files or globs to search in. Defaults to *.config. Multiple items can be separated with a semicolon ;.

Exclude

Exclude

Files or globs to ignore. Multiple items can be separated with a semicolon ;.

Recurse

Recurse = True

Determines whether or not the step should look through the items in Path recursively.

Treat as an error?

TreatAsError = False

Determines if the step will cause the build to fail or issue a warning. By default it will only warn of a problem.

Script body

Steps based on this template will execute the following PowerShell script.

function Find-Unreplaced {
    <#
    .SYNOPSIS
        Looks for Octopus Deploy variables
    .DESCRIPTION
        Analyses `Web/App.Release.configs`, etc... looking for Octopus Deploy 
        variables that have not been replaced.
    .EXAMPLE
        Find-Unreplaced C:\Folder *.config, *.ps1 
    .PARAMETER Path
        Root folder to search in
    .PARAMETER Files
        An array of all the files or globs to search in. Defaults to *.config
    .PARAMETER Exclude
        Files to ignore
    .PARAMETER Recurse
        Should the cmdlet look for the file types recursively
    .PARAMETER TreatAsError
        Will cause the script to write an Error instead of a warning if variables are found
    #>
    [CmdletBinding()]
    param 
    (
        [Parameter(
            Position=0,
            Mandatory=$true,
            ValueFromPipeline=$True)]
        [string] $Path,
        
        [Parameter(
            Position=1,
            Mandatory=$false)]
        [string[]] $Files = @('*.config'),
        
        [Parameter(Mandatory=$false)]
        [string[]] $Exclude,
        
        [Parameter(Mandatory=$false)]
        [switch] $Recurse,
        
        [Parameter(Mandatory=$false)]
        [switch] $TreatAsError
    )

    process {
        Write-Host "Searching for files in '$Path'"
        if (-not (Test-Path $Path -PathType container)) {
            Write-Error "The path '$Path' does not exist or is not a folder."
            return
        }
        
        if (-not $Recurse) {
            # For some reason, a splat is required when not recursing
            if ($Path.EndsWith("\")) { $Path += "*" } else { $Path += "\*" }
        }

        $clean = $true

        $found = Get-ChildItem -Path $Path -Recurse:$Recurse -Include $Files -Exclude $Exclude -File
        foreach ($file in $found) {
            Write-Host "Found '$file'.`nSearching for Octopus variables..." -NoNewline
            $matches = Select-String -Path $file -Pattern "#\{([^}]*)\}" -AllMatches
            $clean = $clean -and ($matches.Count -eq 0)
            if ($clean) {
                Write-Host "clean"
            } else {
                Write-Host "done`n$matches"
            }
        }

        if (-not $clean) {
            $msg = "Unreplaced Octopus Variables were found."
            if ($TreatAsError) {
                Write-Error $msg
            } else {
                Write-Warning $msg
            }
        }
    }
}

if (-not $Path) { throw "A Path must be specified" }
if (-not $Files) { throw "At least one File must be specified" }

$spPaths = $Path -split "`n" | Foreach-Object { $_.Trim() } | Where-Object { -not [string]::IsNullOrEmpty($_) }
$spFiles = $Files -split ";" | Foreach-Object { $_.Trim() } 
$spExcludes = $Exclude -split ";" | Foreach-Object { $_.Trim() } 
$bRecurse = $Recurse -eq 'True'
$bTreatAsError = $TreatAsError -eq 'True'

$spPaths | Find-Unreplaced -Files $spFiles -Exclude $spExcludes -Recurse:$bRecurse -TreatAsError:$bTreatAsError


Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "0b753c94-c12b-46f3-bb82-459e27bbe812",
  "Name": "Variables - Find Unreplaced",
  "Description": "Searches `Web.config` or `App.config` files looking for Octopus Deploy variables that have not been replaced. Alternatively, any arbitrary file can be checked.",
  "Version": 26,
  "ExportedAt": "2021-09-14T10:40:15.430Z",
  "ActionType": "Octopus.Script",
  "Author": "harrisonmeister",
  "Packages": [],
  "Parameters": [
    {
      "Id": "7809f4f9-7388-4067-ae0f-e5d858ad9395",
      "Name": "Path",
      "Label": "Path",
      "HelpText": "The folders to search for files in. Enter multiple paths on separate lines.",
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "MultiLineText"
      }
    },
    {
      "Id": "f9389ec3-1602-48b1-9f03-c95af304a3c2",
      "Name": "Files",
      "Label": "Files",
      "HelpText": "An array of all the files or globs to search in. Defaults to `*.config`. Multiple items can be separated with a semicolon `;`.",
      "DefaultValue": "*.config",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "0b54fdbd-12ac-4fc8-aa26-410cd1a3bd77",
      "Name": "Exclude",
      "Label": "Exclude",
      "HelpText": "Files or globs to ignore. Multiple items can be separated with a semicolon `;`.",
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "29f81ee9-529b-45f6-8452-8e8f464c3225",
      "Name": "Recurse",
      "Label": "Recurse",
      "HelpText": "Determines whether or not the step should look through the items in `Path` recursively.",
      "DefaultValue": "True",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Id": "fd64a155-abe9-483e-b954-e182fbb777b0",
      "Name": "TreatAsError",
      "Label": "Treat as an error?",
      "HelpText": "Determines if the step will cause the build to fail or issue a warning. By default it will only warn of a problem.",
      "DefaultValue": "False",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.ScriptBody": "function Find-Unreplaced {\n    <#\n    .SYNOPSIS\n        Looks for Octopus Deploy variables\n    .DESCRIPTION\n        Analyses `Web/App.Release.configs`, etc... looking for Octopus Deploy \n        variables that have not been replaced.\n    .EXAMPLE\n        Find-Unreplaced C:\\Folder *.config, *.ps1 \n    .PARAMETER Path\n        Root folder to search in\n    .PARAMETER Files\n        An array of all the files or globs to search in. Defaults to *.config\n    .PARAMETER Exclude\n        Files to ignore\n    .PARAMETER Recurse\n        Should the cmdlet look for the file types recursively\n    .PARAMETER TreatAsError\n        Will cause the script to write an Error instead of a warning if variables are found\n    #>\n    [CmdletBinding()]\n    param \n    (\n        [Parameter(\n            Position=0,\n            Mandatory=$true,\n            ValueFromPipeline=$True)]\n        [string] $Path,\n        \n        [Parameter(\n            Position=1,\n            Mandatory=$false)]\n        [string[]] $Files = @('*.config'),\n        \n        [Parameter(Mandatory=$false)]\n        [string[]] $Exclude,\n        \n        [Parameter(Mandatory=$false)]\n        [switch] $Recurse,\n        \n        [Parameter(Mandatory=$false)]\n        [switch] $TreatAsError\n    )\n\n    process {\n        Write-Host \"Searching for files in '$Path'\"\n        if (-not (Test-Path $Path -PathType container)) {\n            Write-Error \"The path '$Path' does not exist or is not a folder.\"\n            return\n        }\n        \n        if (-not $Recurse) {\n            # For some reason, a splat is required when not recursing\n            if ($Path.EndsWith(\"\\\")) { $Path += \"*\" } else { $Path += \"\\*\" }\n        }\n\n        $clean = $true\n\n        $found = Get-ChildItem -Path $Path -Recurse:$Recurse -Include $Files -Exclude $Exclude -File\n        foreach ($file in $found) {\n            Write-Host \"Found '$file'.`nSearching for Octopus variables...\" -NoNewline\n            $matches = Select-String -Path $file -Pattern \"#\\{([^}]*)\\}\" -AllMatches\n            $clean = $clean -and ($matches.Count -eq 0)\n            if ($clean) {\n                Write-Host \"clean\"\n            } else {\n                Write-Host \"done`n$matches\"\n            }\n        }\n\n        if (-not $clean) {\n            $msg = \"Unreplaced Octopus Variables were found.\"\n            if ($TreatAsError) {\n                Write-Error $msg\n            } else {\n                Write-Warning $msg\n            }\n        }\n    }\n}\n\nif (-not $Path) { throw \"A Path must be specified\" }\nif (-not $Files) { throw \"At least one File must be specified\" }\n\n$spPaths = $Path -split \"`n\" | Foreach-Object { $_.Trim() } | Where-Object { -not [string]::IsNullOrEmpty($_) }\n$spFiles = $Files -split \";\" | Foreach-Object { $_.Trim() } \n$spExcludes = $Exclude -split \";\" | Foreach-Object { $_.Trim() } \n$bRecurse = $Recurse -eq 'True'\n$bTreatAsError = $TreatAsError -eq 'True'\n\n$spPaths | Find-Unreplaced -Files $spFiles -Exclude $spExcludes -Recurse:$bRecurse -TreatAsError:$bTreatAsError\n\n",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptSource": "Inline"
  },
  "Category": "Octopus",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/variables-find-unreplaced.json",
  "Website": "/step-templates/0b753c94-c12b-46f3-bb82-459e27bbe812",
  "Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAC1QTFRFT6Tl////L5Pg8vj9Y67omsvwPJrisdfzfbzs5fL7y+T32Ov5isLucLXqvt31CJPHWwAABMJJREFUeNrs3deW4jAMAFDF3U75/89dlp0ZhiU4blJEjvQ8hYubLJsA00UCBCIQgQhEIAIRiEAEIhCBCEQgAhGIQAQiEIEIhD8kJm+t+QprfdKfB9HbYpx6CWfspj8HMi+gMgHL/AmQA8W3JTKH+ALFvzCeL0RbpyoCPE9IJeNOSQwh5Z3qd6yRGWQ2qi2cZQWxqj1WzQYSjeoJmJlAklOd4VlArOqPhQEkqBERToeMcfRJBkC0Uep8CfBpjz4JsHJ0zF3dkEWNje0kiB/sUC6eApndaIiCMyAa1PiwJ0AWhRGJHJJQHG2dC7h1rNbO1QOxSA7lNCkkKrQIpJCAB1GREILYIC1NAiwbpKFJgGWDNExcwGstfExcZBCHC6nOglshHtmhViLIig1RNBCN7qjtW8C0Z1UvJcC1Z9XmwMBzzvobmgAyEzgq91dtEEsBsQSQQAFZCSBAATEEEApHZbrVBIkkEIUPSVeB+KtALA0kXQUSrwKZBCIQBnk8Y4i5CsReBeKvkqLM+BCSDWJlrZFvGk9SRTHshkgjZCGAaArIxm3H3grhVzFlW2msfl1ca79UJ1bofYvsDHHlNdTZnlh5MghuPd5NdBDUNZHyCkfktIh03XzALGRPlBDPac7qgWjHZzWcmF5zmmkhidMQ6boKiDXcDTUEaylZqCGJ0Vjvu/fLJtHqhSANEvqb2OYqkOUqEHuVMbJcZdZCGiPhKhC4yjqiIjEE7XThMp8fAWII3mY3kUIQD+AMKQTzPiBhgQ63HlT/KSvgtoi0dq5mCPah1UIE0eh3sT0NhOByvKeAkFzi8PgQomumFhsyOxpIzZN4gLOj5plVwNpR0b2AuePWKBEHQu24pSsJA+LVCeHHQxZ1SiyDIdqok8IOhSSnTottHEQTdyt4ettAj4KkzA4dMikk2Dht2S5ptm1vswnPDxn0YyDZ5oDM3iToo2T5voWaYe+Q+vdjH80QyAzZhCgcDtLMI1Tmtz9w++XHgziHQHJJu/OZ3bs9Xn8gQ72NcP3dKqEfkp10F51xhoIi2I91R+LurXV/5q7pH+wx061CzO16oSQleMyr8fXvwMA0Pro8432DPD/ySx8XrHfSuDAM8n6UhnjQabaiXf5Bq/lREHvEeNtn1rJ08+C/uXkQZHeguxAPC3UvtcJYUogLzZX5hhZZvS6onG5lxXtzWGaygwb79vT/IXhdlNibwlKYOR6T8xjI7W8n+xV7T+GH4tMzWwR+lZhRkJYSsC0thpmCYqyngOz3rN2FLBZ2wZflBCggUHF0Vnp88JKienzIXLSEZCZqU7IKr/gQW9yx3pzV7Y9kvWZWTRRIqDmTtRUnU7b2lLcTYmoqHqnmiO1poER0SPkAeZMAZxaJx0Y3TCdAclsIqDz03ALcyxfTCZBsthoGXWmigGyVhWPLFJJfuuKQWycoEFdXbH4dJJoJxNR1eD/kshz6yn48cF8yW8sFoitflB1w6Q8n+/15Za7oA17/pYNmYgP5fmWm8L1NOHPWgK8kuFew1/JXtOA0yJCv7ah7X8ObUuT5kObU30+fDZm8+zqP+HTIpK0xQ796b5Kv2hSIQAQiEIEIRCACEYhABCIQgQhEIAIRiEAEIpBf8UeAAQAEjtYmlDTcCgAAAABJRU5ErkJggg==",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Tuesday, September 14, 2021